pgsql-deparser 17.8.2 → 17.8.4

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.
@@ -1,3 +1,90 @@
1
+ import { SqlFormatter } from '../utils/sql-formatter';
2
+ export class DeparserContext {
3
+ indentLevel;
4
+ prettyMode;
5
+ isStringLiteral;
6
+ parentNodeTypes;
7
+ formatter;
8
+ select;
9
+ from;
10
+ group;
11
+ sort;
12
+ insertColumns;
13
+ update;
14
+ bool;
15
+ isColumnConstraint;
16
+ isDomainConstraint;
17
+ alterColumnOptions;
18
+ alterTableOptions;
19
+ isEnumValue;
20
+ objtype;
21
+ subtype;
22
+ constructor({ indentLevel = 0, prettyMode = false, isStringLiteral, parentNodeTypes = [], formatter, select, from, group, sort, insertColumns, update, bool, isColumnConstraint, isDomainConstraint, alterColumnOptions, alterTableOptions, isEnumValue, objtype, subtype, ...rest } = {}) {
23
+ this.indentLevel = indentLevel;
24
+ this.prettyMode = prettyMode;
25
+ this.isStringLiteral = isStringLiteral;
26
+ this.parentNodeTypes = parentNodeTypes;
27
+ this.formatter = formatter || new SqlFormatter('\n', ' ', prettyMode);
28
+ this.select = select;
29
+ this.from = from;
30
+ this.group = group;
31
+ this.sort = sort;
32
+ this.insertColumns = insertColumns;
33
+ this.update = update;
34
+ this.bool = bool;
35
+ this.isColumnConstraint = isColumnConstraint;
36
+ this.isDomainConstraint = isDomainConstraint;
37
+ this.alterColumnOptions = alterColumnOptions;
38
+ this.alterTableOptions = alterTableOptions;
39
+ this.isEnumValue = isEnumValue;
40
+ this.objtype = objtype;
41
+ this.subtype = subtype;
42
+ Object.assign(this, rest);
43
+ }
44
+ spawn(nodeType, overrides = {}) {
45
+ return new DeparserContext({
46
+ indentLevel: this.indentLevel,
47
+ prettyMode: this.prettyMode,
48
+ isStringLiteral: this.isStringLiteral,
49
+ parentNodeTypes: [...this.parentNodeTypes, nodeType],
50
+ formatter: this.formatter,
51
+ select: this.select,
52
+ from: this.from,
53
+ group: this.group,
54
+ sort: this.sort,
55
+ insertColumns: this.insertColumns,
56
+ update: this.update,
57
+ bool: this.bool,
58
+ isColumnConstraint: this.isColumnConstraint,
59
+ isDomainConstraint: this.isDomainConstraint,
60
+ alterColumnOptions: this.alterColumnOptions,
61
+ alterTableOptions: this.alterTableOptions,
62
+ isEnumValue: this.isEnumValue,
63
+ objtype: this.objtype,
64
+ subtype: this.subtype,
65
+ ...overrides,
66
+ });
67
+ }
68
+ indent(text, count) {
69
+ if (!this.prettyMode) {
70
+ return text;
71
+ }
72
+ const indentCount = count !== undefined ? count : this.indentLevel + 1;
73
+ return this.formatter.indent(text, indentCount);
74
+ }
75
+ newline() {
76
+ return this.formatter.newline();
77
+ }
78
+ parens(content) {
79
+ return this.formatter.parens(content);
80
+ }
81
+ format(parts, separator) {
82
+ return this.formatter.format(parts, separator);
83
+ }
84
+ isPretty() {
85
+ return this.formatter.isPretty();
86
+ }
87
+ }
1
88
  export class BaseVisitor {
2
89
  getNodeType(node) {
3
90
  return Object.keys(node)[0];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pgsql-deparser",
3
- "version": "17.8.2",
3
+ "version": "17.8.4",
4
4
  "author": "Dan Lynch <pyramation@gmail.com>",
5
5
  "description": "PostgreSQL AST Deparser",
6
6
  "main": "index.js",
@@ -33,7 +33,14 @@
33
33
  "fixtures:upstream-diff": "ts-node scripts/make-upstream-diff.ts",
34
34
  "lint": "eslint . --fix",
35
35
  "test": "jest",
36
- "test:watch": "jest --watch"
36
+ "test:watch": "jest --watch",
37
+ "strip-transformer-types": "ts-node scripts/strip-transformer-types.ts",
38
+ "strip-direct-transformer-types": "ts-node scripts/strip-direct-transformer-types.ts",
39
+ "strip-deparser-types": "ts-node scripts/strip-deparser-types.ts",
40
+ "organize-transformers": "ts-node scripts/organize-transformers-by-version.ts",
41
+ "generate-version-deparsers": "ts-node scripts/generate-version-deparsers.ts",
42
+ "generate-packages": "ts-node scripts/generate-version-packages.ts",
43
+ "prepare-versions": "npm run strip-transformer-types && npm run strip-direct-transformer-types && npm run strip-deparser-types && npm run organize-transformers && npm run generate-version-deparsers && npm run generate-packages"
37
44
  },
38
45
  "keywords": [
39
46
  "sql",
@@ -46,10 +53,10 @@
46
53
  "database"
47
54
  ],
48
55
  "devDependencies": {
49
- "libpg-query": "17.5.3"
56
+ "libpg-query": "17.5.5"
50
57
  },
51
58
  "dependencies": {
52
59
  "@pgsql/types": "^17.6.1"
53
60
  },
54
- "gitHead": "309bfda0a8a4335ff29093763ad0f14c8a71ee21"
61
+ "gitHead": "db3e424332bcb223c34a1caca3f37fb6fc9a1964"
55
62
  }
