@crvouga/mockingbird-service-postgres 3.2.0 → 3.4.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 (53) hide show
  1. package/CHANGELOG.md +17 -1
  2. package/COMPATIBILITY.md +35 -5
  3. package/README.md +219 -57
  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 +4812 -987
  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 +5390 -744
  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 +6445 -1260
  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/fleet.d.ts +210 -1
  49. package/dist/wire/index.d.ts +21 -1
  50. package/dist/wire/index.js +5383 -741
  51. package/dist/wire/index.js.map +4 -4
  52. package/dist/wire/startup.d.ts +36 -0
  53. package/package.json +1 -1
@@ -0,0 +1,12 @@
1
+ import type { Expr } from "../ast/nodes.js";
2
+ import type { EngineCtx } from "../expressions/context.js";
3
+ import { type ColumnType, type TypeId } from "../types/value.js";
4
+ /** True when the default is a NULL constant, which PostgreSQL does not store as a default. */
5
+ export declare function isNullDefault(ctx: EngineCtx, expr: Expr): boolean;
6
+ /**
7
+ * Static type of a default expression: a type name, `unknown` for an untyped
8
+ * string literal, or null when the expression is outside what is analyzed.
9
+ */
10
+ export declare function defaultExprType(ctx: EngineCtx, expr: Expr): TypeId | null;
11
+ /** PostgreSQL's text for a column default of the given column type, or null for a NULL default. */
12
+ export declare function deparseDefault(ctx: EngineCtx, expr: Expr, column: ColumnType): string | null;
@@ -1,3 +1,13 @@
1
+ import type { EngineCtx } from "../expressions/context.js";
1
2
  import type { IndexMeta } from "../storage/database-state.js";
2
- export declare function deparseIndexColumn(column: IndexMeta["columns"][number]): string;
3
- export declare function deparseIndex(index: IndexMeta): string;
3
+ /** The WHERE predicate of a partial index, or null. */
4
+ export declare function deparseIndexPredicate(ctx: EngineCtx, index: IndexMeta, pretty?: boolean): string | null;
5
+ /** The expression keys of an index, comma-separated (`pg_get_expr(indexprs, indrelid)`), or null. */
6
+ export declare function deparseIndexExpressions(ctx: EngineCtx, index: IndexMeta): string | null;
7
+ /** `pg_get_indexdef(oid)` / `pg_get_indexdef(oid, 0, pretty)`: the whole CREATE INDEX command. */
8
+ export declare function deparseIndex(ctx: EngineCtx, index: IndexMeta, pretty?: boolean): string;
9
+ /**
10
+ * `pg_get_indexdef(oid, n, pretty)` for n >= 1: the n-th index column, key columns first
11
+ * and INCLUDE columns after them, without ordering or opclass. Empty when there is no such column.
12
+ */
13
+ export declare function deparseIndexColumn(ctx: EngineCtx, index: IndexMeta, position: number, pretty?: boolean): string;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Identifier quoting as PostgreSQL's `quote_identifier` does it, used wherever the
3
+ * engine prints a name back as SQL (pg_get_indexdef, regnamespace output).
4
+ */
5
+ /** Quote `name` unless it is safe bare: lower-case letters, digits and `_`, not starting with a digit, not a keyword. */
6
+ export declare function quoteIdentifier(name: string): string;
@@ -0,0 +1,27 @@
1
+ import type { Expr } from "../ast/nodes.js";
2
+ import type { EngineCtx } from "../expressions/context.js";
3
+ import type { TableData } from "../storage/database-state.js";
4
+ import { type ColumnType, type TypeId } from "../types/value.js";
5
+ /**
6
+ * Expression deparsing the way PostgreSQL's ruleutils.c prints a stored expression
7
+ * (pg_get_indexdef, pg_get_expr): constants carry their resolved type, the implicit
8
+ * casts operator resolution added are visible, and parentheses follow the node tree
9
+ * rather than the text the user wrote.
10
+ *
11
+ * PostgreSQL deparses the analyzed tree; this engine keeps the parsed one, so the
12
+ * first half of this file redoes the part of analysis that shows in the output:
13
+ * what type an untyped literal took and where a cast was inserted. It covers the
14
+ * operators, predicates and functions index definitions are written with; anything
15
+ * else falls back to `deparseExpr` and is not claimed to match.
16
+ */
17
+ export interface RuleScope {
18
+ ctx: EngineCtx;
19
+ /** table the expression's columns belong to */
20
+ table: TableData | null;
21
+ }
22
+ /** format_type(): the SQL name of a type with its modifier. */
23
+ export declare function formatType(scope: RuleScope, type: TypeId, mod?: ColumnType["mod"]): string;
24
+ /** A stored expression as PostgreSQL prints it: a predicate, CHECK body or default. */
25
+ export declare function deparseRuleExpr(scope: RuleScope, expr: Expr, pretty?: boolean): string;
26
+ /** An index key expression: parenthesized unless it is a bare function call. */
27
+ export declare function deparseIndexExpr(scope: RuleScope, expr: Expr, pretty?: boolean): string;
@@ -16,16 +16,20 @@ export interface ColumnMeta {
16
16
  collate: string | null;
17
17
  /** resolved domain name when column type came from a domain */
18
18
  domain: string | null;
19
+ /** `pg_attribute.attstorage` override (p/e/x/m); absent = the type's default strategy */
20
+ storage?: "p" | "e" | "x" | "m";
19
21
  }
