pgsql-deparser 18.4.2 → 18.4.3

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/deparser.d.ts CHANGED
@@ -172,6 +172,8 @@ export declare class Deparser implements DeparserVisitor {
172
172
  CheckPointStmt(node: t.CheckPointStmt, context: DeparserContext): string;
173
173
  LoadStmt(node: t.LoadStmt, context: DeparserContext): string;
174
174
  DiscardStmt(node: t.DiscardStmt, context: DeparserContext): string;
175
+ /** `schema.op` for an operator name list: schema parts quoted, the operator symbol as is. */
176
+ private qualifiedOperatorName;
175
177
  CommentStmt(node: t.CommentStmt, context: DeparserContext): string;
176
178
  LockStmt(node: t.LockStmt, context: DeparserContext): string;
177
179
  CreatePolicyStmt(node: t.CreatePolicyStmt, context: DeparserContext): string;
package/deparser.js CHANGED
@@ -5557,10 +5557,13 @@ class Deparser {
5557
5557
  if (node.arg && this.getNodeType(node.arg) === 'List') {
5558
5558
  const listData = this.getNodeData(node.arg);
5559
5559
  const listItems = list_utils_1.ListUtils.unwrapList(listData.items);
5560
+ const preservedName = this.preserveOperatorDefElemCase(node.defname);
5560
5561
  if (listItems.length === 1 && listItems[0].String) {
5561
- const preservedName = this.preserveOperatorDefElemCase(node.defname);
5562
5562
  return `${preservedName} = ${listItems[0].String.sval}`;
5563
5563
  }
5564
+ if (listItems.length > 1 && listItems.every((item) => item.String)) {
5565
+ return `${preservedName} = OPERATOR(${this.qualifiedOperatorName(listItems)})`;
5566
+ }
5564
5567
  }
5565
5568
  }
5566
5569
  // Handle IndexElem opclassopts - MUST be first to preserve string types
@@ -5662,6 +5665,9 @@ class Deparser {
5662
5665
  if (listItems.length === 1 && listItems[0].String) {
5663
5666
  return `${node.defname} = ${listItems[0].String.sval}`;
5664
5667
  }
5668
+ if (listItems.length > 1 && listItems.every((item) => item.String)) {
5669
+ return `${node.defname} = OPERATOR(${this.qualifiedOperatorName(listItems)})`;
5670
+ }
5665
5671
  }
5666
5672
  }
5667
5673
  if (context.parentNodeTypes.includes('CreatedbStmt') || context.parentNodeTypes.includes('DropdbStmt')) {
@@ -6475,6 +6481,13 @@ class Deparser {
6475
6481
  throw new Error(`Unsupported DiscardStmt target: ${node.target}`);
6476
6482
  }
6477
6483
  }
