@crvouga/mockingbird-service-postgres 3.2.0 → 3.3.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.
Files changed (52) hide show
  1. package/CHANGELOG.md +11 -1
  2. package/COMPATIBILITY.md +35 -5
  3. package/README.md +147 -4
  4. package/compat/coverage.json +8 -7
  5. package/compat/divergences.json +37 -2
  6. package/compat/requirements.json +1 -1
  7. package/compat/sections/cat.ts +49 -0
  8. package/compat/sections/ddl.ts +11 -0
  9. package/compat/unsupported-register.json +0 -3
  10. package/dist/admin.js +3197 -542
  11. package/dist/admin.js.map +4 -4
  12. package/dist/api/database.d.ts +11 -0
  13. package/dist/ast/nodes.d.ts +43 -1
  14. package/dist/constraints/enforce.d.ts +2 -0
  15. package/dist/executor/alter-column.d.ts +27 -0
  16. package/dist/executor/comment.d.ts +4 -0
  17. package/dist/executor/ddl.d.ts +1 -2
  18. package/dist/executor/dml.d.ts +2 -0
  19. package/dist/executor/extensions.d.ts +11 -0
  20. package/dist/executor/maintenance.d.ts +25 -0
  21. package/dist/expressions/context.d.ts +1 -1
  22. package/dist/index.d.ts +1 -1
  23. package/dist/index.js +3249 -549
  24. package/dist/index.js.map +4 -4
  25. package/dist/parser/parser.d.ts +9 -0
  26. package/dist/schema/catalog-extensions.d.ts +5 -0
  27. package/dist/schema/extensions.d.ts +33 -0
  28. package/dist/schema/index-catalog.d.ts +40 -0
  29. package/dist/schema/persistence.d.ts +32 -0
  30. package/dist/schema/storage.d.ts +22 -0
  31. package/dist/server.js +5384 -743
  32. package/dist/server.js.map +4 -4
  33. package/dist/sql/deparse-default.d.ts +12 -0
  34. package/dist/sql/deparse-index.d.ts +12 -2
  35. package/dist/sql/keywords.d.ts +6 -0
  36. package/dist/sql/ruleutils.d.ts +27 -0
  37. package/dist/storage/database-state.d.ts +51 -0
  38. package/dist/types/regnamespace.d.ts +23 -0
  39. package/dist/types/value.d.ts +2 -0
  40. package/dist/unstable.js +11520 -8875
  41. package/dist/unstable.js.map +4 -4
  42. package/dist/wire/cli.js +5393 -749
  43. package/dist/wire/cli.js.map +4 -4
  44. package/dist/wire/cluster.d.ts +8 -0
  45. package/dist/wire/connection.d.ts +38 -0
  46. package/dist/wire/durable.d.ts +82 -0
  47. package/dist/wire/file-storage.d.ts +3 -0
  48. package/dist/wire/index.d.ts +21 -1
  49. package/dist/wire/index.js +5383 -741
  50. package/dist/wire/index.js.map +4 -4
  51. package/dist/wire/startup.d.ts +36 -0
  52. package/package.json +1 -1
@@ -1,4 +1,5 @@
1
1
  import { type DatabaseOptions, type Int8Mode, type RandomMode } from "../runtime/index.js";
2
+ import type { EngineFaults } from "../storage/database-state.js";
2
3
  import type { BindValue, JsValue, QueryRow } from "./bind.js";
3
4
  import { type Snapshot } from "./snapshot.js";
4
5
  import { Statement } from "./statement.js";
@@ -24,6 +25,8 @@ export interface QueryOptions {
24
25
  */
25
26
  at?: Snapshot | string;
26
27
  }
28
+ /** One-shot failures armed with {@link Database.fault}. */
29
+ export type DatabaseFaults = EngineFaults;
27
30
  /**
28
31
  * Pure TypeScript in-memory PostgreSQL database.
29
32
  *
@@ -99,6 +102,14 @@ export declare class Database {
99
102
  get history(): DatabaseHistory;
100
103
  /** Open a copy-on-write branch from `at`, or from the current state when omitted. */
101
104
  branch(at?: Snapshot): Database;