20
22
  export type ConstraintMeta = {
21
23
  kind: "primary_key";
22
24
  name: string;
23
25
  columns: string[];
26
+ indexOid?: number;
24
27
  } | {
25
28
  kind: "unique";
26
29
  name: string;
27
30
  columns: string[];
28
31
  nullsNotDistinct: boolean;
32
+ indexOid?: number;
29
33
  } | {
30
34
  kind: "check";
31
35
  name: string;
@@ -46,16 +50,32 @@ export interface IndexMeta {
46
50
  name: string;
47
51
  schema: string;
48
52
  table: string;
53
+ /** oid of the indexed table: the link that survives table and schema renames */
54
+ tableOid?: number;
49
55
  unique: boolean;
50
56
  comment?: string | null;
57
+ /** false after a failed or interrupted CREATE INDEX CONCURRENTLY / REINDEX CONCURRENTLY */
51
58
  valid?: boolean;
52
59
  scans?: bigint;
60
+ /** clock time (ms) of the most recent scan counted in `scans` */
61
+ lastScan?: number;
62
+ /** access method (`USING ...`); absent means btree */
63
+ method?: string;
64
+ /** non-key columns of INCLUDE (...) */
65
+ include?: string[];
66
+ /** WITH (...) storage parameters as written, values unquoted */
67
+ options?: Array<{
68
+ name: string;
69
+ value: string;
70
+ }>;
53
71
  /** simple column indexes store names; expression indexes store the AST */
54
72
  columns: Array<{
55
73
  column: string | null;
56
74
  expr: Expr | null;
57
75
  dir: "asc" | "desc";
58
76
  nulls: "first" | "last";
77
+ /** operator class as written, possibly schema-qualified; absent means the default */
78
+ opclass?: string[] | null;
59
79
  }>;
60
80
  where: Expr | null;
61
81
  nullsNotDistinct: boolean;
@@ -82,6 +102,8 @@ export declare class TableData {
82
102
  constraints: ConstraintMeta[];
83
103
  triggers: TriggerMeta[];
84
104
  temp: boolean;
105
+ /** UNLOGGED table (`pg_class.relpersistence = 'u'`); catalog metadata only, there is no WAL to skip */
106
+ unlogged: boolean;
85
107
  /** monotonically increasing oid-like id for catalog output */
86
108
  readonly oid: number;
87
109
  /** >0 while shared with a clone or transaction snapshot. */
@@ -138,6 +160,8 @@ export interface SequenceData {
138
160
  } | null;
139
161
  dataType: TypeId;
140
162
  temp: boolean;
163
+ /** UNLOGGED sequence (`pg_class.relpersistence = 'u'`); absent = logged */
164
+ unlogged?: boolean;
141
165
  oid: number;
142
166
  shareCount?: number;
143
167
  }
@@ -178,6 +202,8 @@ export interface FunctionData {
178
202
  rawBody: string | null;
179
203
  strict: boolean;
180
204
  oid: number;
205
+ /** on an extension's member functions: the installed version when it is not the extension's default */
206
+ extensionVersion?: string;
181
207
  jsImpl?: (...args: Array<null | boolean | number | bigint | string | Uint8Array>) => null | boolean | number | bigint | string | Uint8Array;
182
208
  }
183
209
  export declare class SchemaData {
@@ -197,6 +223,17 @@ export declare class SchemaData {
197
223
  /** Share table/sequence objects; copy maps so CREATE/DROP is isolated. */
198
224
  cloneShallow(): SchemaData;
199
225
  }
226
+ /** ANALYZE bookkeeping for pg_stat_user_tables, keyed by table oid in {@link DatabaseState.tableStats}. */
227
+ export interface TableStats {
228
+ analyzeCount: number;
229
+ /** clock time (ms) of the most recent ANALYZE */
230
+ lastAnalyze: number;
231
+ }
232
+ /** One-shot failure presets armed by tests (`Database.fault`). */
233
+ export interface EngineFaults {
234
+ /** SQLSTATE raised by the next concurrent index build, which leaves its index invalid. */
235
+ concurrentIndexBuild?: string;
236
+ }
200
237
  export interface PreparedStatement {
201
238
  name: string;
202
239
  argTypes: TypeId[] | null;
@@ -207,6 +244,16 @@ export declare class DatabaseState {
207
244
  settings: Map<string, string>;
208
245
  /** SET LOCAL values, cleared on COMMIT/ROLLBACK */
209
246
  localSettings: Map<string, string>;
247
+ /**
248
+ * What `RESET` and `SET ... TO DEFAULT` return to, over the built-in defaults: the settings a
249
+ * wire session started with. Belongs to the session executing, so clones do not carry it.
250
+ */
251
+ settingDefaults: ReadonlyMap<string, string> | null;
252
+ /**
253
+ * Host functions registered under `pg_catalog`: found ahead of the search path, the way
254
+ * PostgreSQL finds its own functions whatever `search_path` says. Copied to clones, not encoded.
255
+ */
256
+ systemFunctions: Map<string, FunctionData[]>;
210
257
  prepared: Map<string, PreparedStatement>;
211
258
  prng: Prng;
212
259
  clock: Clock;
@@ -220,6 +267,10 @@ export declare class DatabaseState {
220
267
  } | null;
221
268
  /** Session currval per sequence; absent entry means currval is undefined. */
222
269
  sequenceCurrval: Map<string, bigint>;
270
+ /** Per-table ANALYZE bookkeeping, keyed by table oid. */
271
+ tableStats: Map<number, TableStats>;
272
+ /** Armed failure presets. Not part of snapshots, clones or transaction rollback. */
273
+ faults: EngineFaults;
223
274
  constructor(prng: Prng, clock: Clock);
224
275
  nextOid(): number;
225
276
  getSetting(name: string): string | undefined;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * `regnamespace`: an oid that reads and prints as a schema name (regnamespacein /
3
+ * regnamespaceout). The catalog lookups stay with the caller; this is the text form.
4
+ */
5
+ /** Schemas every database has, with the oids PostgreSQL gives them (information_schema's is not fixed). */
6
+ export declare const BUILTIN_NAMESPACES: ReadonlyArray<readonly [name: string, oid: number]>;
7
+ export declare const builtinNamespaceOid: (name: string) => number | undefined;
8
+ export declare const builtinNamespaceName: (oid: number) => string | undefined;
9
+ /** oidin: an unsigned 32-bit integer; a negative literal is its two's-complement reading. */
10
+ export declare function parseOidText(text: string): number;
11
+ /** A cast from an integer type: int2/int4 reinterpret their bits, int8 must fit. */
12
+ export declare function oidFromInteger(value: number | bigint): number;
13
+ /**
14
+ * Split regnamespace input as SplitIdentifierString does. `-` and an all-digit string are
15
+ * oids; anything else must be exactly one identifier, case-folded unless double-quoted.
16
+ */
17
+ export declare function parseNamespaceInput(text: string): {
18
+ oid: number;
19
+ } | {
20
+ name: string;
21
+ };
22
+ /** regnamespaceout: `-` for zero, the quoted schema name, or the bare number when no schema has that oid. */
23
+ export declare function namespaceText(oid: number, name: string | null | undefined): string;
@@ -80,6 +80,7 @@ export declare function parseUuidText(text: string): string;
80
80
  export declare function parseMoneyText(text: string): bigint;
81
81
  export declare function moneyText(cents: bigint): string;
82
82
  export interface OutputCtx {
83
+ /** unquoted schema name for an oid, or null when no schema has it */
83
84
  namespaceName?(oid: number): string | null;
84
85
  /** offset seconds east of UTC for rendering timestamptz at given UTC micros */
85
86
  zoneOffsetAt(utcMicros: bigint): number;
@@ -90,6 +91,7 @@ export declare function recordText(rec: PgRecord, ctx: OutputCtx): string;
90
91
  /** Render a non-null datum of type `t` to PG wire text. */
91
92
  export declare function datumText(t: TypeId, v: Datum, ctx: OutputCtx): string;
92
93
  export interface InputCtx {
94
+ /** oid of the schema with exactly this name; raises 3F000 when there is none */
93
95
  namespaceOid?(name: string): number;
94
96
  /** session zone offset lookup for naive timestamptz input */
95
97
  zoneOffsetForNaive(naiveMicros: bigint): number;