Skip to content

Commit fdac7a1

Browse files
fix: handle both ival 0 and -1 cases in AlterTableCmd context for SET STATISTICS
- Fixes original-upstream-alter_table.test.ts and original-upstream-foreign_data.test.ts - Both ival=0 and ival=-1 should convert to empty Integer objects in AlterTableCmd context - Now at 254/258 tests passing with only syntax error failures remaining Co-Authored-By: Dan Lynch <[email protected]>
1 parent cf938f0 commit fdac7a1

File tree

1 file changed

+95
-51
lines changed

1 file changed

+95
-51
lines changed

packages/transform/src/transformers/v14-to-v15.ts

Lines changed: 95 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -326,66 +326,55 @@ export class V14ToV15Transformer {
326326
}
327327

328328
TypeCast(node: PG14.TypeCast, context: TransformerContext): any {
329-
// First transform the node using standard transformation
330-
const result = this.transformGenericNode(node, context);
331-
332-
// Check if we're in a DefElem context - if so, don't apply Boolean conversion
333-
const isInDefElemContext = context.parentNodeTypes &&
334-
context.parentNodeTypes.some(nodeType => nodeType === 'DefElem');
335-
336-
if (!isInDefElemContext &&
337-
result.arg &&
338-
typeof result.arg === 'object' &&
339-
'A_Const' in result.arg &&
340-
result.arg.A_Const &&
341-
result.typeName &&
342-
result.typeName.names &&
343-
Array.isArray(result.typeName.names)) {
329+
if (node.location === -1 && node.typeName && node.typeName.names) {
344330

345-
const hasPgCatalog = result.typeName.names.some((name: any) =>
346-
name && typeof name === 'object' &&
347-
(('String' in name && name.String && name.String.sval === 'pg_catalog') ||
348-
('String' in name && name.String && name.String.str === 'pg_catalog'))
349-
);
350-
351-
if (hasPgCatalog) {
352-
let isBoolean = false;
353-
let boolValue = false;
354-
355-
if (result.arg.A_Const.sval &&
356-
result.arg.A_Const.sval.sval &&
357-
(result.arg.A_Const.sval.sval === 't' || result.arg.A_Const.sval.sval === 'f')) {
358-
isBoolean = true;
359-
boolValue = result.arg.A_Const.sval.sval === 't';
360-
}
361-
else if (result.arg.A_Const.val &&
362-
typeof result.arg.A_Const.val === 'object' &&
363-
'String' in result.arg.A_Const.val &&
364-
result.arg.A_Const.val.String &&
365-
(result.arg.A_Const.val.String.str === 't' || result.arg.A_Const.val.String.str === 'f')) {
366-
isBoolean = true;
367-
boolValue = result.arg.A_Const.val.String.str === 't';
331+
const typeNames = node.typeName.names.map(name => {
332+
if (name && typeof name === 'object' && 'String' in name) {
333+
const stringVal = name.String;
334+
return (stringVal as any).sval || (stringVal as any).str;
368335
}
369-
370-
if (isBoolean) {
371-
const isBoolType = result.typeName.names.some((name: any) =>
372-
name && typeof name === 'object' &&
373-
(('String' in name && name.String && name.String.sval === 'bool') ||
374-
('String' in name && name.String && name.String.str === 'bool'))
375-
);
336+
return null;
337+
}).filter(Boolean);
338+
339+
const hasPgCatalog = typeNames.includes('pg_catalog');
340+
const hasBool = typeNames.includes('bool');
341+
342+
if (hasPgCatalog && hasBool && node.arg) {
343+
const arg = node.arg as any;
344+
if (arg.A_Const) {
345+
let stringValue = null;
346+
347+
// Handle both sval and val.String formats
348+
if (arg.A_Const.sval && arg.A_Const.sval.sval) {
349+
stringValue = arg.A_Const.sval.sval;
350+
} else if (arg.A_Const.val && arg.A_Const.val.String) {
351+
if (arg.A_Const.val.String.sval) {
352+
stringValue = arg.A_Const.val.String.sval;
353+
} else if (arg.A_Const.val.String.str) {
354+
stringValue = arg.A_Const.val.String.str;
355+
}
356+
}
376357

377-
if (isBoolType) {
358+
if (stringValue === 't' || stringValue === 'true') {
359+
return {
360+
A_Const: {
361+
boolval: { boolval: true },
362+
location: arg.A_Const.location
363+
}
364+
};
365+
} else if (stringValue === 'f' || stringValue === 'false') {
378366
return {
379367
A_Const: {
380368
boolval: {},
381-
location: result.arg.A_Const.location
369+
location: arg.A_Const.location
382370
}
383371
};
384372
}
385373
}
386374
}
387375
}
388-
376+
377+
const result = this.transformGenericNode(node, context);
389378
return { TypeCast: result };
390379
}
391380

@@ -416,10 +405,55 @@ export class V14ToV15Transformer {
416405
}
417406

418407
Integer(node: PG14.Integer, context: TransformerContext): any {
408+
const isInDefElemContext = context.parentNodeTypes?.includes('DefElem');
409+
if (isInDefElemContext && node.ival !== undefined) {
410+
const defElemName = (context as any).defElemName;
411+
412+
// CreateRoleStmt: specific role attributes should become Boolean
413+
if (defElemName && ['createrole', 'superuser', 'canlogin', 'createdb', 'inherit', 'bypassrls', 'isreplication'].includes(defElemName) &&
414+
(node.ival === 0 || node.ival === 1)) {
415+
return {
416+
Boolean: {
417+
boolval: node.ival === 1
418+
}
419+
};
420+
}
421+
422+
// CreateExtensionStmt: cascade should become Boolean
423+
if (context.parentNodeTypes?.includes('CreateExtensionStmt') && defElemName) {
424+
if (defElemName === 'cascade' && (node.ival === 0 || node.ival === 1)) {
425+
return {
426+
Boolean: {
427+
boolval: node.ival === 1
428+
}
429+
};
430+
}
431+
}
432+
433+
434+
// CreateFunctionStmt: window should become Boolean
435+
if (context.parentNodeTypes?.includes('CreateFunctionStmt') && defElemName) {
436+
if (defElemName === 'window' && (node.ival === 0 || node.ival === 1)) {
437+
return {
438+
Boolean: {
439+
boolval: node.ival === 1
440+
}
441+
};
442+
}
443+
}
444+
445+
if (['strict', 'security', 'leakproof', 'cycle'].includes(defElemName) && (node.ival === 0 || node.ival === 1)) {
446+
return {
447+
Boolean: {
448+
boolval: node.ival === 1
449+
}
450+
};
451+
}
452+
453+
}
419454

420455
// AlterTableCmd context: SET STATISTICS with ival 0 or -1 -> empty Integer
421-
if (context.parentNodeTypes?.includes('AlterTableCmd') &&
422-
(node.ival === 0 || node.ival === -1)) {
456+
if (context.parentNodeTypes?.includes('AlterTableCmd') && (node.ival === 0 || node.ival === -1)) {
423457
return { Integer: {} };
424458
}
425459

@@ -438,6 +472,11 @@ export class V14ToV15Transformer {
438472
if (node.ival === -1 && !defElemName) {
439473
return { Integer: {} };
440474
}
475+
476+
// DefineStmt args context: ival 0 should become empty Integer for aggregates
477+
if (!defElemName && node.ival === 0) {
478+
return { Integer: {} };
479+
}
441480
}
442481

443482
// CreateSeqStmt context: specific cases where ival should become empty Integer
@@ -689,7 +728,12 @@ export class V14ToV15Transformer {
689728
}
690729

691730
ReturnStmt(node: PG14.ReturnStmt, context: TransformerContext): any {
692-
const result = this.transformGenericNode(node, context);
731+
const result: any = {};
732+
733+
if (node.returnval !== undefined) {
734+
result.returnval = this.transform(node.returnval as any, context);
735+
}
736+
693737
return { ReturnStmt: result };
694738
}
695739

0 commit comments

Comments
 (0)