6484
+ /** `schema.op` for an operator name list: schema parts quoted, the operator symbol as is. */
6485
+ qualifiedOperatorName(objname) {
6486
+ const names = list_utils_1.ListUtils.unwrapList(objname ?? []).map((n) => (n.String ? n.String.sval : 'unknown'));
6487
+ if (names.length === 0)
6488
+ return 'unknown';
6489
+ return [...names.slice(0, -1).map((n) => quotes_1.QuoteUtils.quoteIdentifier(n)), names[names.length - 1]].join('.');
6490
+ }
6478
6491
  CommentStmt(node, context) {
6479
6492
  const output = ['COMMENT ON'];
6480
6493
  if (node.objtype) {
@@ -6595,22 +6608,20 @@ class Deparser {
6595
6608
  }
6596
6609
  }
6597
6610
  else if (node.objtype === 'OBJECT_TRIGGER') {
6598
- if (objectParts.length === 2) {
6599
- const [table, trigger] = objectParts;
6600
- output.push(trigger);
6611
+ if (objectParts.length >= 2) {
6612
+ output.push(objectParts[objectParts.length - 1]);
6601
6613
  output.push('ON');
6602
- output.push(table);
6614
+ output.push(objectParts.slice(0, -1).join('.'));
6603
6615
  }
6604
6616
  else {
6605
6617
  output.push(objectParts.join('.'));
6606
6618
  }
6607
6619
  }
6608
6620
  else if (node.objtype === 'OBJECT_RULE') {
6609
- if (objectParts.length === 2) {
6610
- const [table, rule] = objectParts;
6611
- output.push(rule);
6621
+ if (objectParts.length >= 2) {
6622
+ output.push(objectParts[objectParts.length - 1]);
6612
6623
  output.push('ON');
6613
- output.push(table);
6624
+ output.push(objectParts.slice(0, -1).join('.'));
6614
6625
  }
6615
6626
  else {
6616
6627
  output.push(objectParts.join('.'));
@@ -6621,8 +6632,7 @@ class Deparser {
6621
6632
  // For operators, we need to handle ObjectWithArgs structure
6622
6633
  if (node.object && node.object.ObjectWithArgs) {
6623
6634
  const objWithArgs = node.object.ObjectWithArgs;
6624
- let operatorName = objWithArgs.objname && objWithArgs.objname[0] && objWithArgs.objname[0].String
6625
- ? objWithArgs.objname[0].String.sval : 'unknown';
6635
+ let operatorName = this.qualifiedOperatorName(objWithArgs.objname);
6626
6636
  if (operatorName.startsWith('"') && operatorName.endsWith('"')) {
6627
6637
  operatorName = operatorName.slice(1, -1);
6628
6638
  }
@@ -6689,6 +6699,9 @@ class Deparser {
6689
6699
  output.push(objectParts.join('.'));
6690
6700
  }
6691
6701
  }
6702
+ else if (node.objtype === 'OBJECT_CAST' && objectParts.length === 2) {
6703
+ output.push(`(${objectParts[0]} AS ${objectParts[1]})`);
6704
+ }
6692
6705
  else {
6693
6706
  output.push(objectParts.join('.'));
6694
6707
  }
@@ -6697,8 +6710,7 @@ class Deparser {
6697
6710
  else if (node.objtype === 'OBJECT_OPERATOR' && node.object && node.object.ObjectWithArgs) {
6698
6711
  // Handle direct ObjectWithArgs for OPERATOR syntax: COMMENT ON OPERATOR -(NONE, integer) IS 'comment'
6699
6712
  const objWithArgs = node.object.ObjectWithArgs;
6700
- let operatorName = objWithArgs.objname && objWithArgs.objname[0] && objWithArgs.objname[0].String
6701
- ? objWithArgs.objname[0].String.sval : 'unknown';
6713
+ let operatorName = this.qualifiedOperatorName(objWithArgs.objname);
6702
6714
  // Remove quotes from operator name if present
6703
6715
  if (operatorName.startsWith('"') && operatorName.endsWith('"')) {
6704
6716
  operatorName = operatorName.slice(1, -1);
@@ -8066,8 +8078,11 @@ class Deparser {
8066
8078
  output.push('DATABASE');
8067
8079
  }
8068
8080
  if (node.objects && node.objects.length > 0) {
8081
+ const qualifiedKinds = ['OBJECT_TYPE', 'OBJECT_DOMAIN'];
8069
8082
  const objects = list_utils_1.ListUtils.unwrapList(node.objects)
8070
- .map(obj => this.visit(obj, context))
8083
+ .map(obj => qualifiedKinds.includes(node.objtype) && obj.List
8084
+ ? list_utils_1.ListUtils.unwrapList(obj.List.items).map((item) => this.visit(item, context)).join('.')
8085
+ : this.visit(obj, context))
8071
8086
  .join(', ');
8072
8087
  output.push(objects);
8073
8088
  }
@@ -8106,8 +8121,11 @@ class Deparser {
8106
8121
  break;
8107
8122
  default:
8108
8123
  if (node.objects && node.objects.length > 0) {
8124
+ const qualifiedKinds = ['OBJECT_TYPE', 'OBJECT_DOMAIN'];
8109
8125
  const objects = list_utils_1.ListUtils.unwrapList(node.objects)
8110
- .map(obj => this.visit(obj, context))
8126
+ .map(obj => qualifiedKinds.includes(node.objtype) && obj.List
8127
+ ? list_utils_1.ListUtils.unwrapList(obj.List.items).map((item) => this.visit(item, context)).join('.')
8128
+ : this.visit(obj, context))
8111
8129
  .join(', ');
8112
8130
  output.push(objects);
8113
8131
  }
@@ -9277,6 +9295,9 @@ class Deparser {
9277
9295
  if (listItems.length === 1 && listItems[0].String) {
9278
9296
  return `${preservedDefName} = ${listItems[0].String.sval}`;
9279
9297
  }
9298
+ if (listItems.length > 1 && listItems.every(item => item.String)) {
9299
+ return `${preservedDefName} = OPERATOR(${this.qualifiedOperatorName(listItems)})`;
9300
+ }
9280
9301
  }
9281
9302
  // For commutator/negator, we already handled them above
9282
9303
  if ((defName.toLowerCase() === 'commutator' || defName.toLowerCase() === 'negator')) {
package/esm/deparser.js CHANGED
@@ -5554,10 +5554,13 @@ export class Deparser {
5554
5554
  if (node.arg && this.getNodeType(node.arg) === 'List') {
5555
5555
  const listData = this.getNodeData(node.arg);
5556
5556
  const listItems = ListUtils.unwrapList(listData.items);
5557
+ const preservedName = this.preserveOperatorDefElemCase(node.defname);
5557
5558
  if (listItems.length === 1 && listItems[0].String) {
5558
- const preservedName = this.preserveOperatorDefElemCase(node.defname);
5559
5559
  return `${preservedName} = ${listItems[0].String.sval}`;
5560
5560
  }
5561
+ if (listItems.length > 1 && listItems.every((item) => item.String)) {
5562
+ return `${preservedName} = OPERATOR(${this.qualifiedOperatorName(listItems)})`;
5563
+ }
5561
5564
  }
5562
5565
  }
5563
5566
  // Handle IndexElem opclassopts - MUST be first to preserve string types
@@ -5659,6 +5662,9 @@ export class Deparser {
5659
5662
  if (listItems.length === 1 && listItems[0].String) {
5660
5663
  return `${node.defname} = ${listItems[0].String.sval}`;
5661
5664
  }
5665
+ if (listItems.length > 1 && listItems.every((item) => item.String)) {
5666
+ return `${node.defname} = OPERATOR(${this.qualifiedOperatorName(listItems)})`;
5667
+ }
5662
5668
  }
5663
5669
  }
5664
5670
  if (context.parentNodeTypes.includes('CreatedbStmt') || context.parentNodeTypes.includes('DropdbStmt')) {
@@ -6472,6 +6478,13 @@ export class Deparser {
6472
6478
  throw new Error(`Unsupported DiscardStmt target: ${node.target}`);
6473
6479
  }
6474
6480
  }
6481
+ /** `schema.op` for an operator name list: schema parts quoted, the operator symbol as is. */
6482
+ qualifiedOperatorName(objname) {
6483
+ const names = ListUtils.unwrapList(objname ?? []).map((n) => (n.String ? n.String.sval : 'unknown'));
6484
+ if (names.length === 0)
6485
+ return 'unknown';
6486
+ return [...names.slice(0, -1).map((n) => QuoteUtils.quoteIdentifier(n)), names[names.length - 1]].join('.');
6487
+ }
6475
6488
  CommentStmt(node, context) {
6476
6489
  const output = ['COMMENT ON'];
6477
6490
  if (node.objtype) {
@@ -6592,22 +6605,20 @@ export class Deparser {
6592
6605
  }
6593
6606
  }
6594
6607
  else if (node.objtype === 'OBJECT_TRIGGER') {
6595
- if (objectParts.length === 2) {
6596
- const [table, trigger] = objectParts;
6597
- output.push(trigger);
6608
+ if (objectParts.length >= 2) {
6609
+ output.push(objectParts[objectParts.length - 1]);
6598
6610
  output.push('ON');
6599
- output.push(table);
6611
+ output.push(objectParts.slice(0, -1).join('.'));
6600
6612
  }
6601
6613
  else {
6602
6614
  output.push(objectParts.join('.'));
6603
6615
  }
6604
6616
  }
6605
6617
  else if (node.objtype === 'OBJECT_RULE') {
6606
- if (objectParts.length === 2) {
6607
- const [table, rule] = objectParts;
6608
- output.push(rule);
6618
+ if (objectParts.length >= 2) {
6619
+ output.push(objectParts[objectParts.length - 1]);
6609
6620
  output.push('ON');
6610
- output.push(table);
6621
+ output.push(objectParts.slice(0, -1).join('.'));
6611
6622
  }
6612
6623
  else {
6613
6624
  output.push(objectParts.join('.'));
@@ -6618,8 +6629,7 @@ export class Deparser {
6618
6629
  // For operators, we need to handle ObjectWithArgs structure
6619
6630
  if (node.object && node.object.ObjectWithArgs) {
6620
6631
  const objWithArgs = node.object.ObjectWithArgs;
6621
- let operatorName = objWithArgs.objname && objWithArgs.objname[0] && objWithArgs.objname[0].String
6622
- ? objWithArgs.objname[0].String.sval : 'unknown';
6632
+ let operatorName = this.qualifiedOperatorName(objWithArgs.objname);
6623
6633
  if (operatorName.startsWith('"') && operatorName.endsWith('"')) {
6624
6634
  operatorName = operatorName.slice(1, -1);
6625
6635
  }
@@ -6686,6 +6696,9 @@ export class Deparser {
6686
6696
  output.push(objectParts.join('.'));
6687
6697
  }
6688
6698
  }
6699
+ else if (node.objtype === 'OBJECT_CAST' && objectParts.length === 2) {
6700
+ output.push(`(${objectParts[0]} AS ${objectParts[1]})`);
6701
+ }
6689
6702
  else {
6690
6703
  output.push(objectParts.join('.'));
6691
6704
  }
@@ -6694,8 +6707,7 @@ export class Deparser {
6694
6707
  else if (node.objtype === 'OBJECT_OPERATOR' && node.object && node.object.ObjectWithArgs) {
6695
6708
  // Handle direct ObjectWithArgs for OPERATOR syntax: COMMENT ON OPERATOR -(NONE, integer) IS 'comment'
6696
6709
  const objWithArgs = node.object.ObjectWithArgs;
6697
- let operatorName = objWithArgs.objname && objWithArgs.objname[0] && objWithArgs.objname[0].String
6698
- ? objWithArgs.objname[0].String.sval : 'unknown';
6710
+ let operatorName = this.qualifiedOperatorName(objWithArgs.objname);
6699
6711
  // Remove quotes from operator name if present
6700
6712
  if (operatorName.startsWith('"') && operatorName.endsWith('"')) {
6701
6713
  operatorName = operatorName.slice(1, -1);
@@ -8063,8 +8075,11 @@ export class Deparser {
8063
8075
  output.push('DATABASE');
8064
8076
  }
8065
8077
  if (node.objects && node.objects.length > 0) {
8078
+ const qualifiedKinds = ['OBJECT_TYPE', 'OBJECT_DOMAIN'];
8066
8079
  const objects = ListUtils.unwrapList(node.objects)
8067
- .map(obj => this.visit(obj, context))
8080
+ .map(obj => qualifiedKinds.includes(node.objtype) && obj.List
8081
+ ? ListUtils.unwrapList(obj.List.items).map((item) => this.visit(item, context)).join('.')
8082
+ : this.visit(obj, context))
8068
8083
  .join(', ');
8069
8084
  output.push(objects);
8070
8085
  }
@@ -8103,8 +8118,11 @@ export class Deparser {
8103
8118
  break;
8104
8119
  default:
8105
8120
  if (node.objects && node.objects.length > 0) {
8121
+ const qualifiedKinds = ['OBJECT_TYPE', 'OBJECT_DOMAIN'];
8106
8122
  const objects = ListUtils.unwrapList(node.objects)
8107
- .map(obj => this.visit(obj, context))
8123
+ .map(obj => qualifiedKinds.includes(node.objtype) && obj.List
8124
+ ? ListUtils.unwrapList(obj.List.items).map((item) => this.visit(item, context)).join('.')
8125
+ : this.visit(obj, context))
8108
8126
  .join(', ');
8109
8127
  output.push(objects);
8110
8128
  }
@@ -9274,6 +9292,9 @@ export class Deparser {
9274
9292
  if (listItems.length === 1 && listItems[0].String) {
9275
9293
  return `${preservedDefName} = ${listItems[0].String.sval}`;
9276
9294
  }
9295
+ if (listItems.length > 1 && listItems.every(item => item.String)) {
9296
+ return `${preservedDefName} = OPERATOR(${this.qualifiedOperatorName(listItems)})`;
9297
+ }
9277
9298
  }
9278
9299
  // For commutator/negator, we already handled them above
9279
9300
  if ((defName.toLowerCase() === 'commutator' || defName.toLowerCase() === 'negator')) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pgsql-deparser",
3
- "version": "18.4.2",
3
+ "version": "18.4.3",
4
4
  "author": "Constructive <developers@constructive.io>",
5
5
  "description": "PostgreSQL AST Deparser",
6
6
  "main": "index.js",
@@ -60,5 +60,5 @@
60
60
  "@pgsql/quotes": "18.2.4",
61
61
  "@pgsql/types": "^18.0.0"
62
62
  },
63
- "gitHead": "d49ec05b871e46de411a2af1630c234d4a2bb38f"
63
+ "gitHead": "ce03e09604aea4b0fd7d62cf23e72d0de8ad33c1"
64
64
  }