pgsql-deparser 18.3.8 → 18.3.9

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
@@ -8,31 +8,6 @@ export interface DeparserOptions {
8
8
  functionDelimiterFallback?: string;
9
9
  pretty?: boolean;
10
10
  }
11
- /**
12
- * Deparser - Converts PostgreSQL AST nodes back to SQL strings
13
- *
14
- * Entry Points:
15
- * 1. ParseResult (from libpg-query) - The complete parse result
16
- * Structure: { version: number, stmts: RawStmt[] }
17
- * Note: stmts is "repeated RawStmt" in protobuf, so array contains RawStmt
18
- * objects inline (not wrapped as { RawStmt: ... } nodes)
19
- * Example: { version: 170004, stmts: [{ stmt: {...}, stmt_len: 32 }] }
20
- *
21
- * 2. Wrapped ParseResult - When explicitly wrapped as a Node
22
- * Structure: { ParseResult: { version: number, stmts: RawStmt[] } }
23
- *
24
- * 3. Wrapped RawStmt - When explicitly wrapped as a Node
25
- * Structure: { RawStmt: { stmt: Node, stmt_len?: number } }
26
- *
27
- * 4. Array of Nodes - Multiple statements to deparse
28
- * Can be: Node[] (e.g., SelectStmt, InsertStmt, etc.)
29
- *
30
- * 5. Single Node - Individual statement node
31
- * Example: { SelectStmt: {...} }, { InsertStmt: {...} }, etc.
32
- *
33
- * The deparser automatically detects bare ParseResult objects for backward
34
- * compatibility and wraps them internally for consistent processing.
35
- */
36
11
  export declare class Deparser implements DeparserVisitor {
37
12
  private tree;
38
13
  private options;
package/deparser.js CHANGED
@@ -122,6 +122,16 @@ function isWrappedParseResult(obj) {
122
122
  * The deparser automatically detects bare ParseResult objects for backward
123
123
  * compatibility and wraps them internally for consistent processing.
124
124
  */
125
+ function formatBitString(bsval) {
126
+ const quote = (value) => value.replace(/'/g, "''");
127
+ if (/^x[0-9A-Fa-f]+$/.test(bsval)) {
128
+ return `x'${bsval.substring(1)}'`;
129
+ }
130
+ if (bsval.startsWith('b')) {
131
+ return `b'${quote(bsval.substring(1))}'`;
132
+ }
133
+ return `b'${quote(bsval)}'`;
134
+ }
125
135
  class Deparser {
126
136
  tree;
127
137
  options;
@@ -1669,15 +1679,7 @@ class Deparser {
1669
1679
  else if (nodeAny.bsval !== undefined) {
1670
1680
  if (typeof nodeAny.bsval === 'object' && nodeAny.bsval !== null) {
1671
1681
  if (nodeAny.bsval.bsval !== undefined) {
1672
- const bsval = nodeAny.bsval.bsval;
1673
- // Check if this is a hexadecimal bit string (starts with x and contains only hex digits)
1674
- if (bsval.startsWith('x') && /^x[0-9A-Fa-f]+$/.test(bsval)) {
1675
- return `x'${bsval.substring(1)}'`;
1676
- }
1677
- if (bsval.startsWith('b')) {
1678
- return `b'${bsval.substring(1)}'`;
1679
- }
1680
- return `b'${bsval}'`;
1682
+ return formatBitString(nodeAny.bsval.bsval);
1681
1683
  }
1682
1684
  else if (Object.keys(nodeAny.bsval).length === 0) {
1683
1685
  return "''";
@@ -1690,15 +1692,7 @@ class Deparser {
1690
1692
  return 'NULL';
1691
1693
  }
1692
1694
  else {
1693
- const bsval = nodeAny.bsval;
1694
- // Check if this is a hexadecimal bit string (starts with x and contains only hex digits)
1695
- if (bsval.startsWith('x') && /^x[0-9A-Fa-f]+$/.test(bsval)) {
1696
- return `x'${bsval.substring(1)}'`;
1697
- }
1698
- if (bsval.startsWith('b')) {
1699
- return `b'${bsval.substring(1)}'`;
1700
- }
1701
- return `b'${bsval}'`;
1695
+ return formatBitString(nodeAny.bsval);
1702
1696
  }
1703
1697
  }
1704
1698
  if (nodeAny.val) {
@@ -1715,7 +1709,7 @@ class Deparser {
1715
1709
  return nodeAny.val.Boolean.boolval ? 'true' : 'false';
1716
1710
  }
1717
1711
  else if (nodeAny.val.BitString?.bsval !== undefined) {
1718
- return nodeAny.val.BitString.bsval;
1712
+ return formatBitString(nodeAny.val.BitString.bsval);
1719
1713
  }
1720
1714
  }
1721
1715
  if (nodeAny.isnull === true) {
@@ -2395,15 +2389,7 @@ class Deparser {
2395
2389
  return node.boolval ? 'true' : 'false';
2396
2390
  }
2397
2391
  BitString(node, context) {
2398
- // Check if this is a hexadecimal bit string (starts with x)
2399
- if (node.bsval.startsWith('x')) {
2400
- return `x'${node.bsval.substring(1)}'`;
2401
- }
2402
- if (node.bsval.startsWith('b')) {
2403
- return `b'${node.bsval.substring(1)}'`;
2404
- }
2405
- // Fallback for raw values without prefix
2406
- return `b'${node.bsval}'`;
2392
+ return formatBitString(node.bsval);
2407
2393
  }
2408
2394
  Null(node, context) {
2409
2395
  return 'NULL';
package/esm/deparser.js CHANGED
@@ -119,6 +119,16 @@ function isWrappedParseResult(obj) {
119
119
  * The deparser automatically detects bare ParseResult objects for backward
120
120
  * compatibility and wraps them internally for consistent processing.
121
121
  */
122
+ function formatBitString(bsval) {
123
+ const quote = (value) => value.replace(/'/g, "''");
124
+ if (/^x[0-9A-Fa-f]+$/.test(bsval)) {
125
+ return `x'${bsval.substring(1)}'`;
126
+ }
127
+ if (bsval.startsWith('b')) {
128
+ return `b'${quote(bsval.substring(1))}'`;
129
+ }
130
+ return `b'${quote(bsval)}'`;
131
+ }
122
132
  export class Deparser {
123
133
  tree;
124
134
  options;
@@ -1666,15 +1676,7 @@ export class Deparser {
1666
1676
  else if (nodeAny.bsval !== undefined) {
1667
1677
  if (typeof nodeAny.bsval === 'object' && nodeAny.bsval !== null) {
1668
1678
  if (nodeAny.bsval.bsval !== undefined) {
1669
- const bsval = nodeAny.bsval.bsval;
1670
- // Check if this is a hexadecimal bit string (starts with x and contains only hex digits)
1671
- if (bsval.startsWith('x') && /^x[0-9A-Fa-f]+$/.test(bsval)) {
1672
- return `x'${bsval.substring(1)}'`;
1673
- }
1674
- if (bsval.startsWith('b')) {
1675
- return `b'${bsval.substring(1)}'`;
1676
- }
1677
- return `b'${bsval}'`;
1679
+ return formatBitString(nodeAny.bsval.bsval);
1678
1680
  }
1679
1681
  else if (Object.keys(nodeAny.bsval).length === 0) {
1680
1682
  return "''";
@@ -1687,15 +1689,7 @@ export class Deparser {
1687
1689
  return 'NULL';
1688
1690
  }
1689
1691
  else {
1690
- const bsval = nodeAny.bsval;
1691
- // Check if this is a hexadecimal bit string (starts with x and contains only hex digits)
1692
- if (bsval.startsWith('x') && /^x[0-9A-Fa-f]+$/.test(bsval)) {
1693
- return `x'${bsval.substring(1)}'`;
1694
- }
1695
- if (bsval.startsWith('b')) {
1696
- return `b'${bsval.substring(1)}'`;
1697
- }
1698
- return `b'${bsval}'`;
1692
+ return formatBitString(nodeAny.bsval);
1699
1693
  }
1700
1694
  }
1701
1695
  if (nodeAny.val) {
@@ -1712,7 +1706,7 @@ export class Deparser {
1712
1706
  return nodeAny.val.Boolean.boolval ? 'true' : 'false';
1713
1707
  }
1714
1708
  else if (nodeAny.val.BitString?.bsval !== undefined) {
1715
- return nodeAny.val.BitString.bsval;
1709
+ return formatBitString(nodeAny.val.BitString.bsval);
1716
1710
  }
1717
1711
  }
1718
1712
  if (nodeAny.isnull === true) {
@@ -2392,15 +2386,7 @@ export class Deparser {
2392
2386
  return node.boolval ? 'true' : 'false';
2393
2387
  }
2394
2388
  BitString(node, context) {
2395
- // Check if this is a hexadecimal bit string (starts with x)
2396
- if (node.bsval.startsWith('x')) {
2397
- return `x'${node.bsval.substring(1)}'`;
2398
- }
2399
- if (node.bsval.startsWith('b')) {
2400
- return `b'${node.bsval.substring(1)}'`;
2401
- }
2402
- // Fallback for raw values without prefix
2403
- return `b'${node.bsval}'`;
2389
+ return formatBitString(node.bsval);
2404
2390
  }
2405
2391
  Null(node, context) {
2406
2392
  return 'NULL';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pgsql-deparser",
3
- "version": "18.3.8",
3
+ "version": "18.3.9",
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": "b93d0f73eab976c7db21f7bc7e2dad165d25173e"
63
+ "gitHead": "506aa3b63613eea04b78afc1ac440bc84b8a07ad"
64
64
  }