105
+ /**
106
+ * Arm a one-shot failure for a test. `concurrentIndexBuild` makes the next
107
+ * `CREATE INDEX CONCURRENTLY` or `REINDEX ... CONCURRENTLY` fail with that SQLSTATE
108
+ * (`57014` canceled, `40P01` deadlock) and, as PostgreSQL does when such a build is
109
+ * interrupted, leave the index it was building in the catalog with `indisvalid = false`.
110
+ * Faults are not part of snapshots and survive transaction rollback until they fire.
111
+ */
112
+ fault(faults: DatabaseFaults): void;
102
113
  /** Close the database. Further SQL throws. Idempotent. */
103
114
  close(): void;
104
115
  /**
@@ -206,6 +206,8 @@ export interface SubstringExpr {
206
206
  readonly forLen: Expr | null;
207
207
  readonly similar: Expr | null;
208
208
  readonly escape: Expr | null;
209
+ /** written as an ordinary call, `substring(x, 1, 2)`, rather than with FROM / FOR */
210
+ readonly call?: boolean;
209
211
  }
210
212
  export interface OverlayExpr {
211
213
  readonly type: "overlay";
@@ -433,6 +435,11 @@ export type ColumnConstraint = {
433
435
  } | {
434
436
  kind: "collate";
435
437
  collation: string[];
438
+ }
439
+ /** `STORAGE mode`; the mode is validated against the column type when the column is built */
440
+ | {
441
+ kind: "storage";
442
+ mode: string;
436
443
  };
437
444
  export type RefAction = "no_action" | "restrict" | "cascade" | "set_null" | "set_default" | null;
438
445
  export interface ColumnDef {
@@ -489,6 +496,7 @@ export interface CreateTableAsStmt {
489
496
  readonly query: SelectStmt;
490
497
  readonly withData: boolean;
491
498
  readonly materialized: boolean;
499
+ readonly unlogged?: boolean;
492
500
  }
493
501
  export interface CreateIndexStmt {
494
502
  readonly type: "create_index";
@@ -505,6 +513,11 @@ export interface CreateIndexStmt {
505
513
  opclass: string[] | null;
506
514
  }>;
507
515
  readonly include: string[];
516
+ /** WITH (...) storage parameters as written */
517
+ readonly options?: ReadonlyArray<{
518
+ name: string;
519
+ value: string;
520
+ }>;
508
521
  readonly where: Expr | null;
509
522
  readonly nullsNotDistinct: boolean;
510
523
  readonly concurrently: boolean;
@@ -530,12 +543,15 @@ export interface SequenceOptions {
530
543
  ownedBy?: string[] | "none";
531
544
  as?: TypeName;
532
545
  restart?: bigint | "default";
546
+ /** ALTER SEQUENCE ... SET LOGGED (true) / SET UNLOGGED (false) */
547
+ logged?: boolean;
533
548
  }
534
549
  export interface CreateSequenceStmt {
535
550
  readonly type: "create_sequence";
536
551
  readonly name: string[];
537
552
  readonly ifNotExists: boolean;
538
553
  readonly temp: boolean;
554
+ readonly unlogged?: boolean;
539
555
  readonly options: SequenceOptions;
540
556
  }
541
557
  export interface AlterSequenceStmt {
@@ -652,6 +668,15 @@ export type AlterTableAction = {
652
668
  } | {
653
669
  kind: "drop_not_null";
654
670
  column: string;
671
+ }
672
+ /** `mode` is the identifier as written (or "default"); validated against the column type at execution */
673
+ | {
674
+ kind: "set_storage";
675
+ column: string;
676
+ mode: string;
677
+ } | {
678
+ kind: "set_logged";
679
+ logged: boolean;
655
680
  } | {
656
681
  kind: "add_constraint";
657
682
  constraint: TableConstraint;
@@ -739,6 +764,8 @@ export interface DropStmt {
739
764
  readonly funcArgs: TypeName[][] | null;
740
765
  readonly ifExists: boolean;
741
766
  readonly cascade: boolean;
767
+ /** DROP INDEX CONCURRENTLY */
768
+ readonly concurrently?: boolean;
742
769
  }
743
770
  export interface TruncateStmt {
744
771
  readonly type: "truncate";
@@ -810,6 +837,21 @@ export interface CommentStmt {
810
837
  readonly objectName: string[];
811
838
  readonly comment: string | null;
812
839
  }
840
+ export interface AnalyzeStmt {
841
+ readonly type: "analyze";
842
+ /** empty means every table */
843
+ readonly targets: ReadonlyArray<{
844
+ table: string[];
845
+ columns: string[] | null;
846
+ }>;
847
+ }
848
+ export interface ReindexStmt {
849
+ readonly type: "reindex";
850
+ readonly kind: "index" | "table" | "schema" | "database" | "system";
851
+ /** null only for REINDEX DATABASE / SYSTEM without a name */
852
+ readonly name: string[] | null;
853
+ readonly concurrently: boolean;
854
+ }
813
855
  export interface NoOpStmt {
814
856
  readonly type: "no_op";
815
857
  readonly what: string;
@@ -819,4 +861,4 @@ export interface DoStmt {
819
861
  readonly language: string;
820
862
  readonly body: string;
821
863
  }
822
- export type Statement = SelectStmt | InsertStmt | UpdateStmt | DeleteStmt | CreateTableStmt | CreateTableAsStmt | CreateIndexStmt | CreateViewStmt | CreateSequenceStmt | AlterSequenceStmt | CreateSchemaStmt | CreateExtensionStmt | CreateEnumStmt | AlterEnumStmt | CreateDomainStmt | CreateFunctionStmt | CreateTriggerStmt | AlterTableStmt | AlterViewStmt | AlterIndexStmt | AlterSchemaStmt | DropStmt | TruncateStmt | RefreshMaterializedViewStmt | TransactionStmt | SetStmt | ShowStmt | ResetStmt | PrepareStmt | ExecuteStmt | DeallocateStmt | ExplainStmt | CopyStmt | CommentStmt | NoOpStmt | DoStmt;
864
+ export type Statement = SelectStmt | InsertStmt | UpdateStmt | DeleteStmt | CreateTableStmt | CreateTableAsStmt | CreateIndexStmt | CreateViewStmt | CreateSequenceStmt | AlterSequenceStmt | CreateSchemaStmt | CreateExtensionStmt | CreateEnumStmt | AlterEnumStmt | CreateDomainStmt | CreateFunctionStmt | CreateTriggerStmt | AlterTableStmt | AlterViewStmt | AlterIndexStmt | AlterSchemaStmt | DropStmt | TruncateStmt | RefreshMaterializedViewStmt | TransactionStmt | SetStmt | ShowStmt | ResetStmt | PrepareStmt | ExecuteStmt | DeallocateStmt | ExplainStmt | CopyStmt | CommentStmt | AnalyzeStmt | ReindexStmt | NoOpStmt | DoStmt;
@@ -18,6 +18,8 @@ interface UniqueSpec {
18
18
  isPrimary: boolean;
19
19
  }
20
20
  export declare function uniqueSpecsFor(env: ExecEnv, table: TableData): UniqueSpec[];
21
+ /** The uniqueness rule a unique index states, whether or not the index is currently valid. */
22
+ export declare function uniqueSpecOfIndex(table: TableData, idx: IndexMeta): UniqueSpec;
21
23
  export declare function uniqueKeyOf(env: ExecEnv, table: TableData, spec: UniqueSpec, row: Datum[]): string | null;
22
24
  /**
23
25
  * Unique / primary key enforcement (23505). `selfIdx` is the row's own index
@@ -0,0 +1,27 @@
1
+ import type { AlterTableAction, AlterTableStmt, Expr } from "../ast/nodes.js";
2
+ import type { ColumnMeta, DatabaseState, SequenceData, TableData } from "../storage/database-state.js";
3
+ import type { ExecEnv } from "./relation.js";
4
+ /** The named user column, or PostgreSQL's error for a system or missing one. */
5
+ export declare function alterableColumn(table: TableData, name: string): ColumnMeta;
6
+ /** `ALTER SEQUENCE ... SET LOGGED | UNLOGGED`, also reachable as `ALTER TABLE <sequence> SET ...`. */
7
+ export declare function setSequenceLogged(state: DatabaseState, seq: SequenceData, logged: boolean): void;
8
+ /**
9
+ * `ALTER TABLE` named something that is not a table. Returns true when the
10
+ * statement was carried out against a sequence; throws PostgreSQL's
11
+ * wrong-object-type error for the actions views do not accept; otherwise
12
+ * returns false and the caller reports the relation as it always has.
13
+ */
14
+ export declare function alterNonTableRelation(state: DatabaseState, stmt: AlterTableStmt): boolean;
15
+ /**
16
+ * Validate every SET LOGGED / SET UNLOGGED action of one statement against
17
+ * the table as it stands, the way PostgreSQL's preparation phase does: once
18
+ * an action really changes the persistence, a second one is an error.
19
+ * Returns the persistence to apply, or null when nothing changes.
20
+ */
21
+ export declare function planLoggedChange(state: DatabaseState, table: TableData, actions: readonly AlterTableAction[]): boolean | null;
22
+ /** Flip the table and the sequences its columns own; indexes report their table's persistence. */
23
+ export declare function applyLoggedChange(state: DatabaseState, table: TableData, logged: boolean): void;
24
+ export declare function setColumnStorage(table: TableData, columnName: string, mode: string): void;
25
+ export declare function dropColumnNotNull(table: TableData, columnName: string): void;
26
+ export declare function setColumnDefault(env: ExecEnv, table: TableData, columnName: string, expr: Expr): void;
27
+ export declare function dropColumnDefault(table: TableData, columnName: string): void;
@@ -1,3 +1,7 @@
1
1
  import type { CommentStmt } from "../ast/nodes.js";
2
2
  import { type ExecEnv, type ExecResult } from "./relation.js";
3
+ /**
4
+ * COMMENT ON. Only index comments are stored (they surface in pg_description);
5
+ * comments on every other kind of object are accepted and dropped.
6
+ */
3
7
  export declare function executeComment(env: ExecEnv, stmt: CommentStmt): ExecResult;
@@ -1,4 +1,4 @@
1
- import type { AlterEnumStmt, AlterIndexStmt, AlterSchemaStmt, AlterSequenceStmt, AlterTableStmt, AlterViewStmt, CreateDomainStmt, CreateEnumStmt, CreateExtensionStmt, CreateFunctionStmt, CreateIndexStmt, CreateSchemaStmt, CreateSequenceStmt, CreateTableAsStmt, CreateTableStmt, CreateTriggerStmt, CreateViewStmt, DropStmt, RefreshMaterializedViewStmt, SequenceOptions, TruncateStmt } from "../ast/nodes.js";
1
+ import type { AlterEnumStmt, AlterIndexStmt, AlterSchemaStmt, AlterSequenceStmt, AlterTableStmt, AlterViewStmt, CreateDomainStmt, CreateEnumStmt, CreateFunctionStmt, CreateIndexStmt, CreateSchemaStmt, CreateSequenceStmt, CreateTableAsStmt, CreateTableStmt, CreateTriggerStmt, CreateViewStmt, DropStmt, RefreshMaterializedViewStmt, SequenceOptions, TruncateStmt } from "../ast/nodes.js";
2
2
  import { SchemaData, type SequenceData } from "../storage/database-state.js";
3
3
  import { type ExecEnv, type ExecResult } from "./relation.js";
4
4
  export declare function buildSequence(env: ExecEnv, schema: SchemaData, name: string, options: SequenceOptions, temp: boolean): SequenceData;
@@ -9,7 +9,6 @@ export declare function executeCreateTableAs(env: ExecEnv, stmt: CreateTableAsSt
9
9
  export declare function executeCreateIndex(env: ExecEnv, stmt: CreateIndexStmt): ExecResult;
10
10
  export declare function executeCreateView(env: ExecEnv, stmt: CreateViewStmt): ExecResult;
11
11
  export declare function executeRefreshMatView(env: ExecEnv, stmt: RefreshMaterializedViewStmt): ExecResult;
12
- export declare function executeCreateExtension(env: ExecEnv, stmt: CreateExtensionStmt): ExecResult;
13
12
  export declare function executeCreateSchema(env: ExecEnv, stmt: CreateSchemaStmt): ExecResult;
14
13
  export declare function executeCreateEnum(env: ExecEnv, stmt: CreateEnumStmt): ExecResult;
15
14
  export declare function executeAlterEnum(env: ExecEnv, stmt: AlterEnumStmt): ExecResult;
@@ -2,6 +2,8 @@ import type { DeleteStmt, InsertStmt, SelectStmt, UpdateStmt } from "../ast/node
2
2
  import type { TableData } from "../storage/database-state.js";
3
3
  import { type Datum } from "../types/value.js";
4
4
  import { type ExecEnv, type ExecResult, type Relation } from "./relation.js";
5
+ /** Roll back trigger/constraint side effects when a statement fails under autocommit. */
6
+ export declare function withStatementRollback<T>(env: ExecEnv, fn: () => T): T;
5
7
  export declare function executeInsert(env0: ExecEnv, stmt: InsertStmt): ExecResult;
6
8
  export declare function executeUpdate(env0: ExecEnv, stmt: UpdateStmt): ExecResult;
7
9
  export declare function executeDelete(env0: ExecEnv, stmt: DeleteStmt): ExecResult;
@@ -0,0 +1,11 @@
1
+ import type { CreateExtensionStmt, DropStmt } from "../ast/nodes.js";
2
+ import type { FunctionData } from "../storage/database-state.js";
3
+ import { type ExecEnv, type ExecResult } from "./relation.js";
4
+ export declare function executeCreateExtension(env: ExecEnv, stmt: CreateExtensionStmt): ExecResult;
5
+ /** A function an extension installed goes away with the extension, not on its own. */
6
+ export declare function assertNotExtensionMember(fn: FunctionData): void;
7
+ /**
8
+ * `DROP EXTENSION [IF EXISTS] name [, ...] [CASCADE | RESTRICT]`: every name
9
+ * is resolved, and every dependency checked, before anything is dropped.
10
+ */
11
+ export declare function executeDropExtension(env: ExecEnv, stmt: DropStmt): ExecResult;
@@ -0,0 +1,25 @@
1
+ import type { AnalyzeStmt, ReindexStmt, Statement } from "../ast/nodes.js";
2
+ import { PostgresError } from "../errors/error.js";
3
+ import type { DatabaseState, IndexMeta, TableData } from "../storage/database-state.js";
4
+ import { type ExecEnv, type ExecResult } from "./relation.js";
5
+ /**
6
+ * Commands PostgreSQL refuses inside a transaction block, named as its 25001 message
7
+ * names them. The sync API and the wire server both check this before running a statement,
8
+ * because each tracks the transaction block in its own way.
9
+ */
10
+ export declare function refusedInTransactionBlock(stmt: Statement): string | null;
11
+ /** A statement whose failure must keep what it wrote: the invalid index a concurrent build leaves behind. */
12
+ export declare function leavesInvalidIndexOnFailure(stmt: Statement): boolean;
13
+ /**
14
+ * Take the armed `concurrentIndexBuild` fault, if any: the error an interrupted concurrent
15
+ * build ends with. PostgreSQL leaves the index it was building in the catalog, invalid.
16
+ */
17
+ export declare function takeConcurrentBuildFault(state: DatabaseState): PostgresError | null;
18
+ /** Raise 23505 when the rows of `table` cannot satisfy unique index `index`, as an index build does. */
19
+ export declare function assertUniqueIndexBuildable(env: ExecEnv, table: TableData, index: IndexMeta, name?: string): void;
20
+ export declare function executeReindex(env: ExecEnv, stmt: ReindexStmt): ExecResult;
21
+ /**
22
+ * ANALYZE. The planner statistics it gathers have no counterpart here; what it leaves
23
+ * is the per-table bookkeeping pg_stat_user_tables reports (analyze_count, last_analyze).
24
+ */
25
+ export declare function executeAnalyze(env: ExecEnv, stmt: AnalyzeStmt): ExecResult;
@@ -14,7 +14,7 @@ export declare class EngineCtx implements CastEnv, CompareCtx {
14
14
  readonly stmtNow: bigint;
15
15
  constructor(state: DatabaseState, txNow?: bigint);
16
16
  timezone(): string;
17
- namespaceOid(input: string): number;
17
+ namespaceOid(name: string): number;
18
18
  namespaceName(oid: number): string | null;
19
19
  zoneOffsetAt(utcMicros: bigint): number;
20
20
  zoneOffsetForNaive(naiveMicros: bigint): number;
package/dist/index.d.ts CHANGED
@@ -23,6 +23,6 @@
23
23
  */
24
24
  import "./serialization/codec.js";
25
25
  export type { BindValue, JsValue, QueryRow } from "./api/bind.js";
26
- export { Database, type DatabaseHistory, type DatabaseOptions, type HistoryCheckpoint, type QueryOptions, type RegisterFunctionOptions, Snapshot, } from "./api/database.js";
26
+ export { Database, type DatabaseFaults, type DatabaseHistory, type DatabaseOptions, type HistoryCheckpoint, type QueryOptions, type RegisterFunctionOptions, Snapshot, } from "./api/database.js";
27
27
  export { type ResultSet, type RunResult, Statement } from "./api/statement.js";
28
28
  export { type ErrorCategory, PostgresError } from "./errors/error.js";