pgsql-deparser 18.3.11 → 18.3.12

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.js CHANGED
@@ -124,7 +124,7 @@ function isWrappedParseResult(obj) {
124
124
  */
125
125
  function formatBitString(bsval) {
126
126
  const quote = (value) => value.replace(/'/g, "''");
127
- if (/^x[0-9A-Fa-f]+$/.test(bsval)) {
127
+ if (/^x[0-9A-Fa-f]*$/.test(bsval)) {
128
128
  return `x'${bsval.substring(1)}'`;
129
129
  }
130
130
  if (bsval.startsWith('b')) {
@@ -132,6 +132,11 @@ function formatBitString(bsval) {
132
132
  }
133
133
  return `b'${quote(bsval)}'`;
134
134
  }
135
+ // A dollar-quoted body ends at the first occurrence of its tag, including one
136
+ // formed by the body's trailing characters plus the closing tag (`...$` + `$$`).
137
+ function dollarTagConflicts(body, tag) {
138
+ return (body + tag).indexOf(tag) < body.length;
139
+ }
135
140
  const NUMERIC_LITERAL = /^[+-]?(?:0[xX](?:_?[0-9A-Fa-f])+|0[oO](?:_?[0-7])+|0[bB](?:_?[01])+|(?:\d(?:_?\d)*(?:\.(?:\d(?:_?\d)*)?)?|\.\d(?:_?\d)*)(?:[eE][+-]?\d(?:_?\d)*)?)$/;
136
141
  function formatInteger(ival) {
137
142
  const value = String(ival);
@@ -206,10 +211,19 @@ class Deparser {
206
211
  */
207
212
  getFunctionDelimiter(body) {
208
213
  const delimiter = this.options.functionDelimiter || '$$';
209
- if (body.includes(delimiter)) {
210
- return this.options.functionDelimiterFallback || '$EOFCODE$';
214
+ if (!dollarTagConflicts(body, delimiter)) {
215
+ return delimiter;
216
+ }
217
+ const fallback = this.options.functionDelimiterFallback || '$EOFCODE$';
218
+ if (!dollarTagConflicts(body, fallback)) {
219
+ return fallback;
220
+ }
221
+ const base = fallback.slice(0, -1);
222
+ let counter = 1;
223
+ while (dollarTagConflicts(body, `${base}${counter}$`)) {
224
+ counter++;
211
225
  }
212
- return delimiter;
226
+ return `${base}${counter}$`;
213
227
  }
214
228
  /**
215
229
  * Maps ObjectType enum values to their corresponding SQL keywords
@@ -9811,7 +9825,9 @@ class Deparser {
9811
9825
  formatOptionValue(arg, argValue) {
9812
9826
  if (arg && this.getNodeType(arg) === 'String') {
9813
9827
  const sval = this.getNodeData(arg).sval || '';
9814
- return /^[A-Za-z_][A-Za-z0-9_]*$/.test(sval) ? sval : quotes_1.QuoteUtils.escape(sval);
9828
+ return /^[a-z_][a-z0-9_]*$/.test(sval) && (0, quotes_1.keywordKindOf)(sval) === 'NO_KEYWORD'
9829
+ ? sval
9830
+ : quotes_1.QuoteUtils.escape(sval);
9815
9831
  }
9816
9832
  return argValue;
9817
9833
  }
package/esm/deparser.js CHANGED
@@ -1,4 +1,4 @@
1
- import { QuoteUtils } from '@pgsql/quotes';
1
+ import { keywordKindOf, QuoteUtils } from '@pgsql/quotes';
2
2
  import { ListUtils } from './utils/list-utils';
3
3
  import { SqlFormatter } from './utils/sql-formatter';
4
4
  import { DeparserContext } from './visitors/base';
@@ -121,7 +121,7 @@ function isWrappedParseResult(obj) {
121
121
  */
122
122
  function formatBitString(bsval) {
123
123
  const quote = (value) => value.replace(/'/g, "''");
124
- if (/^x[0-9A-Fa-f]+$/.test(bsval)) {
124
+ if (/^x[0-9A-Fa-f]*$/.test(bsval)) {
125
125
  return `x'${bsval.substring(1)}'`;
126
126
  }
127
127
  if (bsval.startsWith('b')) {
@@ -129,6 +129,11 @@ function formatBitString(bsval) {
129
129
  }
130
130
  return `b'${quote(bsval)}'`;
131
131
  }
132
+ // A dollar-quoted body ends at the first occurrence of its tag, including one
133
+ // formed by the body's trailing characters plus the closing tag (`...$` + `$$`).
134
+ function dollarTagConflicts(body, tag) {
135
+ return (body + tag).indexOf(tag) < body.length;
136
+ }
132
137
  const NUMERIC_LITERAL = /^[+-]?(?:0[xX](?:_?[0-9A-Fa-f])+|0[oO](?:_?[0-7])+|0[bB](?:_?[01])+|(?:\d(?:_?\d)*(?:\.(?:\d(?:_?\d)*)?)?|\.\d(?:_?\d)*)(?:[eE][+-]?\d(?:_?\d)*)?)$/;
133
138
  function formatInteger(ival) {
134
139
  const value = String(ival);
@@ -203,10 +208,19 @@ export class Deparser {
203
208
  */
204
209
  getFunctionDelimiter(body) {
205
210
  const delimiter = this.options.functionDelimiter || '$$';
206
- if (body.includes(delimiter)) {
207
- return this.options.functionDelimiterFallback || '$EOFCODE$';
211
+ if (!dollarTagConflicts(body, delimiter)) {
212
+ return delimiter;
213
+ }
214
+ const fallback = this.options.functionDelimiterFallback || '$EOFCODE$';
215
+ if (!dollarTagConflicts(body, fallback)) {
216
+ return fallback;
217
+ }
218
+ const base = fallback.slice(0, -1);
219
+ let counter = 1;
220
+ while (dollarTagConflicts(body, `${base}${counter}$`)) {
221
+ counter++;
208
222
  }
209
- return delimiter;
223
+ return `${base}${counter}$`;
210
224
  }
211
225
  /**
212
226
  * Maps ObjectType enum values to their corresponding SQL keywords
@@ -9808,7 +9822,9 @@ export class Deparser {
9808
9822
  formatOptionValue(arg, argValue) {
9809
9823
  if (arg && this.getNodeType(arg) === 'String') {
9810
9824
  const sval = this.getNodeData(arg).sval || '';
9811
- return /^[A-Za-z_][A-Za-z0-9_]*$/.test(sval) ? sval : QuoteUtils.escape(sval);
9825
+ return /^[a-z_][a-z0-9_]*$/.test(sval) && keywordKindOf(sval) === 'NO_KEYWORD'
9826
+ ? sval
9827
+ : QuoteUtils.escape(sval);
9812
9828
  }
9813
9829
  return argValue;
9814
9830
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pgsql-deparser",
3
- "version": "18.3.11",
3
+ "version": "18.3.12",
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": "253de85d89081d866200077492ce69c3a2e96b04"
63
+ "gitHead": "b4605c200dd1ee25af88965997217a312d4afa27"
64
64
  }