@dbsp/adapter-pgsql 2.0.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1265 -945
- package/dist/index.js +2875 -232
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IndexInfo, TruncateOptions, VacuumOptions, AlterColumnOptions, CreateIndexOptions, DropIndexOptions, ExpressionRef, ModelIR as ModelIR$1 } from '@dbsp/core';
|
|
2
2
|
export { normalizeSQL } from '@dbsp/core';
|
|
3
3
|
import * as _dbsp_types from '@dbsp/types';
|
|
4
|
-
import { DialectCapabilities, ModelIR, ColumnListInput, ParamIntent, JsonAggOrderByEntry, IndexIR,
|
|
4
|
+
import { DialectCapabilities, ModelIR, ColumnListInput, ParamIntent, JsonAggOrderByEntry, IndexIR, HierarchyIR, Adapter, DbCasing, AdapterLogger, AdapterCapabilities, PlanReport, CompiledNqlQuery, CompileOptions, CompiledQuery, CompileResultWithIncludes, SubqueryIncludeInfo, ExpressionIntent, InsertIntent, InsertFromIntent, UpdateIntent, BatchUpdateIntent, DeleteIntent, UpsertIntent, UpsertFromIntent, RecursivePlanReport, CteQueryIntent, SetOperationIntent, DumpMeta, Dump, AdapterStreamOptions, CompileOnlyAdapter, ColumnIR, MutationReturningItem, WhereIntent, QueryIntent } from '@dbsp/types';
|
|
5
5
|
import * as _pgsql_types from '@pgsql/types';
|
|
6
6
|
import { Node, OnConflictClause, ParamRef } from '@pgsql/types';
|
|
7
7
|
import { Pool, PoolClient } from 'pg';
|
|
@@ -780,912 +780,168 @@ declare function generateCreateIndex(tableName: string, idx: IndexIR, schemaName
|
|
|
780
780
|
declare function canGenerateCreateIndex(tableName: string, idx: IndexIR, schemaName?: string | undefined, naming?: NamingPlugin): boolean;
|
|
781
781
|
|
|
782
782
|
/**
|
|
783
|
-
* Schema
|
|
783
|
+
* PostgreSQL Schema Introspection (ADAPTER-006)
|
|
784
784
|
*
|
|
785
|
-
*
|
|
786
|
-
*
|
|
785
|
+
* Queries information_schema/pg_catalog to build ModelIR
|
|
786
|
+
* from an existing database. Supports:
|
|
787
|
+
* - Table/column/PK discovery
|
|
788
|
+
* - FK → bidirectional relation inference
|
|
789
|
+
* - Hierarchy detection (adjacency + edge-table)
|
|
790
|
+
* - Include/exclude filtering
|
|
787
791
|
*
|
|
788
|
-
* @module
|
|
792
|
+
* @module introspection
|
|
789
793
|
*/
|
|
790
794
|
|
|
791
|
-
|
|
792
|
-
interface
|
|
793
|
-
|
|
794
|
-
readonly
|
|
795
|
-
readonly column?: string;
|
|
796
|
-
readonly destructive: boolean;
|
|
797
|
-
readonly details: string;
|
|
798
|
-
/** Additional metadata for SQL generation */
|
|
799
|
-
readonly meta?: Readonly<Record<string, unknown>>;
|
|
800
|
-
}
|
|
801
|
-
interface DiffSummary {
|
|
802
|
-
readonly tables: {
|
|
803
|
-
readonly added: number;
|
|
804
|
-
readonly dropped: number;
|
|
805
|
-
};
|
|
806
|
-
readonly columns: {
|
|
807
|
-
readonly added: number;
|
|
808
|
-
readonly dropped: number;
|
|
809
|
-
readonly altered: number;
|
|
810
|
-
};
|
|
811
|
-
readonly indexes: {
|
|
812
|
-
readonly added: number;
|
|
813
|
-
readonly dropped: number;
|
|
814
|
-
};
|
|
815
|
-
readonly constraints: {
|
|
816
|
-
readonly added: number;
|
|
817
|
-
readonly dropped: number;
|
|
818
|
-
readonly altered: number;
|
|
819
|
-
};
|
|
820
|
-
}
|
|
821
|
-
interface SchemaDiff {
|
|
822
|
-
readonly changes: readonly SchemaChange[];
|
|
823
|
-
readonly hasDestructive: boolean;
|
|
824
|
-
readonly summary: DiffSummary;
|
|
825
|
-
}
|
|
826
|
-
interface CompareSchemataOptions {
|
|
827
|
-
/**
|
|
828
|
-
* Database naming convention.
|
|
829
|
-
* When set, schema model names (camelCase) are converted to DB format
|
|
830
|
-
* (e.g. snake_case) before comparison with the introspected model.
|
|
831
|
-
*/
|
|
832
|
-
dbCasing?: DbCasing;
|
|
833
|
-
/** Dialect capabilities — comparisons for unsupported features will be skipped */
|
|
834
|
-
readonly dialectCapabilities?: DialectCapabilities;
|
|
835
|
-
/**
|
|
836
|
-
* When `true`, extensions present in the live DB but absent from the model
|
|
837
|
-
* schema are silently ignored — no `drop_extension` change is emitted for them.
|
|
838
|
-
* Only extensions explicitly declared in the model are managed (created if missing).
|
|
839
|
-
*
|
|
840
|
-
* Use this when the database image pre-installs extensions that the application
|
|
841
|
-
* schema does not own (e.g. pgvector, pg_search bundled in a custom Postgres image).
|
|
842
|
-
* Default: `false` (full-sync behaviour — unmanaged DB extensions produce a
|
|
843
|
-
* `drop_extension` entry).
|
|
844
|
-
*/
|
|
845
|
-
readonly ignoreUnmanagedExtensions?: boolean;
|
|
795
|
+
/** The minimum every schema-level operation needs: which schema. */
|
|
796
|
+
interface SchemaScopeOptions {
|
|
797
|
+
/** Schema name to operate on (default: 'public') */
|
|
798
|
+
readonly schema?: string;
|
|
846
799
|
}
|
|
847
800
|
/**
|
|
848
|
-
*
|
|
849
|
-
*
|
|
850
|
-
*
|
|
851
|
-
* @param db - The current database state (from introspection)
|
|
852
|
-
* @param options - Optional comparison settings (e.g. dbCasing)
|
|
853
|
-
* @returns SchemaDiff with all changes needed to bring DB in sync with schema
|
|
801
|
+
* Introspection additionally chooses WHICH TABLES to read. It is a read-only
|
|
802
|
+
* path, so narrowing it is safe — that is why the table filters live here and
|
|
803
|
+
* nowhere else.
|
|
854
804
|
*/
|
|
855
|
-
|
|
856
|
-
|
|
805
|
+
interface IntrospectionOptions extends SchemaScopeOptions {
|
|
806
|
+
/** Tables to exclude (glob patterns: * matches any chars) */
|
|
807
|
+
readonly exclude?: readonly string[];
|
|
808
|
+
/** Tables to include (default: all). Applied before exclude. */
|
|
809
|
+
readonly include?: readonly string[];
|
|
810
|
+
}
|
|
811
|
+
/** Hierarchy pattern detected during introspection */
|
|
857
812
|
/**
|
|
858
|
-
*
|
|
859
|
-
*
|
|
860
|
-
*
|
|
861
|
-
* Statements are topologically sorted: DROP constraints → DROP objects → CREATE objects → ADD constraints.
|
|
862
|
-
*
|
|
863
|
-
* @module migration-sql
|
|
813
|
+
* Hierarchy pattern detected during introspection.
|
|
814
|
+
* Alias of {@link HierarchyIR} from \@dbsp/types — kept here for
|
|
815
|
+
* public-API backwards compatibility (re-exported from \@dbsp/adapter-pgsql).
|
|
864
816
|
*/
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
*/
|
|
872
|
-
readonly schemaName?: string;
|
|
873
|
-
/** Whether to include destructive changes (drops) */
|
|
874
|
-
readonly includeDestructive?: boolean;
|
|
875
|
-
/** Automatically create indexes on FK columns for new tables (default: true) */
|
|
876
|
-
readonly fkAutoIndex?: boolean;
|
|
877
|
-
/** Dialect capabilities — migration SQL for unsupported features will be filtered */
|
|
878
|
-
readonly dialectCapabilities?: DialectCapabilities;
|
|
817
|
+
type DetectedHierarchy = HierarchyIR;
|
|
818
|
+
/** Extended ModelIR with hierarchy metadata */
|
|
819
|
+
interface IntrospectedModelIR extends ModelIR {
|
|
820
|
+
readonly hierarchies: readonly DetectedHierarchy[];
|
|
821
|
+
readonly introspectedAt: Date;
|
|
822
|
+
readonly warnings: readonly string[];
|
|
879
823
|
}
|
|
880
824
|
/**
|
|
881
|
-
*
|
|
825
|
+
* Introspect a database through a pool.
|
|
882
826
|
*
|
|
883
|
-
*
|
|
884
|
-
*
|
|
885
|
-
*
|
|
886
|
-
*
|
|
887
|
-
*
|
|
888
|
-
*
|
|
889
|
-
*
|
|
890
|
-
* 6. CREATE tables
|
|
891
|
-
* 7. ADD columns
|
|
892
|
-
* 8. ALTER columns (type, nullable, default)
|
|
893
|
-
* 9. ADD primary keys / column UNIQUE constraints
|
|
894
|
-
* 10. ADD FK constraints (must add after referenced tables exist)
|
|
895
|
-
* 11. ALTER FK (drop + re-add)
|
|
896
|
-
* 12. CREATE indexes
|
|
897
|
-
* 13. ADD CHECK constraints
|
|
898
|
-
* 14. ALTER ENUM ADD VALUE (must be last — has transaction visibility caveats in PG)
|
|
899
|
-
* 15. COMMENT ON TABLE / COLUMN (very last)
|
|
900
|
-
*/
|
|
901
|
-
declare function generateMigrationSQL(diff: SchemaDiff, options?: MigrationSQLOptions): readonly string[];
|
|
902
|
-
/**
|
|
903
|
-
* Generate ordered DOWN SQL statements from a SchemaDiff.
|
|
827
|
+
* This does NOT accept a checked-out `PoolClient`, and that is deliberate. A
|
|
828
|
+
* client may be sitting inside a transaction that belongs to its owner, and a
|
|
829
|
+
* catalog query that fails there aborts *their* transaction. Protecting that
|
|
830
|
+
* needs a savepoint, and knowing whether to take one needs the caller to say
|
|
831
|
+
* whose transaction it is — which is what `PgsqlAdapter`'s `borrowedClient`
|
|
832
|
+
* declaration is for. Guessing it from the object's shape is the exact defect
|
|
833
|
+
* this adapter was rewritten to remove.
|
|
904
834
|
*
|
|
905
|
-
*
|
|
906
|
-
*
|
|
835
|
+
* Saying so in a comment is not enough: `CatalogQueryExecutor` is structural, so
|
|
836
|
+
* a `PoolClient` — which has a `query()` — satisfies it, and the prose would have
|
|
837
|
+
* been the only thing standing in the way. It is branded instead, and only the
|
|
838
|
+
* adapter's own protected executor carries the brand. A client cannot be passed
|
|
839
|
+
* here at all.
|
|
907
840
|
*
|
|
908
|
-
*
|
|
841
|
+
* So: hold a client, use `new PgsqlAdapter(client, { borrowedClient: true })`
|
|
842
|
+
* and call `.introspect()` on it.
|
|
909
843
|
*/
|
|
910
|
-
declare function
|
|
844
|
+
declare function introspect(pool: Pool, options?: IntrospectionOptions): Promise<IntrospectedModelIR>;
|
|
911
845
|
|
|
912
846
|
/**
|
|
913
|
-
*
|
|
914
|
-
*
|
|
915
|
-
* File format:
|
|
916
|
-
* -- dbsp:destructive: true|false
|
|
917
|
-
* <UP statements>;
|
|
918
|
-
* -- DOWN
|
|
919
|
-
* <DOWN statements>;
|
|
847
|
+
* PgsqlAdapter - Implements the Adapter interface for PostgreSQL using native pg driver.
|
|
920
848
|
*
|
|
921
|
-
*
|
|
849
|
+
* This adapter wraps a pg Pool instance and provides the unified
|
|
850
|
+
* adapter interface for the db-semantic-planner ORM.
|
|
922
851
|
*
|
|
923
|
-
* @module
|
|
852
|
+
* @module pgsql-adapter
|
|
924
853
|
*/
|
|
925
854
|
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
interface ParsedMigrationFile {
|
|
930
|
-
readonly upStatements: readonly string[];
|
|
931
|
-
readonly downStatements: readonly string[];
|
|
932
|
-
readonly hasDown: boolean;
|
|
933
|
-
readonly destructive?: boolean | undefined;
|
|
855
|
+
declare class PgsqlRawSqlTransactionControlError extends Error {
|
|
856
|
+
readonly dbspRawSqlTransactionControl = true;
|
|
857
|
+
constructor(cause: unknown);
|
|
934
858
|
}
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
* Parse a migration file into UP and DOWN sections.
|
|
943
|
-
* Separator: `^\s*-- DOWN\s*$` (strict regex, own line only — SC-25)
|
|
944
|
-
*/
|
|
945
|
-
declare function parseMigrationFile(content: string): ParsedMigrationFile;
|
|
946
|
-
/**
|
|
947
|
-
* Check if SQL statements contain destructive operations.
|
|
948
|
-
* Destructive: DROP TABLE, DROP COLUMN, lossy ALTER COLUMN TYPE
|
|
949
|
-
*/
|
|
950
|
-
declare function isDestructiveDown(downStatements: readonly string[]): boolean;
|
|
951
|
-
|
|
952
|
-
/**
|
|
953
|
-
* Migration Tracker — `_dbsp_migrations` table CRUD.
|
|
954
|
-
*
|
|
955
|
-
* Manages the tracking table that records which migrations
|
|
956
|
-
* have been applied to a database.
|
|
957
|
-
*/
|
|
958
|
-
|
|
959
|
-
interface MigrationRecord {
|
|
960
|
-
/** Migration filename (e.g., "0001_create_users.sql") */
|
|
961
|
-
readonly name: string;
|
|
962
|
-
/** SHA-256 checksum of the migration file content */
|
|
963
|
-
readonly checksum: string;
|
|
964
|
-
/** When the migration was applied */
|
|
965
|
-
readonly appliedAt: Date;
|
|
966
|
-
/** Schema version at time of this migration */
|
|
967
|
-
readonly schemaVersion: number;
|
|
968
|
-
/** Whether this migration contains destructive changes */
|
|
969
|
-
readonly destructive: boolean;
|
|
859
|
+
declare class PgsqlTransactionAbortedCommitError extends Error {
|
|
860
|
+
readonly dbspTransactionAbortedCommit = true;
|
|
861
|
+
constructor(cause: unknown);
|
|
862
|
+
}
|
|
863
|
+
declare class PgsqlTransactionAbortedError extends Error {
|
|
864
|
+
readonly dbspTransactionAborted = true;
|
|
865
|
+
constructor(cause: unknown);
|
|
970
866
|
}
|
|
971
867
|
/**
|
|
972
|
-
*
|
|
973
|
-
* The lock is held for the duration of the callback.
|
|
974
|
-
* The client is released (and lock freed) after the callback completes.
|
|
975
|
-
*/
|
|
976
|
-
declare function withMigrationLock<T>(pool: Pool, fn: (client: PoolClient) => Promise<T>): Promise<T>;
|
|
977
|
-
/**
|
|
978
|
-
* Ensure the migrations tracking table exists.
|
|
979
|
-
* Auto-migrates existing tables that lack `schema_version`/`destructive` columns,
|
|
980
|
-
* and backfills `schema_version` by `applied_at` order for rows still at 0.
|
|
981
|
-
*/
|
|
982
|
-
declare function ensureMigrationsTable(pool: Pool): Promise<void>;
|
|
983
|
-
/**
|
|
984
|
-
* Get all applied migrations, ordered by name.
|
|
985
|
-
*/
|
|
986
|
-
declare function getAppliedMigrations(pool: Pool): Promise<readonly MigrationRecord[]>;
|
|
987
|
-
/**
|
|
988
|
-
* Record a migration as applied.
|
|
989
|
-
*/
|
|
990
|
-
declare function recordMigration(pool: Pool, name: string, checksum: string, schemaVersion: number, destructive: boolean): Promise<void>;
|
|
991
|
-
/**
|
|
992
|
-
* Check if a specific migration has been applied.
|
|
993
|
-
*/
|
|
994
|
-
declare function isMigrationApplied(pool: Pool, name: string): Promise<boolean>;
|
|
995
|
-
/**
|
|
996
|
-
* Get the next schema version number (max + 1, or 1 if no migrations).
|
|
997
|
-
*/
|
|
998
|
-
declare function getNextSchemaVersion(pool: Pool): Promise<number>;
|
|
999
|
-
/**
|
|
1000
|
-
* Remove a migration record (for rollback).
|
|
868
|
+
* Options for PgsqlAdapter.
|
|
1001
869
|
*/
|
|
1002
|
-
|
|
1003
|
-
|
|
870
|
+
interface PgsqlAdapterOptions {
|
|
871
|
+
/** Schema name for multi-tenant queries */
|
|
872
|
+
readonly schemaName?: string;
|
|
873
|
+
/**
|
|
874
|
+
* DB column casing convention (intuitive semantics).
|
|
875
|
+
* - `'snake_case'`: DB columns are snake_case → transform to camelCase for JS
|
|
876
|
+
* - `'camelCase'`: DB columns are camelCase → no transformation
|
|
877
|
+
* - `'preserve'`: No transformation
|
|
878
|
+
*/
|
|
879
|
+
readonly dbCasing?: DbCasing;
|
|
880
|
+
/** Optional model for WHERE compilation */
|
|
881
|
+
readonly model?: ModelIR;
|
|
882
|
+
/** Optional logger for debug/error messages */
|
|
883
|
+
readonly logger?: AdapterLogger;
|
|
884
|
+
/** Default primary key column name for convention fallbacks (default: 'id') */
|
|
885
|
+
readonly defaultPkColumnName?: string;
|
|
886
|
+
/** Convention for deriving FK column names: (tableName, pkName) => fkColumnName */
|
|
887
|
+
readonly deriveFkColumnName?: FkColumnDerivation;
|
|
888
|
+
}
|
|
889
|
+
interface PgsqlPoolAdapterOptions extends PgsqlAdapterOptions {
|
|
890
|
+
readonly borrowedClient?: false;
|
|
891
|
+
}
|
|
892
|
+
interface PgsqlBorrowedClientAdapterOptions extends PgsqlAdapterOptions {
|
|
893
|
+
/** This connection belongs to the caller. dbsp never releases it. */
|
|
894
|
+
readonly borrowedClient: true;
|
|
895
|
+
/**
|
|
896
|
+
* Let dbsp run transactions on your connection, through a savepoint.
|
|
897
|
+
*
|
|
898
|
+
* When your connection is already inside a transaction, dbsp creates a
|
|
899
|
+
* savepoint and rolls back dbsp's changes after that savepoint if the callback
|
|
900
|
+
* fails. `RELEASE SAVEPOINT` does not commit; it merges the work into your
|
|
901
|
+
* surrounding transaction, so a callback that succeeded is still undone if you
|
|
902
|
+
* later roll back. Deferred constraints or triggers can still make your outer
|
|
903
|
+
* `COMMIT` fail after dbsp has returned. `SET LOCAL` changes inside the callback
|
|
904
|
+
* remain in effect for the rest of your transaction after the savepoint is
|
|
905
|
+
* released. `ON COMMIT DROP` and `ON COMMIT DELETE ROWS` fire at your transaction
|
|
906
|
+
* boundary, not at the savepoint. Sequences are not transactional:
|
|
907
|
+
* `nextval`/`setval` are not reclaimed by a savepoint rollback. Session-level
|
|
908
|
+
* advisory locks ignore rollback; transaction-level advisory locks taken by a
|
|
909
|
+
* successful callback last until your transaction ends.
|
|
910
|
+
*
|
|
911
|
+
* Transaction control through raw SQL inside a scope dbsp is managing is
|
|
912
|
+
* unsupported. `COMMIT`, `ROLLBACK`, and `PREPARE TRANSACTION` end the
|
|
913
|
+
* transaction dbsp is working inside; dbsp detects that and fails loudly, but
|
|
914
|
+
* the data is already whatever your statement made it. Raw savepoint control
|
|
915
|
+
* (`SAVEPOINT`, `RELEASE SAVEPOINT`, `ROLLBACK TO SAVEPOINT`) can alter the
|
|
916
|
+
* savepoint stack before dbsp sees the command tag; dbsp poisons the scope, but
|
|
917
|
+
* it cannot make that command un-run. Manage your transaction outside dbsp's
|
|
918
|
+
* calls.
|
|
919
|
+
*/
|
|
920
|
+
readonly managedTransactions?: true;
|
|
921
|
+
}
|
|
1004
922
|
/**
|
|
1005
|
-
*
|
|
923
|
+
* Adapter implementation for PostgreSQL using native pg driver.
|
|
1006
924
|
*
|
|
1007
|
-
*
|
|
1008
|
-
* Handles auto-increment via SERIAL/BIGSERIAL types.
|
|
1009
|
-
*
|
|
1010
|
-
* @module ddl/type-mapping
|
|
1011
|
-
*/
|
|
1012
|
-
|
|
1013
|
-
/**
|
|
1014
|
-
* Map ColumnType to PostgreSQL data type string.
|
|
1015
|
-
*
|
|
1016
|
-
* Uses originalDbType if available (from introspection), otherwise
|
|
1017
|
-
* falls back to reasonable PostgreSQL defaults.
|
|
1018
|
-
*
|
|
1019
|
-
* @param col - Column definition from ModelIR
|
|
1020
|
-
* @returns PostgreSQL type string (e.g., 'VARCHAR(255)', 'SERIAL', 'JSONB')
|
|
1021
|
-
*/
|
|
1022
|
-
declare function mapColumnType(col: ColumnIR, targetSchema?: string): string;
|
|
1023
|
-
/**
|
|
1024
|
-
* Map OnDeleteAction to PostgreSQL syntax.
|
|
1025
|
-
*/
|
|
1026
|
-
declare function mapOnDeleteAction(action?: string): string;
|
|
1027
|
-
|
|
1028
|
-
/**
|
|
1029
|
-
* EXPLAIN Statement Compiler
|
|
1030
|
-
*
|
|
1031
|
-
* Generates PostgreSQL EXPLAIN statements with various options.
|
|
1032
|
-
* Supports:
|
|
1033
|
-
* - ANALYZE (execute and show actual run times)
|
|
1034
|
-
* - FORMAT (text, json, xml, yaml)
|
|
1035
|
-
* - VERBOSE, COSTS, BUFFERS, TIMING, SETTINGS
|
|
1036
|
-
*/
|
|
1037
|
-
|
|
1038
|
-
/**
|
|
1039
|
-
* Output format for EXPLAIN results.
|
|
1040
|
-
*/
|
|
1041
|
-
type ExplainFormat = 'text' | 'json' | 'xml' | 'yaml';
|
|
1042
|
-
/**
|
|
1043
|
-
* Options for EXPLAIN statement.
|
|
1044
|
-
*/
|
|
1045
|
-
interface ExplainOptions {
|
|
1046
|
-
/** Execute the query and show actual run times */
|
|
1047
|
-
analyze?: boolean;
|
|
1048
|
-
/** Show more detailed output */
|
|
1049
|
-
verbose?: boolean;
|
|
1050
|
-
/** Show cost estimates (default: true) */
|
|
1051
|
-
costs?: boolean;
|
|
1052
|
-
/** Show buffer usage (requires analyze) */
|
|
1053
|
-
buffers?: boolean;
|
|
1054
|
-
/** Show actual timing (requires analyze) */
|
|
1055
|
-
timing?: boolean;
|
|
1056
|
-
/** Show non-default settings */
|
|
1057
|
-
settings?: boolean;
|
|
1058
|
-
/** Output format */
|
|
1059
|
-
format?: ExplainFormat;
|
|
1060
|
-
}
|
|
1061
|
-
/**
|
|
1062
|
-
* Build an EXPLAIN statement wrapping a query.
|
|
1063
|
-
*
|
|
1064
|
-
* @param query - The query to explain (SelectStmt, InsertStmt, etc.)
|
|
1065
|
-
* @param options - EXPLAIN options
|
|
1066
|
-
* @returns ExplainStmt AST node
|
|
925
|
+
* @typeParam DB - Database schema type
|
|
1067
926
|
*
|
|
1068
927
|
* @example
|
|
1069
928
|
* ```typescript
|
|
1070
|
-
*
|
|
1071
|
-
*
|
|
1072
|
-
* // Produces: EXPLAIN (ANALYZE, FORMAT JSON) SELECT ...
|
|
1073
|
-
* ```
|
|
1074
|
-
*/
|
|
1075
|
-
declare function buildExplain(query: Node, options?: ExplainOptions): Node;
|
|
1076
|
-
/**
|
|
1077
|
-
* Build EXPLAIN ANALYZE with JSON format (common pattern).
|
|
1078
|
-
*
|
|
1079
|
-
* @param query - The query to explain
|
|
1080
|
-
* @returns ExplainStmt with ANALYZE and JSON format
|
|
1081
|
-
*/
|
|
1082
|
-
declare function buildExplainAnalyzeJson(query: Node): Node;
|
|
1083
|
-
/**
|
|
1084
|
-
* Build simple EXPLAIN (plan only, no execution).
|
|
1085
|
-
*
|
|
1086
|
-
* @param query - The query to explain
|
|
1087
|
-
* @returns ExplainStmt with default options
|
|
1088
|
-
*/
|
|
1089
|
-
declare function buildExplainPlan(query: Node): Node;
|
|
1090
|
-
/**
|
|
1091
|
-
* Build verbose EXPLAIN with costs and buffers.
|
|
1092
|
-
*
|
|
1093
|
-
* @param query - The query to explain
|
|
1094
|
-
* @returns ExplainStmt with verbose options
|
|
1095
|
-
*/
|
|
1096
|
-
declare function buildExplainVerbose(query: Node): Node;
|
|
1097
|
-
/**
|
|
1098
|
-
* Parse EXPLAIN JSON output to get execution statistics.
|
|
1099
|
-
*
|
|
1100
|
-
* @param jsonOutput - The JSON string from EXPLAIN (ANALYZE, FORMAT JSON)
|
|
1101
|
-
* @returns Parsed plan with execution statistics
|
|
1102
|
-
*/
|
|
1103
|
-
declare function parseExplainJson(jsonOutput: string): ExplainPlan[];
|
|
1104
|
-
/**
|
|
1105
|
-
* Parsed EXPLAIN plan structure (simplified).
|
|
1106
|
-
*/
|
|
1107
|
-
interface ExplainPlan {
|
|
1108
|
-
Plan: {
|
|
1109
|
-
'Node Type': string;
|
|
1110
|
-
'Relation Name'?: string;
|
|
1111
|
-
Alias?: string;
|
|
1112
|
-
'Startup Cost'?: number;
|
|
1113
|
-
'Total Cost'?: number;
|
|
1114
|
-
'Plan Rows'?: number;
|
|
1115
|
-
'Plan Width'?: number;
|
|
1116
|
-
'Actual Startup Time'?: number;
|
|
1117
|
-
'Actual Total Time'?: number;
|
|
1118
|
-
'Actual Rows'?: number;
|
|
1119
|
-
'Actual Loops'?: number;
|
|
1120
|
-
Plans?: ExplainPlan['Plan'][];
|
|
1121
|
-
};
|
|
1122
|
-
'Planning Time'?: number;
|
|
1123
|
-
'Execution Time'?: number;
|
|
1124
|
-
Triggers?: unknown[];
|
|
1125
|
-
}
|
|
1126
|
-
/**
|
|
1127
|
-
* Extract total execution time from EXPLAIN ANALYZE JSON output.
|
|
1128
|
-
*
|
|
1129
|
-
* @param plans - Parsed EXPLAIN plans
|
|
1130
|
-
* @returns Total execution time in milliseconds
|
|
1131
|
-
*/
|
|
1132
|
-
declare function getTotalExecutionTime(plans: ExplainPlan[]): number;
|
|
1133
|
-
/**
|
|
1134
|
-
* Extract row counts from EXPLAIN ANALYZE JSON output.
|
|
1135
|
-
*
|
|
1136
|
-
* @param plans - Parsed EXPLAIN plans
|
|
1137
|
-
* @returns Object with estimated and actual row counts
|
|
1138
|
-
*/
|
|
1139
|
-
declare function getRowEstimates(plans: ExplainPlan[]): {
|
|
1140
|
-
estimated: number;
|
|
1141
|
-
actual: number;
|
|
1142
|
-
};
|
|
1143
|
-
|
|
1144
|
-
/**
|
|
1145
|
-
* ParadeDB Extension Wrappers
|
|
1146
|
-
*
|
|
1147
|
-
* Type-safe query builders for ParadeDB BM25 full-text search.
|
|
1148
|
-
* All functions return ExpressionRef instances that can be used in:
|
|
1149
|
-
* - SELECT: .column(score('id').as('score'))
|
|
1150
|
-
* - WHERE: .where(bm25Search('symbols', query, { name: 3.0, doc: 1.0 }))
|
|
1151
|
-
* - ORDER BY: .orderBy(score('id'), 'desc')
|
|
1152
|
-
*
|
|
1153
|
-
* @remarks
|
|
1154
|
-
* ParadeDB functions accept both named and positional arguments.
|
|
1155
|
-
* This module uses named args via namedArg() for parse(), which produces:
|
|
1156
|
-
* paradedb.parse(field => 'field_name', query_string => $1)
|
|
1157
|
-
* Named parameter syntax is supported via the NamedArgExpressionIntent (EXT-NAMED-PARAMS).
|
|
1158
|
-
*/
|
|
1159
|
-
|
|
1160
|
-
/**
|
|
1161
|
-
* BM25 relevance score for a row.
|
|
1162
|
-
*
|
|
1163
|
-
* Use in SELECT and ORDER BY to retrieve and sort by full-text relevance.
|
|
1164
|
-
* Requires a BM25 index on the table.
|
|
1165
|
-
*
|
|
1166
|
-
* @param keyField - The key field of the BM25 index (typically the primary key, e.g. 'id')
|
|
1167
|
-
* @returns ExpressionRef that compiles to: paradedb.score("keyField")
|
|
1168
|
-
*
|
|
1169
|
-
* @example
|
|
1170
|
-
* orm.select('symbols').column(score('id').as('score')).orderBy(score('id'), 'desc')
|
|
1171
|
-
* // → paradedb.score("id") AS "score"
|
|
1172
|
-
*/
|
|
1173
|
-
declare function score(keyField: string): ExpressionRef;
|
|
1174
|
-
/**
|
|
1175
|
-
* Parse a single-field BM25 query expression.
|
|
1176
|
-
*
|
|
1177
|
-
* Compiles to: paradedb.parse(field => 'field_name', query_string => $N)
|
|
1178
|
-
*
|
|
1179
|
-
* @param field - Column name to search in (must be indexed in the BM25 index)
|
|
1180
|
-
* @param query - Query string value (will be bound as a parameter)
|
|
1181
|
-
* @returns ExpressionRef for use with boost() or booleanSearch()
|
|
1182
|
-
*
|
|
1183
|
-
* @example
|
|
1184
|
-
* parse('name', 'hello world')
|
|
1185
|
-
* // → paradedb.parse(field => 'name', query_string => $1)
|
|
1186
|
-
*/
|
|
1187
|
-
declare function parse(field: string, query: ExpressionRef | unknown): ExpressionRef;
|
|
1188
|
-
/**
|
|
1189
|
-
* Apply a boost multiplier to a BM25 sub-expression.
|
|
1190
|
-
*
|
|
1191
|
-
* Compiles to: paradedb.boost(factor, expr)
|
|
1192
|
-
*
|
|
1193
|
-
* @param factor - Boost multiplier (e.g. 3.0 for 3x weight)
|
|
1194
|
-
* @param expr - Expression to boost (typically a parse() call)
|
|
1195
|
-
* @returns ExpressionRef for use with booleanSearch()
|
|
1196
|
-
*
|
|
1197
|
-
* @example
|
|
1198
|
-
* boost(3.0, parse('name', 'hello'))
|
|
1199
|
-
* // → paradedb.boost(3.0, paradedb.parse('name', $1))
|
|
1200
|
-
*/
|
|
1201
|
-
declare function boost(factor: number, expr: ExpressionRef): ExpressionRef;
|
|
1202
|
-
/**
|
|
1203
|
-
* Combine multiple BM25 sub-expressions with boolean OR logic.
|
|
1204
|
-
*
|
|
1205
|
-
* Compiles to: paradedb.boolean(expr1, expr2, ...)
|
|
1206
|
-
*
|
|
1207
|
-
* @param exprs - One or more sub-expressions (typically boost() calls)
|
|
1208
|
-
* @returns ExpressionRef for use on the right side of the @@@ operator
|
|
1209
|
-
*
|
|
1210
|
-
* @example
|
|
1211
|
-
* booleanSearch([boost(3.0, parse('name', q)), boost(1.0, parse('doc', q))])
|
|
1212
|
-
* // → paradedb.boolean(paradedb.boost(3.0, ...), paradedb.boost(1.0, ...))
|
|
1213
|
-
*/
|
|
1214
|
-
/**
|
|
1215
|
-
* Combine multiple BM25 sub-expressions with boolean OR logic.
|
|
1216
|
-
*
|
|
1217
|
-
* Compiles to: paradedb.boolean(should => ARRAY[expr1, expr2, ...])
|
|
1218
|
-
*
|
|
1219
|
-
* @param exprs - One or more sub-expressions (typically boost() calls)
|
|
1220
|
-
* @returns ExpressionRef for use on the right side of the @@@ operator
|
|
1221
|
-
*
|
|
1222
|
-
* @example
|
|
1223
|
-
* booleanSearch([boost(3.0, parse('name', q)), boost(1.0, parse('doc', q))])
|
|
1224
|
-
* // → paradedb.boolean(should => ARRAY[paradedb.boost(3.0, ...), paradedb.boost(1.0, ...)])
|
|
1225
|
-
*/
|
|
1226
|
-
declare function booleanSearch(exprs: ExpressionRef[]): ExpressionRef;
|
|
1227
|
-
/**
|
|
1228
|
-
* Full BM25 multi-field search with per-field boost weights.
|
|
1229
|
-
*
|
|
1230
|
-
* Produces: table @@@ paradedb.boolean(boost1, boost2, ...)
|
|
1231
|
-
*
|
|
1232
|
-
* Each field in `fieldBoosts` generates a `paradedb.boost(weight, paradedb.parse(field, $N))`
|
|
1233
|
-
* sub-expression. The same query string is used for all fields (single parameter binding).
|
|
1234
|
-
*
|
|
1235
|
-
* @param table - Table alias for the left side of the @@@ operator
|
|
1236
|
-
* @param query - Query string (bound as a single $N parameter, shared across all fields)
|
|
1237
|
-
* @param fieldBoosts - Map of column name → boost weight
|
|
1238
|
-
* @returns ExpressionRef for use in .where()
|
|
1239
|
-
*
|
|
1240
|
-
* @example
|
|
1241
|
-
* bm25Search('s', searchTerm, {
|
|
1242
|
-
* name_searchable: 3.0,
|
|
1243
|
-
* name: 1.0,
|
|
1244
|
-
* signature: 1.5,
|
|
1245
|
-
* doc_searchable: 1.0,
|
|
1246
|
-
* })
|
|
1247
|
-
* // → s @@@ paradedb.boolean(
|
|
1248
|
-
* // paradedb.boost(3.0, paradedb.parse('name_searchable', $1)),
|
|
1249
|
-
* // paradedb.boost(1.0, paradedb.parse('name', $1)),
|
|
1250
|
-
* // paradedb.boost(1.5, paradedb.parse('signature', $1)),
|
|
1251
|
-
* // paradedb.boost(1.0, paradedb.parse('doc_searchable', $1))
|
|
1252
|
-
* // )
|
|
1253
|
-
*
|
|
1254
|
-
* @remarks
|
|
1255
|
-
* The query parameter is shared: all parse() calls reference the same $N slot.
|
|
1256
|
-
* If you need different query strings per field, compose parse()/boost()/booleanSearch() manually.
|
|
929
|
+
* import { Pool } from 'pg';
|
|
930
|
+
* import { createPgsqlAdapter } from '@dbsp/adapter-pgsql';
|
|
1257
931
|
*
|
|
1258
|
-
*
|
|
1259
|
-
*
|
|
1260
|
-
*
|
|
1261
|
-
*
|
|
1262
|
-
*/
|
|
1263
|
-
declare function bm25Search(table: string, query: unknown, fieldBoosts: Record<string, number>): ExpressionRef;
|
|
1264
|
-
|
|
1265
|
-
/**
|
|
1266
|
-
* PostgreSQL built-in function helpers.
|
|
1267
|
-
*
|
|
1268
|
-
* Thin wrappers around core expression primitives for common PostgreSQL functions.
|
|
1269
|
-
* Same pattern as pgvector.ts and paradedb.ts.
|
|
1270
|
-
*/
|
|
1271
|
-
|
|
1272
|
-
/**
|
|
1273
|
-
* Generate a series of values: generate_series(start, stop[, step])
|
|
1274
|
-
*
|
|
1275
|
-
* Returns a set of values from start to stop (inclusive), with an optional step.
|
|
1276
|
-
* Commonly used with CTE for batch operations.
|
|
1277
|
-
*
|
|
1278
|
-
* @example generateSeries(1, 100) → generate_series(1, 100)
|
|
1279
|
-
* @example generateSeries(0, 50, 5) → generate_series(0, 50, 5)
|
|
1280
|
-
*/
|
|
1281
|
-
declare function generateSeries(start: number, stop: number, step?: number): ExpressionRef;
|
|
1282
|
-
/**
|
|
1283
|
-
* Get next value from a sequence: nextval('sequence_name')
|
|
1284
|
-
*
|
|
1285
|
-
* @example nextval('order_id_seq') → nextval('order_id_seq')
|
|
1286
|
-
*/
|
|
1287
|
-
declare function nextval(sequenceName: string): ExpressionRef;
|
|
1288
|
-
|
|
1289
|
-
/**
|
|
1290
|
-
* pgvector Extension Wrappers
|
|
1291
|
-
*
|
|
1292
|
-
* Type-safe query builders for pgvector distance operators.
|
|
1293
|
-
* All functions return ExpressionRef instances that can be used in:
|
|
1294
|
-
* - SELECT: .column(cosineDistance('vector', qv).as('score'))
|
|
1295
|
-
* - WHERE: .where(cosineDistance('vector', qv).gte(0.5))
|
|
1296
|
-
* - ORDER BY: .orderBy(rawDistance('vector', qv), 'asc')
|
|
1297
|
-
*/
|
|
1298
|
-
|
|
1299
|
-
/**
|
|
1300
|
-
* Cosine similarity: 1 - (col <=> vector)
|
|
1301
|
-
*
|
|
1302
|
-
* Score in [0, 1], higher = more similar.
|
|
1303
|
-
* Use in SELECT to get a similarity score.
|
|
1304
|
-
*
|
|
1305
|
-
* @example
|
|
1306
|
-
* orm.select('embeddings').column(cosineDistance('vector', qv).as('score'))
|
|
1307
|
-
*/
|
|
1308
|
-
declare function cosineDistance(column: string, vector: number[]): ExpressionRef;
|
|
1309
|
-
/**
|
|
1310
|
-
* Raw cosine distance: col <=> vector
|
|
1311
|
-
*
|
|
1312
|
-
* Lower = closer. Index-friendly — use in ORDER BY for ANN search.
|
|
1313
|
-
* Do NOT use in SELECT as a similarity score (lower = closer is counterintuitive).
|
|
1314
|
-
*
|
|
1315
|
-
* @example
|
|
1316
|
-
* orm.select('embeddings').orderBy(rawDistance('vector', qv), 'asc')
|
|
1317
|
-
*/
|
|
1318
|
-
declare function rawDistance(column: string, vector: number[]): ExpressionRef;
|
|
1319
|
-
/**
|
|
1320
|
-
* L2 (Euclidean) distance: col <-> vector
|
|
1321
|
-
*
|
|
1322
|
-
* @example
|
|
1323
|
-
* orm.select('embeddings').orderBy(l2Distance('vector', qv), 'asc')
|
|
1324
|
-
*/
|
|
1325
|
-
declare function l2Distance(column: string, vector: number[]): ExpressionRef;
|
|
1326
|
-
/**
|
|
1327
|
-
* Inner product distance: col <#> vector (negative inner product)
|
|
1328
|
-
*
|
|
1329
|
-
* For maximum inner product search: ORDER BY innerProduct('vector', qv) ASC.
|
|
1330
|
-
*
|
|
1331
|
-
* @example
|
|
1332
|
-
* orm.select('embeddings').orderBy(innerProduct('vector', qv), 'asc')
|
|
1333
|
-
*/
|
|
1334
|
-
declare function innerProduct(column: string, vector: number[]): ExpressionRef;
|
|
1335
|
-
/**
|
|
1336
|
-
* Get the number of dimensions of a vector column: vector_dims(col)
|
|
1337
|
-
*
|
|
1338
|
-
* Returns an integer — the dimension count of the stored vector.
|
|
1339
|
-
* Useful for sanity-checking that embeddings match the expected model dimension.
|
|
1340
|
-
*
|
|
1341
|
-
* @example
|
|
1342
|
-
* orm.from(embeddings).columns([vectorDims('vector').as('dim')]).first()
|
|
1343
|
-
* // → SELECT vector_dims("t0"."vector") AS "dim" FROM "embeddings" AS "t0"
|
|
1344
|
-
*/
|
|
1345
|
-
declare function vectorDims(column: string): ExpressionRef;
|
|
1346
|
-
|
|
1347
|
-
/**
|
|
1348
|
-
* PostgreSQL Schema Introspection (ADAPTER-006)
|
|
1349
|
-
*
|
|
1350
|
-
* Queries information_schema/pg_catalog to build ModelIR
|
|
1351
|
-
* from an existing database. Supports:
|
|
1352
|
-
* - Table/column/PK discovery
|
|
1353
|
-
* - FK → bidirectional relation inference
|
|
1354
|
-
* - Hierarchy detection (adjacency + edge-table)
|
|
1355
|
-
* - Include/exclude filtering
|
|
1356
|
-
*
|
|
1357
|
-
* @module introspection
|
|
1358
|
-
*/
|
|
1359
|
-
|
|
1360
|
-
/** Options for database introspection */
|
|
1361
|
-
interface IntrospectionOptions {
|
|
1362
|
-
/** Tables to exclude (glob patterns: * matches any chars) */
|
|
1363
|
-
readonly exclude?: readonly string[];
|
|
1364
|
-
/** Tables to include (default: all). Applied before exclude. */
|
|
1365
|
-
readonly include?: readonly string[];
|
|
1366
|
-
/** Schema name to introspect (default: 'public') */
|
|
1367
|
-
readonly schema?: string;
|
|
1368
|
-
}
|
|
1369
|
-
/** Hierarchy pattern detected during introspection */
|
|
1370
|
-
/**
|
|
1371
|
-
* Hierarchy pattern detected during introspection.
|
|
1372
|
-
* Alias of {@link HierarchyIR} from \@dbsp/types — kept here for
|
|
1373
|
-
* public-API backwards compatibility (re-exported from \@dbsp/adapter-pgsql).
|
|
1374
|
-
*/
|
|
1375
|
-
type DetectedHierarchy = HierarchyIR;
|
|
1376
|
-
/** Extended ModelIR with hierarchy metadata */
|
|
1377
|
-
interface IntrospectedModelIR extends ModelIR {
|
|
1378
|
-
readonly hierarchies: readonly DetectedHierarchy[];
|
|
1379
|
-
readonly introspectedAt: Date;
|
|
1380
|
-
readonly warnings: readonly string[];
|
|
1381
|
-
}
|
|
1382
|
-
declare function introspect(pool: Pool, options?: IntrospectionOptions): Promise<IntrospectedModelIR>;
|
|
1383
|
-
|
|
1384
|
-
/**
|
|
1385
|
-
* Mutation Compiler
|
|
1386
|
-
*
|
|
1387
|
-
* Compiles INSERT, UPDATE, and DELETE statements from plan decisions.
|
|
1388
|
-
* Supports:
|
|
1389
|
-
* - INSERT with values/from subquery
|
|
1390
|
-
* - INSERT with RETURNING
|
|
1391
|
-
* - UPDATE with SET and WHERE
|
|
1392
|
-
* - DELETE with WHERE
|
|
1393
|
-
* - RETURNING clause for all mutations
|
|
1394
|
-
*/
|
|
1395
|
-
|
|
1396
|
-
/**
|
|
1397
|
-
* Configuration for INSERT compilation
|
|
1398
|
-
*/
|
|
1399
|
-
interface InsertConfig {
|
|
1400
|
-
/** Table to insert into */
|
|
1401
|
-
table: string;
|
|
1402
|
-
/** Columns to insert */
|
|
1403
|
-
columns: string[];
|
|
1404
|
-
/** Values for each column (array of rows) */
|
|
1405
|
-
values: unknown[][];
|
|
1406
|
-
/** Columns to return (RETURNING clause) */
|
|
1407
|
-
returning?: string[];
|
|
1408
|
-
/** Alias-aware RETURNING projection items */
|
|
1409
|
-
returningItems?: readonly MutationReturningItem[];
|
|
1410
|
-
/** Subquery for INSERT ... SELECT */
|
|
1411
|
-
selectQuery?: Node;
|
|
1412
|
-
/** Column database types for type-cast emission (e.g. range types) */
|
|
1413
|
-
columnTypes?: Record<string, string>;
|
|
1414
|
-
}
|
|
1415
|
-
/**
|
|
1416
|
-
* Configuration for UPDATE compilation
|
|
1417
|
-
*/
|
|
1418
|
-
interface UpdateConfig {
|
|
1419
|
-
/** Table to update */
|
|
1420
|
-
table: string;
|
|
1421
|
-
/** Column-value pairs to set */
|
|
1422
|
-
set: {
|
|
1423
|
-
column: string;
|
|
1424
|
-
value: unknown;
|
|
1425
|
-
}[];
|
|
1426
|
-
/** WHERE conditions */
|
|
1427
|
-
where?: Decision[];
|
|
1428
|
-
/** Columns to return (RETURNING clause) */
|
|
1429
|
-
returning?: string[];
|
|
1430
|
-
/** Alias-aware RETURNING projection items */
|
|
1431
|
-
returningItems?: readonly MutationReturningItem[];
|
|
1432
|
-
/** Column database types for type-cast emission (e.g. range types) */
|
|
1433
|
-
columnTypes?: Record<string, string>;
|
|
1434
|
-
}
|
|
1435
|
-
/**
|
|
1436
|
-
* Configuration for DELETE compilation
|
|
1437
|
-
*/
|
|
1438
|
-
interface DeleteConfig {
|
|
1439
|
-
/** Table to delete from */
|
|
1440
|
-
table: string;
|
|
1441
|
-
/** WHERE conditions */
|
|
1442
|
-
where?: Decision[];
|
|
1443
|
-
/** Columns to return (RETURNING clause) */
|
|
1444
|
-
returning?: string[];
|
|
1445
|
-
/** Alias-aware RETURNING projection items */
|
|
1446
|
-
returningItems?: readonly MutationReturningItem[];
|
|
1447
|
-
}
|
|
1448
|
-
/**
|
|
1449
|
-
* Compile an INSERT statement from configuration.
|
|
1450
|
-
*/
|
|
1451
|
-
declare function compileInsert(config: InsertConfig, ctx: CompilerContext, state: CompilerState): Node;
|
|
1452
|
-
/**
|
|
1453
|
-
* Compile an UPDATE statement from configuration.
|
|
1454
|
-
*/
|
|
1455
|
-
declare function compileUpdate(config: UpdateConfig, ctx: CompilerContext, state: CompilerState): Node;
|
|
1456
|
-
declare function compileDelete(config: DeleteConfig, ctx: CompilerContext, state: CompilerState): Node;
|
|
1457
|
-
/**
|
|
1458
|
-
* Compile a mutation decision to AST.
|
|
1459
|
-
* Determines mutation type from decision.type and delegates.
|
|
1460
|
-
*/
|
|
1461
|
-
declare function compileMutation(decision: Decision, ctx: CompilerContext, state: CompilerState): Node;
|
|
1462
|
-
|
|
1463
|
-
/**
|
|
1464
|
-
* Upsert (INSERT ... ON CONFLICT) Compiler
|
|
1465
|
-
*
|
|
1466
|
-
* Compiles UPSERT statements with ON CONFLICT handling.
|
|
1467
|
-
* Supports:
|
|
1468
|
-
* - ON CONFLICT DO NOTHING
|
|
1469
|
-
* - ON CONFLICT DO UPDATE SET ...
|
|
1470
|
-
* - Conflict target (columns or constraint name)
|
|
1471
|
-
* - WHERE clause for conflict resolution
|
|
1472
|
-
*/
|
|
1473
|
-
|
|
1474
|
-
/**
|
|
1475
|
-
* Conflict resolution strategy
|
|
1476
|
-
*/
|
|
1477
|
-
type ConflictAction = 'nothing' | 'update';
|
|
1478
|
-
/**
|
|
1479
|
-
* Conflict target specification
|
|
1480
|
-
*/
|
|
1481
|
-
interface ConflictTarget {
|
|
1482
|
-
/** Column names that form the unique constraint */
|
|
1483
|
-
columns?: string[];
|
|
1484
|
-
/** Named constraint */
|
|
1485
|
-
constraint?: string;
|
|
1486
|
-
/** WHERE clause for partial index */
|
|
1487
|
-
where?: Decision[];
|
|
1488
|
-
}
|
|
1489
|
-
/**
|
|
1490
|
-
* Configuration for UPSERT compilation
|
|
1491
|
-
*/
|
|
1492
|
-
interface UpsertConfig {
|
|
1493
|
-
/** Table to upsert into */
|
|
1494
|
-
table: string;
|
|
1495
|
-
/** Columns to insert */
|
|
1496
|
-
columns: string[];
|
|
1497
|
-
/** Values for each column (array of rows) */
|
|
1498
|
-
values: unknown[][];
|
|
1499
|
-
/** Conflict target (unique columns or constraint) */
|
|
1500
|
-
conflictTarget: ConflictTarget;
|
|
1501
|
-
/** What to do on conflict */
|
|
1502
|
-
conflictAction: ConflictAction;
|
|
1503
|
-
/** Columns to update on conflict (for 'update' action) */
|
|
1504
|
-
updateColumns?: string[];
|
|
1505
|
-
/** Optional WHERE clause for ON CONFLICT DO UPDATE */
|
|
1506
|
-
actionWhere?: Decision[];
|
|
1507
|
-
/** Optional direct WHERE intent for ON CONFLICT DO UPDATE */
|
|
1508
|
-
actionWhereIntent?: WhereIntent;
|
|
1509
|
-
/** Compile the direct action WHERE intent using the caller's WHERE compiler */
|
|
1510
|
-
compileActionWhere?: (where: WhereIntent, state: CompilerState) => Node;
|
|
1511
|
-
/** Use EXCLUDED.column for update values (default: true) */
|
|
1512
|
-
useExcluded?: boolean;
|
|
1513
|
-
/** Columns to return (RETURNING clause) */
|
|
1514
|
-
returning?: string[];
|
|
1515
|
-
/** Alias-aware RETURNING projection items */
|
|
1516
|
-
returningItems?: readonly MutationReturningItem[];
|
|
1517
|
-
/** Optional column type hints for unnest casting (schema-driven) */
|
|
1518
|
-
columnTypes?: Record<string, string>;
|
|
1519
|
-
/**
|
|
1520
|
-
* Raw SQL expressions for specific update columns.
|
|
1521
|
-
* These are injected verbatim into the ON CONFLICT DO UPDATE SET clause.
|
|
1522
|
-
* Keys are logical column names (before naming plugin), values are raw SQL fragments.
|
|
1523
|
-
*
|
|
1524
|
-
* @warning SECURITY: fragments are inserted without parameterization.
|
|
1525
|
-
* Only use with hardcoded expressions. Never with user input.
|
|
1526
|
-
*
|
|
1527
|
-
* @example { last_parsed: 'now()', count: 'excluded.count + 1' }
|
|
1528
|
-
*/
|
|
1529
|
-
updateExpressions?: Record<string, string>;
|
|
1530
|
-
}
|
|
1531
|
-
/**
|
|
1532
|
-
* Build ON CONFLICT clause for INSERT statement.
|
|
1533
|
-
*/
|
|
1534
|
-
declare function buildOnConflictClause(config: UpsertConfig, ctx: CompilerContext, state: CompilerState): OnConflictClause;
|
|
1535
|
-
/**
|
|
1536
|
-
* Compile a complete UPSERT statement.
|
|
1537
|
-
*/
|
|
1538
|
-
declare function compileUpsert(config: UpsertConfig, ctx: CompilerContext, state: CompilerState): Node;
|
|
1539
|
-
/**
|
|
1540
|
-
* Build EXCLUDED.column reference.
|
|
1541
|
-
* EXCLUDED is a special table alias in ON CONFLICT ... DO UPDATE
|
|
1542
|
-
* that refers to the row that would have been inserted.
|
|
1543
|
-
*/
|
|
1544
|
-
declare function excludedRef(column: string, naming: {
|
|
1545
|
-
toDatabase: (s: string) => string;
|
|
1546
|
-
}): Node;
|
|
1547
|
-
/**
|
|
1548
|
-
* Build conditional update using COALESCE.
|
|
1549
|
-
*
|
|
1550
|
-
* Produces: COALESCE(EXCLUDED.col, table.col)
|
|
1551
|
-
* This keeps existing value if new value is NULL.
|
|
1552
|
-
*/
|
|
1553
|
-
declare function conditionalUpdate(column: string, table: string, ctx: CompilerContext): Node;
|
|
1554
|
-
|
|
1555
|
-
/**
|
|
1556
|
-
* @module naming
|
|
1557
|
-
* Utilities for resolving database names to logical model names.
|
|
1558
|
-
*
|
|
1559
|
-
* The ModelIR.getTable() method expects logical (camelCase) names,
|
|
1560
|
-
* but the adapter often works with database (snake_case) names.
|
|
1561
|
-
* This module bridges that gap.
|
|
1562
|
-
*/
|
|
1563
|
-
|
|
1564
|
-
/**
|
|
1565
|
-
* Resolve a database table name to the corresponding logical model name.
|
|
1566
|
-
*
|
|
1567
|
-
* Converts the DB name using the naming convention, then looks it up in the model.
|
|
1568
|
-
* Falls back to exact match if conversion doesn't find a match.
|
|
1569
|
-
*
|
|
1570
|
-
* @param model - The model IR to search in
|
|
1571
|
-
* @param dbName - Database table name (e.g. "post_comments")
|
|
1572
|
-
* @param convention - Naming convention used by the adapter
|
|
1573
|
-
* @returns The logical table name if found, undefined otherwise
|
|
1574
|
-
*
|
|
1575
|
-
* @example
|
|
1576
|
-
* ```typescript
|
|
1577
|
-
* // With camelCase convention:
|
|
1578
|
-
* resolveLogicalName(model, "post_comments", "camelCase") // → "postComments"
|
|
1579
|
-
* resolveLogicalName(model, "posts", "camelCase") // → "posts"
|
|
1580
|
-
* resolveLogicalName(model, "unknown", "camelCase") // → undefined
|
|
1581
|
-
* ```
|
|
1582
|
-
*/
|
|
1583
|
-
declare function resolveLogicalName(model: ModelIR, dbName: string, casing: DbCasing): string | undefined;
|
|
1584
|
-
|
|
1585
|
-
/**
|
|
1586
|
-
* ParamRef validation and helpers for PostgreSQL AST
|
|
1587
|
-
*
|
|
1588
|
-
* ParamRef nodes represent parameterized query placeholders ($1, $2, etc.)
|
|
1589
|
-
* This module provides validation and creation helpers for safe AST construction.
|
|
1590
|
-
*/
|
|
1591
|
-
|
|
1592
|
-
/**
|
|
1593
|
-
* Validation result for ParamRef nodes
|
|
1594
|
-
*/
|
|
1595
|
-
interface ParamRefValidationResult {
|
|
1596
|
-
valid: boolean;
|
|
1597
|
-
errors: string[];
|
|
1598
|
-
}
|
|
1599
|
-
/**
|
|
1600
|
-
* Validates a ParamRef node
|
|
1601
|
-
*
|
|
1602
|
-
* Rules:
|
|
1603
|
-
* - `number` must be a positive integer (1-based indexing)
|
|
1604
|
-
* - `number` must not exceed reasonable bounds (e.g., 65535)
|
|
1605
|
-
*/
|
|
1606
|
-
declare function validateParamRef(paramRef: ParamRef): ParamRefValidationResult;
|
|
1607
|
-
/**
|
|
1608
|
-
* Creates a validated ParamRef node
|
|
1609
|
-
* @throws Error if validation fails
|
|
1610
|
-
*/
|
|
1611
|
-
declare function createParamRef(number: number, location?: number): Node;
|
|
1612
|
-
/**
|
|
1613
|
-
* Creates a TypeCast node wrapping a ParamRef
|
|
1614
|
-
* Example: $1::integer, $2::text[]
|
|
1615
|
-
*/
|
|
1616
|
-
declare function createTypeCastParamRef(paramNumber: number, typeName: string, isArray?: boolean, location?: number): Node;
|
|
1617
|
-
/**
|
|
1618
|
-
* Creates an A_Expr node for equality comparison with ParamRef
|
|
1619
|
-
* Example: col = $1
|
|
1620
|
-
*/
|
|
1621
|
-
declare function createEqualityExpr(columnName: string, paramNumber: number, tableName?: string, location?: number): Node;
|
|
1622
|
-
/**
|
|
1623
|
-
* Creates a FuncCall node for ANY() with ParamRef
|
|
1624
|
-
* Example: col = ANY($1) for array parameter matching
|
|
1625
|
-
*/
|
|
1626
|
-
declare function createAnyExpr(columnName: string, paramNumber: number, tableName?: string, location?: number): Node;
|
|
1627
|
-
/**
|
|
1628
|
-
* Collects all ParamRef nodes from an AST, validating each
|
|
1629
|
-
* Returns validation results for all found ParamRefs
|
|
1630
|
-
*/
|
|
1631
|
-
declare function collectAndValidateParamRefs(node: unknown): {
|
|
1632
|
-
paramRefs: Array<{
|
|
1633
|
-
paramRef: ParamRef;
|
|
1634
|
-
path: string;
|
|
1635
|
-
}>;
|
|
1636
|
-
validationResults: ParamRefValidationResult[];
|
|
1637
|
-
allValid: boolean;
|
|
1638
|
-
};
|
|
1639
|
-
|
|
1640
|
-
/**
|
|
1641
|
-
* PgsqlAdapter - Implements the Adapter interface for PostgreSQL using native pg driver.
|
|
1642
|
-
*
|
|
1643
|
-
* This adapter wraps a pg Pool instance and provides the unified
|
|
1644
|
-
* adapter interface for the db-semantic-planner ORM.
|
|
1645
|
-
*
|
|
1646
|
-
* @module pgsql-adapter
|
|
1647
|
-
*/
|
|
1648
|
-
|
|
1649
|
-
/**
|
|
1650
|
-
* Options for PgsqlAdapter.
|
|
1651
|
-
*/
|
|
1652
|
-
interface PgsqlAdapterOptions {
|
|
1653
|
-
/** Schema name for multi-tenant queries */
|
|
1654
|
-
readonly schemaName?: string;
|
|
1655
|
-
/**
|
|
1656
|
-
* DB column casing convention (intuitive semantics).
|
|
1657
|
-
* - `'snake_case'`: DB columns are snake_case → transform to camelCase for JS
|
|
1658
|
-
* - `'camelCase'`: DB columns are camelCase → no transformation
|
|
1659
|
-
* - `'preserve'`: No transformation
|
|
1660
|
-
*/
|
|
1661
|
-
readonly dbCasing?: DbCasing;
|
|
1662
|
-
/** Optional model for WHERE compilation */
|
|
1663
|
-
readonly model?: ModelIR;
|
|
1664
|
-
/** Optional logger for debug/error messages */
|
|
1665
|
-
readonly logger?: AdapterLogger;
|
|
1666
|
-
/** Default primary key column name for convention fallbacks (default: 'id') */
|
|
1667
|
-
readonly defaultPkColumnName?: string;
|
|
1668
|
-
/** Convention for deriving FK column names: (tableName, pkName) => fkColumnName */
|
|
1669
|
-
readonly deriveFkColumnName?: FkColumnDerivation;
|
|
1670
|
-
}
|
|
1671
|
-
/**
|
|
1672
|
-
* Adapter implementation for PostgreSQL using native pg driver.
|
|
1673
|
-
*
|
|
1674
|
-
* @typeParam DB - Database schema type
|
|
1675
|
-
*
|
|
1676
|
-
* @example
|
|
1677
|
-
* ```typescript
|
|
1678
|
-
* import { Pool } from 'pg';
|
|
1679
|
-
* import { createPgsqlAdapter } from '@dbsp/adapter-pgsql';
|
|
1680
|
-
*
|
|
1681
|
-
* const pool = new Pool({ connectionString: process.env.DATABASE_URL });
|
|
1682
|
-
* const adapter = createPgsqlAdapter(pool);
|
|
1683
|
-
* const orm = createOrm({ model, adapter });
|
|
1684
|
-
* ```
|
|
932
|
+
* const pool = new Pool({ connectionString: process.env.DATABASE_URL });
|
|
933
|
+
* const adapter = createPgsqlAdapter(pool);
|
|
934
|
+
* const orm = createOrm({ model, adapter });
|
|
935
|
+
* ```
|
|
1685
936
|
*/
|
|
1686
937
|
declare class PgsqlAdapter<DB = unknown> implements Adapter<DB> {
|
|
1687
938
|
private readonly pool;
|
|
1688
939
|
private readonly client;
|
|
940
|
+
private readonly borrowedClient;
|
|
941
|
+
private readonly managedTransactions;
|
|
942
|
+
private readonly adapterManagedTransaction;
|
|
943
|
+
private readonly scopeToken;
|
|
944
|
+
private readonly scopeState;
|
|
1689
945
|
private readonly schemaName;
|
|
1690
946
|
private readonly _dbCasing;
|
|
1691
947
|
private readonly naming;
|
|
@@ -1697,10 +953,19 @@ declare class PgsqlAdapter<DB = unknown> implements Adapter<DB> {
|
|
|
1697
953
|
/**
|
|
1698
954
|
* Create a new PgsqlAdapter.
|
|
1699
955
|
*
|
|
1700
|
-
*
|
|
1701
|
-
*
|
|
956
|
+
* Ownership of the connection is **declared**, never inferred. Handing over a
|
|
957
|
+
* `PoolClient` means nothing on its own — it says the object has a `release()`
|
|
958
|
+
* method, not that a transaction is open or that the caller owns the lifecycle.
|
|
959
|
+
* Pass `borrowedClient: true` to say so.
|
|
960
|
+
*
|
|
961
|
+
* @param pool - a pg.Pool, a caller-owned pg.PoolClient (with `borrowedClient: true`),
|
|
962
|
+
* or nothing at all for compile-only mode
|
|
963
|
+
* @param options - configuration; declares connection ownership
|
|
1702
964
|
*/
|
|
1703
|
-
constructor(pool?: Pool |
|
|
965
|
+
constructor(pool?: Pool | undefined, options?: PgsqlPoolAdapterOptions);
|
|
966
|
+
constructor(pool: Pool, options?: PgsqlPoolAdapterOptions);
|
|
967
|
+
constructor(client: PoolClient, options: PgsqlBorrowedClientAdapterOptions);
|
|
968
|
+
constructor(pool: undefined, options?: PgsqlAdapterOptions);
|
|
1704
969
|
/**
|
|
1705
970
|
* Shared compilation dependencies — built lazily from adapter fields.
|
|
1706
971
|
* Passed to compiler sub-modules instead of `this`.
|
|
@@ -1730,9 +995,9 @@ declare class PgsqlAdapter<DB = unknown> implements Adapter<DB> {
|
|
|
1730
995
|
*/
|
|
1731
996
|
get dbCasing(): DbCasing;
|
|
1732
997
|
/**
|
|
1733
|
-
* Get the underlying pg Pool instance.
|
|
998
|
+
* Get the underlying pg Pool or borrowed PoolClient instance.
|
|
1734
999
|
*/
|
|
1735
|
-
getPoolInstance(): Pool;
|
|
1000
|
+
getPoolInstance(): Pool | PoolClient;
|
|
1736
1001
|
/**
|
|
1737
1002
|
* Compile a plan to executable SQL.
|
|
1738
1003
|
*
|
|
@@ -1862,6 +1127,9 @@ declare class PgsqlAdapter<DB = unknown> implements Adapter<DB> {
|
|
|
1862
1127
|
* Internal: Stream with an existing client using cursors.
|
|
1863
1128
|
*/
|
|
1864
1129
|
private streamWithClient;
|
|
1130
|
+
private streamWithManagedClient;
|
|
1131
|
+
private streamWithManagedClientSavepointScope;
|
|
1132
|
+
private streamWithClientTransaction;
|
|
1865
1133
|
/**
|
|
1866
1134
|
* Introspect the database schema and return a ModelIR.
|
|
1867
1135
|
*
|
|
@@ -1878,8 +1146,83 @@ declare class PgsqlAdapter<DB = unknown> implements Adapter<DB> {
|
|
|
1878
1146
|
introspect(options?: IntrospectionOptions): Promise<IntrospectedModelIR>;
|
|
1879
1147
|
/**
|
|
1880
1148
|
* Execute a callback within a database transaction.
|
|
1149
|
+
*
|
|
1150
|
+
* ## What this guarantees
|
|
1151
|
+
*
|
|
1152
|
+
* The callback's work commits together or not at all; a statement issued inside
|
|
1153
|
+
* the transaction never executes after its boundary, even if you forget to
|
|
1154
|
+
* `await` it; a nested `transaction()` is a real savepoint; and the connection
|
|
1155
|
+
* never goes back to the pool with a transaction still open on it.
|
|
1156
|
+
*
|
|
1157
|
+
* ## What it cannot guarantee, and you should know before you reach for raw SQL
|
|
1158
|
+
*
|
|
1159
|
+
* **Raw SQL that ends the transaction ends it.** `COMMIT`, `ROLLBACK` and
|
|
1160
|
+
* `PREPARE TRANSACTION` issued through `executeRaw` — or through several commands
|
|
1161
|
+
* in one call — reach PostgreSQL and take effect *before* dbsp is told what they
|
|
1162
|
+
* were: the command tag arrives after the statement has run. dbsp detects it, kills
|
|
1163
|
+
* the scope so nothing else escapes, and throws — but **it cannot un-run what your
|
|
1164
|
+
* statement already did**, and `transaction()` rejecting does not mean nothing was
|
|
1165
|
+
* committed.
|
|
1166
|
+
*
|
|
1167
|
+
* The same holds for session state raw SQL creates: a sequence that advanced stays
|
|
1168
|
+
* advanced, an advisory lock stays held, a `PREPARE` or a `SET` you issued survives
|
|
1169
|
+
* on a pooled connection. dbsp cleans up only what dbsp created.
|
|
1170
|
+
*
|
|
1171
|
+
* This is the contract of an escape hatch, not an oversight — see #327. If you need
|
|
1172
|
+
* transaction control, own the transaction: take a client, `BEGIN` on it yourself,
|
|
1173
|
+
* and hand dbsp a `borrowedClient` **without** `managedTransactions`. dbsp will then
|
|
1174
|
+
* contain its own statements inside *your* transaction instead of the other way round.
|
|
1881
1175
|
*/
|
|
1882
1176
|
transaction<T>(fn: (adapter: Adapter<DB>) => Promise<T>): Promise<T>;
|
|
1177
|
+
/**
|
|
1178
|
+
* Execute scratch PostgreSQL work in a scope that always rolls back on success.
|
|
1179
|
+
*
|
|
1180
|
+
* This is intentionally PostgreSQL-adapter-specific. It is used for catalog
|
|
1181
|
+
* shaped scratch DDL such as CHECK expression canonicalisation, where the
|
|
1182
|
+
* caller needs PostgreSQL's rendering but must not keep the scratch objects.
|
|
1183
|
+
* Rollback here is cleanup of dbsp-created work, not a sandbox for arbitrary
|
|
1184
|
+
* session effects.
|
|
1185
|
+
*/
|
|
1186
|
+
withScratchScope<T>(fn: (adapter: PgsqlAdapter<DB>) => Promise<T>): Promise<T>;
|
|
1187
|
+
private createManagedClientAdapter;
|
|
1188
|
+
private createChildTransactionObserver;
|
|
1189
|
+
private observeChildTransaction;
|
|
1190
|
+
private markChildTransactionObserved;
|
|
1191
|
+
private refreshScopeChildrenFailure;
|
|
1192
|
+
private transactionWithManagedClient;
|
|
1193
|
+
private transactionWithManagedClientSavepointScope;
|
|
1194
|
+
private transactionWithClientTransaction;
|
|
1195
|
+
private releaseClient;
|
|
1196
|
+
private rollbackAndReleaseSavepoint;
|
|
1197
|
+
private rollbackSavepoint;
|
|
1198
|
+
private releaseSavepoint;
|
|
1199
|
+
private rollbackTransactionIfOpen;
|
|
1200
|
+
private classifyTransactionStateError;
|
|
1201
|
+
private probeTransactionState;
|
|
1202
|
+
private classifySavepointReleaseFailure;
|
|
1203
|
+
private rollbackSavepointAfterReleaseFailure;
|
|
1204
|
+
private enterTransactionScope;
|
|
1205
|
+
private enterSavepointScope;
|
|
1206
|
+
private pushClientScope;
|
|
1207
|
+
private currentClientScope;
|
|
1208
|
+
private assertCanUseClient;
|
|
1209
|
+
private assertUsableScopeAncestors;
|
|
1210
|
+
private findClientScope;
|
|
1211
|
+
private assertScopeNotPoisoned;
|
|
1212
|
+
private throwIfScopePoisoned;
|
|
1213
|
+
private scopePoisonOutranksError;
|
|
1214
|
+
private poisonScopeState;
|
|
1215
|
+
private poisonClientScope;
|
|
1216
|
+
private poisonClientScopeStack;
|
|
1217
|
+
private runWithScopeStatementLock;
|
|
1218
|
+
private closeScope;
|
|
1219
|
+
private closeScopeAndAssertChildren;
|
|
1220
|
+
private drainScopeStatements;
|
|
1221
|
+
private drainScopeChildren;
|
|
1222
|
+
private assertScopeChildrenSettled;
|
|
1223
|
+
private drainScopeWork;
|
|
1224
|
+
private executeScopeBoundaryStatement;
|
|
1225
|
+
private assertCommitSucceeded;
|
|
1883
1226
|
/**
|
|
1884
1227
|
* Create a schema-scoped adapter for multi-tenant queries.
|
|
1885
1228
|
*/
|
|
@@ -1888,6 +1231,15 @@ declare class PgsqlAdapter<DB = unknown> implements Adapter<DB> {
|
|
|
1888
1231
|
* Execute raw SQL directly.
|
|
1889
1232
|
*
|
|
1890
1233
|
* ⚠️ WARNING: Use parameter placeholders ($1, $2, etc.) for all values.
|
|
1234
|
+
*
|
|
1235
|
+
* Transaction control through raw SQL inside a scope dbsp is managing is
|
|
1236
|
+
* unsupported. `COMMIT`, `ROLLBACK`, and `PREPARE TRANSACTION` end the
|
|
1237
|
+
* transaction dbsp is working inside; dbsp detects that and fails loudly, but
|
|
1238
|
+
* the data is already whatever your statement made it. Raw savepoint control
|
|
1239
|
+
* (`SAVEPOINT`, `RELEASE SAVEPOINT`, `ROLLBACK TO SAVEPOINT`) can alter the
|
|
1240
|
+
* savepoint stack before dbsp sees the command tag; dbsp poisons the scope, but
|
|
1241
|
+
* it cannot make that command un-run. Manage your transaction outside dbsp's
|
|
1242
|
+
* calls.
|
|
1891
1243
|
*/
|
|
1892
1244
|
executeRaw<T = unknown>(sql: string, parameters?: readonly unknown[]): Promise<T[]>;
|
|
1893
1245
|
/**
|
|
@@ -1909,12 +1261,22 @@ declare class PgsqlAdapter<DB = unknown> implements Adapter<DB> {
|
|
|
1909
1261
|
*/
|
|
1910
1262
|
executeDDL(sql: string): Promise<void>;
|
|
1911
1263
|
/**
|
|
1912
|
-
* Whether
|
|
1913
|
-
*
|
|
1264
|
+
* Whether a transaction is open on this adapter's connection.
|
|
1265
|
+
* This is true for dbsp-managed scopes and for borrowed pg clients whose
|
|
1266
|
+
* ReadyForQuery status says the caller has an open transaction.
|
|
1914
1267
|
*
|
|
1915
1268
|
* @since DDL-TABLE-001
|
|
1916
1269
|
*/
|
|
1917
1270
|
get inTransaction(): boolean;
|
|
1271
|
+
private adapterManagedScopeIsLive;
|
|
1272
|
+
private executeQueryProtectingOpenTransaction;
|
|
1273
|
+
private executeConnectionStatement;
|
|
1274
|
+
private executeConnectionStatementUnlocked;
|
|
1275
|
+
private executeConnectionStatementInSavepoint;
|
|
1276
|
+
private issueConnectionQuery;
|
|
1277
|
+
private assertNoMultiCommandRawCall;
|
|
1278
|
+
private assertNoTransactionControlCommand;
|
|
1279
|
+
private assertPrepareDidNotEndTransaction;
|
|
1918
1280
|
/**
|
|
1919
1281
|
* Resolve the explicit schema for a catalog read: an explicit argument, else
|
|
1920
1282
|
* the adapter's configured schema, else `undefined` (resolve in-query). NOT a
|
|
@@ -1941,85 +1303,1043 @@ declare class PgsqlAdapter<DB = unknown> implements Adapter<DB> {
|
|
|
1941
1303
|
*/
|
|
1942
1304
|
indexExists(name: string, table: string, schema?: string): Promise<boolean>;
|
|
1943
1305
|
/**
|
|
1944
|
-
* Return the total storage size of a table in bytes (includes indexes and TOAST).
|
|
1306
|
+
* Return the total storage size of a table in bytes (includes indexes and TOAST).
|
|
1307
|
+
*
|
|
1308
|
+
* The table name is a SQL identifier — it is double-quoted, not parameterized,
|
|
1309
|
+
* because PostgreSQL does not allow parameterized table names in FROM clauses.
|
|
1310
|
+
* With no known schema the table is left unqualified so ::regclass resolves it
|
|
1311
|
+
* through search_path (the same table an unqualified reference would hit).
|
|
1312
|
+
*
|
|
1313
|
+
* @param table - Table name
|
|
1314
|
+
* @param schema - Schema name (defaults to the search_path-resolved schema)
|
|
1315
|
+
*/
|
|
1316
|
+
storageSize(table: string, schema?: string): Promise<number>;
|
|
1317
|
+
/**
|
|
1318
|
+
* Generate SQL for TRUNCATE TABLE.
|
|
1319
|
+
* Implements TableDDLGeneratorAdapter.generateTruncate.
|
|
1320
|
+
*/
|
|
1321
|
+
generateTruncate(table: string, schema?: string, options?: TruncateOptions): string;
|
|
1322
|
+
/**
|
|
1323
|
+
* Generate SQL for VACUUM.
|
|
1324
|
+
* Implements TableDDLGeneratorAdapter.generateVacuum.
|
|
1325
|
+
*/
|
|
1326
|
+
generateVacuum(table: string, schema?: string, options?: VacuumOptions): string;
|
|
1327
|
+
/**
|
|
1328
|
+
* Generate SQL for ALTER TABLE ... ALTER COLUMN.
|
|
1329
|
+
* Implements TableDDLGeneratorAdapter.generateAlterColumn.
|
|
1330
|
+
*/
|
|
1331
|
+
generateAlterColumn(table: string, column: string, options: AlterColumnOptions, schema?: string): string;
|
|
1332
|
+
/**
|
|
1333
|
+
* Generate SQL for CREATE INDEX.
|
|
1334
|
+
* Implements TableDDLGeneratorAdapter.generateCreateIndex.
|
|
1335
|
+
*/
|
|
1336
|
+
generateCreateIndex(table: string, options: CreateIndexOptions, schema?: string): string;
|
|
1337
|
+
/**
|
|
1338
|
+
* Generate SQL for DROP INDEX.
|
|
1339
|
+
* Implements TableDDLGeneratorAdapter.generateDropIndex.
|
|
1340
|
+
*/
|
|
1341
|
+
generateDropIndex(name: string, options?: DropIndexOptions): string;
|
|
1342
|
+
/**
|
|
1343
|
+
* Validate an identifier (table name, column name, schema name).
|
|
1344
|
+
*/
|
|
1345
|
+
validateIdentifier(value: string, type: string): void;
|
|
1346
|
+
}
|
|
1347
|
+
/**
|
|
1348
|
+
* Create a PgsqlAdapter from a pg Pool instance.
|
|
1349
|
+
*
|
|
1350
|
+
* @param pool - pg Pool instance
|
|
1351
|
+
* @param options - Optional configuration
|
|
1352
|
+
* @returns A new PgsqlAdapter instance
|
|
1353
|
+
*
|
|
1354
|
+
* @example
|
|
1355
|
+
* ```typescript
|
|
1356
|
+
* import { Pool } from 'pg';
|
|
1357
|
+
* import { createPgsqlAdapter } from '@dbsp/adapter-pgsql';
|
|
1358
|
+
*
|
|
1359
|
+
* const pool = new Pool({ connectionString: process.env.DATABASE_URL });
|
|
1360
|
+
* const adapter = createPgsqlAdapter(pool);
|
|
1361
|
+
*
|
|
1362
|
+
* // With naming convention
|
|
1363
|
+
* const adapter = createPgsqlAdapter(pool, { dbCasing: 'snake_case' });
|
|
1364
|
+
* ```
|
|
1365
|
+
*/
|
|
1366
|
+
declare function createPgsqlAdapter<DB = unknown>(pool: Pool, options?: PgsqlPoolAdapterOptions): PgsqlAdapter<DB>;
|
|
1367
|
+
declare function createPgsqlAdapter<DB = unknown>(client: PoolClient, options: PgsqlBorrowedClientAdapterOptions): PgsqlAdapter<DB>;
|
|
1368
|
+
/**
|
|
1369
|
+
* Creates a compile-only PgsqlAdapter for SQL generation without a database connection.
|
|
1370
|
+
*
|
|
1371
|
+
* All compilation methods (compile, compileInsert, etc.), createDump(), and generateDDL()
|
|
1372
|
+
* work normally. Execution methods (execute, stream, transaction, etc.) throw an error.
|
|
1373
|
+
*
|
|
1374
|
+
* @example
|
|
1375
|
+
* ```typescript
|
|
1376
|
+
* import { createPgsqlCompileOnlyAdapter } from '@dbsp/adapter-pgsql';
|
|
1377
|
+
* import { createOrm } from '@dbsp/core';
|
|
1378
|
+
*
|
|
1379
|
+
* const adapter = createPgsqlCompileOnlyAdapter();
|
|
1380
|
+
* const orm = createOrm({ model, adapter });
|
|
1381
|
+
* const dump = await orm.select('users').dump();
|
|
1382
|
+
* console.log(dump.sql);
|
|
1383
|
+
* ```
|
|
1384
|
+
*/
|
|
1385
|
+
declare function createPgsqlCompileOnlyAdapter<DB = unknown>(options?: PgsqlAdapterOptions): CompileOnlyAdapter;
|
|
1386
|
+
|
|
1387
|
+
/**
|
|
1388
|
+
* Schema Comparison Engine (DDL-PROV Block 1)
|
|
1389
|
+
*
|
|
1390
|
+
* Compares two ModelIRs (schema definition vs database state)
|
|
1391
|
+
* and produces a structured diff of changes needed.
|
|
1392
|
+
*
|
|
1393
|
+
* @module schema-diff
|
|
1394
|
+
*/
|
|
1395
|
+
|
|
1396
|
+
type ChangeKind = 'create_table' | 'drop_table' | 'add_column' | 'drop_column' | 'alter_column_type' | 'alter_column_nullable' | 'alter_column_default' | 'alter_column_unique' | 'add_primary_key' | 'drop_primary_key' | 'add_foreign_key' | 'drop_foreign_key' | 'alter_foreign_key' | 'validate_constraint' | 'create_index' | 'drop_index' | 'add_check_constraint' | 'drop_check_constraint' | 'create_enum' | 'alter_enum_add_value' | 'drop_enum' | 'alter_column_collation' | 'alter_column_identity' | 'add_comment' | 'drop_comment' | 'create_extension' | 'drop_extension' | 'create_sequence' | 'alter_sequence' | 'drop_sequence' | 'enable_rls' | 'disable_rls' | 'create_policy' | 'drop_policy';
|
|
1397
|
+
interface SchemaChange {
|
|
1398
|
+
readonly kind: ChangeKind;
|
|
1399
|
+
readonly table: string;
|
|
1400
|
+
readonly column?: string;
|
|
1401
|
+
readonly destructive: boolean;
|
|
1402
|
+
readonly details: string;
|
|
1403
|
+
/** Additional metadata for SQL generation */
|
|
1404
|
+
readonly meta?: Readonly<Record<string, unknown>>;
|
|
1405
|
+
}
|
|
1406
|
+
interface DiffSummary {
|
|
1407
|
+
readonly tables: {
|
|
1408
|
+
readonly added: number;
|
|
1409
|
+
readonly dropped: number;
|
|
1410
|
+
};
|
|
1411
|
+
readonly columns: {
|
|
1412
|
+
readonly added: number;
|
|
1413
|
+
readonly dropped: number;
|
|
1414
|
+
readonly altered: number;
|
|
1415
|
+
};
|
|
1416
|
+
readonly indexes: {
|
|
1417
|
+
readonly added: number;
|
|
1418
|
+
readonly dropped: number;
|
|
1419
|
+
};
|
|
1420
|
+
readonly constraints: {
|
|
1421
|
+
readonly added: number;
|
|
1422
|
+
readonly dropped: number;
|
|
1423
|
+
readonly altered: number;
|
|
1424
|
+
};
|
|
1425
|
+
}
|
|
1426
|
+
interface SchemaDiff {
|
|
1427
|
+
readonly changes: readonly SchemaChange[];
|
|
1428
|
+
readonly hasDestructive: boolean;
|
|
1429
|
+
readonly summary: DiffSummary;
|
|
1430
|
+
}
|
|
1431
|
+
interface CompareSchemataOptions {
|
|
1432
|
+
/**
|
|
1433
|
+
* Database naming convention.
|
|
1434
|
+
* When set, schema model names (camelCase) are converted to DB format
|
|
1435
|
+
* (e.g. snake_case) before comparison with the introspected model.
|
|
1436
|
+
*/
|
|
1437
|
+
dbCasing?: DbCasing;
|
|
1438
|
+
/** Dialect capabilities — comparisons for unsupported features will be skipped */
|
|
1439
|
+
readonly dialectCapabilities?: DialectCapabilities;
|
|
1440
|
+
/**
|
|
1441
|
+
* When `true`, extensions present in the live DB but absent from the model
|
|
1442
|
+
* schema are silently ignored — no `drop_extension` change is emitted for them.
|
|
1443
|
+
* Only extensions explicitly declared in the model are managed (created if missing).
|
|
1444
|
+
*
|
|
1445
|
+
* Use this when the database image pre-installs extensions that the application
|
|
1446
|
+
* schema does not own (e.g. pgvector, pg_search bundled in a custom Postgres image).
|
|
1447
|
+
* Default: `false` (full-sync behaviour — unmanaged DB extensions produce a
|
|
1448
|
+
* `drop_extension` entry).
|
|
1449
|
+
*/
|
|
1450
|
+
readonly ignoreUnmanagedExtensions?: boolean;
|
|
1451
|
+
/**
|
|
1452
|
+
* Strict compile-only mode for callers that require convergence guarantees.
|
|
1453
|
+
*
|
|
1454
|
+
* `compareSchemata()` is intentionally pure and cannot ask PostgreSQL to
|
|
1455
|
+
* canonicalise raw-SQL expression surfaces. By default it keeps the historic
|
|
1456
|
+
* best-effort raw string comparison for CHECK expressions, partial-index
|
|
1457
|
+
* predicates, and index expressions. Set this flag to throw when either model
|
|
1458
|
+
* contains one of those surfaces so a caller cannot accidentally rely on a
|
|
1459
|
+
* compile-only diff for a convergence-sensitive check.
|
|
1460
|
+
*
|
|
1461
|
+
* Live PostgreSQL callers should use `comparePgsqlDatabaseSchema()`, which
|
|
1462
|
+
* canonicalises CHECK constraint expressions before calling this function.
|
|
1463
|
+
* Partial-index predicates and index expressions are not canonicalised by the
|
|
1464
|
+
* live helper and are rejected there when this strict flag is set.
|
|
1465
|
+
*/
|
|
1466
|
+
readonly requireExpressionCanonicalization?: boolean;
|
|
1467
|
+
}
|
|
1468
|
+
declare class ExpressionCanonicalizationUnavailableError extends Error {
|
|
1469
|
+
readonly surfaces: readonly string[];
|
|
1470
|
+
constructor(surfaces: readonly string[]);
|
|
1471
|
+
}
|
|
1472
|
+
/**
|
|
1473
|
+
* Compare two ModelIRs and produce a structured diff.
|
|
1474
|
+
*
|
|
1475
|
+
* @param schema - The desired schema (from definition)
|
|
1476
|
+
* @param db - The current database state (from introspection)
|
|
1477
|
+
* @param options - Optional comparison settings (e.g. dbCasing)
|
|
1478
|
+
* @returns SchemaDiff with all changes needed to bring DB in sync with schema
|
|
1479
|
+
*/
|
|
1480
|
+
declare function compareSchemata(schema: ModelIR, db: ModelIR, options?: CompareSchemataOptions): SchemaDiff;
|
|
1481
|
+
|
|
1482
|
+
interface ComparePgsqlDatabaseSchemaOptions extends CompareSchemataOptions, SchemaScopeOptions {
|
|
1483
|
+
/**
|
|
1484
|
+
* Whether to canonicalise PostgreSQL CHECK constraint expressions before
|
|
1485
|
+
* comparing. Defaults to `true`. Set to `false` only for compatibility with
|
|
1486
|
+
* legacy raw-string live diffs.
|
|
1487
|
+
*
|
|
1488
|
+
* Live canonicalisation creates temporary scratch tables and missing desired
|
|
1489
|
+
* enum types inside an adapter scratch scope whose successful cleanup is
|
|
1490
|
+
* rollback. The database role needs permission to create temporary tables,
|
|
1491
|
+
* and enum-dependent checks may need permission to create the pending enum
|
|
1492
|
+
* type. If PostgreSQL refuses that scratch DDL, non-strict mode warns and
|
|
1493
|
+
* falls back to best-effort raw string comparison for the affected CHECK
|
|
1494
|
+
* constraints.
|
|
1495
|
+
*/
|
|
1496
|
+
readonly canonicalizeExpressions?: boolean;
|
|
1497
|
+
/**
|
|
1498
|
+
* Receives live CHECK canonicalisation warnings. Defaults to console.warn.
|
|
1499
|
+
*/
|
|
1500
|
+
readonly onWarning?: (message: string) => void;
|
|
1501
|
+
/**
|
|
1502
|
+
* Diff that the caller just applied before this live re-diff. Used only when
|
|
1503
|
+
* CHECK expressions are compared by raw text to fail loudly if the exact same
|
|
1504
|
+
* expression-surface drift appears again after re-introspection.
|
|
1505
|
+
*/
|
|
1506
|
+
readonly previouslyAppliedDiff?: SchemaDiff;
|
|
1507
|
+
}
|
|
1508
|
+
declare class NonConvergentSchemaDiffError extends Error {
|
|
1509
|
+
readonly table: string;
|
|
1510
|
+
readonly constraint: string;
|
|
1511
|
+
readonly desiredExpression: string;
|
|
1512
|
+
readonly databaseExpression: string;
|
|
1513
|
+
constructor(table: string, constraint: string, desiredExpression: string, databaseExpression: string);
|
|
1514
|
+
}
|
|
1515
|
+
/** An enum value this diff adds, reported as a candidate cause — never asserted. */
|
|
1516
|
+
interface AddedEnumValue {
|
|
1517
|
+
readonly enumName: string;
|
|
1518
|
+
readonly value: string;
|
|
1519
|
+
}
|
|
1520
|
+
declare class CheckConstraintNewEnumValueError extends Error {
|
|
1521
|
+
readonly table: string;
|
|
1522
|
+
readonly constraint: string;
|
|
1523
|
+
readonly addedEnumValues: readonly AddedEnumValue[];
|
|
1524
|
+
constructor(table: string, constraint: string, addedEnumValues: readonly AddedEnumValue[]);
|
|
1525
|
+
}
|
|
1526
|
+
/**
|
|
1527
|
+
* Live PostgreSQL schema diff: introspect, canonicalise desired CHECK
|
|
1528
|
+
* constraint expressions through PostgreSQL, then call the pure synchronous
|
|
1529
|
+
* schema comparator.
|
|
1530
|
+
*
|
|
1531
|
+
* If CHECK canonicalisation falls back while the same diff adds a plausibly
|
|
1532
|
+
* referenced enum value, the diff is refused. dbsp currently applies each
|
|
1533
|
+
* migration in one transaction, and PostgreSQL forbids using a newly added enum
|
|
1534
|
+
* value in that same transaction; emitting the CHECK would produce a migration
|
|
1535
|
+
* that cannot run. Apply the enum addition by itself first, then add or update
|
|
1536
|
+
* the CHECK constraint in a later migration.
|
|
1537
|
+
*
|
|
1538
|
+
* Partial-index predicates and index expressions are intentionally not
|
|
1539
|
+
* canonicalised here; non-strict diffs compare them by raw string, and strict
|
|
1540
|
+
* diffs reject them.
|
|
1541
|
+
*/
|
|
1542
|
+
declare function comparePgsqlDatabaseSchema(adapter: PgsqlAdapter, desired: ModelIR, options?: ComparePgsqlDatabaseSchemaOptions): Promise<SchemaDiff>;
|
|
1543
|
+
declare function assertNoRepeatedExpressionSurfaceDrift(previouslyAppliedDiff: SchemaDiff, currentDiff: SchemaDiff, rawCheckExpressionSurfaces?: ReadonlySet<string>): void;
|
|
1544
|
+
|
|
1545
|
+
/**
|
|
1546
|
+
* Migration SQL Generator (DDL-PROV Block 1)
|
|
1547
|
+
*
|
|
1548
|
+
* Generates ordered SQL statements from a SchemaDiff.
|
|
1549
|
+
* Statements are topologically sorted: DROP constraints → DROP objects → CREATE objects → ADD constraints.
|
|
1550
|
+
*
|
|
1551
|
+
* @module migration-sql
|
|
1552
|
+
*/
|
|
1553
|
+
|
|
1554
|
+
interface MigrationSQLOptions {
|
|
1555
|
+
/**
|
|
1556
|
+
* Schema namespace (default: none — unqualified).
|
|
1557
|
+
* Required when emitted migration SQL would otherwise mix non-default
|
|
1558
|
+
* target-scoped custom types/enums with unqualified table SQL.
|
|
1559
|
+
*/
|
|
1560
|
+
readonly schemaName?: string;
|
|
1561
|
+
/** Whether to include destructive changes (drops) */
|
|
1562
|
+
readonly includeDestructive?: boolean;
|
|
1563
|
+
/** Automatically create indexes on FK columns for new tables (default: true) */
|
|
1564
|
+
readonly fkAutoIndex?: boolean;
|
|
1565
|
+
/** Dialect capabilities — migration SQL for unsupported features will be filtered */
|
|
1566
|
+
readonly dialectCapabilities?: DialectCapabilities;
|
|
1567
|
+
}
|
|
1568
|
+
/**
|
|
1569
|
+
* Generate ordered SQL statements from a SchemaDiff.
|
|
1570
|
+
*
|
|
1571
|
+
* Topological order:
|
|
1572
|
+
* 0. DROP FK/CHECK constraints (must drop before referenced tables)
|
|
1573
|
+
* 1. DROP indexes
|
|
1574
|
+
* 2. DROP columns
|
|
1575
|
+
* 3. DROP primary keys
|
|
1576
|
+
* 4. DROP tables, DROP ENUMs
|
|
1577
|
+
* 5. CREATE ENUMs (must exist before tables that use them)
|
|
1578
|
+
* 6. CREATE tables
|
|
1579
|
+
* 7. ADD columns
|
|
1580
|
+
* 8. ALTER columns (type, nullable, default)
|
|
1581
|
+
* 9. ADD primary keys / column UNIQUE constraints
|
|
1582
|
+
* 10. ADD FK constraints (must add after referenced tables exist)
|
|
1583
|
+
* 11. ALTER FK (drop + re-add)
|
|
1584
|
+
* 12. CREATE indexes
|
|
1585
|
+
* 13. ADD CHECK constraints
|
|
1586
|
+
* 14. ALTER ENUM ADD VALUE (must be last — has transaction visibility caveats in PG)
|
|
1587
|
+
* 15. COMMENT ON TABLE / COLUMN (very last)
|
|
1588
|
+
*/
|
|
1589
|
+
declare function generateMigrationSQL(diff: SchemaDiff, options?: MigrationSQLOptions): readonly string[];
|
|
1590
|
+
/**
|
|
1591
|
+
* Generate ordered DOWN SQL statements from a SchemaDiff.
|
|
1592
|
+
*
|
|
1593
|
+
* Reverses the topological order used in UP migrations:
|
|
1594
|
+
* phases run in descending order (11, 10, 9, ..., 0).
|
|
1595
|
+
*
|
|
1596
|
+
* Irreversible changes (drops that lose data) produce SQL WARNING comments.
|
|
1597
|
+
*/
|
|
1598
|
+
declare function generateDownSQL(diff: SchemaDiff, options?: MigrationSQLOptions): readonly string[];
|
|
1599
|
+
|
|
1600
|
+
/**
|
|
1601
|
+
* Migration File Format v2 — UP + DOWN sections.
|
|
1602
|
+
*
|
|
1603
|
+
* File format:
|
|
1604
|
+
* -- dbsp:destructive: true|false
|
|
1605
|
+
* <UP statements>;
|
|
1606
|
+
* -- DOWN
|
|
1607
|
+
* <DOWN statements>;
|
|
1608
|
+
*
|
|
1609
|
+
* The separator `-- DOWN` must be on its own line (SC-25).
|
|
1610
|
+
*
|
|
1611
|
+
* @module ddl/migration-file
|
|
1612
|
+
*/
|
|
1613
|
+
|
|
1614
|
+
/**
|
|
1615
|
+
* Result of parsing a migration file's UP/DOWN sections.
|
|
1616
|
+
*/
|
|
1617
|
+
interface ParsedMigrationFile {
|
|
1618
|
+
readonly upStatements: readonly string[];
|
|
1619
|
+
readonly downStatements: readonly string[];
|
|
1620
|
+
readonly hasDown: boolean;
|
|
1621
|
+
readonly destructive?: boolean | undefined;
|
|
1622
|
+
}
|
|
1623
|
+
/**
|
|
1624
|
+
* Generate a migration file content with UP and DOWN sections.
|
|
1625
|
+
*/
|
|
1626
|
+
declare function generateMigrationFile(diff: SchemaDiff, options?: MigrationSQLOptions & {
|
|
1627
|
+
name?: string;
|
|
1628
|
+
}): string;
|
|
1629
|
+
/**
|
|
1630
|
+
* Parse a migration file into UP and DOWN sections.
|
|
1631
|
+
* Separator: `^\s*-- DOWN\s*$` (strict regex, own line only — SC-25)
|
|
1632
|
+
*/
|
|
1633
|
+
declare function parseMigrationFile(content: string): ParsedMigrationFile;
|
|
1634
|
+
/**
|
|
1635
|
+
* Check if SQL statements contain destructive operations.
|
|
1636
|
+
* Destructive: DROP TABLE, DROP COLUMN, lossy ALTER COLUMN TYPE
|
|
1637
|
+
*/
|
|
1638
|
+
declare function isDestructiveDown(downStatements: readonly string[]): boolean;
|
|
1639
|
+
|
|
1640
|
+
/**
|
|
1641
|
+
* Migration Tracker — `_dbsp_migrations` table CRUD.
|
|
1642
|
+
*
|
|
1643
|
+
* Manages the tracking table that records which migrations
|
|
1644
|
+
* have been applied to a database.
|
|
1645
|
+
*/
|
|
1646
|
+
|
|
1647
|
+
interface MigrationRecord {
|
|
1648
|
+
/** Migration filename (e.g., "0001_create_users.sql") */
|
|
1649
|
+
readonly name: string;
|
|
1650
|
+
/** SHA-256 checksum of the migration file content */
|
|
1651
|
+
readonly checksum: string;
|
|
1652
|
+
/** When the migration was applied */
|
|
1653
|
+
readonly appliedAt: Date;
|
|
1654
|
+
/** Schema version at time of this migration */
|
|
1655
|
+
readonly schemaVersion: number;
|
|
1656
|
+
/** Whether this migration contains destructive changes */
|
|
1657
|
+
readonly destructive: boolean;
|
|
1658
|
+
}
|
|
1659
|
+
/**
|
|
1660
|
+
* Execute a callback under an advisory lock using a dedicated client.
|
|
1661
|
+
* The lock is held for the duration of the callback.
|
|
1662
|
+
* The client is released (and lock freed) after the callback completes.
|
|
1663
|
+
*/
|
|
1664
|
+
declare function withMigrationLock<T>(pool: Pool, fn: (client: PoolClient) => Promise<T>): Promise<T>;
|
|
1665
|
+
/**
|
|
1666
|
+
* Ensure the migrations tracking table exists.
|
|
1667
|
+
* Auto-migrates existing tables that lack `schema_version`/`destructive` columns,
|
|
1668
|
+
* and backfills `schema_version` by `applied_at` order for rows still at 0.
|
|
1669
|
+
*/
|
|
1670
|
+
declare function ensureMigrationsTable(pool: Pool): Promise<void>;
|
|
1671
|
+
/**
|
|
1672
|
+
* Get all applied migrations, ordered by name.
|
|
1673
|
+
*/
|
|
1674
|
+
declare function getAppliedMigrations(pool: Pool): Promise<readonly MigrationRecord[]>;
|
|
1675
|
+
/**
|
|
1676
|
+
* Record a migration as applied.
|
|
1677
|
+
*/
|
|
1678
|
+
declare function recordMigration(pool: Pool, name: string, checksum: string, schemaVersion: number, destructive: boolean): Promise<void>;
|
|
1679
|
+
/**
|
|
1680
|
+
* Check if a specific migration has been applied.
|
|
1681
|
+
*/
|
|
1682
|
+
declare function isMigrationApplied(pool: Pool, name: string): Promise<boolean>;
|
|
1683
|
+
/**
|
|
1684
|
+
* Get the next schema version number (max + 1, or 1 if no migrations).
|
|
1685
|
+
*/
|
|
1686
|
+
declare function getNextSchemaVersion(pool: Pool): Promise<number>;
|
|
1687
|
+
/**
|
|
1688
|
+
* Remove a migration record (for rollback).
|
|
1689
|
+
*/
|
|
1690
|
+
declare function removeMigrationRecord(pool: Pool, name: string): Promise<void>;
|
|
1691
|
+
|
|
1692
|
+
/**
|
|
1693
|
+
* Type Mapping - Maps ModelIR ColumnType to PostgreSQL data types
|
|
1694
|
+
*
|
|
1695
|
+
* Supports both manual schemas and introspected schemas (preserving originalDbType).
|
|
1696
|
+
* Handles auto-increment via SERIAL/BIGSERIAL types.
|
|
1697
|
+
*
|
|
1698
|
+
* @module ddl/type-mapping
|
|
1699
|
+
*/
|
|
1700
|
+
|
|
1701
|
+
/**
|
|
1702
|
+
* Map ColumnType to PostgreSQL data type string.
|
|
1703
|
+
*
|
|
1704
|
+
* Uses originalDbType if available (from introspection), otherwise
|
|
1705
|
+
* falls back to reasonable PostgreSQL defaults.
|
|
1706
|
+
*
|
|
1707
|
+
* @param col - Column definition from ModelIR
|
|
1708
|
+
* @returns PostgreSQL type string (e.g., 'VARCHAR(255)', 'SERIAL', 'JSONB')
|
|
1709
|
+
*/
|
|
1710
|
+
declare function mapColumnType(col: ColumnIR, targetSchema?: string): string;
|
|
1711
|
+
/**
|
|
1712
|
+
* Map OnDeleteAction to PostgreSQL syntax.
|
|
1713
|
+
*/
|
|
1714
|
+
declare function mapOnDeleteAction(action?: string): string;
|
|
1715
|
+
|
|
1716
|
+
/**
|
|
1717
|
+
* EXPLAIN Statement Compiler
|
|
1718
|
+
*
|
|
1719
|
+
* Generates PostgreSQL EXPLAIN statements with various options.
|
|
1720
|
+
* Supports:
|
|
1721
|
+
* - ANALYZE (execute and show actual run times)
|
|
1722
|
+
* - FORMAT (text, json, xml, yaml)
|
|
1723
|
+
* - VERBOSE, COSTS, BUFFERS, TIMING, SETTINGS
|
|
1724
|
+
*/
|
|
1725
|
+
|
|
1726
|
+
/**
|
|
1727
|
+
* Output format for EXPLAIN results.
|
|
1728
|
+
*/
|
|
1729
|
+
type ExplainFormat = 'text' | 'json' | 'xml' | 'yaml';
|
|
1730
|
+
/**
|
|
1731
|
+
* Options for EXPLAIN statement.
|
|
1732
|
+
*/
|
|
1733
|
+
interface ExplainOptions {
|
|
1734
|
+
/** Execute the query and show actual run times */
|
|
1735
|
+
analyze?: boolean;
|
|
1736
|
+
/** Show more detailed output */
|
|
1737
|
+
verbose?: boolean;
|
|
1738
|
+
/** Show cost estimates (default: true) */
|
|
1739
|
+
costs?: boolean;
|
|
1740
|
+
/** Show buffer usage (requires analyze) */
|
|
1741
|
+
buffers?: boolean;
|
|
1742
|
+
/** Show actual timing (requires analyze) */
|
|
1743
|
+
timing?: boolean;
|
|
1744
|
+
/** Show non-default settings */
|
|
1745
|
+
settings?: boolean;
|
|
1746
|
+
/** Output format */
|
|
1747
|
+
format?: ExplainFormat;
|
|
1748
|
+
}
|
|
1749
|
+
/**
|
|
1750
|
+
* Build an EXPLAIN statement wrapping a query.
|
|
1751
|
+
*
|
|
1752
|
+
* @param query - The query to explain (SelectStmt, InsertStmt, etc.)
|
|
1753
|
+
* @param options - EXPLAIN options
|
|
1754
|
+
* @returns ExplainStmt AST node
|
|
1755
|
+
*
|
|
1756
|
+
* @example
|
|
1757
|
+
* ```typescript
|
|
1758
|
+
* const selectAst = { SelectStmt: { ... } };
|
|
1759
|
+
* const explainAst = buildExplain(selectAst, { analyze: true, format: 'json' });
|
|
1760
|
+
* // Produces: EXPLAIN (ANALYZE, FORMAT JSON) SELECT ...
|
|
1761
|
+
* ```
|
|
1762
|
+
*/
|
|
1763
|
+
declare function buildExplain(query: Node, options?: ExplainOptions): Node;
|
|
1764
|
+
/**
|
|
1765
|
+
* Build EXPLAIN ANALYZE with JSON format (common pattern).
|
|
1766
|
+
*
|
|
1767
|
+
* @param query - The query to explain
|
|
1768
|
+
* @returns ExplainStmt with ANALYZE and JSON format
|
|
1769
|
+
*/
|
|
1770
|
+
declare function buildExplainAnalyzeJson(query: Node): Node;
|
|
1771
|
+
/**
|
|
1772
|
+
* Build simple EXPLAIN (plan only, no execution).
|
|
1773
|
+
*
|
|
1774
|
+
* @param query - The query to explain
|
|
1775
|
+
* @returns ExplainStmt with default options
|
|
1776
|
+
*/
|
|
1777
|
+
declare function buildExplainPlan(query: Node): Node;
|
|
1778
|
+
/**
|
|
1779
|
+
* Build verbose EXPLAIN with costs and buffers.
|
|
1780
|
+
*
|
|
1781
|
+
* @param query - The query to explain
|
|
1782
|
+
* @returns ExplainStmt with verbose options
|
|
1783
|
+
*/
|
|
1784
|
+
declare function buildExplainVerbose(query: Node): Node;
|
|
1785
|
+
/**
|
|
1786
|
+
* Parse EXPLAIN JSON output to get execution statistics.
|
|
1787
|
+
*
|
|
1788
|
+
* @param jsonOutput - The JSON string from EXPLAIN (ANALYZE, FORMAT JSON)
|
|
1789
|
+
* @returns Parsed plan with execution statistics
|
|
1790
|
+
*/
|
|
1791
|
+
declare function parseExplainJson(jsonOutput: string): ExplainPlan[];
|
|
1792
|
+
/**
|
|
1793
|
+
* Parsed EXPLAIN plan structure (simplified).
|
|
1794
|
+
*/
|
|
1795
|
+
interface ExplainPlan {
|
|
1796
|
+
Plan: {
|
|
1797
|
+
'Node Type': string;
|
|
1798
|
+
'Relation Name'?: string;
|
|
1799
|
+
Alias?: string;
|
|
1800
|
+
'Startup Cost'?: number;
|
|
1801
|
+
'Total Cost'?: number;
|
|
1802
|
+
'Plan Rows'?: number;
|
|
1803
|
+
'Plan Width'?: number;
|
|
1804
|
+
'Actual Startup Time'?: number;
|
|
1805
|
+
'Actual Total Time'?: number;
|
|
1806
|
+
'Actual Rows'?: number;
|
|
1807
|
+
'Actual Loops'?: number;
|
|
1808
|
+
Plans?: ExplainPlan['Plan'][];
|
|
1809
|
+
};
|
|
1810
|
+
'Planning Time'?: number;
|
|
1811
|
+
'Execution Time'?: number;
|
|
1812
|
+
Triggers?: unknown[];
|
|
1813
|
+
}
|
|
1814
|
+
/**
|
|
1815
|
+
* Extract total execution time from EXPLAIN ANALYZE JSON output.
|
|
1816
|
+
*
|
|
1817
|
+
* @param plans - Parsed EXPLAIN plans
|
|
1818
|
+
* @returns Total execution time in milliseconds
|
|
1819
|
+
*/
|
|
1820
|
+
declare function getTotalExecutionTime(plans: ExplainPlan[]): number;
|
|
1821
|
+
/**
|
|
1822
|
+
* Extract row counts from EXPLAIN ANALYZE JSON output.
|
|
1823
|
+
*
|
|
1824
|
+
* @param plans - Parsed EXPLAIN plans
|
|
1825
|
+
* @returns Object with estimated and actual row counts
|
|
1826
|
+
*/
|
|
1827
|
+
declare function getRowEstimates(plans: ExplainPlan[]): {
|
|
1828
|
+
estimated: number;
|
|
1829
|
+
actual: number;
|
|
1830
|
+
};
|
|
1831
|
+
|
|
1832
|
+
interface CheckConstraintCanonicalizationWarning {
|
|
1833
|
+
readonly table: string;
|
|
1834
|
+
readonly constraint: string;
|
|
1835
|
+
readonly message: string;
|
|
1836
|
+
readonly cause: unknown;
|
|
1837
|
+
}
|
|
1838
|
+
interface CanonicalizeCheckConstraintsOptions {
|
|
1839
|
+
/** Database schema that owns the target tables and target-scoped enum types. */
|
|
1840
|
+
readonly schemaName?: string;
|
|
1841
|
+
/** Naming convention used when matching desired table names to DB table names. */
|
|
1842
|
+
readonly dbCasing?: DbCasing;
|
|
1843
|
+
/** Called when PostgreSQL CHECK canonicalisation fails and raw comparison is used. */
|
|
1844
|
+
readonly onWarning?: (warning: CheckConstraintCanonicalizationWarning) => void;
|
|
1845
|
+
/** Throw instead of falling back to raw comparison when canonicalisation fails. */
|
|
1846
|
+
readonly requireCanonicalization?: boolean;
|
|
1847
|
+
}
|
|
1848
|
+
type PgsqlCanonicalizationScope = Pick<Adapter, 'executeRaw' | 'transaction'>;
|
|
1849
|
+
declare class CheckConstraintCanonicalizationError extends Error {
|
|
1850
|
+
readonly table: string;
|
|
1851
|
+
readonly constraints: readonly string[];
|
|
1852
|
+
readonly cause: unknown;
|
|
1853
|
+
constructor(table: string, constraints: readonly string[], cause: unknown);
|
|
1854
|
+
}
|
|
1855
|
+
/**
|
|
1856
|
+
* Canonicalise PostgreSQL CHECK constraint expressions in a desired model.
|
|
1857
|
+
*
|
|
1858
|
+
* CHECK constraints are canonicalised by creating a transaction-local temp table
|
|
1859
|
+
* with the desired table's column definitions (borrowing live database type
|
|
1860
|
+
* detail for existing columns when the desired model omits it), adding the
|
|
1861
|
+
* authored CHECK constraints to that temp table, and reading PostgreSQL's
|
|
1862
|
+
* `pg_get_constraintdef()` rendering. The caller must provide a rollback-only
|
|
1863
|
+
* scratch scope; that rollback is cleanup for dbsp-created scratch objects, not
|
|
1864
|
+
* a sandbox for arbitrary session effects.
|
|
1865
|
+
* Missing desired enum types are also created inside that scratch scope before
|
|
1866
|
+
* scratch tables.
|
|
1867
|
+
* Scratch columns include only names and types; defaults, identity, uniqueness,
|
|
1868
|
+
* nullability, and other table-shape clauses are deliberately omitted.
|
|
1869
|
+
*
|
|
1870
|
+
* The returned expression is the full `CHECK (...)` clause. Bare authored
|
|
1871
|
+
* predicates are accepted and become full CHECK clauses.
|
|
1872
|
+
*
|
|
1873
|
+
* PostgreSQL does not allow an enum value added by `ALTER TYPE ... ADD VALUE`
|
|
1874
|
+
* to be used in the same transaction that added it. Because dbsp currently
|
|
1875
|
+
* emits and applies each migration in one transaction, the live diff layer
|
|
1876
|
+
* deliberately refuses CHECK constraints that fall back while the same diff adds
|
|
1877
|
+
* a plausibly referenced enum value. Splitting that into multiple transaction
|
|
1878
|
+
* phases is a separate migration-runner feature.
|
|
1879
|
+
*
|
|
1880
|
+
* This does not canonicalise partial-index predicates or index expressions, so
|
|
1881
|
+
* those surfaces may still compare by raw text in non-strict diffs.
|
|
1882
|
+
*/
|
|
1883
|
+
declare function canonicalizeCheckConstraints(adapter: PgsqlCanonicalizationScope, desired: ModelIR, dbModel: ModelIR, options?: CanonicalizeCheckConstraintsOptions): Promise<ModelIR>;
|
|
1884
|
+
|
|
1885
|
+
/**
|
|
1886
|
+
* ParadeDB Extension Wrappers
|
|
1887
|
+
*
|
|
1888
|
+
* Type-safe query builders for ParadeDB BM25 full-text search.
|
|
1889
|
+
* All functions return ExpressionRef instances that can be used in:
|
|
1890
|
+
* - SELECT: .column(score('id').as('score'))
|
|
1891
|
+
* - WHERE: .where(bm25Search('symbols', query, { name: 3.0, doc: 1.0 }))
|
|
1892
|
+
* - ORDER BY: .orderBy(score('id'), 'desc')
|
|
1893
|
+
*
|
|
1894
|
+
* @remarks
|
|
1895
|
+
* ParadeDB functions accept both named and positional arguments.
|
|
1896
|
+
* This module uses named args via namedArg() for parse(), which produces:
|
|
1897
|
+
* paradedb.parse(field => 'field_name', query_string => $1)
|
|
1898
|
+
* Named parameter syntax is supported via the NamedArgExpressionIntent (EXT-NAMED-PARAMS).
|
|
1899
|
+
*/
|
|
1900
|
+
|
|
1901
|
+
/**
|
|
1902
|
+
* BM25 relevance score for a row.
|
|
1903
|
+
*
|
|
1904
|
+
* Use in SELECT and ORDER BY to retrieve and sort by full-text relevance.
|
|
1905
|
+
* Requires a BM25 index on the table.
|
|
1906
|
+
*
|
|
1907
|
+
* @param keyField - The key field of the BM25 index (typically the primary key, e.g. 'id')
|
|
1908
|
+
* @returns ExpressionRef that compiles to: paradedb.score("keyField")
|
|
1909
|
+
*
|
|
1910
|
+
* @example
|
|
1911
|
+
* orm.select('symbols').column(score('id').as('score')).orderBy(score('id'), 'desc')
|
|
1912
|
+
* // → paradedb.score("id") AS "score"
|
|
1913
|
+
*/
|
|
1914
|
+
declare function score(keyField: string): ExpressionRef;
|
|
1915
|
+
/**
|
|
1916
|
+
* Parse a single-field BM25 query expression.
|
|
1917
|
+
*
|
|
1918
|
+
* Compiles to: paradedb.parse(field => 'field_name', query_string => $N)
|
|
1919
|
+
*
|
|
1920
|
+
* @param field - Column name to search in (must be indexed in the BM25 index)
|
|
1921
|
+
* @param query - Query string value (will be bound as a parameter)
|
|
1922
|
+
* @returns ExpressionRef for use with boost() or booleanSearch()
|
|
1923
|
+
*
|
|
1924
|
+
* @example
|
|
1925
|
+
* parse('name', 'hello world')
|
|
1926
|
+
* // → paradedb.parse(field => 'name', query_string => $1)
|
|
1927
|
+
*/
|
|
1928
|
+
declare function parse(field: string, query: ExpressionRef | unknown): ExpressionRef;
|
|
1929
|
+
/**
|
|
1930
|
+
* Apply a boost multiplier to a BM25 sub-expression.
|
|
1931
|
+
*
|
|
1932
|
+
* Compiles to: paradedb.boost(factor, expr)
|
|
1933
|
+
*
|
|
1934
|
+
* @param factor - Boost multiplier (e.g. 3.0 for 3x weight)
|
|
1935
|
+
* @param expr - Expression to boost (typically a parse() call)
|
|
1936
|
+
* @returns ExpressionRef for use with booleanSearch()
|
|
1937
|
+
*
|
|
1938
|
+
* @example
|
|
1939
|
+
* boost(3.0, parse('name', 'hello'))
|
|
1940
|
+
* // → paradedb.boost(3.0, paradedb.parse('name', $1))
|
|
1941
|
+
*/
|
|
1942
|
+
declare function boost(factor: number, expr: ExpressionRef): ExpressionRef;
|
|
1943
|
+
/**
|
|
1944
|
+
* Combine multiple BM25 sub-expressions with boolean OR logic.
|
|
1945
|
+
*
|
|
1946
|
+
* Compiles to: paradedb.boolean(expr1, expr2, ...)
|
|
1947
|
+
*
|
|
1948
|
+
* @param exprs - One or more sub-expressions (typically boost() calls)
|
|
1949
|
+
* @returns ExpressionRef for use on the right side of the @@@ operator
|
|
1950
|
+
*
|
|
1951
|
+
* @example
|
|
1952
|
+
* booleanSearch([boost(3.0, parse('name', q)), boost(1.0, parse('doc', q))])
|
|
1953
|
+
* // → paradedb.boolean(paradedb.boost(3.0, ...), paradedb.boost(1.0, ...))
|
|
1954
|
+
*/
|
|
1955
|
+
/**
|
|
1956
|
+
* Combine multiple BM25 sub-expressions with boolean OR logic.
|
|
1957
|
+
*
|
|
1958
|
+
* Compiles to: paradedb.boolean(should => ARRAY[expr1, expr2, ...])
|
|
1959
|
+
*
|
|
1960
|
+
* @param exprs - One or more sub-expressions (typically boost() calls)
|
|
1961
|
+
* @returns ExpressionRef for use on the right side of the @@@ operator
|
|
1962
|
+
*
|
|
1963
|
+
* @example
|
|
1964
|
+
* booleanSearch([boost(3.0, parse('name', q)), boost(1.0, parse('doc', q))])
|
|
1965
|
+
* // → paradedb.boolean(should => ARRAY[paradedb.boost(3.0, ...), paradedb.boost(1.0, ...)])
|
|
1966
|
+
*/
|
|
1967
|
+
declare function booleanSearch(exprs: ExpressionRef[]): ExpressionRef;
|
|
1968
|
+
/**
|
|
1969
|
+
* Full BM25 multi-field search with per-field boost weights.
|
|
1970
|
+
*
|
|
1971
|
+
* Produces: table @@@ paradedb.boolean(boost1, boost2, ...)
|
|
1972
|
+
*
|
|
1973
|
+
* Each field in `fieldBoosts` generates a `paradedb.boost(weight, paradedb.parse(field, $N))`
|
|
1974
|
+
* sub-expression. The same query string is used for all fields (single parameter binding).
|
|
1975
|
+
*
|
|
1976
|
+
* @param table - Table alias for the left side of the @@@ operator
|
|
1977
|
+
* @param query - Query string (bound as a single $N parameter, shared across all fields)
|
|
1978
|
+
* @param fieldBoosts - Map of column name → boost weight
|
|
1979
|
+
* @returns ExpressionRef for use in .where()
|
|
1980
|
+
*
|
|
1981
|
+
* @example
|
|
1982
|
+
* bm25Search('s', searchTerm, {
|
|
1983
|
+
* name_searchable: 3.0,
|
|
1984
|
+
* name: 1.0,
|
|
1985
|
+
* signature: 1.5,
|
|
1986
|
+
* doc_searchable: 1.0,
|
|
1987
|
+
* })
|
|
1988
|
+
* // → s @@@ paradedb.boolean(
|
|
1989
|
+
* // paradedb.boost(3.0, paradedb.parse('name_searchable', $1)),
|
|
1990
|
+
* // paradedb.boost(1.0, paradedb.parse('name', $1)),
|
|
1991
|
+
* // paradedb.boost(1.5, paradedb.parse('signature', $1)),
|
|
1992
|
+
* // paradedb.boost(1.0, paradedb.parse('doc_searchable', $1))
|
|
1993
|
+
* // )
|
|
1994
|
+
*
|
|
1995
|
+
* @remarks
|
|
1996
|
+
* The query parameter is shared: all parse() calls reference the same $N slot.
|
|
1997
|
+
* If you need different query strings per field, compose parse()/boost()/booleanSearch() manually.
|
|
1998
|
+
*
|
|
1999
|
+
* @remarks
|
|
2000
|
+
* ParadeDB's boolean() function accepts both positional args and the named
|
|
2001
|
+
* `should => ARRAY[...]` syntax. This wrapper uses positional args.
|
|
2002
|
+
* Named parameter syntax is deferred to EXT-NAMED-PARAMS.
|
|
2003
|
+
*/
|
|
2004
|
+
declare function bm25Search(table: string, query: unknown, fieldBoosts: Record<string, number>): ExpressionRef;
|
|
2005
|
+
|
|
2006
|
+
/**
|
|
2007
|
+
* PostgreSQL built-in function helpers.
|
|
2008
|
+
*
|
|
2009
|
+
* Thin wrappers around core expression primitives for common PostgreSQL functions.
|
|
2010
|
+
* Same pattern as pgvector.ts and paradedb.ts.
|
|
2011
|
+
*/
|
|
2012
|
+
|
|
2013
|
+
/**
|
|
2014
|
+
* Generate a series of values: generate_series(start, stop[, step])
|
|
2015
|
+
*
|
|
2016
|
+
* Returns a set of values from start to stop (inclusive), with an optional step.
|
|
2017
|
+
* Commonly used with CTE for batch operations.
|
|
2018
|
+
*
|
|
2019
|
+
* @example generateSeries(1, 100) → generate_series(1, 100)
|
|
2020
|
+
* @example generateSeries(0, 50, 5) → generate_series(0, 50, 5)
|
|
2021
|
+
*/
|
|
2022
|
+
declare function generateSeries(start: number, stop: number, step?: number): ExpressionRef;
|
|
2023
|
+
/**
|
|
2024
|
+
* Get next value from a sequence: nextval('sequence_name')
|
|
2025
|
+
*
|
|
2026
|
+
* @example nextval('order_id_seq') → nextval('order_id_seq')
|
|
2027
|
+
*/
|
|
2028
|
+
declare function nextval(sequenceName: string): ExpressionRef;
|
|
2029
|
+
|
|
2030
|
+
/**
|
|
2031
|
+
* pgvector Extension Wrappers
|
|
2032
|
+
*
|
|
2033
|
+
* Type-safe query builders for pgvector distance operators.
|
|
2034
|
+
* All functions return ExpressionRef instances that can be used in:
|
|
2035
|
+
* - SELECT: .column(cosineDistance('vector', qv).as('score'))
|
|
2036
|
+
* - WHERE: .where(cosineDistance('vector', qv).gte(0.5))
|
|
2037
|
+
* - ORDER BY: .orderBy(rawDistance('vector', qv), 'asc')
|
|
2038
|
+
*/
|
|
2039
|
+
|
|
2040
|
+
/**
|
|
2041
|
+
* Cosine similarity: 1 - (col <=> vector)
|
|
2042
|
+
*
|
|
2043
|
+
* Score in [0, 1], higher = more similar.
|
|
2044
|
+
* Use in SELECT to get a similarity score.
|
|
2045
|
+
*
|
|
2046
|
+
* @example
|
|
2047
|
+
* orm.select('embeddings').column(cosineDistance('vector', qv).as('score'))
|
|
2048
|
+
*/
|
|
2049
|
+
declare function cosineDistance(column: string, vector: number[]): ExpressionRef;
|
|
2050
|
+
/**
|
|
2051
|
+
* Raw cosine distance: col <=> vector
|
|
2052
|
+
*
|
|
2053
|
+
* Lower = closer. Index-friendly — use in ORDER BY for ANN search.
|
|
2054
|
+
* Do NOT use in SELECT as a similarity score (lower = closer is counterintuitive).
|
|
2055
|
+
*
|
|
2056
|
+
* @example
|
|
2057
|
+
* orm.select('embeddings').orderBy(rawDistance('vector', qv), 'asc')
|
|
2058
|
+
*/
|
|
2059
|
+
declare function rawDistance(column: string, vector: number[]): ExpressionRef;
|
|
2060
|
+
/**
|
|
2061
|
+
* L2 (Euclidean) distance: col <-> vector
|
|
2062
|
+
*
|
|
2063
|
+
* @example
|
|
2064
|
+
* orm.select('embeddings').orderBy(l2Distance('vector', qv), 'asc')
|
|
2065
|
+
*/
|
|
2066
|
+
declare function l2Distance(column: string, vector: number[]): ExpressionRef;
|
|
2067
|
+
/**
|
|
2068
|
+
* Inner product distance: col <#> vector (negative inner product)
|
|
2069
|
+
*
|
|
2070
|
+
* For maximum inner product search: ORDER BY innerProduct('vector', qv) ASC.
|
|
2071
|
+
*
|
|
2072
|
+
* @example
|
|
2073
|
+
* orm.select('embeddings').orderBy(innerProduct('vector', qv), 'asc')
|
|
2074
|
+
*/
|
|
2075
|
+
declare function innerProduct(column: string, vector: number[]): ExpressionRef;
|
|
2076
|
+
/**
|
|
2077
|
+
* Get the number of dimensions of a vector column: vector_dims(col)
|
|
2078
|
+
*
|
|
2079
|
+
* Returns an integer — the dimension count of the stored vector.
|
|
2080
|
+
* Useful for sanity-checking that embeddings match the expected model dimension.
|
|
2081
|
+
*
|
|
2082
|
+
* @example
|
|
2083
|
+
* orm.from(embeddings).columns([vectorDims('vector').as('dim')]).first()
|
|
2084
|
+
* // → SELECT vector_dims("t0"."vector") AS "dim" FROM "embeddings" AS "t0"
|
|
2085
|
+
*/
|
|
2086
|
+
declare function vectorDims(column: string): ExpressionRef;
|
|
2087
|
+
|
|
2088
|
+
/**
|
|
2089
|
+
* Mutation Compiler
|
|
2090
|
+
*
|
|
2091
|
+
* Compiles INSERT, UPDATE, and DELETE statements from plan decisions.
|
|
2092
|
+
* Supports:
|
|
2093
|
+
* - INSERT with values/from subquery
|
|
2094
|
+
* - INSERT with RETURNING
|
|
2095
|
+
* - UPDATE with SET and WHERE
|
|
2096
|
+
* - DELETE with WHERE
|
|
2097
|
+
* - RETURNING clause for all mutations
|
|
2098
|
+
*/
|
|
2099
|
+
|
|
2100
|
+
/**
|
|
2101
|
+
* Configuration for INSERT compilation
|
|
2102
|
+
*/
|
|
2103
|
+
interface InsertConfig {
|
|
2104
|
+
/** Table to insert into */
|
|
2105
|
+
table: string;
|
|
2106
|
+
/** Columns to insert */
|
|
2107
|
+
columns: string[];
|
|
2108
|
+
/** Values for each column (array of rows) */
|
|
2109
|
+
values: unknown[][];
|
|
2110
|
+
/** Columns to return (RETURNING clause) */
|
|
2111
|
+
returning?: string[];
|
|
2112
|
+
/** Alias-aware RETURNING projection items */
|
|
2113
|
+
returningItems?: readonly MutationReturningItem[];
|
|
2114
|
+
/** Subquery for INSERT ... SELECT */
|
|
2115
|
+
selectQuery?: Node;
|
|
2116
|
+
/** Column database types for type-cast emission (e.g. range types) */
|
|
2117
|
+
columnTypes?: Record<string, string>;
|
|
2118
|
+
}
|
|
2119
|
+
/**
|
|
2120
|
+
* Configuration for UPDATE compilation
|
|
2121
|
+
*/
|
|
2122
|
+
interface UpdateConfig {
|
|
2123
|
+
/** Table to update */
|
|
2124
|
+
table: string;
|
|
2125
|
+
/** Column-value pairs to set */
|
|
2126
|
+
set: {
|
|
2127
|
+
column: string;
|
|
2128
|
+
value: unknown;
|
|
2129
|
+
}[];
|
|
2130
|
+
/** WHERE conditions */
|
|
2131
|
+
where?: Decision[];
|
|
2132
|
+
/** Columns to return (RETURNING clause) */
|
|
2133
|
+
returning?: string[];
|
|
2134
|
+
/** Alias-aware RETURNING projection items */
|
|
2135
|
+
returningItems?: readonly MutationReturningItem[];
|
|
2136
|
+
/** Column database types for type-cast emission (e.g. range types) */
|
|
2137
|
+
columnTypes?: Record<string, string>;
|
|
2138
|
+
}
|
|
2139
|
+
/**
|
|
2140
|
+
* Configuration for DELETE compilation
|
|
2141
|
+
*/
|
|
2142
|
+
interface DeleteConfig {
|
|
2143
|
+
/** Table to delete from */
|
|
2144
|
+
table: string;
|
|
2145
|
+
/** WHERE conditions */
|
|
2146
|
+
where?: Decision[];
|
|
2147
|
+
/** Columns to return (RETURNING clause) */
|
|
2148
|
+
returning?: string[];
|
|
2149
|
+
/** Alias-aware RETURNING projection items */
|
|
2150
|
+
returningItems?: readonly MutationReturningItem[];
|
|
2151
|
+
}
|
|
2152
|
+
/**
|
|
2153
|
+
* Compile an INSERT statement from configuration.
|
|
2154
|
+
*/
|
|
2155
|
+
declare function compileInsert(config: InsertConfig, ctx: CompilerContext, state: CompilerState): Node;
|
|
2156
|
+
/**
|
|
2157
|
+
* Compile an UPDATE statement from configuration.
|
|
2158
|
+
*/
|
|
2159
|
+
declare function compileUpdate(config: UpdateConfig, ctx: CompilerContext, state: CompilerState): Node;
|
|
2160
|
+
declare function compileDelete(config: DeleteConfig, ctx: CompilerContext, state: CompilerState): Node;
|
|
2161
|
+
/**
|
|
2162
|
+
* Compile a mutation decision to AST.
|
|
2163
|
+
* Determines mutation type from decision.type and delegates.
|
|
2164
|
+
*/
|
|
2165
|
+
declare function compileMutation(decision: Decision, ctx: CompilerContext, state: CompilerState): Node;
|
|
2166
|
+
|
|
2167
|
+
/**
|
|
2168
|
+
* Upsert (INSERT ... ON CONFLICT) Compiler
|
|
2169
|
+
*
|
|
2170
|
+
* Compiles UPSERT statements with ON CONFLICT handling.
|
|
2171
|
+
* Supports:
|
|
2172
|
+
* - ON CONFLICT DO NOTHING
|
|
2173
|
+
* - ON CONFLICT DO UPDATE SET ...
|
|
2174
|
+
* - Conflict target (columns or constraint name)
|
|
2175
|
+
* - WHERE clause for conflict resolution
|
|
2176
|
+
*/
|
|
2177
|
+
|
|
2178
|
+
/**
|
|
2179
|
+
* Conflict resolution strategy
|
|
2180
|
+
*/
|
|
2181
|
+
type ConflictAction = 'nothing' | 'update';
|
|
2182
|
+
/**
|
|
2183
|
+
* Conflict target specification
|
|
2184
|
+
*/
|
|
2185
|
+
interface ConflictTarget {
|
|
2186
|
+
/** Column names that form the unique constraint */
|
|
2187
|
+
columns?: string[];
|
|
2188
|
+
/** Named constraint */
|
|
2189
|
+
constraint?: string;
|
|
2190
|
+
/** WHERE clause for partial index */
|
|
2191
|
+
where?: Decision[];
|
|
2192
|
+
}
|
|
2193
|
+
/**
|
|
2194
|
+
* Configuration for UPSERT compilation
|
|
2195
|
+
*/
|
|
2196
|
+
interface UpsertConfig {
|
|
2197
|
+
/** Table to upsert into */
|
|
2198
|
+
table: string;
|
|
2199
|
+
/** Columns to insert */
|
|
2200
|
+
columns: string[];
|
|
2201
|
+
/** Values for each column (array of rows) */
|
|
2202
|
+
values: unknown[][];
|
|
2203
|
+
/** Conflict target (unique columns or constraint) */
|
|
2204
|
+
conflictTarget: ConflictTarget;
|
|
2205
|
+
/** What to do on conflict */
|
|
2206
|
+
conflictAction: ConflictAction;
|
|
2207
|
+
/** Columns to update on conflict (for 'update' action) */
|
|
2208
|
+
updateColumns?: string[];
|
|
2209
|
+
/** Optional WHERE clause for ON CONFLICT DO UPDATE */
|
|
2210
|
+
actionWhere?: Decision[];
|
|
2211
|
+
/** Optional direct WHERE intent for ON CONFLICT DO UPDATE */
|
|
2212
|
+
actionWhereIntent?: WhereIntent;
|
|
2213
|
+
/** Compile the direct action WHERE intent using the caller's WHERE compiler */
|
|
2214
|
+
compileActionWhere?: (where: WhereIntent, state: CompilerState) => Node;
|
|
2215
|
+
/** Use EXCLUDED.column for update values (default: true) */
|
|
2216
|
+
useExcluded?: boolean;
|
|
2217
|
+
/** Columns to return (RETURNING clause) */
|
|
2218
|
+
returning?: string[];
|
|
2219
|
+
/** Alias-aware RETURNING projection items */
|
|
2220
|
+
returningItems?: readonly MutationReturningItem[];
|
|
2221
|
+
/** Optional column type hints for unnest casting (schema-driven) */
|
|
2222
|
+
columnTypes?: Record<string, string>;
|
|
2223
|
+
/**
|
|
2224
|
+
* Raw SQL expressions for specific update columns.
|
|
2225
|
+
* These are injected verbatim into the ON CONFLICT DO UPDATE SET clause.
|
|
2226
|
+
* Keys are logical column names (before naming plugin), values are raw SQL fragments.
|
|
1945
2227
|
*
|
|
1946
|
-
*
|
|
1947
|
-
*
|
|
1948
|
-
* With no known schema the table is left unqualified so ::regclass resolves it
|
|
1949
|
-
* through search_path (the same table an unqualified reference would hit).
|
|
2228
|
+
* @warning SECURITY: fragments are inserted without parameterization.
|
|
2229
|
+
* Only use with hardcoded expressions. Never with user input.
|
|
1950
2230
|
*
|
|
1951
|
-
* @
|
|
1952
|
-
* @param schema - Schema name (defaults to the search_path-resolved schema)
|
|
1953
|
-
*/
|
|
1954
|
-
storageSize(table: string, schema?: string): Promise<number>;
|
|
1955
|
-
/**
|
|
1956
|
-
* Generate SQL for TRUNCATE TABLE.
|
|
1957
|
-
* Implements TableDDLGeneratorAdapter.generateTruncate.
|
|
1958
|
-
*/
|
|
1959
|
-
generateTruncate(table: string, schema?: string, options?: TruncateOptions): string;
|
|
1960
|
-
/**
|
|
1961
|
-
* Generate SQL for VACUUM.
|
|
1962
|
-
* Implements TableDDLGeneratorAdapter.generateVacuum.
|
|
1963
|
-
*/
|
|
1964
|
-
generateVacuum(table: string, schema?: string, options?: VacuumOptions): string;
|
|
1965
|
-
/**
|
|
1966
|
-
* Generate SQL for ALTER TABLE ... ALTER COLUMN.
|
|
1967
|
-
* Implements TableDDLGeneratorAdapter.generateAlterColumn.
|
|
1968
|
-
*/
|
|
1969
|
-
generateAlterColumn(table: string, column: string, options: AlterColumnOptions, schema?: string): string;
|
|
1970
|
-
/**
|
|
1971
|
-
* Generate SQL for CREATE INDEX.
|
|
1972
|
-
* Implements TableDDLGeneratorAdapter.generateCreateIndex.
|
|
1973
|
-
*/
|
|
1974
|
-
generateCreateIndex(table: string, options: CreateIndexOptions, schema?: string): string;
|
|
1975
|
-
/**
|
|
1976
|
-
* Generate SQL for DROP INDEX.
|
|
1977
|
-
* Implements TableDDLGeneratorAdapter.generateDropIndex.
|
|
1978
|
-
*/
|
|
1979
|
-
generateDropIndex(name: string, options?: DropIndexOptions): string;
|
|
1980
|
-
/**
|
|
1981
|
-
* Validate an identifier (table name, column name, schema name).
|
|
2231
|
+
* @example { last_parsed: 'now()', count: 'excluded.count + 1' }
|
|
1982
2232
|
*/
|
|
1983
|
-
|
|
2233
|
+
updateExpressions?: Record<string, string>;
|
|
1984
2234
|
}
|
|
1985
2235
|
/**
|
|
1986
|
-
*
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
*
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
*
|
|
1995
|
-
*
|
|
2236
|
+
* Build ON CONFLICT clause for INSERT statement.
|
|
2237
|
+
*/
|
|
2238
|
+
declare function buildOnConflictClause(config: UpsertConfig, ctx: CompilerContext, state: CompilerState): OnConflictClause;
|
|
2239
|
+
/**
|
|
2240
|
+
* Compile a complete UPSERT statement.
|
|
2241
|
+
*/
|
|
2242
|
+
declare function compileUpsert(config: UpsertConfig, ctx: CompilerContext, state: CompilerState): Node;
|
|
2243
|
+
/**
|
|
2244
|
+
* Build EXCLUDED.column reference.
|
|
2245
|
+
* EXCLUDED is a special table alias in ON CONFLICT ... DO UPDATE
|
|
2246
|
+
* that refers to the row that would have been inserted.
|
|
2247
|
+
*/
|
|
2248
|
+
declare function excludedRef(column: string, naming: {
|
|
2249
|
+
toDatabase: (s: string) => string;
|
|
2250
|
+
}): Node;
|
|
2251
|
+
/**
|
|
2252
|
+
* Build conditional update using COALESCE.
|
|
1996
2253
|
*
|
|
1997
|
-
*
|
|
1998
|
-
*
|
|
2254
|
+
* Produces: COALESCE(EXCLUDED.col, table.col)
|
|
2255
|
+
* This keeps existing value if new value is NULL.
|
|
2256
|
+
*/
|
|
2257
|
+
declare function conditionalUpdate(column: string, table: string, ctx: CompilerContext): Node;
|
|
2258
|
+
|
|
2259
|
+
/**
|
|
2260
|
+
* @module naming
|
|
2261
|
+
* Utilities for resolving database names to logical model names.
|
|
1999
2262
|
*
|
|
2000
|
-
*
|
|
2001
|
-
*
|
|
2002
|
-
*
|
|
2263
|
+
* The ModelIR.getTable() method expects logical (camelCase) names,
|
|
2264
|
+
* but the adapter often works with database (snake_case) names.
|
|
2265
|
+
* This module bridges that gap.
|
|
2003
2266
|
*/
|
|
2004
|
-
|
|
2267
|
+
|
|
2005
2268
|
/**
|
|
2006
|
-
*
|
|
2269
|
+
* Resolve a database table name to the corresponding logical model name.
|
|
2007
2270
|
*
|
|
2008
|
-
*
|
|
2009
|
-
*
|
|
2271
|
+
* Converts the DB name using the naming convention, then looks it up in the model.
|
|
2272
|
+
* Falls back to exact match if conversion doesn't find a match.
|
|
2273
|
+
*
|
|
2274
|
+
* @param model - The model IR to search in
|
|
2275
|
+
* @param dbName - Database table name (e.g. "post_comments")
|
|
2276
|
+
* @param convention - Naming convention used by the adapter
|
|
2277
|
+
* @returns The logical table name if found, undefined otherwise
|
|
2010
2278
|
*
|
|
2011
2279
|
* @example
|
|
2012
2280
|
* ```typescript
|
|
2013
|
-
*
|
|
2014
|
-
*
|
|
2015
|
-
*
|
|
2016
|
-
*
|
|
2017
|
-
* const orm = createOrm({ model, adapter });
|
|
2018
|
-
* const dump = await orm.select('users').dump();
|
|
2019
|
-
* console.log(dump.sql);
|
|
2281
|
+
* // With camelCase convention:
|
|
2282
|
+
* resolveLogicalName(model, "post_comments", "camelCase") // → "postComments"
|
|
2283
|
+
* resolveLogicalName(model, "posts", "camelCase") // → "posts"
|
|
2284
|
+
* resolveLogicalName(model, "unknown", "camelCase") // → undefined
|
|
2020
2285
|
* ```
|
|
2021
2286
|
*/
|
|
2022
|
-
declare function
|
|
2287
|
+
declare function resolveLogicalName(model: ModelIR, dbName: string, casing: DbCasing): string | undefined;
|
|
2288
|
+
|
|
2289
|
+
/**
|
|
2290
|
+
* ParamRef validation and helpers for PostgreSQL AST
|
|
2291
|
+
*
|
|
2292
|
+
* ParamRef nodes represent parameterized query placeholders ($1, $2, etc.)
|
|
2293
|
+
* This module provides validation and creation helpers for safe AST construction.
|
|
2294
|
+
*/
|
|
2295
|
+
|
|
2296
|
+
/**
|
|
2297
|
+
* Validation result for ParamRef nodes
|
|
2298
|
+
*/
|
|
2299
|
+
interface ParamRefValidationResult {
|
|
2300
|
+
valid: boolean;
|
|
2301
|
+
errors: string[];
|
|
2302
|
+
}
|
|
2303
|
+
/**
|
|
2304
|
+
* Validates a ParamRef node
|
|
2305
|
+
*
|
|
2306
|
+
* Rules:
|
|
2307
|
+
* - `number` must be a positive integer (1-based indexing)
|
|
2308
|
+
* - `number` must not exceed reasonable bounds (e.g., 65535)
|
|
2309
|
+
*/
|
|
2310
|
+
declare function validateParamRef(paramRef: ParamRef): ParamRefValidationResult;
|
|
2311
|
+
/**
|
|
2312
|
+
* Creates a validated ParamRef node
|
|
2313
|
+
* @throws Error if validation fails
|
|
2314
|
+
*/
|
|
2315
|
+
declare function createParamRef(number: number, location?: number): Node;
|
|
2316
|
+
/**
|
|
2317
|
+
* Creates a TypeCast node wrapping a ParamRef
|
|
2318
|
+
* Example: $1::integer, $2::text[]
|
|
2319
|
+
*/
|
|
2320
|
+
declare function createTypeCastParamRef(paramNumber: number, typeName: string, isArray?: boolean, location?: number): Node;
|
|
2321
|
+
/**
|
|
2322
|
+
* Creates an A_Expr node for equality comparison with ParamRef
|
|
2323
|
+
* Example: col = $1
|
|
2324
|
+
*/
|
|
2325
|
+
declare function createEqualityExpr(columnName: string, paramNumber: number, tableName?: string, location?: number): Node;
|
|
2326
|
+
/**
|
|
2327
|
+
* Creates a FuncCall node for ANY() with ParamRef
|
|
2328
|
+
* Example: col = ANY($1) for array parameter matching
|
|
2329
|
+
*/
|
|
2330
|
+
declare function createAnyExpr(columnName: string, paramNumber: number, tableName?: string, location?: number): Node;
|
|
2331
|
+
/**
|
|
2332
|
+
* Collects all ParamRef nodes from an AST, validating each
|
|
2333
|
+
* Returns validation results for all found ParamRefs
|
|
2334
|
+
*/
|
|
2335
|
+
declare function collectAndValidateParamRefs(node: unknown): {
|
|
2336
|
+
paramRefs: Array<{
|
|
2337
|
+
paramRef: ParamRef;
|
|
2338
|
+
path: string;
|
|
2339
|
+
}>;
|
|
2340
|
+
validationResults: ParamRefValidationResult[];
|
|
2341
|
+
allValid: boolean;
|
|
2342
|
+
};
|
|
2023
2343
|
|
|
2024
2344
|
/**
|
|
2025
2345
|
* Redact sensitive values in a query dump's `params` array before logging.
|
|
@@ -2342,4 +2662,4 @@ declare function sanitizeForDisplay(value: string): string;
|
|
|
2342
2662
|
*/
|
|
2343
2663
|
declare function validateSqlExpression(sql: string, context: string): void;
|
|
2344
2664
|
|
|
2345
|
-
export { type BatchValuesJoinDecision, CamelCaseNamingPlugin, type ChangeKind, type CompareSchemataOptions, type CompiledResult, type CompilerContext, type CompilerOptions, type CompilerState, type ConflictAction, type ConflictTarget, type CursorHoldOption, type CursorOptions, type CursorScrollOption, DEFAULT_PK_COLUMN, DEFAULT_REDACTION_PATTERNS, type Decision, type DeleteConfig, type DetectedHierarchy, type DiffSummary, type ExplainFormat, type ExplainOptions, type ExplainPlan, type ExpressionHandler, type FetchDirection, type FetchOptions, type FkColumnDerivation, type GenerateDDLOptions, IdentityNamingPlugin, type IncludeHandler, type IncludeResult, type InsertConfig, type IntrospectedModelIR, type IntrospectionOptions, InvalidIdentifierError, type JoinDecision, type LeafCompileFn, type MigrationRecord, type MigrationSQLOptions, type NamingPlugin, type ParamRefValidationResult, type ParsedMigrationFile, PgsqlAdapter, type PgsqlAdapterOptions, PlanCompiler, type PlanDecision, type PrecompiledJoinDecision, type RedactionConfig, type RedactionPattern, type SchemaChange, type SchemaDiff, type SetOperationResult, type SimplifiedPlanReport, type StreamConfig, type UpdateConfig, type UpsertConfig, type WhereDispatcher, type WhereHandler, bm25Search, booleanSearch, boost, buildCloseCursor, buildDeclareCursor, buildExplain, buildExplainAnalyzeJson, buildExplainPlan, buildExplainVerbose, buildFetch, buildFetchAll, buildFetchFirst, buildFetchForward, buildFetchNext, buildOnConflictClause, buildStreamingStatements, camelCaseNaming, canGenerateCreateIndex, collectAndValidateParamRefs, compareSchemata, compileDelete, compileInsert, compileMutation, compilePlan, compileSetOperation, compileUpdate, compileUpsert, conditionalUpdate, cosineDistance, createAnyExpr, createEqualityExpr, createLeafCompileFn, createParamRef, createPgsqlAdapter, createPgsqlCompileOnlyAdapter, createTypeCastParamRef, defaultFkDerivation, ensureMigrationsTable, excludedRef, generateCreateIndex, generateCursorName, generateDDL, generateDownSQL, generateMigrationFile, generateMigrationSQL, generateSeries, getAppliedMigrations, getNamingPluginForDbCasing, getNextSchemaVersion, getRowEstimates, getTotalExecutionTime, identityNaming, innerProduct, introspect, isBatchValuesJoinDecision, isDestructiveDown, isJoinDecision, isMigrationApplied, isPrecompiledJoinDecision, isReservedKeyword, l2Distance, mapColumnType, mapOnDeleteAction, nextval, parse, parseExplainJson, parseMigrationFile, rawDistance, recordMigration, redactParams, removeMigrationRecord, resolveLogicalName, sanitizeForDisplay, score, validateIdentifier, validateIdentifiers, validateParamRef, validateQualifiedIdentifier, validateSqlExpression, vectorDims, withMigrationLock };
|
|
2665
|
+
export { type AddedEnumValue, type BatchValuesJoinDecision, CamelCaseNamingPlugin, type CanonicalizeCheckConstraintsOptions, type ChangeKind, CheckConstraintCanonicalizationError, type CheckConstraintCanonicalizationWarning, CheckConstraintNewEnumValueError, type ComparePgsqlDatabaseSchemaOptions, type CompareSchemataOptions, type CompiledResult, type CompilerContext, type CompilerOptions, type CompilerState, type ConflictAction, type ConflictTarget, type CursorHoldOption, type CursorOptions, type CursorScrollOption, DEFAULT_PK_COLUMN, DEFAULT_REDACTION_PATTERNS, type Decision, type DeleteConfig, type DetectedHierarchy, type DiffSummary, type ExplainFormat, type ExplainOptions, type ExplainPlan, ExpressionCanonicalizationUnavailableError, type ExpressionHandler, type FetchDirection, type FetchOptions, type FkColumnDerivation, type GenerateDDLOptions, IdentityNamingPlugin, type IncludeHandler, type IncludeResult, type InsertConfig, type IntrospectedModelIR, type IntrospectionOptions, InvalidIdentifierError, type JoinDecision, type LeafCompileFn, type MigrationRecord, type MigrationSQLOptions, type NamingPlugin, NonConvergentSchemaDiffError, type ParamRefValidationResult, type ParsedMigrationFile, PgsqlAdapter, type PgsqlAdapterOptions, type PgsqlBorrowedClientAdapterOptions, type PgsqlPoolAdapterOptions, PgsqlRawSqlTransactionControlError, PgsqlTransactionAbortedCommitError, PgsqlTransactionAbortedError, PlanCompiler, type PlanDecision, type PrecompiledJoinDecision, type RedactionConfig, type RedactionPattern, type SchemaChange, type SchemaDiff, type SchemaScopeOptions, type SetOperationResult, type SimplifiedPlanReport, type StreamConfig, type UpdateConfig, type UpsertConfig, type WhereDispatcher, type WhereHandler, assertNoRepeatedExpressionSurfaceDrift, bm25Search, booleanSearch, boost, buildCloseCursor, buildDeclareCursor, buildExplain, buildExplainAnalyzeJson, buildExplainPlan, buildExplainVerbose, buildFetch, buildFetchAll, buildFetchFirst, buildFetchForward, buildFetchNext, buildOnConflictClause, buildStreamingStatements, camelCaseNaming, canGenerateCreateIndex, canonicalizeCheckConstraints, collectAndValidateParamRefs, comparePgsqlDatabaseSchema, compareSchemata, compileDelete, compileInsert, compileMutation, compilePlan, compileSetOperation, compileUpdate, compileUpsert, conditionalUpdate, cosineDistance, createAnyExpr, createEqualityExpr, createLeafCompileFn, createParamRef, createPgsqlAdapter, createPgsqlCompileOnlyAdapter, createTypeCastParamRef, defaultFkDerivation, ensureMigrationsTable, excludedRef, generateCreateIndex, generateCursorName, generateDDL, generateDownSQL, generateMigrationFile, generateMigrationSQL, generateSeries, getAppliedMigrations, getNamingPluginForDbCasing, getNextSchemaVersion, getRowEstimates, getTotalExecutionTime, identityNaming, innerProduct, introspect, isBatchValuesJoinDecision, isDestructiveDown, isJoinDecision, isMigrationApplied, isPrecompiledJoinDecision, isReservedKeyword, l2Distance, mapColumnType, mapOnDeleteAction, nextval, parse, parseExplainJson, parseMigrationFile, rawDistance, recordMigration, redactParams, removeMigrationRecord, resolveLogicalName, sanitizeForDisplay, score, validateIdentifier, validateIdentifiers, validateParamRef, validateQualifiedIdentifier, validateSqlExpression, vectorDims, withMigrationLock };
|