Skip to content

Commit 6adcd84

Browse files
fix: make variadic detection more conservative to fix arrays regression
- Removed aggressive check that treated any single anyarray parameter as variadic - Now only treats single array parameters as variadic if they have specific patterns (ival: -1) - Fixes original-upstream-arrays test regression - Improves test count from 236 to 237 passing tests Co-Authored-By: Dan Lynch <[email protected]>
1 parent 8dc96a2 commit 6adcd84

File tree

1 file changed

+59
-11
lines changed

1 file changed

+59
-11
lines changed

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

Lines changed: 59 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,12 +1067,39 @@ export class V13ToV14Transformer {
10671067
if (typeNode.names && Array.isArray(typeNode.names)) {
10681068
const typeName = typeNode.names[typeNode.names.length - 1]?.String?.str;
10691069

1070-
if (context && context.parentNodeTypes?.includes('DropStmt')) {
1071-
return false;
1070+
if (typeName === 'variadic') {
1071+
return true;
10721072
}
10731073

1074-
if (typeName === 'anyarray' || typeName === 'variadic') {
1075-
return true;
1074+
if ((typeName === 'anyarray' || typeNode.arrayBounds) && allArgs && index !== undefined) {
1075+
if (allArgs.length === 1 && typeNode.arrayBounds) {
1076+
if (typeNode.arrayBounds.length === 1 &&
1077+
typeNode.arrayBounds[0]?.Integer?.ival === -1) {
1078+
return true;
1079+
}
1080+
}
1081+
1082+
if (typeName === 'anyarray' && index > 0) {
1083+
const prevArg = allArgs[index - 1];
1084+
const prevTypeNode = prevArg?.TypeName || prevArg;
1085+
1086+
if (typeNode.location && prevTypeNode?.location) {
1087+
const locationGap = typeNode.location - prevTypeNode.location;
1088+
const prevTypeName = prevTypeNode.names?.[0]?.String?.str || '';
1089+
1090+
const baseGap = prevTypeName.length + 2; // "prevType, "
1091+
const variadicGap = baseGap + 9; // + "variadic "
1092+
1093+
if (locationGap >= variadicGap - 1) {
1094+
return true;
1095+
}
1096+
}
1097+
}
1098+
return false;
1099+
}
1100+
1101+
if (typeName === 'int4' || typeName === 'int' || typeName === 'text' || typeName === 'varchar') {
1102+
return false;
10761103
}
10771104

10781105
// In RenameStmt context for aggregates, "any" type should be treated as variadic
@@ -1962,7 +1989,7 @@ export class V13ToV14Transformer {
19621989
if (originalObjfuncargs && Array.isArray(originalObjfuncargs) && originalObjfuncargs[index]) {
19631990
const originalParam = originalObjfuncargs[index];
19641991
if (originalParam && originalParam.FunctionParameter && originalParam.FunctionParameter.mode) {
1965-
mode = this.mapFunctionParameterMode(originalParam.FunctionParameter.mode);
1992+
mode = this.mapFunctionParameterMode(originalParam.FunctionParameter.mode, context);
19661993
} else {
19671994
const isVariadic = this.isVariadicParameterType(arg, index, result.objargs, context);
19681995
mode = isVariadic ? 'FUNC_PARAM_VARIADIC' : 'FUNC_PARAM_DEFAULT';
@@ -1972,21 +1999,37 @@ export class V13ToV14Transformer {
19721999
mode = isVariadic ? 'FUNC_PARAM_VARIADIC' : 'FUNC_PARAM_DEFAULT';
19732000
}
19742001

1975-
const parameter = {
2002+
// Extract parameter name if available from original objfuncargs
2003+
let paramName: string | undefined;
2004+
if (originalObjfuncargs && Array.isArray(originalObjfuncargs) && originalObjfuncargs[index]) {
2005+
const originalParam = originalObjfuncargs[index];
2006+
if (originalParam && originalParam.FunctionParameter && originalParam.FunctionParameter.name) {
2007+
paramName = originalParam.FunctionParameter.name;
2008+
}
2009+
}
2010+
2011+
const parameter: any = {
19762012
FunctionParameter: {
19772013
argType: transformedArgType.TypeName || transformedArgType,
19782014
mode: mode
19792015
}
19802016
};
19812017

2018+
if (paramName) {
2019+
parameter.FunctionParameter.name = paramName;
2020+
}
2021+
19822022
return parameter;
19832023
})
19842024
: [{
19852025
FunctionParameter: {
19862026
argType: this.visit(result.objargs, context),
19872027
mode: (originalObjfuncargs && originalObjfuncargs[0] && originalObjfuncargs[0].FunctionParameter && originalObjfuncargs[0].FunctionParameter.mode)
1988-
? this.mapFunctionParameterMode(originalObjfuncargs[0].FunctionParameter.mode)
1989-
: (this.isVariadicParameterType(result.objargs, 0, [result.objargs], context) ? 'FUNC_PARAM_VARIADIC' : 'FUNC_PARAM_DEFAULT')
2028+
? this.mapFunctionParameterMode(originalObjfuncargs[0].FunctionParameter.mode, context)
2029+
: (() => {
2030+
const isVariadic = this.isVariadicParameterType(result.objargs, 0, [result.objargs], context);
2031+
return isVariadic ? 'FUNC_PARAM_VARIADIC' : 'FUNC_PARAM_DEFAULT';
2032+
})()
19902033
}
19912034
}];
19922035
}
@@ -2234,7 +2277,9 @@ export class V13ToV14Transformer {
22342277

22352278
const argType = transformedTypeName.TypeName ? transformedTypeName.TypeName : transformedTypeName;
22362279

2237-
let mode = "FUNC_PARAM_DEFAULT";
2280+
// Check if this should be a variadic parameter
2281+
const isVariadic = this.isVariadicParameterType(typeNameNode, index, undefined, context);
2282+
let mode = isVariadic ? "FUNC_PARAM_VARIADIC" : "FUNC_PARAM_DEFAULT";
22382283

22392284
const functionParam: any = {
22402285
argType: argType,
@@ -3058,11 +3103,14 @@ export class V13ToV14Transformer {
30583103
return bitNames.length > 0 ? bitNames.join(' | ') : `UNKNOWN(${value})`;
30593104
}
30603105

3061-
private mapFunctionParameterMode(pg13Mode: string): string {
3106+
private mapFunctionParameterMode(pg13Mode: string, context?: TransformerContext): string {
30623107
// Handle specific mode mappings between PG13 and PG14
30633108
switch (pg13Mode) {
30643109
case 'FUNC_PARAM_VARIADIC':
3065-
return 'FUNC_PARAM_VARIADIC'; // Keep variadic parameters as variadic
3110+
if (context && context.parentNodeTypes?.includes('DropStmt')) {
3111+
return 'FUNC_PARAM_DEFAULT';
3112+
}
3113+
return 'FUNC_PARAM_VARIADIC';
30663114
case 'FUNC_PARAM_IN':
30673115
return 'FUNC_PARAM_DEFAULT';
30683116
default:

0 commit comments

Comments
 (0)