@crvouga/mockingbird-service-postgres 3.6.0 → 3.7.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/unstable.js CHANGED
@@ -1,3 +1,175 @@
1
+ // src/sql/keywords.ts
2
+ var QUOTED_KEYWORDS = /* @__PURE__ */ new Set([
3
+ "all",
4
+ "analyse",
5
+ "analyze",
6
+ "and",
7
+ "any",
8
+ "array",
9
+ "as",
10
+ "asc",
11
+ "asymmetric",
12
+ "authorization",
13
+ "between",
14
+ "bigint",
15
+ "binary",
16
+ "bit",
17
+ "boolean",
18
+ "both",
19
+ "case",
20
+ "cast",
21
+ "char",
22
+ "character",
23
+ "check",
24
+ "coalesce",
25
+ "collate",
26
+ "collation",
27
+ "column",
28
+ "concurrently",
29
+ "constraint",
30
+ "create",
31
+ "cross",
32
+ "current_catalog",
33
+ "current_date",
34
+ "current_role",
35
+ "current_schema",
36
+ "current_time",
37
+ "current_timestamp",
38
+ "current_user",
39
+ "dec",
40
+ "decimal",
41
+ "default",
42
+ "deferrable",
43
+ "desc",
44
+ "distinct",
45
+ "do",
46
+ "else",
47
+ "end",
48
+ "except",
49
+ "exists",
50
+ "extract",
51
+ "false",
52
+ "fetch",
53
+ "float",
54
+ "for",
55
+ "foreign",
56
+ "freeze",
57
+ "from",
58
+ "full",
59
+ "grant",
60
+ "greatest",
61
+ "group",
62
+ "grouping",
63
+ "having",
64
+ "ilike",
65
+ "in",
66
+ "initially",
67
+ "inner",
68
+ "inout",
69
+ "int",
70
+ "integer",
71
+ "intersect",
72
+ "interval",
73
+ "into",
74
+ "is",
75
+ "isnull",
76
+ "join",
77
+ "json",
78
+ "json_array",
79
+ "json_arrayagg",
80
+ "json_exists",
81
+ "json_object",
82
+ "json_objectagg",
83
+ "json_query",
84
+ "json_scalar",
85
+ "json_serialize",
86
+ "json_table",
87
+ "json_value",
88
+ "lateral",
89
+ "leading",
90
+ "least",
91
+ "left",
92
+ "like",
93
+ "limit",
94
+ "localtime",
95
+ "localtimestamp",
96
+ "merge_action",
97
+ "national",
98
+ "natural",
99
+ "nchar",
100
+ "none",
101
+ "normalize",
102
+ "not",
103
+ "notnull",
104
+ "null",
105
+ "nullif",
106
+ "numeric",
107
+ "offset",
108
+ "on",
109
+ "only",
110
+ "or",
111
+ "order",
112
+ "out",
113
+ "outer",
114
+ "overlaps",
115
+ "overlay",
116
+ "placing",
117
+ "position",
118
+ "precision",
119
+ "primary",
120
+ "real",
121
+ "references",
122
+ "returning",
123
+ "right",
124
+ "row",
125
+ "select",
126
+ "session_user",
127
+ "setof",
128
+ "similar",
129
+ "smallint",
130
+ "some",
131
+ "substring",
132
+ "symmetric",
133
+ "system_user",
134
+ "table",
135
+ "tablesample",
136
+ "then",
137
+ "time",
138
+ "timestamp",
139
+ "to",
140
+ "trailing",
141
+ "treat",
142
+ "trim",
143
+ "true",
144
+ "union",
145
+ "unique",
146
+ "user",
147
+ "using",
148
+ "values",
149
+ "varchar",
150
+ "variadic",
151
+ "verbose",
152
+ "when",
153
+ "where",
154
+ "window",
155
+ "with",
156
+ "xmlattributes",
157
+ "xmlconcat",
158
+ "xmlelement",
159
+ "xmlexists",
160
+ "xmlforest",
161
+ "xmlnamespaces",
162
+ "xmlparse",
163
+ "xmlpi",
164
+ "xmlroot",
165
+ "xmlserialize",
166
+ "xmltable"
167
+ ]);
168
+ function quoteIdentifier(name) {
169
+ if (/^[a-z_][a-z0-9_]*$/.test(name) && !QUOTED_KEYWORDS.has(name)) return name;
170
+ return `"${name.replaceAll('"', '""')}"`;
171
+ }
172
+
1
173
  // src/errors/error.ts
