001package gudusoft.gsqlparser.nodes;
002/*
003 * Date: 2010-1-27
004 * Time: 11:30:12
005 */
006
007import gudusoft.gsqlparser.*;
008import gudusoft.gsqlparser.nodes.flink.TFlinkTableProperty;
009import gudusoft.gsqlparser.nodes.flink.TFlinkWithClause;
010import gudusoft.gsqlparser.nodes.starrocks.TFilesTableFunction;
011import gudusoft.gsqlparser.nodes.hive.THiveVariable;
012import gudusoft.gsqlparser.nodes.mssql.TForXMLClause;
013import gudusoft.gsqlparser.nodes.mssql.TMssqlStmtStubSqlNode;
014import gudusoft.gsqlparser.nodes.oracle.TStorageItem;
015import gudusoft.gsqlparser.nodes.snowflake.*;
016import gudusoft.gsqlparser.stmt.TCursorDeclStmt;
017import gudusoft.gsqlparser.stmt.TVarDeclStmt;
018import gudusoft.gsqlparser.stmt.oracle.TPlsqlCreateType;
019import gudusoft.gsqlparser.util.functionChecker;
020
021import java.util.concurrent.ConcurrentHashMap;
022import java.util.Map;
023import java.util.function.Supplier;
024
025public class TNodeFactory {
026
027    // Cache of Class objects to avoid repeated lookups - made thread-safe
028    private static final Map<Integer, Class<? extends TParseTreeNode>> NODE_TYPE_CLASSES = new ConcurrentHashMap<>();
029    
030    // Factory methods for frequently used node types to avoid reflection entirely - made thread-safe
031    private static final Map<Integer, Supplier<TParseTreeNode>> NODE_FACTORIES = new ConcurrentHashMap<>();
032    
033    static {
034        // Pre-populate cache for all known node types
035        // for (ENodeType nodeType : ENodeType.values()) {
036        //     try {
037        //         NODE_TYPE_CLASSES.put(nodeType.getId(), 
038        //             (Class<? extends TParseTreeNode>) Class.forName(nodeType.toString()));
039        //     } catch (ClassNotFoundException e) {
040        //         // Log error but continue - handle during runtime if needed
041        //         System.out.println("Failed to preload class for node type: " + nodeType + ": " + e.getMessage());
042        //     }
043        // }
044        
045        // Add specialized factory methods for common node types
046        NODE_FACTORIES.put(ENodeType.T_AliasClause.getId(), () -> new TAliasClause());
047        NODE_FACTORIES.put(ENodeType.T_AlterIndexSqlNode.getId(), () -> new TAlterIndexSqlNode());
048        NODE_FACTORIES.put(ENodeType.T_AlterTableOption.getId(), () -> new TAlterTableOption());
049        NODE_FACTORIES.put(ENodeType.T_AlterTriggerSqlNode.getId(), () -> new TAlterTriggerSqlNode());
050        NODE_FACTORIES.put(ENodeType.T_AlterTypeOption.getId(), () -> new TAlterTypeOption());
051        NODE_FACTORIES.put(ENodeType.T_BlockSqlNode.getId(), () -> new TBlockSqlNode());
052        NODE_FACTORIES.put(ENodeType.T_ColumnDefinition.getId(), () -> new TColumnDefinition());
053        NODE_FACTORIES.put(ENodeType.T_ColumnDefinitionList.getId(), () -> new TColumnDefinitionList());
054        NODE_FACTORIES.put(ENodeType.T_ColumnReference.getId(), () -> new TColumnReference());
055        NODE_FACTORIES.put(ENodeType.T_CommentSqlNode.getId(), () -> new TCommentSqlNode());
056        NODE_FACTORIES.put(ENodeType.T_Constant.getId(), () -> new TConstant());
057        NODE_FACTORIES.put(ENodeType.T_Constraint.getId(), () -> new TConstraint());
058        NODE_FACTORIES.put(ENodeType.T_CreateFunctionSqlNode.getId(), () -> new TCreateFunctionSqlNode());
059        NODE_FACTORIES.put(ENodeType.T_CreateProcedureSqlNode.getId(), () -> new TCreateProcedureSqlNode());
060        NODE_FACTORIES.put(ENodeType.T_CreateTableSqlNode.getId(), () -> new TCreateTableSqlNode());
061        NODE_FACTORIES.put(ENodeType.T_CTE.getId(), () -> new TCTE());
062        NODE_FACTORIES.put(ENodeType.T_CTEList.getId(), () -> new TCTEList());
063        NODE_FACTORIES.put(ENodeType.T_CursorDeclStmt.getId(), () -> new TCursorDeclStmt());
064        NODE_FACTORIES.put(ENodeType.T_DeclareVariable.getId(), () -> new TDeclareVariable());
065        NODE_FACTORIES.put(ENodeType.T_DdlEventItem.getId(), () -> new TDdlEventItem());
066        NODE_FACTORIES.put(ENodeType.T_OnConflictClause.getId(), () -> new TOnConflictClause());
067        NODE_FACTORIES.put(ENodeType.T_Dummy.getId(), () -> new TDummy());
068        NODE_FACTORIES.put(ENodeType.T_DummyList.getId(), () -> new TDummyList());
069        NODE_FACTORIES.put(ENodeType.T_IterationControl.getId(), () -> new TIterationControl());
070        NODE_FACTORIES.put(ENodeType.T_IterationControlList.getId(), () -> new TIterationControlList());
071        NODE_FACTORIES.put(ENodeType.T_ExecuteSqlNode.getId(), () -> new TExecuteSqlNode());
072        NODE_FACTORIES.put(ENodeType.T_Expression.getId(), () -> new TExpression());
073        NODE_FACTORIES.put(ENodeType.T_ExpressionList.getId(), () -> new TExpressionList());
074        NODE_FACTORIES.put(ENodeType.T_FromTable.getId(), () -> new TFromTable());
075        NODE_FACTORIES.put(ENodeType.T_FunctionCall.getId(), () -> new TFunctionCall());
076        NODE_FACTORIES.put(ENodeType.T_ForUpdate.getId(), () -> new TForUpdate());
077        NODE_FACTORIES.put(ENodeType.T_ForXMLClause.getId(), () -> new TForXMLClause());
078        NODE_FACTORIES.put(ENodeType.T_GruopBy.getId(), () -> new TGroupBy());
079        NODE_FACTORIES.put(ENodeType.T_InsertSqlNode.getId(), () -> new TInsertSqlNode());
080        NODE_FACTORIES.put(ENodeType.T_JoinExpr.getId(), () -> new TJoinExpr());
081        NODE_FACTORIES.put(ENodeType.T_Join.getId(), () -> new TJoin());
082        NODE_FACTORIES.put(ENodeType.T_MssqlStmtStubSqlNode.getId(), () -> new TMssqlStmtStubSqlNode());
083        NODE_FACTORIES.put(ENodeType.T_ObjectName.getId(), () -> new TObjectName());
084        NODE_FACTORIES.put(ENodeType.T_ObjectNameList.getId(), () -> new TObjectNameList());
085        NODE_FACTORIES.put(ENodeType.T_OrderBy.getId(), () -> new TOrderBy());
086        NODE_FACTORIES.put(ENodeType.T_OrderByItem.getId(), () -> new TOrderByItem());
087        NODE_FACTORIES.put(ENodeType.T_OrderByItemList.getId(), () -> new TOrderByItemList());
088        NODE_FACTORIES.put(ENodeType.T_PlsqlCreateType.getId(), () -> new TPlsqlCreateType());
089        NODE_FACTORIES.put(ENodeType.T_QueryHint.getId(), () -> new TQueryHint());
090        NODE_FACTORIES.put(ENodeType.T_ResultColumn.getId(), () -> new TResultColumn());
091        NODE_FACTORIES.put(ENodeType.T_ResultColumnList.getId(), () -> new TResultColumnList());
092        NODE_FACTORIES.put(ENodeType.T_SelectSqlNode.getId(), () -> new TSelectSqlNode());
093        NODE_FACTORIES.put(ENodeType.T_SequenceOption.getId(), () -> new TSequenceOption());
094        NODE_FACTORIES.put(ENodeType.T_SetSqlNode.getId(), () -> new TSetSqlNode());
095        NODE_FACTORIES.put(ENodeType.T_StatementSqlNode.getId(), () -> new TStatementSqlNode());
096        NODE_FACTORIES.put(ENodeType.T_StorageItem.getId(), () -> new TStorageItem());
097        NODE_FACTORIES.put(ENodeType.T_Table.getId(), () -> new TTable());
098        NODE_FACTORIES.put(ENodeType.T_TableElementList.getId(), () -> new TTableElementList());
099        NODE_FACTORIES.put(ENodeType.T_TableReference.getId(), () -> new TTableReference());
100        NODE_FACTORIES.put(ENodeType.T_Typename.getId(), () -> new TTypeName());
101        NODE_FACTORIES.put(ENodeType.T_VarDeclStmt.getId(), () -> new TVarDeclStmt());
102        NODE_FACTORIES.put(ENodeType.T_ViewAliasItem.getId(), () -> new TViewAliasItem());
103        NODE_FACTORIES.put(ENodeType.T_WhereClause.getId(), () -> new TWhereClause());
104        NODE_FACTORIES.put(ENodeType.T_WindowFrameBoundary.getId(), () -> new TWindowFrameBoundary());
105
106        // Snowflake Semantic View nodes
107        NODE_FACTORIES.put(ENodeType.T_CreateSemanticViewSqlNode.getId(), () -> new TCreateSemanticViewSqlNode());
108        NODE_FACTORIES.put(ENodeType.T_SemanticViewClause.getId(), () -> new TSemanticViewClause());
109        NODE_FACTORIES.put(ENodeType.T_SemanticTableDef.getId(), () -> new TSemanticTableDef());
110        NODE_FACTORIES.put(ENodeType.T_SemanticTableDefList.getId(), () -> new TSemanticTableDefList());
111        NODE_FACTORIES.put(ENodeType.T_SemanticRelationshipDef.getId(), () -> new TSemanticRelationshipDef());
112        NODE_FACTORIES.put(ENodeType.T_SemanticRelationshipDefList.getId(), () -> new TSemanticRelationshipDefList());
113        NODE_FACTORIES.put(ENodeType.T_SemanticAttributeDef.getId(), () -> new TSemanticAttributeDef());
114        NODE_FACTORIES.put(ENodeType.T_SemanticAttributeDefList.getId(), () -> new TSemanticAttributeDefList());
115        NODE_FACTORIES.put(ENodeType.T_SemanticViewClauseList.getId(), () -> new TSemanticViewClauseList());
116
117        // Flink nodes
118        NODE_FACTORIES.put(ENodeType.T_FlinkTableProperty.getId(), () -> new TFlinkTableProperty());
119        NODE_FACTORIES.put(ENodeType.T_FlinkWithClause.getId(), () -> new TFlinkWithClause());
120
121        // StarRocks nodes
122        NODE_FACTORIES.put(ENodeType.T_FilesTableFunction.getId(), () -> new TFilesTableFunction());
123        NODE_FACTORIES.put(ENodeType.T_SubmitTaskSqlNode.getId(), () -> new TSubmitTaskSqlNode());
124        NODE_FACTORIES.put(ENodeType.T_DropTaskSqlNode.getId(), () -> new TDropTaskSqlNode());
125        NODE_FACTORIES.put(ENodeType.T_BeginLoadTransactionSqlNode.getId(), () -> new TBeginLoadTransactionSqlNode());
126        NODE_FACTORIES.put(ENodeType.T_CommitLoadTransactionSqlNode.getId(), () -> new TCommitLoadTransactionSqlNode());
127        NODE_FACTORIES.put(ENodeType.T_AbortLoadTransactionSqlNode.getId(), () -> new TAbortLoadTransactionSqlNode());
128        NODE_FACTORIES.put(ENodeType.T_ShowLoadTransactionSqlNode.getId(), () -> new TShowLoadTransactionSqlNode());
129        NODE_FACTORIES.put(ENodeType.T_ExportSqlNode.getId(), () -> new TExportSqlNode());
130        NODE_FACTORIES.put(ENodeType.T_ShowExportSqlNode.getId(), () -> new TShowExportSqlNode());
131        NODE_FACTORIES.put(ENodeType.T_CancelExportSqlNode.getId(), () -> new TCancelExportSqlNode());
132        NODE_FACTORIES.put(ENodeType.T_CreateResourceGroupSqlNode.getId(), () -> new TCreateResourceGroupSqlNode());
133        NODE_FACTORIES.put(ENodeType.T_DropResourceGroupSqlNode.getId(), () -> new TDropResourceGroupSqlNode());
134        NODE_FACTORIES.put(ENodeType.T_ResourceGroupClassifier.getId(), () -> new TResourceGroupClassifier());
135        NODE_FACTORIES.put(ENodeType.T_AlterResourceGroupSqlNode.getId(), () -> new TAlterResourceGroupSqlNode());
136        NODE_FACTORIES.put(ENodeType.T_ShowResourceGroupSqlNode.getId(), () -> new TShowResourceGroupSqlNode());
137        NODE_FACTORIES.put(ENodeType.T_CreateStorageVolumeSqlNode.getId(), () -> new TCreateStorageVolumeSqlNode());
138        NODE_FACTORIES.put(ENodeType.T_AlterStorageVolumeSqlNode.getId(), () -> new TAlterStorageVolumeSqlNode());
139        NODE_FACTORIES.put(ENodeType.T_DropStorageVolumeSqlNode.getId(), () -> new TDropStorageVolumeSqlNode());
140        NODE_FACTORIES.put(ENodeType.T_ShowStorageVolumeSqlNode.getId(), () -> new TShowStorageVolumeSqlNode());
141        NODE_FACTORIES.put(ENodeType.T_DescStorageVolumeSqlNode.getId(), () -> new TDescStorageVolumeSqlNode());
142        NODE_FACTORIES.put(ENodeType.T_BackupSnapshotSqlNode.getId(), () -> new TBackupSnapshotSqlNode());
143        NODE_FACTORIES.put(ENodeType.T_CreateRepositorySqlNode.getId(), () -> new TCreateRepositorySqlNode());
144        NODE_FACTORIES.put(ENodeType.T_DropRepositorySqlNode.getId(), () -> new TDropRepositorySqlNode());
145        NODE_FACTORIES.put(ENodeType.T_RestoreSnapshotSqlNode.getId(), () -> new TRestoreSnapshotSqlNode());
146        NODE_FACTORIES.put(ENodeType.T_ShowBackupRestoreSqlNode.getId(), () -> new TShowBackupRestoreSqlNode());
147        NODE_FACTORIES.put(ENodeType.T_ShowSnapshotSqlNode.getId(), () -> new TShowSnapshotSqlNode());
148        NODE_FACTORIES.put(ENodeType.T_CancelBackupRestoreSqlNode.getId(), () -> new TCancelBackupRestoreSqlNode());
149        NODE_FACTORIES.put(ENodeType.T_CacheSelectSqlNode.getId(), () -> new TCacheSelectSqlNode());
150        NODE_FACTORIES.put(ENodeType.T_CreateDictionarySqlNode.getId(), () -> new TCreateDictionarySqlNode());
151        NODE_FACTORIES.put(ENodeType.T_DropDictionarySqlNode.getId(), () -> new TDropDictionarySqlNode());
152        NODE_FACTORIES.put(ENodeType.T_RefreshDictionarySqlNode.getId(), () -> new TRefreshDictionarySqlNode());
153        NODE_FACTORIES.put(ENodeType.T_ShowDictionarySqlNode.getId(), () -> new TShowDictionarySqlNode());
154        NODE_FACTORIES.put(ENodeType.T_ShowFunctionsSqlNode.getId(), () -> new TShowFunctionsSqlNode());
155
156    }
157
158    public TNodeFactory(){
159    }
160
161    public TNodeFactory(EDbVendor dbVendor){
162        this.dbVendor = dbVendor;
163    }
164
165    public EDbVendor getDbVendor() {
166        return dbVendor;
167    }
168
169    public synchronized void setDbVendor(EDbVendor dbVendor) {
170        this.dbVendor = dbVendor;
171    }
172
173
174    private volatile EDbVendor dbVendor = EDbVendor.dbvgeneric;
175
176    public synchronized void setGsqlParser(TGSqlParser parser) {
177        this.gsqlparser = parser;
178    }
179
180    private volatile TGSqlParser gsqlparser = null;
181
182    public TColumnReference createColumnReference(TObjectName objectname){
183        TColumnReference retval = (TColumnReference)createNode(ENodeType.T_ColumnReference.getId(),objectname);
184        return retval;
185    }
186
187    public TColumnReference createColumnReference(TSourceToken objectname){
188        TColumnReference retval = (TColumnReference)createNode(ENodeType.T_ColumnReference.getId(),objectname);
189        return retval;
190    }
191
192    public TTableReference createTableReference(TObjectName objectname){
193        TTableReference retval = (TTableReference)createNode(ENodeType.T_TableReference.getId(),objectname);
194        return retval;
195    }
196
197    public TObjectReference createObjectReference(TObjectName objectname, int objecttype){
198        TObjectReference retval = (TObjectReference)createNode(ENodeType.T_ObjectReference.getId(),objectname);
199        retval.setObjectType(objecttype);
200        return retval;
201    }
202
203    public TParseTreeNode createIntervalExpression(){
204        TIntervalExpression retval = (TIntervalExpression)createNode(ENodeType.T_IntervalExression.getId());
205        return retval;
206    }
207
208    public TParseTreeNode createDatetimeExpression(){
209        TDatetimeExpression retval = (TDatetimeExpression)createNode(ENodeType.T_DatetimeExression.getId());
210        return retval;
211    }
212
213    public TParseTreeNode createFunctionCall(EFunctionType eFunctionType, TObjectName functionName){
214        TFunctionCall retval = (TFunctionCall)createNode(ENodeType.T_FunctionCall.getId(),functionName,eFunctionType);
215     //   functionName.parseFunctionName();
216        return retval;
217    }
218
219    public TParseTreeNode createSelectSqlNode(){
220        TSelectSqlNode retval = (TSelectSqlNode)createNode(ENodeType.T_SelectSqlNode.getId());
221        return retval;
222    }
223    
224
225
226    public TParseTreeNode createExpression(EExpressionType operatorType){
227        TExpression retval = (TExpression)createNode(ENodeType.T_Expression.getId(),operatorType);
228        //retval.setExpressionType(operatorType);
229        //retval.setExprType(operatorType);
230        return retval;
231    }
232
233    public TParseTreeNode createExpression(EExpressionType operatorType,TExpression leftOperand,TExpression rightOperand){
234        TExpression retval = (TExpression)createNode(ENodeType.T_Expression.getId(),operatorType);
235        //retval.setExpressionType(operatorType);
236        //retval.setExprType(operatorType);
237        retval.setLeftOperand(leftOperand);
238        retval.setRightOperand(rightOperand);
239        return retval;
240    }
241
242    public TParseTreeNode createCompoundExpression(EExpressionType operatorType,TExpression leftOperand,TExpression rightOperand ){
243        EExpressionType lcOperatorType = operatorType;
244        if (lcOperatorType == EExpressionType.group_comparison_t){
245            if (leftOperand.getExpressionType() == EExpressionType.list_t){
246
247            }else{
248                lcOperatorType = EExpressionType.simple_comparison_t;
249            }
250        }
251       TExpression retval = (TExpression)createNode(ENodeType.T_Expression.getId(),lcOperatorType);
252        //retval.setExpressionType(operatorType);
253        //retval.setExprType(operatorType);
254        retval.setLeftOperand(leftOperand);
255        retval.setRightOperand(rightOperand);
256        return retval;
257    }
258
259    public TExpression createSimpleExpression(TObjectName or){
260       boolean isOracleDBMS_package_call = false;
261        TExpression retval;
262
263        if ((dbVendor == EDbVendor.dbvoracle) && (or.getNumberOfPart() == 2)){
264           // 检查是否为oracle DBMS_ package, 如果是的话,需要转为function_t, 而不是simple_object_name_t
265            isOracleDBMS_package_call = functionChecker.isOraclePredefinedPackageFunction(or.toString());
266       }
267        if (isOracleDBMS_package_call){
268            retval = (TExpression)createNode(ENodeType.T_Expression.getId(),EExpressionType.function_t);
269            retval.setFunctionCall((TFunctionCall) this.createFunctionCall(EFunctionType.oracle_dbms_package_t,or));
270        }else{
271            retval = (TExpression)createNode(ENodeType.T_Expression.getId(),EExpressionType.simple_object_name_t);
272            retval.setObjectOperand(or);
273        }
274
275        //retval.setExpressionType(TExpression.simpleObjectname);
276        //retval.setExprType(EExpressionType.simple_object_name_t);
277
278        retval.setStartToken(or);
279        retval.setEndToken(or);
280        return retval;
281    }
282
283    public TObjectName createObjectNameWithType(EDbObjectType dbObjectType, TSourceToken part) {
284        if ((part == null)) return null;
285        TObjectName retval = (TObjectName)createNode(ENodeType.T_ObjectName.getId(),dbObjectType,part);
286        retval.setStartToken(part);
287        retval.setEndToken(part);
288        return retval;
289    }
290
291    public TObjectName createObjectNameWithType(EDbObjectType dbObjectType, TSourceToken object,TSourceToken part) {
292        if ((object == null)&&(part == null)) return null;
293        TObjectName retval = (TObjectName)createNode(ENodeType.T_ObjectName.getId(),dbObjectType,object,part);
294
295        if (part != null){
296            retval.setEndToken(part);
297        }else {
298            if(object != null){
299                retval.setEndToken(object);
300            } else {
301            }
302        }
303
304
305        if(object != null){
306            retval.setStartToken(object);
307        } else {
308            if(part != null){
309                retval.setStartToken(part);
310            }
311        }
312
313        return retval;
314    }
315
316    public TObjectName createObjectNameWithType(EDbObjectType dbObjectType, TSourceToken schema,TSourceToken object,TSourceToken part) {
317        if ((object == null)&&(part == null)) return null;
318        TObjectName retval = (TObjectName)createNode(ENodeType.T_ObjectName.getId(),dbObjectType,schema,object,part);
319        retval.setStartToken(schema);
320        retval.setEndToken(part);
321
322        return retval;
323    }
324
325    public TObjectName createObjectName(EDbObjectType dbObjectType, TSourceToken schema,TSourceToken object,TSourceToken part){
326        if ((schema == null)&&(object == null)&&(part == null)) return null;
327        TObjectName retval = (TObjectName)createNode(ENodeType.T_ObjectName.getId(),dbObjectType,schema,object,part);
328
329        if (part != null){
330            retval.setEndToken(part);
331        }else {
332            if(object != null){
333                retval.setEndToken(object);
334            } else {
335                if(schema != null){
336                    retval.setEndToken(schema);
337                }
338            }
339        }
340
341        if (schema != null){
342            retval.setStartToken(schema);
343        }else {
344            if(object != null){
345                retval.setStartToken(object);
346            } else {
347                if(part != null){
348                    retval.setStartToken(part);
349                }
350            }
351        }
352
353        return retval;
354
355    }
356
357    /**
358     *  create a database object with schema, object and part name, type of this object will be
359     *  determined later in the context where it appears.
360     * @param schema schema name of this object.
361     * @param object object name such as table, view, function and etc.
362     * @param part part of object, depends on object, if object is table, then part will be column name; will be null if object is function
363     * @return
364     */
365    public TObjectName createObjectName(TSourceToken schema,TSourceToken object,TSourceToken part){
366        if ((schema == null)&&(object == null)&&(part == null)) return null;
367        TObjectName retval = (TObjectName)createNode(ENodeType.T_ObjectName.getId(),schema,object,part);
368
369        if (part != null){
370            retval.setEndToken(part);
371        }else {
372            if(object != null){
373                retval.setEndToken(object);
374            } else {
375                if(schema != null){
376                    retval.setEndToken(schema);
377                }
378            }
379        }
380
381        if (schema != null){
382            retval.setStartToken(schema);
383        }else {
384            if(object != null){
385                retval.setStartToken(object);
386            } else {
387                if(part != null){
388                    retval.setStartToken(part);
389                }
390            }
391        }
392
393        return retval;
394    }
395
396    public TObjectName createObjectNameWithPart(TSourceToken part){
397        return createObjectName(null,null,part);
398    }
399
400    public TObjectName createObjectNameWithObject(TSourceToken object){
401        return createObjectName(null,object,null);
402    }
403
404    public TObjectName createObjectNameWithPartAndObject(TSourceToken object,TSourceToken part){
405        return createObjectName(null,object,part);
406    }
407
408    public TParseTreeNode createSimpleExpression(TConstant cnt){
409        if (cnt.getLiteralType() == ELiteralType.etFakeDate){
410
411            TFunctionCall functionCall = (TFunctionCall)createFunctionCall(EFunctionType.date_t,TObjectName.createObjectName ( this.dbVendor, EDbObjectType.function,cnt.getStartToken()));
412            TExpression expression = (TExpression)createExpression(EExpressionType.function_t);
413            expression.setFunctionCall(functionCall);
414            expression.setStartToken(functionCall.getStartToken());
415            expression.setEndToken(functionCall.getEndToken());
416            return expression;
417
418        }else{
419            TExpression retval = (TExpression)createNode(ENodeType.T_Expression.getId(),EExpressionType.simple_constant_t);
420            //retval.setExpressionType(TExpression.simpleConstant);
421            //retval.setExprType(EExpressionType.simple_constant_t);
422            retval.setConstantOperand(cnt);
423            retval.setStartToken(cnt.getStartToken());
424            retval.setEndToken(cnt.getEndToken());
425            return retval;
426        }
427    }
428
429    public TParseTreeNode createSimpleExpression(TSourceToken st){
430       TExpression retval = (TExpression)createNode(ENodeType.T_Expression.getId(),EExpressionType.simple_source_token_t);
431       //retval.setExpressionType(TExpression.simpleSourcetoken);
432       //retval.setExprType(EExpressionType.simple_source_token_t);
433       retval.setSourcetokenOperand(st);
434        retval.setStartToken(st);
435        retval.setObjectOperand(createObjectNameWithPart(st));
436        retval.setEndToken(st);
437       return retval;
438    }
439
440    public TParseTreeNode createSimpleExpression(THiveVariable variable){
441       TExpression retval = (TExpression)createNode(ENodeType.T_Expression.getId(),EExpressionType.hive_variable_t);
442       retval.setHive_variable(variable);
443        retval.setStartToken(variable);
444        retval.setEndToken(variable);
445       return retval;
446    }
447
448    private ELiteralType getETByNT(ENodeType ent){
449        ELiteralType et = ELiteralType.etString;
450        switch (ent){
451            case T_Constant:
452                et = ELiteralType.etString;
453                break;
454            case T_Constant_Double:
455            case T_Constant_Float:
456                et = ELiteralType.etFloat;
457                break;
458            case T_Constant_Integer:
459                et = ELiteralType.etNumber;
460                break;
461            case T_Constant_String:
462                et = ELiteralType.etString;
463                break;
464            case T_Constant_BindV:
465                break;
466            case T_Constant_Boolean:
467                et = ELiteralType.bool;
468                break;
469            case T_Constant_Date:
470                et = ELiteralType.datetime_date;
471                break;
472            case T_Constant_Interval:
473                et = ELiteralType.interval;
474                break;
475            case T_Constant_Null:
476                et = ELiteralType.character_string;
477                break;
478            case T_Constant_Time:
479                et = ELiteralType.datetime_time;
480                break;
481            case T_Constant_Timestamp:
482                et = ELiteralType.datetime_timestamp;
483                break;
484            default:
485                break;
486        }
487        return et;
488    }
489    public TParseTreeNode createConstant(TSourceToken st,ENodeType ent){
490         TConstant retval = (TConstant)createNode(ENodeType.T_Constant.getId(),getETByNT(ent)); //(TConstant) createNode(ent.getId());
491         retval.setStartToken(st);
492         retval.setEndToken(st);
493         retval.setValueToken(st);
494         return retval;
495    }
496
497//    public TParseTreeNode createConstant(TParseTreeNode node,ENodeType ent){
498//         TConstant retval = (TConstant)createNode(ENodeType.T_Constant.getId(),getETByNT(ent));//(TConstant) createNode(ent.getId());
499//        retval.setStartToken(node);
500//        retval.setEndToken(node);
501//         return retval;
502//    }
503
504    private Class<? extends TParseTreeNode> getNodeClass(int nodeType) {
505        // ConcurrentHashMap.computeIfAbsent is thread-safe, but we add extra safety
506        return NODE_TYPE_CLASSES.computeIfAbsent(nodeType, id -> {
507            try {
508                ENodeType type = ENodeType.fromId(id);
509                if (type != null) {
510                    return (Class<? extends TParseTreeNode>) Class.forName(type.toString());
511                }
512                return null;
513            } catch (ClassNotFoundException e) {
514                // Log the error but return null to indicate class not found
515                System.err.println("Failed to load class for node type " + id + ": " + e.getMessage());
516                return null;
517            }
518        });
519    }
520
521    /**
522     * Get a node that takes no initializer arguments.
523     *
524     * @param nodeType          Identifier for the type of node.
525     *
526     * @return  A new ParseTree node.
527     */
528    public TParseTreeNode createNode(int nodeType) {
529        TParseTreeNode retval = null;
530        
531        // First check for a specialized factory method
532        Supplier<TParseTreeNode> factory = NODE_FACTORIES.get(nodeType);
533        if (factory != null) {
534            // Use direct instantiation without reflection
535            retval = factory.get();
536        } else {
537            // Get from class cache - this method handles thread-safe caching internally
538            Class<? extends TParseTreeNode> nodeClass = getNodeClass(nodeType);
539            
540            if (nodeClass == null) {
541                System.err.println("Unable to find or load class for nodeType: " + nodeType);
542                return null;
543            }
544
545            try {
546                retval = nodeClass.newInstance();
547            } catch (Exception iae) {
548                System.err.println("Failed to instantiate node: " + iae.toString() + ", nodeType: " + nodeType);
549                return null;
550            }
551        }
552
553        if (retval == null) {
554            return null;
555        }
556
557        // Thread-safe initialization of the created node
558        retval.setNodeType(nodeType);
559        if (nodeType != 25) {
560            // T_Typename(25,"gudusoft.gsqlparser.nodes.TTypeName"),
561            // don't sqlparser instance to a ttypename to avoid memory leak
562            TGSqlParser currentParser = this.gsqlparser; // Read volatile field once
563            if (currentParser != null) {
564                retval.setGsqlparser(currentParser);
565            }
566        }
567        
568        EDbVendor currentDbVendor = this.dbVendor; // Read volatile field once
569        if ((retval.dbvendor == EDbVendor.dbvgeneric) && (currentDbVendor != EDbVendor.dbvgeneric)){
570            // not already set in retval.setGsqlparser(this.gsqlparser);
571            retval.dbvendor = currentDbVendor;
572        }
573
574        return retval;
575    }
576
577    public <T>  TPTNodeList<T> createPTNodeList(T c) {
578        int nodeType = ENodeType.T_PTNodeList.getId(); // T_PTNodeList(14,"gudusoft.gsqlparser.nodes.TPTNodeList"),
579        TPTNodeList<T> retval = new gudusoft.gsqlparser.nodes.TPTNodeList<T>();
580        retval.setNodeType(nodeType);
581
582        // Thread-safe access to volatile field
583        TGSqlParser currentParser = this.gsqlparser;
584        if (currentParser != null) {
585            retval.setGsqlparser(currentParser);
586        }
587
588        retval.init(c);
589        return retval;
590    }
591
592    /**
593     * Create a TPTNodeList from an ArrayList.
594     * This is useful when the grammar collects elements into an ArrayList
595     * but the AST node expects a TPTNodeList.
596     *
597     * @param list The ArrayList of elements
598     * @return A new TPTNodeList containing all elements from the ArrayList
599     */
600    public <T>  TPTNodeList<T> createPTNodeListFromArrayList(java.util.ArrayList<T> list) {
601        int nodeType = ENodeType.T_PTNodeList.getId();
602        TPTNodeList<T> retval = new gudusoft.gsqlparser.nodes.TPTNodeList<T>();
603        retval.setNodeType(nodeType);
604
605        // Thread-safe access to volatile field
606        TGSqlParser currentParser = this.gsqlparser;
607        if (currentParser != null) {
608            retval.setGsqlparser(currentParser);
609        }
610
611        if (list != null) {
612            for (T element : list) {
613                retval.addElement(element);
614            }
615        }
616        return retval;
617    }
618
619
620    /**
621     * Translate a node type to a class name
622     *
623     * @param nodeType  A node type identifier 
624     *
625     */
626    protected String nodeName(int nodeType)
627    {
628       return ENodeType.fromId(nodeType).toString();
629    }
630
631    /**
632     * Get a node that takes one initializer argument.
633     *
634     * @param nodeType          Identifier for the type of node.
635     * @param arg1      The initializer argument
636     *
637     * @return  A new ParseTree node.
638     *
639     */
640    public final TParseTreeNode createNode(int nodeType, Object arg1)
641    {
642        TParseTreeNode retval = createNode(nodeType);
643
644        retval.init(arg1);
645
646        return  retval;
647    }
648
649    /**
650     * Get a node that takes one initializer argument.
651     *
652     * @param nodeType          Identifier for the type of node.
653     * @param arg1      The initializer argument
654     * @param arg2      The initializer argument
655     *
656     * @return  A new ParseTreeNode node.
657     *
658     */
659    public final TParseTreeNode createNode(int nodeType, Object arg1, Object arg2)
660    {
661        TParseTreeNode retval = createNode(nodeType);
662
663        retval.init(arg1,arg2);
664
665        return  retval;
666    }
667
668    /**
669     * Get a node that takes one initializer argument.
670     *
671     * @param nodeType          Identifier for the type of node.
672     * @param arg1      The initializer argument
673     * @param arg2      The initializer argument
674     * @param arg3      The initializer argument
675     *
676     * @return  A new ParseTreeNode node.
677     *
678     */
679    public final TParseTreeNode createNode(int nodeType, Object arg1, Object arg2, Object arg3)
680    {
681        TParseTreeNode retval = createNode(nodeType);
682
683        retval.init(arg1,arg2,arg3);
684
685        return  retval;
686    }
687
688    public final TParseTreeNode createNode(int nodeType, Object arg1, Object arg2, Object arg3, Object arg4)
689    {
690        TParseTreeNode retval = createNode(nodeType);
691
692        retval.init(arg1,arg2,arg3,arg4);
693
694        return  retval;
695    }
696
697    public final TParseTreeNode createNode(int nodeType, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5)
698    {
699        TParseTreeNode retval = createNode(nodeType);
700
701        retval.init(arg1,arg2,arg3,arg4,arg5);
702
703        return  retval;
704    }
705
706    public final TParseTreeNode createNode(int nodeType, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6)
707    {
708        TParseTreeNode retval = createNode(nodeType);
709
710        retval.init(arg1,arg2,arg3,arg4,arg5,arg6);
711
712        return  retval;
713    }
714
715    /**
716     * Create node with 7 parameters - for deeply nested struct field access (BigQuery, etc.)
717     */
718    public final TParseTreeNode createNode(int nodeType, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7)
719    {
720        TParseTreeNode retval = createNode(nodeType);
721
722        retval.init(arg1,arg2,arg3,arg4,arg5,arg6,arg7);
723
724        return  retval;
725    }
726
727    /**
728     * Create node with 8 parameters - for deeply nested struct field access
729     */
730    public final TParseTreeNode createNode(int nodeType, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7, Object arg8)
731    {
732        TParseTreeNode retval = createNode(nodeType);
733
734        retval.init(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8);
735
736        return  retval;
737    }
738
739    /**
740     * Create node with 9 parameters - for deeply nested struct field access
741     */
742    public final TParseTreeNode createNode(int nodeType, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7, Object arg8, Object arg9)
743    {
744        TParseTreeNode retval = createNode(nodeType);
745
746        retval.init(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9);
747
748        return  retval;
749    }
750
751    /**
752     * Create node with 10 parameters - for deeply nested struct field access
753     */
754    public final TParseTreeNode createNode(int nodeType, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7, Object arg8, Object arg9, Object arg10)
755    {
756        TParseTreeNode retval = createNode(nodeType);
757
758        retval.init(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10);
759
760        return  retval;
761    }
762
763
764}