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,131 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.extractStatement = extractStatement;
4
- exports.splitStatements = splitStatements;
5
- exports.generateStatementKey = generateStatementKey;
6
- exports.debugUnicodeExtraction = debugUnicodeExtraction;
7
- const libpg_query_1 = require("libpg-query");
8
- /**
9
- * Extracts a single statement from SQL using PostgreSQL's location information.
10
- * Handles Unicode properly by using byte positions instead of character positions.
11
- */
12
- function extractStatement(originalSQL, rawStmt, isFirst = false, options = {}) {
13
- let extracted = null;
14
- // Convert string to buffer to handle byte positions correctly (for Unicode)
15
- const sqlBuffer = Buffer.from(originalSQL, 'utf8');
16
- if (rawStmt.stmt_location !== undefined && rawStmt.stmt_len !== undefined) {
17
- // Use byte positions as provided by PostgreSQL
18
- const startByte = rawStmt.stmt_location;
19
- const endByte = rawStmt.stmt_location + rawStmt.stmt_len;
20
- // Extract using byte positions and convert back to string
21
- const extractedBuffer = sqlBuffer.slice(startByte, endByte);
22
- extracted = extractedBuffer.toString('utf8');
23
- }
24
- else if (rawStmt.stmt_location !== undefined && rawStmt.stmt_len === undefined) {
25
- // We have location but no length - extract from location to end of file
26
- const extractedBuffer = sqlBuffer.slice(rawStmt.stmt_location);
27
- extracted = extractedBuffer.toString('utf8');
28
- }
29
- else if (isFirst && rawStmt.stmt_len !== undefined) {
30
- // For first statement when location is missing but we have length
31
- const extractedBuffer = sqlBuffer.slice(0, rawStmt.stmt_len);
32
- extracted = extractedBuffer.toString('utf8');
33
- }
34
- else if (isFirst && rawStmt.stmt_location === undefined && rawStmt.stmt_len === undefined) {
35
- // For first statement when both location and length are missing, use entire SQL
36
- extracted = originalSQL;
37
- }
38
- if (extracted && options.stripComments !== false) {
39
- // Split into lines to handle leading whitespace and comments properly
40
- const lines = extracted.split('\n');
41
- let startLineIndex = 0;
42
- // Find the first line that contains actual SQL content
43
- for (let i = 0; i < lines.length; i++) {
44
- const line = lines[i].trim();
45
- // Skip empty lines and comment-only lines
46
- if (line === '' || line.startsWith('--')) {
47
- continue;
48
- }
49
- startLineIndex = i;
50
- break;
51
- }
52
- // Reconstruct from the first SQL line, preserving the original indentation of that line
53
- if (startLineIndex < lines.length) {
54
- const resultLines = lines.slice(startLineIndex);
55
- extracted = resultLines.join('\n').trim();
56
- }
57
- }
58
- // Final validation unless skipped
59
- if (extracted && !options.skipValidation) {
60
- const firstLine = extracted.split('\n')[0].trim();
61
- const firstWord = firstLine.split(/\s+/)[0].toUpperCase();
62
- // Only check for most obvious malformed patterns at the BEGINNING
63
- if (
64
- // Check if it starts with truncated patterns (not just contains anywhere)
65
- extracted.trim().startsWith('ELECT ') || // Missing S from SELECT
66
- extracted.trim().startsWith('REATE ') || // Missing C from CREATE
67
- extracted.trim().startsWith('NSERT ') || // Missing I from INSERT
68
- // Completely empty or whitespace only
69
- extracted.trim().length === 0) {
70
- return null; // Invalid extraction, skip this statement
71
- }
72
- }
73
- return extracted;
74
- }
75
- /**
76
- * Splits SQL text into individual statements using PostgreSQL's parser.
77
- * Handles Unicode characters properly and provides detailed location information.
78
- */
79
- async function splitStatements(sql, options = {}) {
80
- const parseResult = await (0, libpg_query_1.parse)(sql);
81
- const statements = [];
82
- if (!parseResult.stmts) {
83
- return statements;
84
- }
85
- for (let idx = 0; idx < parseResult.stmts.length; idx++) {
86
- const stmt = parseResult.stmts[idx];
87
- const extracted = extractStatement(sql, stmt, idx === 0, options);
88
- if (extracted) {
89
- statements.push({
90
- statement: extracted,
91
- index: idx,
92
- location: stmt.stmt_location,
93
- length: stmt.stmt_len
94
- });
95
- }
96
- }
97
- return statements;
98
- }
99
- /**
100
- * Utility to generate statement keys for fixtures
101
- */
102
- function generateStatementKey(relativePath, statementIndex, extension = 'sql') {
103
- return `${relativePath.replace(/\.sql$/, '')}-${statementIndex + 1}.${extension}`;
104
- }
105
- /**
106
- * Test utility to compare byte vs character extraction for debugging Unicode issues
107
- */
108
- function debugUnicodeExtraction(sql, rawStmt) {
109
- const charLength = sql.length;
110
- const byteLength = Buffer.from(sql, 'utf8').length;
111
- // Character-based extraction (old way)
112
- let characterBased = '';
113
- if (rawStmt.stmt_location !== undefined && rawStmt.stmt_len !== undefined) {
114
- characterBased = sql.substring(rawStmt.stmt_location, rawStmt.stmt_location + rawStmt.stmt_len);
115
- }
116
- // Byte-based extraction (new way)
117
- let byteBased = '';
118
- if (rawStmt.stmt_location !== undefined && rawStmt.stmt_len !== undefined) {
119
- const sqlBuffer = Buffer.from(sql, 'utf8');
120
- const extractedBuffer = sqlBuffer.slice(rawStmt.stmt_location, rawStmt.stmt_location + rawStmt.stmt_len);
121
- byteBased = extractedBuffer.toString('utf8');
122
- }
123
- return {
124
- characterBased,
125
- byteBased,
126
- matches: characterBased === byteBased,
127
- unicodeChars: byteLength - charLength,
128
- byteLength,
129
- charLength
130
- };
131
- }