001package gudusoft.gsqlparser.nodes; 002/* 003 * Date: 2010-1-27 004 * Time: 11:30:12 005 */ 006 007import gudusoft.gsqlparser.*; 008import gudusoft.gsqlparser.nodes.hive.THiveVariable; 009import gudusoft.gsqlparser.util.functionChecker; 010 011import java.util.HashMap; 012import java.util.Map; 013import java.util.function.Supplier; 014 015public class TNodeFactory { 016 017 // Cache of Class objects to avoid repeated lookups 018 private static final Map<Integer, Class<? extends TParseTreeNode>> NODE_TYPE_CLASSES = new HashMap<>(); 019 020 // Factory methods for frequently used node types to avoid reflection entirely 021 private static final Map<Integer, Supplier<TParseTreeNode>> NODE_FACTORIES = new HashMap<>(); 022 023 static { 024 // Pre-populate cache for all known node types 025 // for (ENodeType nodeType : ENodeType.values()) { 026 // try { 027 // NODE_TYPE_CLASSES.put(nodeType.getId(), 028 // (Class<? extends TParseTreeNode>) Class.forName(nodeType.toString())); 029 // } catch (ClassNotFoundException e) { 030 // // Log error but continue - handle during runtime if needed 031 // System.out.println("Failed to preload class for node type: " + nodeType + ": " + e.getMessage()); 032 // } 033 // } 034 035 // Add specialized factory methods for common node types 036 NODE_FACTORIES.put(ENodeType.T_Expression.getId(), () -> new TExpression()); 037 NODE_FACTORIES.put(ENodeType.T_FunctionCall.getId(), () -> new TFunctionCall()); 038 NODE_FACTORIES.put(ENodeType.T_SelectSqlNode.getId(), () -> new TSelectSqlNode()); 039 NODE_FACTORIES.put(ENodeType.T_WhereClause.getId(), () -> new TWhereClause()); 040 NODE_FACTORIES.put(ENodeType.T_Constant.getId(), () -> new TConstant()); 041 NODE_FACTORIES.put(ENodeType.T_ObjectName.getId(), () -> new TObjectName()); 042 NODE_FACTORIES.put(ENodeType.T_TableReference.getId(), () -> new TTableReference()); 043 NODE_FACTORIES.put(ENodeType.T_ColumnReference.getId(), () -> new TColumnReference()); 044 NODE_FACTORIES.put(ENodeType.T_CreateTableSqlNode.getId(), () -> new TCreateTableSqlNode()); 045 } 046 047 public TNodeFactory(){ 048 } 049 050 public TNodeFactory(EDbVendor dbVendor){ 051 this.dbVendor = dbVendor; 052 } 053 054 public EDbVendor getDbVendor() { 055 return dbVendor; 056 } 057 058 059 private EDbVendor dbVendor = EDbVendor.dbvgeneric; 060 061 public void setGsqlParser(TGSqlParser parser) { 062 this.gsqlparser = parser; 063 } 064 065 private TGSqlParser gsqlparser = null; 066 067 public TColumnReference createColumnReference(TObjectName objectname){ 068 TColumnReference retval = (TColumnReference)createNode(ENodeType.T_ColumnReference.getId(),objectname); 069 return retval; 070 } 071 072 public TColumnReference createColumnReference(TSourceToken objectname){ 073 TColumnReference retval = (TColumnReference)createNode(ENodeType.T_ColumnReference.getId(),objectname); 074 return retval; 075 } 076 077 public TTableReference createTableReference(TObjectName objectname){ 078 TTableReference retval = (TTableReference)createNode(ENodeType.T_TableReference.getId(),objectname); 079 return retval; 080 } 081 082 public TObjectReference createObjectReference(TObjectName objectname, int objecttype){ 083 TObjectReference retval = (TObjectReference)createNode(ENodeType.T_ObjectReference.getId(),objectname); 084 retval.setObjectType(objecttype); 085 return retval; 086 } 087 088 public TParseTreeNode createIntervalExpression(){ 089 TIntervalExpression retval = (TIntervalExpression)createNode(ENodeType.T_IntervalExression.getId()); 090 return retval; 091 } 092 093 public TParseTreeNode createDatetimeExpression(){ 094 TDatetimeExpression retval = (TDatetimeExpression)createNode(ENodeType.T_DatetimeExression.getId()); 095 return retval; 096 } 097 098 public TParseTreeNode createFunctionCall(EFunctionType eFunctionType, TObjectName functionName){ 099 TFunctionCall retval = (TFunctionCall)createNode(ENodeType.T_FunctionCall.getId(),functionName,eFunctionType); 100 // functionName.parseFunctionName(); 101 return retval; 102 } 103 104 public TParseTreeNode createSelectSqlNode(){ 105 TSelectSqlNode retval = (TSelectSqlNode)createNode(ENodeType.T_SelectSqlNode.getId()); 106 return retval; 107 } 108 109 110 111 public TParseTreeNode createExpression(EExpressionType operatorType){ 112 TExpression retval = (TExpression)createNode(ENodeType.T_Expression.getId(),operatorType); 113 //retval.setExpressionType(operatorType); 114 //retval.setExprType(operatorType); 115 return retval; 116 } 117 118 public TParseTreeNode createExpression(EExpressionType operatorType,TExpression leftOperand,TExpression rightOperand){ 119 TExpression retval = (TExpression)createNode(ENodeType.T_Expression.getId(),operatorType); 120 //retval.setExpressionType(operatorType); 121 //retval.setExprType(operatorType); 122 retval.setLeftOperand(leftOperand); 123 retval.setRightOperand(rightOperand); 124 return retval; 125 } 126 127 public TParseTreeNode createCompoundExpression(EExpressionType operatorType,TExpression leftOperand,TExpression rightOperand ){ 128 EExpressionType lcOperatorType = operatorType; 129 if (lcOperatorType == EExpressionType.group_comparison_t){ 130 if (leftOperand.getExpressionType() == EExpressionType.list_t){ 131 132 }else{ 133 lcOperatorType = EExpressionType.simple_comparison_t; 134 } 135 } 136 TExpression retval = (TExpression)createNode(ENodeType.T_Expression.getId(),lcOperatorType); 137 //retval.setExpressionType(operatorType); 138 //retval.setExprType(operatorType); 139 retval.setLeftOperand(leftOperand); 140 retval.setRightOperand(rightOperand); 141 return retval; 142 } 143 144 public TExpression createSimpleExpression(TObjectName or){ 145 boolean isOracleDBMS_package_call = false; 146 TExpression retval; 147 148 if ((dbVendor == EDbVendor.dbvoracle) && (or.getNumberOfPart() == 2)){ 149 // 检查是否为oracle DBMS_ package, 如果是的话,需要转为function_t, 而不是simple_object_name_t 150 isOracleDBMS_package_call = functionChecker.isOraclePredefinedPackageFunction(or.toString()); 151 } 152 if (isOracleDBMS_package_call){ 153 retval = (TExpression)createNode(ENodeType.T_Expression.getId(),EExpressionType.function_t); 154 retval.setFunctionCall((TFunctionCall) this.createFunctionCall(EFunctionType.oracle_dbms_package_t,or)); 155 }else{ 156 retval = (TExpression)createNode(ENodeType.T_Expression.getId(),EExpressionType.simple_object_name_t); 157 retval.setObjectOperand(or); 158 } 159 160 //retval.setExpressionType(TExpression.simpleObjectname); 161 //retval.setExprType(EExpressionType.simple_object_name_t); 162 163 retval.setStartToken(or); 164 retval.setEndToken(or); 165 return retval; 166 } 167 168 public TObjectName createObjectNameWithType(EDbObjectType dbObjectType, TSourceToken part) { 169 if ((part == null)) return null; 170 TObjectName retval = (TObjectName)createNode(ENodeType.T_ObjectName.getId(),dbObjectType,part); 171 retval.setStartToken(part); 172 retval.setEndToken(part); 173 return retval; 174 } 175 176 public TObjectName createObjectNameWithType(EDbObjectType dbObjectType, TSourceToken object,TSourceToken part) { 177 if ((object == null)&&(part == null)) return null; 178 TObjectName retval = (TObjectName)createNode(ENodeType.T_ObjectName.getId(),dbObjectType,object,part); 179 180 if (part != null){ 181 retval.setEndToken(part); 182 }else { 183 if(object != null){ 184 retval.setEndToken(object); 185 } else { 186 } 187 } 188 189 190 if(object != null){ 191 retval.setStartToken(object); 192 } else { 193 if(part != null){ 194 retval.setStartToken(part); 195 } 196 } 197 198 return retval; 199 } 200 201 public TObjectName createObjectNameWithType(EDbObjectType dbObjectType, TSourceToken schema,TSourceToken object,TSourceToken part) { 202 if ((object == null)&&(part == null)) return null; 203 TObjectName retval = (TObjectName)createNode(ENodeType.T_ObjectName.getId(),dbObjectType,schema,object,part); 204 retval.setStartToken(schema); 205 retval.setEndToken(part); 206 207 return retval; 208 } 209 210 public TObjectName createObjectName(EDbObjectType dbObjectType, TSourceToken schema,TSourceToken object,TSourceToken part){ 211 if ((schema == null)&&(object == null)&&(part == null)) return null; 212 TObjectName retval = (TObjectName)createNode(ENodeType.T_ObjectName.getId(),dbObjectType,schema,object,part); 213 214 if (part != null){ 215 retval.setEndToken(part); 216 }else { 217 if(object != null){ 218 retval.setEndToken(object); 219 } else { 220 if(schema != null){ 221 retval.setEndToken(schema); 222 } 223 } 224 } 225 226 if (schema != null){ 227 retval.setStartToken(schema); 228 }else { 229 if(object != null){ 230 retval.setStartToken(object); 231 } else { 232 if(part != null){ 233 retval.setStartToken(part); 234 } 235 } 236 } 237 238 return retval; 239 240 } 241 242 /** 243 * create a database object with schema, object and part name, type of this object will be 244 * determined later in the context where it appears. 245 * @param schema schema name of this object. 246 * @param object object name such as table, view, function and etc. 247 * @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 248 * @return 249 */ 250 public TObjectName createObjectName(TSourceToken schema,TSourceToken object,TSourceToken part){ 251 if ((schema == null)&&(object == null)&&(part == null)) return null; 252 TObjectName retval = (TObjectName)createNode(ENodeType.T_ObjectName.getId(),schema,object,part); 253 254 if (part != null){ 255 retval.setEndToken(part); 256 }else { 257 if(object != null){ 258 retval.setEndToken(object); 259 } else { 260 if(schema != null){ 261 retval.setEndToken(schema); 262 } 263 } 264 } 265 266 if (schema != null){ 267 retval.setStartToken(schema); 268 }else { 269 if(object != null){ 270 retval.setStartToken(object); 271 } else { 272 if(part != null){ 273 retval.setStartToken(part); 274 } 275 } 276 } 277 278 return retval; 279 } 280 281 public TObjectName createObjectNameWithPart(TSourceToken part){ 282 return createObjectName(null,null,part); 283 } 284 285 public TObjectName createObjectNameWithObject(TSourceToken object){ 286 return createObjectName(null,object,null); 287 } 288 289 public TObjectName createObjectNameWithPartAndObject(TSourceToken object,TSourceToken part){ 290 return createObjectName(null,object,part); 291 } 292 293 public TParseTreeNode createSimpleExpression(TConstant cnt){ 294 if (cnt.getLiteralType() == ELiteralType.etFakeDate){ 295 296 TFunctionCall functionCall = (TFunctionCall)createFunctionCall(EFunctionType.date_t,TObjectName.createObjectName ( this.dbVendor, EDbObjectType.function,cnt.getStartToken())); 297 TExpression expression = (TExpression)createExpression(EExpressionType.function_t); 298 expression.setFunctionCall(functionCall); 299 expression.setStartToken(functionCall.getStartToken()); 300 expression.setEndToken(functionCall.getEndToken()); 301 return expression; 302 303 }else{ 304 TExpression retval = (TExpression)createNode(ENodeType.T_Expression.getId(),EExpressionType.simple_constant_t); 305 //retval.setExpressionType(TExpression.simpleConstant); 306 //retval.setExprType(EExpressionType.simple_constant_t); 307 retval.setConstantOperand(cnt); 308 retval.setStartToken(cnt.getStartToken()); 309 retval.setEndToken(cnt.getEndToken()); 310 return retval; 311 } 312 } 313 314 public TParseTreeNode createSimpleExpression(TSourceToken st){ 315 TExpression retval = (TExpression)createNode(ENodeType.T_Expression.getId(),EExpressionType.simple_source_token_t); 316 //retval.setExpressionType(TExpression.simpleSourcetoken); 317 //retval.setExprType(EExpressionType.simple_source_token_t); 318 retval.setSourcetokenOperand(st); 319 retval.setStartToken(st); 320 retval.setObjectOperand(createObjectNameWithPart(st)); 321 retval.setEndToken(st); 322 return retval; 323 } 324 325 public TParseTreeNode createSimpleExpression(THiveVariable variable){ 326 TExpression retval = (TExpression)createNode(ENodeType.T_Expression.getId(),EExpressionType.hive_variable_t); 327 retval.setHive_variable(variable); 328 retval.setStartToken(variable); 329 retval.setEndToken(variable); 330 return retval; 331 } 332 333 private ELiteralType getETByNT(ENodeType ent){ 334 ELiteralType et = ELiteralType.etString; 335 switch (ent){ 336 case T_Constant: 337 et = ELiteralType.etString; 338 break; 339 case T_Constant_Double: 340 case T_Constant_Float: 341 et = ELiteralType.etFloat; 342 break; 343 case T_Constant_Integer: 344 et = ELiteralType.etNumber; 345 break; 346 case T_Constant_String: 347 et = ELiteralType.etString; 348 break; 349 case T_Constant_BindV: 350 break; 351 case T_Constant_Boolean: 352 et = ELiteralType.bool; 353 break; 354 case T_Constant_Date: 355 et = ELiteralType.datetime_date; 356 break; 357 case T_Constant_Interval: 358 et = ELiteralType.interval; 359 break; 360 case T_Constant_Null: 361 et = ELiteralType.character_string; 362 break; 363 case T_Constant_Time: 364 et = ELiteralType.datetime_time; 365 break; 366 case T_Constant_Timestamp: 367 et = ELiteralType.datetime_timestamp; 368 break; 369 default: 370 break; 371 } 372 return et; 373 } 374 public TParseTreeNode createConstant(TSourceToken st,ENodeType ent){ 375 TConstant retval = (TConstant)createNode(ENodeType.T_Constant.getId(),getETByNT(ent)); //(TConstant) createNode(ent.getId()); 376 retval.setStartToken(st); 377 retval.setEndToken(st); 378 retval.setValueToken(st); 379 return retval; 380 } 381 382// public TParseTreeNode createConstant(TParseTreeNode node,ENodeType ent){ 383// TConstant retval = (TConstant)createNode(ENodeType.T_Constant.getId(),getETByNT(ent));//(TConstant) createNode(ent.getId()); 384// retval.setStartToken(node); 385// retval.setEndToken(node); 386// return retval; 387// } 388 389 private Class<? extends TParseTreeNode> getNodeClass(int nodeType) { 390 return NODE_TYPE_CLASSES.computeIfAbsent(nodeType, id -> { 391 try { 392 ENodeType type = ENodeType.fromId(id); 393 return type != null ? 394 (Class<? extends TParseTreeNode>) Class.forName(type.toString()) : null; 395 } catch (ClassNotFoundException e) { 396 return null; 397 } 398 }); 399 } 400 401 /** 402 * Get a node that takes no initializer arguments. 403 * 404 * @param nodeType Identifier for the type of node. 405 * 406 * @return A new ParseTree node. 407 */ 408 public TParseTreeNode createNode(int nodeType) { 409 TParseTreeNode retval = null; 410 411 // First check for a specialized factory method 412 Supplier<TParseTreeNode> factory = NODE_FACTORIES.get(nodeType); 413 if (factory != null) { 414 // Use direct instantiation without reflection 415 retval = factory.get(); 416 } else { 417 // Get from class cache 418 Class<? extends TParseTreeNode> nodeClass = getNodeClass(nodeType);// NODE_TYPE_CLASSES.get(nodeType); 419 420 // If not found in cache, try to load it dynamically 421 if (nodeClass == null) { 422 String nodeName = nodeName(nodeType); 423 try { 424 nodeClass = (Class<? extends TParseTreeNode>) Class.forName(nodeName); 425 // Store in cache for future use 426 NODE_TYPE_CLASSES.put(nodeType, nodeClass); 427 } catch (ClassNotFoundException cnfe) { 428 System.out.println(cnfe.toString()+", nodename: "+nodeName); 429 return null; 430 } 431 } 432 433 try { 434 retval = nodeClass.newInstance(); 435 } catch (Exception iae) { 436 System.out.println(iae.toString()+", nodeType: "+nodeType); 437 return null; 438 } 439 } 440 441 retval.setNodeType(nodeType); 442 if (nodeType != 25) { 443 // T_Typename(25,"gudusoft.gsqlparser.nodes.TTypeName"), 444 // don't sqlparser instance to a ttypename to avoid memory leak 445 retval.setGsqlparser(this.gsqlparser); 446 } 447 if ((retval.dbvendor == EDbVendor.dbvgeneric) && (this.dbVendor != EDbVendor.dbvgeneric)){ 448 // not already set in retval.setGsqlparser(this.gsqlparser); 449 retval.dbvendor = this.dbVendor; 450 } 451 452 return retval; 453 } 454 455 public <T> TPTNodeList<T> createPTNodeList(T c) { 456 int nodeType = ENodeType.T_PTNodeList.getId(); // T_PTNodeList(14,"gudusoft.gsqlparser.nodes.TPTNodeList"), 457 TPTNodeList<T> retval = new gudusoft.gsqlparser.nodes.TPTNodeList<T>(); 458 retval.setNodeType(nodeType); 459 retval.setGsqlparser(this.gsqlparser); 460 retval.init(c); 461 return retval; 462 } 463 464 465 /** 466 * Translate a node type to a class name 467 * 468 * @param nodeType A node type identifier 469 * 470 */ 471 protected String nodeName(int nodeType) 472 { 473 return ENodeType.fromId(nodeType).toString(); 474 } 475 476 /** 477 * Get a node that takes one initializer argument. 478 * 479 * @param nodeType Identifier for the type of node. 480 * @param arg1 The initializer argument 481 * 482 * @return A new ParseTree node. 483 * 484 */ 485 public final TParseTreeNode createNode(int nodeType, Object arg1) 486 { 487 TParseTreeNode retval = createNode(nodeType); 488 489 retval.init(arg1); 490 491 return retval; 492 } 493 494 /** 495 * Get a node that takes one initializer argument. 496 * 497 * @param nodeType Identifier for the type of node. 498 * @param arg1 The initializer argument 499 * @param arg2 The initializer argument 500 * 501 * @return A new ParseTreeNode node. 502 * 503 */ 504 public final TParseTreeNode createNode(int nodeType, Object arg1, Object arg2) 505 { 506 TParseTreeNode retval = createNode(nodeType); 507 508 retval.init(arg1,arg2); 509 510 return retval; 511 } 512 513 /** 514 * Get a node that takes one initializer argument. 515 * 516 * @param nodeType Identifier for the type of node. 517 * @param arg1 The initializer argument 518 * @param arg2 The initializer argument 519 * @param arg3 The initializer argument 520 * 521 * @return A new ParseTreeNode node. 522 * 523 */ 524 public final TParseTreeNode createNode(int nodeType, Object arg1, Object arg2, Object arg3) 525 { 526 TParseTreeNode retval = createNode(nodeType); 527 528 retval.init(arg1,arg2,arg3); 529 530 return retval; 531 } 532 533 public final TParseTreeNode createNode(int nodeType, Object arg1, Object arg2, Object arg3, Object arg4) 534 { 535 TParseTreeNode retval = createNode(nodeType); 536 537 retval.init(arg1,arg2,arg3,arg4); 538 539 return retval; 540 } 541 542 public final TParseTreeNode createNode(int nodeType, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) 543 { 544 TParseTreeNode retval = createNode(nodeType); 545 546 retval.init(arg1,arg2,arg3,arg4,arg5); 547 548 return retval; 549 } 550 551 public final TParseTreeNode createNode(int nodeType, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6) 552 { 553 TParseTreeNode retval = createNode(nodeType); 554 555 retval.init(arg1,arg2,arg3,arg4,arg5,arg6); 556 557 return retval; 558 } 559 560 561}