2
174
  var CATEGORY_TO_SQLSTATE = {
3
175
  syntax: "42601",
@@ -509,178 +681,6 @@ function timestampAddInterval(ts, iv) {
509
681
  return result;
510
682
  }
511
683
 
512
- // src/sql/keywords.ts
513
- var QUOTED_KEYWORDS = /* @__PURE__ */ new Set([
514
- "all",
515
- "analyse",
516
- "analyze",
517
- "and",
518
- "any",
519
- "array",
520
- "as",
521
- "asc",
522
- "asymmetric",
523
- "authorization",
524
- "between",
525
- "bigint",
526
- "binary",
527
- "bit",
528
- "boolean",
529
- "both",
530
- "case",
531
- "cast",
532
- "char",
533
- "character",
534
- "check",
535
- "coalesce",
536
- "collate",
537
- "collation",
538
- "column",
539
- "concurrently",
540
- "constraint",
541
- "create",
542
- "cross",
543
- "current_catalog",
544
- "current_date",
545
- "current_role",
546
- "current_schema",
547
- "current_time",
548
- "current_timestamp",
549
- "current_user",
550
- "dec",
551
- "decimal",
552
- "default",
553
- "deferrable",
554
- "desc",
555
- "distinct",
556
- "do",
557
- "else",
558
- "end",
559
- "except",
560
- "exists",
561
- "extract",
562
- "false",
563
- "fetch",
564
- "float",
565
- "for",
566
- "foreign",
567
- "freeze",
568
- "from",
569
- "full",
570
- "grant",
571
- "greatest",
572
- "group",
573
- "grouping",
574
- "having",
575
- "ilike",
576
- "in",
577
- "initially",
578
- "inner",
579
- "inout",
580
- "int",
581
- "integer",
582
- "intersect",
583
- "interval",
584
- "into",
585
- "is",
586
- "isnull",
587
- "join",
588
- "json",
589
- "json_array",
590
- "json_arrayagg",
591
- "json_exists",
592
- "json_object",
593
- "json_objectagg",
594
- "json_query",
595
- "json_scalar",
596
- "json_serialize",
597
- "json_table",
598
- "json_value",
599
- "lateral",
600
- "leading",
601
- "least",
602
- "left",
603
- "like",
604
- "limit",
605
- "localtime",
606
- "localtimestamp",
607
- "merge_action",
608
- "national",
609
- "natural",
610
- "nchar",
611
- "none",
612
- "normalize",
613
- "not",
614
- "notnull",
615
- "null",
616
- "nullif",
617
- "numeric",
618
- "offset",
619
- "on",
620
- "only",
621
- "or",
622
- "order",
623
- "out",
624
- "outer",
625
- "overlaps",
626
- "overlay",
627
- "placing",
628
- "position",
629
- "precision",
630
- "primary",
631
- "real",
632
- "references",
633
- "returning",
634
- "right",
635
- "row",
636
- "select",
637
- "session_user",
638
- "setof",
639
- "similar",
640
- "smallint",
641
- "some",
642
- "substring",
643
- "symmetric",
644
- "system_user",
645
- "table",
646
- "tablesample",
647
- "then",
648
- "time",
649
- "timestamp",
650
- "to",
651
- "trailing",
652
- "treat",
653
- "trim",
654
- "true",
655
- "union",
656
- "unique",
657
- "user",
658
- "using",
659
- "values",
660
- "varchar",
661
- "variadic",
662
- "verbose",
663
- "when",
664
- "where",
665
- "window",
666
- "with",
667
- "xmlattributes",
668
- "xmlconcat",
669
- "xmlelement",
670
- "xmlexists",
671
- "xmlforest",
672
- "xmlnamespaces",
673
- "xmlparse",
674
- "xmlpi",
675
- "xmlroot",
676
- "xmlserialize",
677
- "xmltable"
678
- ]);
679
- function quoteIdentifier(name) {
680
- if (/^[a-z_][a-z0-9_]*$/.test(name) && !QUOTED_KEYWORDS.has(name)) return name;
681
- return `"${name.replaceAll('"', '""')}"`;
682
- }
683
-
684
684
  // src/types/regnamespace.ts
685
685
  var BUILTIN_NAMESPACES = [
686
686
  ["pg_toast", 99],
@@ -710,6 +710,12 @@ var invalidName = () => {
710
710
  throw pgError("syntax", "invalid name syntax", "42602");
711
711
  };
712
712
  function parseNamespaceInput(text) {
713
+ const parsed = parseRelationInput(text);
714
+ if ("oid" in parsed) return parsed;
715
+ if (parsed.parts.length !== 1) invalidName();
716
+ return { name: parsed.parts[0] };
717
+ }
718
+ function parseRelationInput(text) {
713
719
  if (text === "-") return { oid: 0 };
714
720
  if (/^\d+$/.test(text)) return { oid: parseOidText(text) };
715
721
  const names = [];
@@ -745,8 +751,8 @@ function parseNamespaceInput(text) {
745
751
  skipSpace();
746
752
  if (at === text.length) invalidName();
747
753
  }
748
- if (names.length !== 1) invalidName();
749
- return { name: names[0] };
754
+ if (names.length === 0 || names.length > 3) invalidName();
755
+ return { parts: names };
750
756
  }
751
757
  function namespaceText(oid, name) {
752
758
  if (oid === 0) return "-";
@@ -2664,6 +2670,7 @@ var TYPE_ALIASES = {
2664
2670
  regtype: "regtype",
2665
2671
  regproc: "regproc",
2666
2672
  regnamespace: "regnamespace",
2673
+ xid: "xid",
2667
2674
  oid: "oid",
2668
2675
  void: "void",
2669
2676
  record: "record",
@@ -2740,6 +2747,7 @@ var TYPE_OIDS = {
2740
2747
  regproc: 24,
2741
2748
  text: 25,
2742
2749
  oid: 26,
2750
+ xid: 28,
2743
2751
  json: 114,
2744
2752
  float4: 700,
2745
2753
  float8: 701,
@@ -3058,6 +3066,7 @@ function recordText(rec, ctx) {
3058
3066
  return `(${parts.join(",")})`;
3059
3067
  }
3060
3068
  function datumText(t, v, ctx) {
3069
+ if (t === "regclass") return v === 0 ? "-" : ctx.relationName?.(v) ?? String(v);
3061
3070
  if (t === "regnamespace") return namespaceText(v, ctx.namespaceName?.(v));
3062
3071
  if (v === null) throw pgError("internal", "datumText called with null");
3063
3072
  if (isArrayType(t)) return arrayText(v, ctx);
@@ -3068,6 +3077,7 @@ function datumText(t, v, ctx) {
3068
3077
  case "int2":
3069
3078
  case "int4":
3070
3079
  case "oid":
3080
+ case "xid":
3071
3081
  return String(v);
3072
3082
  case "int8":
3073
3083
  return String(v);
@@ -3132,6 +3142,12 @@ function datumText(t, v, ctx) {
3132
3142
  }
3133
3143
  var UTC_INPUT = { zoneOffsetForNaive: () => 0 };
3134
3144
  function datumFromText(t, text, ctx) {
3145
+ if (t === "regclass") {
3146
+ const parsed = parseRelationInput(text);
3147
+ if ("oid" in parsed) return parsed.oid;
3148
+ if (!ctx.relationOid) throw unsupported("regclass input without a catalog");
3149
+ return ctx.relationOid(parsed.parts);
3150
+ }
3135
3151
  if (t === "regnamespace") {
3136
3152
  const parsed = parseNamespaceInput(text);
3137
3153
  if ("oid" in parsed) return parsed.oid;
@@ -3153,6 +3169,7 @@ function datumFromText(t, text, ctx) {
3153
3169
  case "int8":
3154
3170
  return parseIntegerText(text, t);
3155
3171
  case "oid":
3172
+ case "xid":
3156
3173
  return parseOidText(text);
3157
3174
  case "float4":
3158
3175
  return Math.fround(parseFloatText(text, "float4"));
@@ -3306,6 +3323,11 @@ function parseArrayText(t, text, ctx) {
3306
3323
  // src/expressions/context.ts
3307
3324
  var EngineCtx = class {
3308
3325
  state;
3326
+ writeXid = null;
3327
+ rowVersionXid() {
3328
+ if (this.state.inTransaction) return this.state.transactionXid ??= this.state.allocateXid();
3329
+ return this.writeXid ??= this.state.allocateXid();
3330
+ }
3309
3331
  /** transaction timestamp (now(), current_timestamp) — UTC micros since PG epoch */
3310
3332
  txNow;
3311
3333
  /** statement timestamp */
@@ -3320,6 +3342,23 @@ var EngineCtx = class {
3320
3342
  timezone() {
3321
3343
  return this.state.getSetting("timezone") ?? "UTC";
3322
3344
  }
3345
+ relationOid(parts) {
3346
+ const target = this.state.resolveRelationSchema(parts);
3347
+ const schema = target ? this.state.schemas.get(target.schema) : void 0;
3348
+ const relation = target ? schema?.sequences.get(target.name) ?? schema?.tables.get(target.name) ?? schema?.views.get(target.name) : void 0;
3349
+ if (!relation) throw pgError("undefined_table", `relation "${parts.join(".")}" does not exist`, "42P01");
3350
+ return relation.oid;
3351
+ }
3352
+ relationName(oid) {
3353
+ for (const schema of this.state.schemas.values()) {
3354
+ for (const relation of [...schema.tables.values(), ...schema.sequences.values(), ...schema.views.values()]) {
3355
+ if (relation.oid !== oid) continue;
3356
+ const visible = this.state.resolveRelationSchema([relation.name])?.schema === schema.name;
3357
+ return (visible ? [relation.name] : [schema.name, relation.name]).map(quoteIdentifier).join(".");
3358
+ }
3359
+ }
3360
+ return null;
3361
+ }
3323
3362
  namespaceOid(name) {
3324
3363
  const oid = builtinNamespaceOid(name) ?? this.state.schemas.get(name)?.oid;
3325
3364
  if (oid === void 0) throw pgError("undefined_object", `schema "${name}" does not exist`, "3F000");
@@ -3620,7 +3659,7 @@ function castTo(env, value, target, opts = {}) {
3620
3659
  return tv(target, makeArray(toElem, items, arr.dims.slice(), arr.lbs.slice()));
3621
3660
  }
3622
3661
  if (from === "oid" && target === "regnamespace") return tv(target, v);
3623
- if (from === "regnamespace" && (target === "oid" || target === "int4" || target === "int8")) {
3662
+ if ((from === "regnamespace" || from === "regclass") && (target === "oid" || target === "int4" || target === "int8")) {
3624
3663
  return tv(target, target === "int8" ? BigInt(v) : v);
3625
3664
  }
3626
3665
  if ((from === "int4" || from === "int8" || from === "int2") && (target === "oid" || target === "regnamespace")) {
@@ -4321,6 +4360,8 @@ function datumCompare(t, a, b, ctx = DEFAULT_COMPARE_CTX) {
4321
4360
  case "int2":
4322
4361
  case "int4":
4323
4362
  case "oid":
4363
+ case "regclass":
4364
+ case "xid":
4324
4365
  case "regnamespace":
4325
4366
  case "date":
4326
4367
  return expectNumber(a, t) - expectNumber(b, t);
@@ -4440,6 +4481,8 @@ function datumKey(t, v) {
4440
4481
  case "int2":
4441
4482
  case "int4":
4442
4483
  case "oid":
4484
+ case "regclass":
4485
+ case "xid":
4443
4486
  case "date":
4444
4487
  return `i${v}`;
4445
4488
  case "float4":
@@ -6465,6 +6508,8 @@ var TableData = class _TableData {
6465
6508
  schema;
6466
6509
  columns;
6467
6510
  rows;
6511
+ rowXmins = /* @__PURE__ */ new WeakMap();
6512
+ slabXmins = null;
6468
6513
  /** Frozen columnar storage after snapshot hydrate; `rows` stays empty until materialized. */
6469
6514
  slab = null;
6470
6515
  constraints;
@@ -6507,6 +6552,11 @@ var TableData = class _TableData {
6507
6552
  materializeSlab() {
6508
6553
  if (!this.slab) return;
6509
6554
  this.rows = this.slab.materialize();
6555
+ if (this.slabXmins)
6556
+ this.rows.forEach((row, index) => {
6557
+ this.rowXmins.set(row, this.slabXmins[index] ?? 2);
6558
+ });
6559
+ this.slabXmins = null;
6510
6560
  this.slab = null;
6511
6561
  this.indexStores = null;
6512
6562
  }
@@ -6540,6 +6590,10 @@ var TableData = class _TableData {
6540
6590
  } else {
6541
6591
  t.rows = this.rows.map((r) => r.slice());
6542
6592
  }
6593
+ t.rows.forEach((row, index) => {
6594
+ const xmin = this.slabXmins?.[index] ?? this.rowXmins.get(this.rows[index]);
6595
+ if (xmin !== void 0) t.rowXmins.set(row, xmin);
6596
+ });
6543
6597
  t.unlogged = this.unlogged;
6544
6598
  t.constraints = this.constraints.map((c) => ({ ...c }));
6545
6599
  t.triggers = this.triggers.map((tr) => ({ ...tr }));
@@ -6625,6 +6679,14 @@ var DatabaseState = class _DatabaseState {
6625
6679
  clock;
6626
6680
  changes = 0;
6627
6681
  oidCounter = 16384;
6682
+ /** Local monotonic xid allocator; 2 denotes a row from a legacy snapshot without metadata. */
6683
+ xidCounter = 3;
6684
+ transactionXid = null;
6685
+ allocateXid() {
6686
+ if (this.xidCounter > 4294967295)
6687
+ throw pgError("program_limit_exceeded", "transaction ID space exhausted; xid wraparound is not modeled", "54000");
6688
+ return this.xidCounter++;
6689
+ }
6628
6690
  inTransaction = false;
6629
6691
  /** Transaction-only events: included in rollback clones, never in exported snapshots. */
6630
6692
  pendingTriggers = [];
@@ -6838,6 +6900,8 @@ var DatabaseState = class _DatabaseState {
6838
6900
  s.sequenceCurrval = new Map(this.sequenceCurrval);
6839
6901
  s.tableStats = new Map(this.tableStats);
6840
6902
  s.oidCounter = this.oidCounter;
6903
+ s.xidCounter = this.xidCounter;
6904
+ s.transactionXid = this.transactionXid;
6841
6905
  for (const [name, overloads] of this.systemFunctions) s.systemFunctions.set(name, overloads.slice());
6842
6906
  return s;
6843
6907
  }
@@ -6857,6 +6921,8 @@ var DatabaseState = class _DatabaseState {
6857
6921
  s.sequenceCurrval = new Map(this.sequenceCurrval);
6858
6922
  s.tableStats = new Map(this.tableStats);
6859
6923
  s.oidCounter = this.oidCounter;
6924
+ s.xidCounter = this.xidCounter;
6925
+ s.transactionXid = this.transactionXid;
6860
6926
  for (const [name, overloads] of this.systemFunctions) s.systemFunctions.set(name, overloads.slice());
6861
6927
  return s;
6862
6928
  }
@@ -6932,6 +6998,8 @@ var DatabaseState = class _DatabaseState {
6932
6998
  this.sequenceCurrval = other.sequenceCurrval;
6933
6999
  this.tableStats = other.tableStats;
6934
7000
  this.oidCounter = other.oidCounter;
7001
+ this.xidCounter = Math.max(this.xidCounter, other.xidCounter);
7002
+ this.transactionXid = other.transactionXid;
6935
7003
  }
6936
7004
  /** @internal Snapshot codec access to the oid allocator. */
6937
7005
  snapshotOidCounter() {
@@ -7874,7 +7942,7 @@ function databaseCatalogContext(state) {
7874
7942
  var PG_VERSION_TEXT = "PostgreSQL 18.3 (postgres-mem) on TypeScript, in-memory engine";
7875
7943
  function findSequenceForCall(ctx, name) {
7876
7944
  const parts = parseQualifiedName(name);
7877
- const seq = ctx.state.findSequence(parts);
7945
+ const seq = /^\d+$/.test(name) ? [...ctx.state.schemas.values()].flatMap((schema) => [...schema.sequences.values()]).find((sequence) => sequence.oid === Number(name)) : ctx.state.findSequence(parts);
7878
7946
  if (!seq) {
7879
7947
  throw pgError("undefined_table", `relation "${name}" does not exist`, "42P01");
7880
7948
  }
@@ -8098,14 +8166,16 @@ function getMiscFunctions() {
8098
8166
  "pg_get_serial_sequence",
8099
8167
  strict("text", (ctx, args) => {
8100
8168
  const tableName2 = argText(ctx, args[0]);
8101
- const column = argText(ctx, args[1]).toLowerCase();
8169
+ const column = argText(ctx, args[1]);
8102
8170
  const table = ctx.state.findTable(parseQualifiedName(tableName2));
8103
8171
  if (!table) throw pgError("undefined_table", `relation "${tableName2}" does not exist`, "42P01");
8104
8172
  const col = table.columns.find((c) => c.name === column);
8105
8173
  if (!col)
8106
8174
  throw pgError("undefined_column", `column "${column}" of relation "${table.name}" does not exist`, "42703");
8107
- if (!col.identity) return tv("text", null);
8108
- return tv("text", col.identity.sequence.split(".").map(quoteIdent).join("."));
8175
+ const seq = [...ctx.state.schemas.get(table.schema)?.sequences.values() ?? []].find(
8176
+ (candidate) => candidate.ownedBy?.table === table.name && candidate.ownedBy.column === column
8177
+ );
8178
+ return tv("text", seq ? [seq.schema, seq.name].map(quoteIdent).join(".") : null);
8109
8179
  })
8110
8180
  );
8111
8181
  m.set("format_type", (ctx, args) => {
@@ -13049,7 +13119,7 @@ var RowScope = class {
13049
13119
  let count2 = 0;
13050
13120
  for (let i = 0; i < this.columns.length; i++) {
13051
13121
  const c = this.columns[i];
13052
- if (c.name === name2 && !c.hidden) {
13122
+ if (c.name === name2 && (!c.hidden || c.system)) {
13053
13123
  count2++;
13054
13124
  if (count2 > 1) {
13055
13125
  throw pgError("ambiguous_column", `column reference "${name2}" is ambiguous`);
@@ -13087,7 +13157,7 @@ var RowScope = class {
13087
13157
  const names = [];
13088
13158
  for (let i = 0; i < this.columns.length; i++) {
13089
13159
  const c = this.columns[i];
13090
- if (c.table === rangeVar) {
13160
+ if (c.table === rangeVar && !c.system) {
13091
13161
  types.push(c.type);
13092
13162
  values.push(this.row[i] ?? null);
13093
13163
  names.push(c.name);
@@ -13530,7 +13600,7 @@ function tryIndexedFromItem(env, item, where) {
13530
13600
  if (!table) return null;
13531
13601
  const alias = item.alias ?? item.name[item.name.length - 1];
13532
13602
  table.materializeSlab();
13533
- return tryIndexedTableRows(env, table, alias, where);
13603
+ return tryIndexedTableRows(env, table, alias, where)?.map((row) => [...row, table.rowXmins.get(row) ?? 2]) ?? null;
13534
13604
  }
13535
13605
  function joinKeyFromRow(row, colIdxs, srcTypes, unifiedTypes, ctx) {
13536
13606
  const parts = [];
@@ -16020,6 +16090,7 @@ var Parser = class {
16020
16090
  let sqlBody = null;
16021
16091
  let volatility = null;
16022
16092
  let strict2 = false;
16093
+ const settings = {};
16023
16094
  for (; ; ) {
16024
16095
  if (this.eatKw("language")) {
16025
16096
  language = this.peek().type === "string" ? this.next().value : this.ident(true);
@@ -16077,8 +16148,23 @@ var Parser = class {
16077
16148
  continue;
16078
16149
  }
16079
16150
  if (this.eatKw("set")) {
16080
- this.ident(true);
16081
- if (this.eatOp("=") || this.eatKw("to")) this.next();
16151
+ const key = this.ident(true).toLowerCase();
16152
+ if (this.eatKw("from")) {
16153
+ this.expectKw("current");
16154
+ settings[key] = "__from_current__";
16155
+ } else {
16156
+ if (!this.eatOp("=")) this.expectKw("to");
16157
+ const values = [];
16158
+ do {
16159
+ const value = this.next();
16160
+ if (!["string", "ident", "quoted_ident", "number"].includes(value.type))
16161
+ this.errorAt(value, "expected setting value");
16162
+ values.push(
16163
+ key === "search_path" && /[^a-z0-9_]/.test(value.value) ? `"${value.value.replaceAll('"', '""')}"` : value.value
16164
+ );
16165
+ } while (this.eatPunct(","));
16166
+ settings[key] = values.join(", ");
16167
+ }
16082
16168
  continue;
16083
16169
  }
16084
16170
  if (this.eatKw("window")) throw unsupported("window functions via CREATE FUNCTION");
@@ -16158,7 +16244,8 @@ var Parser = class {
16158
16244
  body,
16159
16245
  sqlBody,
16160
16246
  volatility,
16161
- strict: strict2
16247
+ strict: strict2,
16248
+ settings
16162
16249
  };
16163
16250
  }
16164
16251
  parseCreateTrigger(orReplace, constraint) {
@@ -16267,8 +16354,8 @@ var Parser = class {
16267
16354
  type: "alter_sequence",
16268
16355
  name,
16269
16356
  ifExists,
16270
- options: { ownedBy: void 0 },
16271
- ...{ renameTo: to }
16357
+ options: {},
16358
+ renameTo: to
16272
16359
  };
16273
16360
  }
16274
16361
  if (this.atKw("set") && (this.atKw("logged", 1) || this.atKw("unlogged", 1))) {
@@ -18854,7 +18941,20 @@ function runFunctionBody(env, fn, args) {
18854
18941
  }
18855
18942
  return last;
18856
18943
  }
18944
+ function withFunctionSettings(env, fn, run) {
18945
+ const state = env.ctx.state;
18946
+ const saved = new Map(state.localSettings);
18947
+ for (const [name, value] of Object.entries(fn.settings ?? {})) state.localSettings.set(name, value);
18948
+ try {
18949
+ return run();
18950
+ } finally {
18951
+ state.localSettings = saved;
18952
+ }
18953
+ }
18857
18954
  function callSqlFunctionScalar(env, fn, args) {
18955
+ return withFunctionSettings(env, fn, () => callSqlFunctionScalarBody(env, fn, args));
18956
+ }
18957
+ function callSqlFunctionScalarBody(env, fn, args) {
18858
18958
  const retT = fn.returns ?? "text";
18859
18959
  if (fn.language === "plpgsql") {
18860
18960
  return callPlpgsqlScalar(env, fn, args);
@@ -18884,6 +18984,9 @@ function callSqlFunctionScalar(env, fn, args) {
18884
18984
  return castTo(env.ctx, tv(rawT, raw), retT, {});
18885
18985
  }
18886
18986
  function callSqlFunctionSet(env, fn, args) {
18987
+ return withFunctionSettings(env, fn, () => callSqlFunctionSetBody(env, fn, args));
18988
+ }
18989
+ function callSqlFunctionSetBody(env, fn, args) {
18887
18990
  if (fn.language === "plpgsql") {
18888
18991
  return callPlpgsqlSet(env, fn, args);
18889
18992
  }
@@ -19038,15 +19141,17 @@ function executeRecursiveCte(env, cte, query) {
19038
19141
  return rel3;
19039
19142
  }
19040
19143
  function renameWithAliases(rel3, label, colAliases, what) {
19041
- if (colAliases && colAliases.length > rel3.columns.length) {
19144
+ const visibleWidth = rel3.columns.filter((column) => !column.system).length;
19145
+ if (colAliases && colAliases.length > visibleWidth) {
19042
19146
  throw pgError(
19043
19147
  "invalid_column_reference",
19044
- `table "${what}" has ${rel3.columns.length} columns available but ${colAliases.length} columns specified`,
19148
+ `table "${what}" has ${visibleWidth} columns available but ${colAliases.length} columns specified`,
19045
19149
  "42P10"
19046
19150
  );
19047
19151
  }
19048
19152
  const columns = rel3.columns.map((c, i) => ({
19049
- name: colAliases?.[i] ?? c.name,
19153
+ ...c,
19154
+ name: c.system ? c.name : colAliases?.[i] ?? c.name,
19050
19155
  type: c.type === UNKNOWN ? "text" : c.type,
19051
19156
  table: label
19052
19157
  }));
@@ -19067,8 +19172,11 @@ function materializeItem(env, item, scope) {
19067
19172
  if (table) {
19068
19173
  table.materializeSlab();
19069
19174
  const rel3 = {
19070
- columns: table.columns.map((c) => ({ name: c.name, type: c.type.id, table: label })),
19071
- rows: table.rows
19175
+ columns: [
19176
+ ...table.columns.map((c) => ({ name: c.name, type: c.type.id, table: label })),
19177
+ { name: "xmin", type: "xid", table: label, hidden: true, system: true }
19178
+ ],
19179
+ rows: table.rows.map((row) => [...row, table.rowXmins.get(row) ?? 2])
19072
19180
  };
19073
19181
  return { rel: renameWithAliases(rel3, label, item.colAliases, label), rangeVars: /* @__PURE__ */ new Set([label]) };
19074
19182
  }
@@ -19698,7 +19806,7 @@ function resolveColIdx(columns, parts) {
19698
19806
  let found = -1;
19699
19807
  for (let i = 0; i < columns.length; i++) {
19700
19808
  const c = columns[i];
19701
- if (!c.hidden && c.name === name2) {
19809
+ if ((!c.hidden || c.system) && c.name === name2) {
19702
19810
  if (found !== -1) return null;
19703
19811
  found = i;
19704
19812
  }
@@ -20282,7 +20390,7 @@ function expandTargets(core, columns) {
20282
20390
  let any = false;
20283
20391
  for (let i = 0; i < columns.length; i++) {
20284
20392
  const c = columns[i];
20285
- if (c.table === label) {
20393
+ if (c.table === label && !c.system) {
20286
20394
  any = true;
20287
20395
  items.push({ name: c.name, kind: "col", colIdx: i, expr: null, hidden: false });
20288
20396
  }
@@ -23350,13 +23458,63 @@ function executeCreateSequence(env, stmt) {
23350
23458
  schema.sequences.set(name, seq);
23351
23459
  return commandResult("CREATE SEQUENCE", 0);
23352
23460
  }
23461
+ function renameSequenceReferences(env, seq, newName) {
23462
+ const state = env.ctx.state;
23463
+ const matches2 = (value) => {
23464
+ try {
23465
+ const input = parseRelationInput(value);
23466
+ if ("oid" in input) return input.oid === seq.oid;
23467
+ return state.findSequence(input.parts)?.oid === seq.oid;
23468
+ } catch {
23469
+ return false;
23470
+ }
23471
+ };
23472
+ const rewrite = (value) => {
23473
+ if (Array.isArray(value)) return value.map(rewrite);
23474
+ if (value === null || typeof value !== "object") return value;
23475
+ const node = value;
23476
+ const updated = Object.fromEntries(Object.entries(node).map(([key, child]) => [key, rewrite(child)]));
23477
+ const rewriteLiteral = (literal2) => {
23478
+ if (literal2 && typeof literal2 === "object" && "type" in literal2 && literal2.type === "string_lit" && "value" in literal2 && typeof literal2.value === "string" && matches2(literal2.value)) {
23479
+ return { ...literal2, value: [seq.schema, newName].map(quoteIdent).join(".") };
23480
+ }
23481
+ return literal2;
23482
+ };
23483
+ if (node.type === "func" && Array.isArray(node.name) && ["nextval", "currval", "setval"].includes(String(node.name.at(-1))) && Array.isArray(updated.args))
23484
+ updated.args[0] = rewriteLiteral(updated.args[0]);
23485
+ if (node.type === "cast" && node.target && typeof node.target === "object" && "parts" in node.target && Array.isArray(node.target.parts) && node.target.parts.at(-1) === "regclass")
23486
+ updated.expr = rewriteLiteral(updated.expr);
23487
+ return updated;
23488
+ };
23489
+ for (const schema of state.schemas.values()) {
23490
+ for (const table of [...schema.tables.values()]) {
23491
+ const writable = state.ensureWritableTable(table);
23492
+ for (const column of writable.columns) {
23493
+ if (column.defaultExpr) column.defaultExpr = rewrite(column.defaultExpr);
23494
+ if (column.identity?.sequence === `${seq.schema}.${seq.name}`)
23495
+ column.identity = { ...column.identity, sequence: `${seq.schema}.${newName}` };
23496
+ }
23497
+ }
23498
+ }
23499
+ }
23353
23500
  function executeAlterSequence(env, stmt) {
23354
23501
  const state = env.ctx.state;
23355
- const seq = state.findSequence(stmt.name);
23356
- if (!seq) {
23502
+ const foundSequence = state.findSequence(stmt.name);
23503
+ if (!foundSequence) {
23357
23504
  if (stmt.ifExists) return commandResult("ALTER SEQUENCE", 0);
23358
23505
  throw pgError("undefined_table", `relation "${stmt.name.join(".")}" does not exist`, "42P01");
23359
23506
  }
23507
+ const seq = state.ensureWritableSequence(foundSequence);
23508
+ if (stmt.renameTo) {
23509
+ const schema = state.getSchema(seq.schema);
23510
+ if (schema.hasRelation(stmt.renameTo))
23511
+ throw pgError("duplicate_table", `relation "${stmt.renameTo}" already exists`, "42P07");
23512
+ renameSequenceReferences(env, seq, stmt.renameTo);
23513
+ schema.sequences.delete(seq.name);
23514
+ seq.name = stmt.renameTo;
23515
+ schema.sequences.set(seq.name, seq);
23516
+ return commandResult("ALTER SEQUENCE", 0);
23517
+ }
23360
23518
  const o = stmt.options;
23361
23519
  if (o.logged !== void 0) {
23362
23520
  setSequenceLogged(state, seq, o.logged);
@@ -23414,7 +23572,7 @@ function buildColumn(env, schema, tableName2, def, out, taken) {
23414
23572
  col.defaultExpr = {
23415
23573
  type: "func",
23416
23574
  name: ["nextval"],
23417
- args: [{ type: "string_lit", value: `${schema.name}.${seqName}` }]
23575
+ args: [{ type: "string_lit", value: [schema.name, seqName].map(quoteIdent).join(".") }]
23418
23576
  };
23419
23577
  }
23420
23578
  for (const c of def.constraints) {
@@ -23667,7 +23825,11 @@ function executeCreateTableAs(env, stmt) {
23667
23825
  const table = new TableData(schema.name, name, columns, state.nextOid(), stmt.temp);
23668
23826
  table.unlogged = stmt.unlogged === true;
23669
23827
  if (stmt.withData) {
23670
- for (const row of rel3.rows) table.mutableRows().push(row.slice());
23828
+ for (const row of rel3.rows) {
23829
+ const stored = row.slice();
23830
+ table.rowXmins.set(stored, env.ctx.rowVersionXid());
23831
+ table.mutableRows().push(stored);
23832
+ }
23671
23833
  }
23672
23834
  schema.tables.set(name, table);
23673
23835
  const count = stmt.withData ? table.rowCount() : 0;
@@ -23936,6 +24098,12 @@ function executeCreateFunction(env, stmt) {
23936
24098
  language: lang,
23937
24099
  body,
23938
24100
  rawBody: stmt.body,
24101
+ settings: Object.fromEntries(
24102
+ Object.entries(stmt.settings ?? {}).map(([key, value]) => [
24103
+ key,
24104
+ value === "__from_current__" ? state.getSetting(key) ?? "" : value
24105
+ ])
24106
+ ),
23939
24107
  strict: stmt.strict,
23940
24108
  oid: state.nextOid()
23941
24109
  };
@@ -24120,6 +24288,7 @@ function executeAlterTable(env, stmt) {
24120
24288
  }
24121
24289
  const next = row.slice();
24122
24290
  next[idx] = nv;
24291
+ table.rowXmins.set(next, table.rowXmins.get(rows[i]) ?? 2);
24123
24292
  rows[i] = next;
24124
24293
  }
24125
24294
  col.type = resolved.column;
@@ -24221,6 +24390,11 @@ function executeAlterTable(env, stmt) {
24221
24390
  );
24222
24391
  }
24223
24392
  table.columns[idx].name = action.to;
24393
+ for (const seq of [...schema.sequences.values()]) {
24394
+ if (seq.ownedBy?.table === table.name && seq.ownedBy.column === action.from) {
24395
+ state.ensureWritableSequence(seq).ownedBy = { table: table.name, column: action.to };
24396
+ }
24397
+ }
24224
24398
  for (const con of table.constraints) {
24225
24399
  if (con.kind === "primary_key" || con.kind === "unique" || con.kind === "foreign_key") {
24226
24400
  con.columns = con.columns.map((c) => c === action.from ? action.to : c);
@@ -24257,6 +24431,11 @@ function executeAlterTable(env, stmt) {
24257
24431
  throw pgError("duplicate_table", `relation "${action.to}" already exists`, "42P07");
24258
24432
  }
24259
24433
  const oldName = table.name;
24434
+ for (const seq of [...schema.sequences.values()]) {
24435
+ if (seq.ownedBy?.table === oldName) {
24436
+ state.ensureWritableSequence(seq).ownedBy = { ...seq.ownedBy, table: action.to };
24437
+ }
24438
+ }
24260
24439
  schema.tables.delete(table.name);
24261
24440
  table.name = action.to;
24262
24441
  schema.tables.set(action.to, table);
@@ -24895,6 +25074,7 @@ function applyOnConflictUpdate(env, table, label, existingIdx, newRow, sets, whe
24895
25074
  const updated = existing.slice();
24896
25075
  applyUpdateSets(env, table, sets, scope, updated);
24897
25076
  computeGeneratedColumns(env, table, updated);
25077
+ table.rowXmins.set(updated, env.ctx.rowVersionXid());
24898
25078
  rows[existingIdx] = updated;
24899
25079
  indexUpdateRow(env, table, existingIdx, existing, updated);
24900
25080
  checkNotNull(env, table, updated);
@@ -24980,6 +25160,7 @@ function executeInsert(env0, stmt) {
24980
25160
  checkChecks(env, table, newRow);
24981
25161
  checkUnique(env, table, newRow, rows.length);
24982
25162
  checkForeignKeys(env, table, newRow);
25163
+ table.rowXmins.set(newRow, env.ctx.rowVersionXid());
24983
25164
  rows.push(newRow);
24984
25165
  indexInsertRow(env, table, rows.length - 1, newRow);
24985
25166
  insertedCount++;
@@ -25097,6 +25278,7 @@ function executeUpdate(env0, stmt) {
25097
25278
  if (fired.row === null) continue;
25098
25279
  const finalRow = fired.row;
25099
25280
  computeGeneratedColumns(env, table, finalRow);
25281
+ table.rowXmins.set(finalRow, env.ctx.rowVersionXid());
25100
25282
  rows[ri] = finalRow;
25101
25283
  try {
25102
25284
  checkNotNull(env, table, finalRow);
@@ -25216,6 +25398,7 @@ function handleReferencedDelete(env, table, row, depth) {
25216
25398
  for (const c of con.columns) {
25217
25399
  newRow[child.columnIndex(c)] = null;
25218
25400
  }
25401
+ child.rowXmins.set(newRow, env.ctx.rowVersionXid());
25219
25402
  childRows[i] = newRow;
25220
25403
  checkNotNull(env, child, newRow);
25221
25404
  checkChecks(env, child, newRow);
@@ -25229,6 +25412,7 @@ function handleReferencedDelete(env, table, row, depth) {
25229
25412
  const ci = child.columnIndex(c);
25230
25413
  newRow[ci] = columnDefault(env, child, child.columns[ci]);
25231
25414
  }
25415
+ child.rowXmins.set(newRow, env.ctx.rowVersionXid());
25232
25416
  childRows[i] = newRow;
25233
25417
  checkNotNull(env, child, newRow);
25234
25418
  checkChecks(env, child, newRow);
@@ -25266,6 +25450,7 @@ function handleReferencedUpdate(env, table, oldRows, newRows) {
25266
25450
  const refIdx = table.columnIndex(con.refColumns[c]);
25267
25451
  newRow[localIdx] = newRows[r][refIdx] ?? null;
25268
25452
  }
25453
+ child.rowXmins.set(newRow, env.ctx.rowVersionXid());
25269
25454
  childRows[i] = newRow;
25270
25455
  checkChecks(env, child, newRow);
25271
25456
  }
@@ -25275,6 +25460,7 @@ function handleReferencedUpdate(env, table, oldRows, newRows) {
25275
25460
  for (const i of idxs) {
25276
25461
  const newRow = childRows[i].slice();
25277
25462
  for (const c of con.columns) newRow[child.columnIndex(c)] = null;
25463
+ child.rowXmins.set(newRow, env.ctx.rowVersionXid());
25278
25464
  childRows[i] = newRow;
25279
25465
  checkNotNull(env, child, newRow);
25280
25466
  }
@@ -25287,6 +25473,7 @@ function handleReferencedUpdate(env, table, oldRows, newRows) {
25287
25473
  const ci = child.columnIndex(c);
25288
25474
  newRow[ci] = columnDefault(env, child, child.columns[ci]);
25289
25475
  }
25476
+ child.rowXmins.set(newRow, env.ctx.rowVersionXid());
25290
25477
  childRows[i] = newRow;
25291
25478
  checkForeignKeys(env, child, newRow);
25292
25479
  }
@@ -25477,6 +25664,7 @@ var TransactionManager = class {
25477
25664
  this.base = null;
25478
25665
  this.savepoints = [];
25479
25666
  this.state.inTransaction = false;
25667
+ this.state.transactionXid = null;
25480
25668
  this.state.localSettings.clear();
25481
25669
  this.state.pendingTriggers = [];
25482
25670
  this.state.constraintModes.clear();
@@ -25489,6 +25677,7 @@ var TransactionManager = class {
25489
25677
  this.base = null;
25490
25678
  this.savepoints = [];
25491
25679
  this.state.inTransaction = false;
25680
+ this.state.transactionXid = null;
25492
25681
  this.state.localSettings.clear();
25493
25682
  this.state.pendingTriggers = [];
25494
25683
  this.state.constraintModes.clear();
@@ -25523,6 +25712,7 @@ var TransactionManager = class {
25523
25712
  this.base = null;
25524
25713
  this.savepoints = [];
25525
25714
  this.state.inTransaction = false;
25715
+ this.state.transactionXid = null;
25526
25716
  this.freezeDepth = 0;
25527
25717
  }
25528
25718
  };