|
| 1 | +const { Parser } = require('@pgsql/parser'); |
| 2 | + |
| 3 | +async function exploreDualParseApproach() { |
| 4 | + const parser15 = new Parser(15); |
| 5 | + const parser16 = new Parser(16); |
| 6 | + |
| 7 | + const testCases = [ |
| 8 | + { sql: "insert into atacc2 (test2) values (-3)", expected: "negative" }, |
| 9 | + { sql: "insert into atacc2 (test2) values (0)", expected: "zero" }, |
| 10 | + { sql: "insert into atacc2 (test2) values (5)", expected: "positive" }, |
| 11 | + { sql: "ALTER TABLE onek ADD CONSTRAINT onek_check_constraint CHECK (unique1 >= -1)", expected: "negative" }, |
| 12 | + { sql: "ALTER TABLE onek ADD CONSTRAINT onek_check_constraint CHECK (unique1 >= 0)", expected: "zero" } |
| 13 | + ]; |
| 14 | + |
| 15 | + console.log("=== DUAL-PARSE APPROACH EXPLORATION ==="); |
| 16 | + console.log("Strategy: Parse same SQL with both PG15 and PG16, compare A_Const ival structures"); |
| 17 | + console.log("If PG15 has empty {} but PG16 has nested {ival: X}, then transform is needed\n"); |
| 18 | + |
| 19 | + const transformationRules = []; |
| 20 | + |
| 21 | + for (const testCase of testCases) { |
| 22 | + console.log(`=== ${testCase.expected.toUpperCase()}: ${testCase.sql} ===`); |
| 23 | + |
| 24 | + try { |
| 25 | + const pg15Result = await parser15.parse(testCase.sql); |
| 26 | + const pg16Result = await parser16.parse(testCase.sql); |
| 27 | + |
| 28 | + const pg15AConst = findAConstInAST(pg15Result); |
| 29 | + const pg16AConst = findAConstInAST(pg16Result); |
| 30 | + |
| 31 | + if (pg15AConst && pg16AConst) { |
| 32 | + const pg15IsEmpty = pg15AConst.ival && Object.keys(pg15AConst.ival).length === 0; |
| 33 | + const pg16HasNested = pg16AConst.ival && typeof pg16AConst.ival.ival === 'number'; |
| 34 | + const shouldTransform = pg15IsEmpty && pg16HasNested; |
| 35 | + |
| 36 | + console.log("PG15 ival:", JSON.stringify(pg15AConst.ival)); |
| 37 | + console.log("PG16 ival:", JSON.stringify(pg16AConst.ival)); |
| 38 | + console.log("PG15 is empty:", pg15IsEmpty); |
| 39 | + console.log("PG16 has nested:", pg16HasNested); |
| 40 | + console.log("Should transform:", shouldTransform); |
| 41 | + |
| 42 | + if (shouldTransform) { |
| 43 | + const targetValue = pg16AConst.ival.ival; |
| 44 | + console.log(`RULE: Transform empty {} to {ival: ${targetValue}}`); |
| 45 | + transformationRules.push({ |
| 46 | + sql: testCase.sql, |
| 47 | + targetValue: targetValue, |
| 48 | + type: testCase.expected |
| 49 | + }); |
| 50 | + } else { |
| 51 | + console.log("RULE: Keep empty {} as is"); |
| 52 | + } |
| 53 | + |
| 54 | + console.log(""); |
| 55 | + } |
| 56 | + |
| 57 | + } catch (error) { |
| 58 | + console.error("Error:", error.message); |
| 59 | + } |
| 60 | + } |
| 61 | + |
| 62 | + console.log("=== TRANSFORMATION RULES DISCOVERED ==="); |
| 63 | + transformationRules.forEach((rule, i) => { |
| 64 | + console.log(`${i + 1}. ${rule.type} integers: Transform {} to {ival: ${rule.targetValue}}`); |
| 65 | + }); |
| 66 | + |
| 67 | + console.log("\n=== DUAL-PARSE IMPLEMENTATION STRATEGY ==="); |
| 68 | + console.log("1. In A_Const method, when encountering empty ival object:"); |
| 69 | + console.log("2. Extract the original SQL from the current transformation context"); |
| 70 | + console.log("3. Parse the SQL with both PG15 and PG16"); |
| 71 | + console.log("4. Compare the A_Const ival structures"); |
| 72 | + console.log("5. If PG16 expects nested structure, transform; otherwise keep empty"); |
| 73 | + console.log("6. Cache results to avoid re-parsing the same SQL multiple times"); |
| 74 | + |
| 75 | + console.log("\n=== FEASIBILITY ASSESSMENT ==="); |
| 76 | + console.log("✅ Technically feasible - can access both parsers in transformer"); |
| 77 | + console.log("✅ Accurate - directly compares what PG16 expects vs PG15 produces"); |
| 78 | + console.log("⚠️ Performance - may be slower due to dual parsing"); |
| 79 | + console.log("⚠️ Complexity - need to extract original SQL from transformation context"); |
| 80 | + console.log("✅ Reliable - eliminates guesswork about when to transform"); |
| 81 | +} |
| 82 | + |
| 83 | +function findAConstInAST(obj) { |
| 84 | + if (!obj || typeof obj !== 'object') return null; |
| 85 | + |
| 86 | + if (obj.A_Const) return obj.A_Const; |
| 87 | + |
| 88 | + for (const key in obj) { |
| 89 | + if (typeof obj[key] === 'object') { |
| 90 | + const result = findAConstInAST(obj[key]); |
| 91 | + if (result) return result; |
| 92 | + } |
| 93 | + } |
| 94 | + |
| 95 | + return null; |
| 96 | +} |
| 97 | + |
| 98 | +exploreDualParseApproach(); |
0 commit comments