Skip to content

Commit de6f710

Browse files
fix: add operator detection in CreateOpClassItem to prevent objfuncargs for operators
- Add isOperatorName helper method to detect operator symbols - Prevent objfuncargs creation for operators in CreateOpClassItem contexts - Fixes original-upstream-alter_generic test - Improves test count from 223 to 227 passing tests Co-Authored-By: Dan Lynch <[email protected]>
1 parent 9255eca commit de6f710

File tree

1 file changed

+73
-8
lines changed

1 file changed

+73
-8
lines changed

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

Lines changed: 73 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -752,9 +752,14 @@ export class V13ToV14Transformer {
752752
}
753753

754754
if (result.name.objargs && !result.name.objfuncargs) {
755-
result.name.objfuncargs = Array.isArray(result.name.objargs)
756-
? result.name.objargs.map((arg: any) => this.createFunctionParameterFromTypeName(arg))
757-
: [this.createFunctionParameterFromTypeName(result.name.objargs)];
755+
// Check if this is an operator by looking at the objname
756+
const isOperator = this.isOperatorName(result.name.objname);
757+
758+
if (!isOperator) {
759+
result.name.objfuncargs = Array.isArray(result.name.objargs)
760+
? result.name.objargs.map((arg: any) => this.createFunctionParameterFromTypeName(arg))
761+
: [this.createFunctionParameterFromTypeName(result.name.objargs)];
762+
}
758763
}
759764
}
760765
}
@@ -888,6 +893,26 @@ export class V13ToV14Transformer {
888893
return null;
889894
}
890895

896+
private isOperatorName(objname: any): boolean {
897+
if (!objname || !Array.isArray(objname) || objname.length === 0) {
898+
return false;
899+
}
900+
901+
const firstElement = objname[0];
902+
if (!firstElement || typeof firstElement !== 'object' || !('String' in firstElement)) {
903+
return false;
904+
}
905+
906+
const name = firstElement.String?.str;
907+
if (!name || typeof name !== 'string') {
908+
return false;
909+
}
910+
911+
// Check if it's an operator symbol (contains operator characters)
912+
const operatorChars = /[+\-*/<>=!~@#%^&|`?]/;
913+
return operatorChars.test(name);
914+
}
915+
891916
private getFuncformatValue(node: any, context: TransformerContext): string {
892917
const funcname = this.getFunctionName(node);
893918

@@ -1003,7 +1028,12 @@ export class V13ToV14Transformer {
10031028
}
10041029

10051030
if (node.object !== undefined) {
1006-
const transformedObject = this.transform(node.object as any, context);
1031+
const childContext = {
1032+
...context,
1033+
alterOwnerObjectType: node.objectType
1034+
};
1035+
1036+
const transformedObject = this.transform(node.object as any, childContext);
10071037

10081038
if (node.objectType === 'OBJECT_FUNCTION' && transformedObject &&
10091039
typeof transformedObject === 'object' && 'ObjectWithArgs' in transformedObject) {
@@ -1844,8 +1874,41 @@ export class V13ToV14Transformer {
18441874
return false;
18451875
}
18461876

1847-
1877+
// Check if this is an operator context - operators should NOT get objfuncargs
18481878
const path = context.path || [];
1879+
1880+
// Check if we're in any statement with OBJECT_OPERATOR
1881+
if ((context as any).alterOwnerObjectType === 'OBJECT_OPERATOR' ||
1882+
(context as any).alterObjectSchemaObjectType === 'OBJECT_OPERATOR' ||
1883+
(context as any).renameObjectType === 'OBJECT_OPERATOR') {
1884+
return false;
1885+
}
1886+
for (const node of path) {
1887+
if (node && typeof node === 'object') {
1888+
const nodeData = Object.values(node)[0] as any;
1889+
if (nodeData && (nodeData.objtype === 'OBJECT_OPERATOR' ||
1890+
nodeData.objectType === 'OBJECT_OPERATOR' ||
1891+
nodeData.renameType === 'OBJECT_OPERATOR')) {
1892+
return false;
1893+
}
1894+
if (nodeData && nodeData.objname && Array.isArray(nodeData.objname)) {
1895+
// Check if objname contains operator symbols - but only if it's actually an operator context
1896+
const objnameStr = nodeData.objname.map((item: any) => {
1897+
if (item && typeof item === 'object' && item.String && item.String.str) {
1898+
return item.String.str;
1899+
}
1900+
return '';
1901+
}).join('');
1902+
if (objnameStr.match(/^[@#~!%^&*+=<>?|-]+$/) &&
1903+
(nodeData.objtype === 'OBJECT_OPERATOR' ||
1904+
nodeData.objectType === 'OBJECT_OPERATOR' ||
1905+
nodeData.renameType === 'OBJECT_OPERATOR')) {
1906+
return false;
1907+
}
1908+
}
1909+
}
1910+
}
1911+
18491912
const excludedNodeTypes = [
18501913
'CreateOpClassStmt', 'CreateAggregateStmt', 'AlterAggregateStmt',
18511914
'CreateFunctionStmt', 'CreateStmt', 'CreateTypeStmt', 'CreateOpFamilyStmt',
@@ -1868,7 +1931,7 @@ export class V13ToV14Transformer {
18681931
}
18691932

18701933
const allowedNodeTypes = [
1871-
'CommentStmt', 'AlterFunctionStmt', 'AlterOwnerStmt', 'RenameStmt', 'AlterObjectSchemaStmt', 'CreateCastStmt', 'AlterOpFamilyStmt', 'CreateOpClassItem'
1934+
'CommentStmt', 'AlterFunctionStmt', 'RenameStmt', 'AlterOwnerStmt', 'AlterObjectSchemaStmt', 'CreateCastStmt', 'AlterOpFamilyStmt', 'CreateOpClassItem'
18721935
];
18731936

18741937
for (const node of path) {
@@ -2637,7 +2700,8 @@ export class V13ToV14Transformer {
26372700
// Create child context with RenameStmt as parent
26382701
const childContext: TransformerContext = {
26392702
...context,
2640-
parentNodeTypes: [...(context.parentNodeTypes || []), 'RenameStmt']
2703+
parentNodeTypes: [...(context.parentNodeTypes || []), 'RenameStmt'],
2704+
renameObjectType: node.renameType
26412705
};
26422706

26432707
if (node.renameType !== undefined) {
@@ -2681,7 +2745,8 @@ export class V13ToV14Transformer {
26812745
// Create child context with AlterObjectSchemaStmt as parent
26822746
const childContext: TransformerContext = {
26832747
...context,
2684-
parentNodeTypes: [...(context.parentNodeTypes || []), 'AlterObjectSchemaStmt']
2748+
parentNodeTypes: [...(context.parentNodeTypes || []), 'AlterObjectSchemaStmt'],
2749+
alterObjectSchemaObjectType: node.objectType
26852750
};
26862751

26872752
if (node.objectType !== undefined) {

0 commit comments

Comments
 (0)