@@ -1,10 +1,56 @@
1
1
  import { Node } from '@pgsql/types';
2
- export interface DeparserContext {
2
+ import { SqlFormatter } from '../utils/sql-formatter';
3
+ export interface DeparserContextOptions {
3
4
  isStringLiteral?: boolean;
4
- parentNodeTypes: string[];
5
+ parentNodeTypes?: string[];
5
6
  indentLevel?: number;
7
+ prettyMode?: boolean;
8
+ formatter?: SqlFormatter;
9
+ select?: boolean;
10
+ from?: boolean;
11
+ group?: boolean;
12
+ sort?: boolean;
13
+ insertColumns?: boolean;
14
+ update?: boolean;
15
+ bool?: boolean;
16
+ isColumnConstraint?: boolean;
17
+ isDomainConstraint?: boolean;
18
+ alterColumnOptions?: boolean;
19
+ alterTableOptions?: boolean;
20
+ isEnumValue?: boolean;
21
+ objtype?: string;
22
+ subtype?: string;
6
23
  [key: string]: any;
7
24
  }
25
+ export declare class DeparserContext {
26
+ readonly indentLevel: number;
27
+ readonly prettyMode: boolean;
28
+ readonly isStringLiteral?: boolean;
29
+ readonly parentNodeTypes: string[];
30
+ private readonly formatter;
31
+ readonly select?: boolean;
32
+ readonly from?: boolean;
33
+ readonly group?: boolean;
34
+ readonly sort?: boolean;
35
+ readonly insertColumns?: boolean;
36
+ readonly update?: boolean;
37
+ readonly bool?: boolean;
38
+ readonly isColumnConstraint?: boolean;
39
+ readonly isDomainConstraint?: boolean;
40
+ readonly alterColumnOptions?: boolean;
41
+ readonly alterTableOptions?: boolean;
42
+ readonly isEnumValue?: boolean;
43
+ readonly objtype?: string;
44
+ readonly subtype?: string;
45
+ readonly [key: string]: any;
46
+ constructor({ indentLevel, prettyMode, isStringLiteral, parentNodeTypes, formatter, select, from, group, sort, insertColumns, update, bool, isColumnConstraint, isDomainConstraint, alterColumnOptions, alterTableOptions, isEnumValue, objtype, subtype, ...rest }?: DeparserContextOptions);
47
+ spawn(nodeType: string, overrides?: Partial<DeparserContextOptions>): DeparserContext;
48
+ indent(text: string, count?: number): string;
49
+ newline(): string;
50
+ parens(content: string): string;
51
+ format(parts: string[], separator?: string): string;
52
+ isPretty(): boolean;
53
+ }
8
54
  export interface DeparserVisitor {
9
55
  visit(node: Node, context?: DeparserContext): string;
10
56
  }
package/visitors/base.js CHANGED
@@ -1,6 +1,94 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.BaseVisitor = void 0;
3
+ exports.BaseVisitor = exports.DeparserContext = void 0;
4
+ const sql_formatter_1 = require("../utils/sql-formatter");
5
+ class DeparserContext {
6
+ indentLevel;
7
+ prettyMode;
8
+ isStringLiteral;
9
+ parentNodeTypes;
10
+ formatter;
11
+ select;
12
+ from;
13
+ group;
14
+ sort;
15
+ insertColumns;
16
+ update;
17
+ bool;
18
+ isColumnConstraint;
19
+ isDomainConstraint;
20
+ alterColumnOptions;
21
+ alterTableOptions;
22
+ isEnumValue;
23
+ objtype;
24
+ subtype;
25
+ constructor({ indentLevel = 0, prettyMode = false, isStringLiteral, parentNodeTypes = [], formatter, select, from, group, sort, insertColumns, update, bool, isColumnConstraint, isDomainConstraint, alterColumnOptions, alterTableOptions, isEnumValue, objtype, subtype, ...rest } = {}) {
26
+ this.indentLevel = indentLevel;
27
+ this.prettyMode = prettyMode;
28
+ this.isStringLiteral = isStringLiteral;
29
+ this.parentNodeTypes = parentNodeTypes;
30
+ this.formatter = formatter || new sql_formatter_1.SqlFormatter('\n', ' ', prettyMode);
31
+ this.select = select;
32
+ this.from = from;
33
+ this.group = group;
34
+ this.sort = sort;
35
+ this.insertColumns = insertColumns;
36
+ this.update = update;
37
+ this.bool = bool;
38
+ this.isColumnConstraint = isColumnConstraint;
39
+ this.isDomainConstraint = isDomainConstraint;
40
+ this.alterColumnOptions = alterColumnOptions;
41
+ this.alterTableOptions = alterTableOptions;
42
+ this.isEnumValue = isEnumValue;
43
+ this.objtype = objtype;
44
+ this.subtype = subtype;
45
+ Object.assign(this, rest);
46
+ }
47
+ spawn(nodeType, overrides = {}) {
48
+ return new DeparserContext({
49
+ indentLevel: this.indentLevel,
50
+ prettyMode: this.prettyMode,
51
+ isStringLiteral: this.isStringLiteral,
52
+ parentNodeTypes: [...this.parentNodeTypes, nodeType],
53
+ formatter: this.formatter,
54
+ select: this.select,
55
+ from: this.from,
56
+ group: this.group,
57
+ sort: this.sort,
58
+ insertColumns: this.insertColumns,
59
+ update: this.update,
60
+ bool: this.bool,
61
+ isColumnConstraint: this.isColumnConstraint,
62
+ isDomainConstraint: this.isDomainConstraint,
63
+ alterColumnOptions: this.alterColumnOptions,
64
+ alterTableOptions: this.alterTableOptions,
65
+ isEnumValue: this.isEnumValue,
66
+ objtype: this.objtype,
67
+ subtype: this.subtype,
68
+ ...overrides,
69
+ });
70
+ }
71
+ indent(text, count) {
72
+ if (!this.prettyMode) {
73
+ return text;
74
+ }
75
+ const indentCount = count !== undefined ? count : this.indentLevel + 1;
76
+ return this.formatter.indent(text, indentCount);
77
+ }
78
+ newline() {
79
+ return this.formatter.newline();
80
+ }
81
+ parens(content) {
82
+ return this.formatter.parens(content);
83
+ }
84
+ format(parts, separator) {
85
+ return this.formatter.format(parts, separator);
86
+ }
87
+ isPretty() {
88
+ return this.formatter.isPretty();
89
+ }
90
+ }
91
+ exports.DeparserContext = DeparserContext;
4
92
  class BaseVisitor {
5
93
  getNodeType(node) {
6
94
  return Object.keys(node)[0];
@@ -1,90 +0,0 @@
1
- /* eslint-disable no-restricted-syntax */
2
- export const cleanLines = (sql) => {
3
- return sql
4
- .split('\n')
5
- .map((l) => l.trim())
6
- .filter((a) => a)
7
- .join('\n');
8
- };
9
- export const transform = (obj, props) => {
10
- let copy = null;
11
- // Handle the 3 simple types, and null or undefined
12
- if (obj == null || typeof obj !== 'object') {
13
- return obj;
14
- }
15
- // Handle Date
16
- if (obj instanceof Date) {
17
- copy = new Date();
18
- copy.setTime(obj.getTime());
19
- return copy;
20
- }
21
- // Handle Array
22
- if (obj instanceof Array) {
23
- copy = [];
24
- for (let i = 0, len = obj.length; i < len; i++) {
25
- copy[i] = transform(obj[i], props);
26
- }
27
- return copy;
28
- }
29
- // Handle Object
30
- if (obj instanceof Object || typeof obj === 'object') {
31
- copy = {};
32
- for (const attr in obj) {
33
- if (obj.hasOwnProperty(attr)) {
34
- if (props.hasOwnProperty(attr)) {
35
- if (typeof props[attr] === 'function') {
36
- copy[attr] = props[attr](obj[attr]);
37
- }
38
- else if (props[attr].hasOwnProperty(obj[attr])) {
39
- copy[attr] = props[attr][obj[attr]];
40
- }
41
- else {
42
- copy[attr] = transform(obj[attr], props);
43
- }
44
- }
45
- else {
46
- copy[attr] = transform(obj[attr], props);
47
- }
48
- }
49
- else {
50
- copy[attr] = transform(obj[attr], props);
51
- }
52
- }
53
- return copy;
54
- }
55
- throw new Error("Unable to copy obj! Its type isn't supported.");
56
- };
57
- const noop = () => undefined;
58
- export const cleanTree = (tree) => {
59
- return transform(tree, {
60
- stmt_len: noop,
61
- stmt_location: noop,
62
- location: noop,
63
- DefElem: (obj) => {
64
- if (obj.defname === 'as') {
65
- if (Array.isArray(obj.arg) && obj.arg.length) {
66
- // function
67
- obj.arg[0].String.sval = obj.arg[0].String.sval.trim();
68
- }
69
- else if (obj.arg.List && obj.arg.List.items) {
70
- // function
71
- obj.arg.List.items[0].String.sval = obj.arg.List.items[0].String.sval.trim();
72
- }
73
- else {
74
- // do stmt
75
- obj.arg.String.sval = obj.arg.String.sval.trim();
76
- }
77
- return cleanTree(obj);
78
- }
79
- else {
80
- return cleanTree(obj);
81
- }
82
- }
83
- });
84
- };
85
- export const cleanTreeWithStmt = (tree) => {
86
- return transform(tree, {
87
- stmt_location: noop,
88
- location: noop
89
- });
90
- };
@@ -1,125 +0,0 @@
1
- import { parse } from 'libpg-query';
2
- /**
3
- * Extracts a single statement from SQL using PostgreSQL's location information.
4
- * Handles Unicode properly by using byte positions instead of character positions.
5
- */
6
- export function extractStatement(originalSQL, rawStmt, isFirst = false, options = {}) {
7
- let extracted = null;
8
- // Convert string to buffer to handle byte positions correctly (for Unicode)
9
- const sqlBuffer = Buffer.from(originalSQL, 'utf8');
10
- if (rawStmt.stmt_location !== undefined && rawStmt.stmt_len !== undefined) {
11
- // Use byte positions as provided by PostgreSQL
12
- const startByte = rawStmt.stmt_location;
13
- const endByte = rawStmt.stmt_location + rawStmt.stmt_len;
14
- // Extract using byte positions and convert back to string
15
- const extractedBuffer = sqlBuffer.slice(startByte, endByte);
16
- extracted = extractedBuffer.toString('utf8');
17
- }
18
- else if (rawStmt.stmt_location !== undefined && rawStmt.stmt_len === undefined) {
19
- // We have location but no length - extract from location to end of file
20
- const extractedBuffer = sqlBuffer.slice(rawStmt.stmt_location);
21
- extracted = extractedBuffer.toString('utf8');
22
- }
23
- else if (isFirst && rawStmt.stmt_len !== undefined) {
24
- // For first statement when location is missing but we have length
25
- const extractedBuffer = sqlBuffer.slice(0, rawStmt.stmt_len);
26
- extracted = extractedBuffer.toString('utf8');
27
- }
28
- else if (isFirst && rawStmt.stmt_location === undefined && rawStmt.stmt_len === undefined) {
29
- // For first statement when both location and length are missing, use entire SQL
30
- extracted = originalSQL;
31
- }
32
- if (extracted && options.stripComments !== false) {
33
- // Split into lines to handle leading whitespace and comments properly
34
- const lines = extracted.split('\n');
35
- let startLineIndex = 0;
36
- // Find the first line that contains actual SQL content
37
- for (let i = 0; i < lines.length; i++) {
38
- const line = lines[i].trim();
39
- // Skip empty lines and comment-only lines
40
- if (line === '' || line.startsWith('--')) {
41
- continue;
42
- }
43
- startLineIndex = i;
44
- break;
45
- }
46
- // Reconstruct from the first SQL line, preserving the original indentation of that line
47
- if (startLineIndex < lines.length) {
48
- const resultLines = lines.slice(startLineIndex);
49
- extracted = resultLines.join('\n').trim();
50
- }
51
- }
52
- // Final validation unless skipped
53
- if (extracted && !options.skipValidation) {
54
- const firstLine = extracted.split('\n')[0].trim();
55
- const firstWord = firstLine.split(/\s+/)[0].toUpperCase();
56
- // Only check for most obvious malformed patterns at the BEGINNING
57
- if (
58
- // Check if it starts with truncated patterns (not just contains anywhere)
59
- extracted.trim().startsWith('ELECT ') || // Missing S from SELECT
60
- extracted.trim().startsWith('REATE ') || // Missing C from CREATE
61
- extracted.trim().startsWith('NSERT ') || // Missing I from INSERT
62
- // Completely empty or whitespace only
63
- extracted.trim().length === 0) {
64
- return null; // Invalid extraction, skip this statement
65
- }
66
- }
67
- return extracted;
68
- }
69
- /**
70
- * Splits SQL text into individual statements using PostgreSQL's parser.
71
- * Handles Unicode characters properly and provides detailed location information.
72
- */
73
- export async function splitStatements(sql, options = {}) {
74
- const parseResult = await parse(sql);
75
- const statements = [];
76
- if (!parseResult.stmts) {
77
- return statements;
78
- }
79
- for (let idx = 0; idx < parseResult.stmts.length; idx++) {
80
- const stmt = parseResult.stmts[idx];
81
- const extracted = extractStatement(sql, stmt, idx === 0, options);
82
- if (extracted) {
83
- statements.push({
84
- statement: extracted,
85
- index: idx,
86
- location: stmt.stmt_location,
87
- length: stmt.stmt_len
88
- });
89
- }
90
- }
91
- return statements;
92
- }
93
- /**
94
- * Utility to generate statement keys for fixtures
95
- */
96
- export function generateStatementKey(relativePath, statementIndex, extension = 'sql') {
97
- return `${relativePath.replace(/\.sql$/, '')}-${statementIndex + 1}.${extension}`;
98
- }
99
- /**
100
- * Test utility to compare byte vs character extraction for debugging Unicode issues
101
- */
102
- export function debugUnicodeExtraction(sql, rawStmt) {
103
- const charLength = sql.length;
104
- const byteLength = Buffer.from(sql, 'utf8').length;
105
- // Character-based extraction (old way)
106
- let characterBased = '';
107
- if (rawStmt.stmt_location !== undefined && rawStmt.stmt_len !== undefined) {
108
- characterBased = sql.substring(rawStmt.stmt_location, rawStmt.stmt_location + rawStmt.stmt_len);
109
- }
110
- // Byte-based extraction (new way)
111
- let byteBased = '';
112
- if (rawStmt.stmt_location !== undefined && rawStmt.stmt_len !== undefined) {
113
- const sqlBuffer = Buffer.from(sql, 'utf8');
114
- const extractedBuffer = sqlBuffer.slice(rawStmt.stmt_location, rawStmt.stmt_location + rawStmt.stmt_len);
115
- byteBased = extractedBuffer.toString('utf8');
116
- }
117
- return {
118
- characterBased,
119
- byteBased,
120
- matches: characterBased === byteBased,
121
- unicodeChars: byteLength - charLength,
122
- byteLength,
123
- charLength
124
- };
125
- }
package/utils/index.d.ts DELETED
@@ -1,4 +0,0 @@
1
- export declare const cleanLines: (sql: string) => string;
2
- export declare const transform: (obj: any, props: any) => any;
3
- export declare const cleanTree: (tree: any) => any;
4
- export declare const cleanTreeWithStmt: (tree: any) => any;
package/utils/index.js DELETED
@@ -1,97 +0,0 @@
1
- "use strict";
2
- /* eslint-disable no-restricted-syntax */
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.cleanTreeWithStmt = exports.cleanTree = exports.transform = exports.cleanLines = void 0;
5
- const cleanLines = (sql) => {
6
- return sql
7
- .split('\n')
8
- .map((l) => l.trim())
9
- .filter((a) => a)
10
- .join('\n');
11
- };
12
- exports.cleanLines = cleanLines;
13
- const transform = (obj, props) => {
14
- let copy = null;
15
- // Handle the 3 simple types, and null or undefined
16
- if (obj == null || typeof obj !== 'object') {
17
- return obj;
18
- }
19
- // Handle Date
20
- if (obj instanceof Date) {
21
- copy = new Date();
22
- copy.setTime(obj.getTime());
23
- return copy;
24
- }
25
- // Handle Array
26
- if (obj instanceof Array) {
27
- copy = [];
28
- for (let i = 0, len = obj.length; i < len; i++) {
29
- copy[i] = (0, exports.transform)(obj[i], props);
30
- }
31
- return copy;
32
- }
33
- // Handle Object
34
- if (obj instanceof Object || typeof obj === 'object') {
35
- copy = {};
36
- for (const attr in obj) {
37
- if (obj.hasOwnProperty(attr)) {
38
- if (props.hasOwnProperty(attr)) {
39
- if (typeof props[attr] === 'function') {
40
- copy[attr] = props[attr](obj[attr]);
41
- }
42
- else if (props[attr].hasOwnProperty(obj[attr])) {
43
- copy[attr] = props[attr][obj[attr]];
44
- }
45
- else {
46
- copy[attr] = (0, exports.transform)(obj[attr], props);
47
- }
48
- }
49
- else {
50
- copy[attr] = (0, exports.transform)(obj[attr], props);
51
- }
52
- }
53
- else {
54
- copy[attr] = (0, exports.transform)(obj[attr], props);
55
- }
56
- }
57
- return copy;
58
- }
59
- throw new Error("Unable to copy obj! Its type isn't supported.");
60
- };
61
- exports.transform = transform;
62
- const noop = () => undefined;
63
- const cleanTree = (tree) => {
64
- return (0, exports.transform)(tree, {
65
- stmt_len: noop,
66
- stmt_location: noop,
67
- location: noop,
68
- DefElem: (obj) => {
69
- if (obj.defname === 'as') {
70
- if (Array.isArray(obj.arg) && obj.arg.length) {
71
- // function
72
- obj.arg[0].String.sval = obj.arg[0].String.sval.trim();
73
- }
74
- else if (obj.arg.List && obj.arg.List.items) {
75
- // function
76
- obj.arg.List.items[0].String.sval = obj.arg.List.items[0].String.sval.trim();
77
- }
78
- else {
79
- // do stmt
80
- obj.arg.String.sval = obj.arg.String.sval.trim();
81
- }
82
- return (0, exports.cleanTree)(obj);
83
- }
84
- else {
85
- return (0, exports.cleanTree)(obj);
86
- }
87
- }
88
- });
89
- };
90
- exports.cleanTree = cleanTree;
91
- const cleanTreeWithStmt = (tree) => {
92
- return (0, exports.transform)(tree, {
93
- stmt_location: noop,
94
- location: noop
95
- });
96
- };
97
- exports.cleanTreeWithStmt = cleanTreeWithStmt;
@@ -1,38 +0,0 @@
1
- import { RawStmt } from '@pgsql/types';
2
- export interface ExtractedStatement {
3
- statement: string;
4
- index: number;
5
- location?: number;
6
- length?: number;
7
- }
8
- export interface StatementSplitterOptions {
9
- /** Skip validation for malformed statements */
10
- skipValidation?: boolean;
11
- /** Strip leading comments from extracted statements */
12
- stripComments?: boolean;
13
- }
14
- /**
15
- * Extracts a single statement from SQL using PostgreSQL's location information.
16
- * Handles Unicode properly by using byte positions instead of character positions.
17
- */
18
- export declare function extractStatement(originalSQL: string, rawStmt: RawStmt, isFirst?: boolean, options?: StatementSplitterOptions): string | null;
19
- /**
20
- * Splits SQL text into individual statements using PostgreSQL's parser.
21
- * Handles Unicode characters properly and provides detailed location information.
22
- */
23
- export declare function splitStatements(sql: string, options?: StatementSplitterOptions): Promise<ExtractedStatement[]>;
24
- /**
25
- * Utility to generate statement keys for fixtures
26
- */
27
- export declare function generateStatementKey(relativePath: string, statementIndex: number, extension?: string): string;
28
- /**
29
- * Test utility to compare byte vs character extraction for debugging Unicode issues
30
- */
31
- export declare function debugUnicodeExtraction(sql: string, rawStmt: RawStmt): {
32
- characterBased: string;
33
- byteBased: string;
34
- matches: boolean;
35
- unicodeChars: number;
36
- byteLength: number;
37
- charLength: number;
38
- };