001package gudusoft.gsqlparser.nodes; 002 003import gudusoft.gsqlparser.*; 004 005import java.util.ArrayList; 006 007 008/** 009 * SQL constant (sometimes called a literal) specifies a value. 010 * Constants are classified as: 011 * <ul> 012 * <li>string(text) constants</li> 013 * <li>numeric constants,Numeric constants are further classified as integer, floating-point, or decimal</li> 014 * <li>datetime constants</li> 015 * <li>interval constants</li> 016 * <li>boolean constants</li> 017 * </ul> 018 * {@link #getLiteralType()} returns the type of this constant, {@link #getValueToken()} returns the value of this constant. 019 * {@link #toString} returns the text of this constant. 020 * 021 * 022 */ 023public class TConstant extends TParseTreeNode { 024 025 public Integer getIntegerValue(){ 026 Integer result = null; 027 028 switch (getLiteralType()){ 029 case integer_et: 030 case numeric_et: 031 case etNumber: 032 try { 033 result = Integer.parseInt(valueToken.toString()); 034 035 } catch (NumberFormatException e) { 036 } 037 break; 038 } 039 040 return result; 041 } 042 private ArrayList<TKeyValueSqlNode> keyValues; 043 044 public ArrayList<TKeyValueSqlNode> getKeyValues() { 045 return keyValues; 046 } 047 048 /** 049 * Set the explicit type of this constant 050 * 051 * @param castType explicit type 052 * @see #getCastType 053 */ 054 public void setCastType(TTypeName castType) { 055 this.castType = castType; 056 switch (castType.getDataType()){ 057 case time_t: 058 this.literalType = ELiteralType.etTime; 059 break; 060 case timestamp_t: 061 this.literalType = ELiteralType.etTimestamp; 062 break; 063 case interval_t: 064 this.literalType = ELiteralType.etInterval; 065 break; 066 } 067 } 068 069 public void setLiteralType(TSourceToken st){ 070 if (st == null) return; 071 for(ELiteralType et:ELiteralType.values()){ 072 if (et.getText().equalsIgnoreCase(st.toString())){ 073 this.literalType = et; 074 break; 075 } 076 } 077 } 078 079 /** 080 * Constants can be specified with explicit types. This method returns the explicit type. 081 * In PostgreSQL, a constant of an arbitrary type can be entered using any one of the following notations: 082 * <pre> 083 * type 'string' 084 * 'string'::type 085 * CAST 'string' AS type 086 * </pre> 087 * 088 * @return explicit type for this constant 089 */ 090 public TTypeName getCastType() { 091 092 return castType; 093 } 094 095 private TTypeName castType; 096 private TSourceToken valueToken; 097 private TSourceToken signToken; // +,- 098 099 public void setSignToken(TSourceToken signToken) { 100 this.signToken = signToken; 101 } 102 103 public TSourceToken getSignToken() { 104 return signToken; 105 } 106 107 private TSourceToken charSetName; 108 private TSourceToken char_String_SetLiteral; 109 private TSourceTokenList stringLiteralSequence; 110 private ELiteralType literalType = ELiteralType.unknownType; 111 private TSourceToken leadingPrecision; 112 private EIntervalType intervalType; 113 114 /** 115 * Set the sub-type of interval constant 116 * 117 * @param intervalType sub-type of interval constant 118 * @see #getIntervalType 119 */ 120 public void setIntervalType(EIntervalType intervalType) { 121 this.intervalType = intervalType; 122 } 123 124 /** 125 * Oracle interval year to month and interval day to second constant. 126 * This method return sub-type of interval constant such as year to month, minute to second. 127 * 128 * @return sub-type of interval constant 129 */ 130 public EIntervalType getIntervalType() { 131 132 return intervalType; 133 } 134 135 /** 136 * set value of this constant 137 * <pre> 138 * INTERVAL '30.12345' SECOND(2,4) 139 * </pre> 140 * '30.12345' in the above SQL in the valueToken 141 * 142 * @param valueToken value of this constant 143 */ 144 public void setValueToken(TSourceToken valueToken) { 145 this.valueToken = valueToken; 146 stringValue = valueToken.toString(); 147 } 148 149 /** 150 * set the precision which is the maximum number of digits in the leading field of a interval constant. 151 * <pre> 152 * INTERVAL '400 5' DAY(3) TO HOUR 153 * </pre> 154 * 3 in the above SQL is the <code>leadingPrecision</code> 155 * 156 * 157 * @param leadingPrecision the precision of the leading field 158 */ 159 public void setLeadingPrecision(TSourceToken leadingPrecision) { 160 161 this.leadingPrecision = leadingPrecision; 162 } 163 164 /** 165 * set the fractional precision which is the number of digits in the fractional part of the SECOND datetime field 166 * in a interval day to second constant. 167 * <pre> 168 * INTERVAL '30.12345' SECOND(2,4) 169 * </pre> 170 * 4 in the above SQL is the <code>fractionalSecondsPrecision</code>, 2 is the <code>leadingPrecision</code> 171 * 172 * @param fractionalSecondsPrecision 173 */ 174 public void setFractionalSecondsPrecision(TSourceToken fractionalSecondsPrecision) { 175 this.fractionalSecondsPrecision = fractionalSecondsPrecision; 176 } 177 178 /** 179 * the maximum number of digits in the leading field of a interval constant. 180 * <pre> 181 * INTERVAL '400 5' DAY(3) TO HOUR 182 * </pre> 183 * 3 in the above SQL is the <code>leadingPrecision</code> 184 * 185 * @return the leading precision 186 */ 187 public TSourceToken getLeadingPrecision() { 188 189 return leadingPrecision; 190 } 191 192 /** 193 * the number of digits in the fractional part of the SECOND datetime field in a interval day to second constant. 194 * 195 * <pre> 196 * INTERVAL '30.12345' SECOND(2,4) 197 * </pre> 198 * 4 in the above SQL is the <code>fractionalSecondsPrecision</code>, 2 is the <code>leadingPrecision</code> 199 * 200 * @return the fractional seconds precision 201 */ 202 public TSourceToken getFractionalSecondsPrecision() { 203 return fractionalSecondsPrecision; 204 } 205 206 private TSourceToken fractionalSecondsPrecision; 207 208 public TConstant(){} 209 210 /** 211 * Class constructor, set the type of this constant while creating a new instance of the constant 212 * 213 * @param pLiteralType type of this constant 214 * 215 */ 216 public TConstant(ELiteralType pLiteralType){ 217 this.literalType = pLiteralType; 218 } 219 220 /** 221 * Class constructor, set the type and value of this constant when creating a new instance of the constant 222 * 223 * @param literalType type of this constant 224 * @param valueToken value of this constant 225 */ 226 public TConstant (ELiteralType literalType, TSourceToken valueToken){ 227 this(literalType); 228 this.valueToken = valueToken; 229 this.stringValue = valueToken.toString(); 230 this.setStartToken(valueToken); 231 this.setEndToken(valueToken); 232 } 233 234 /** 235 * Class constructor, set the type and value of this constant when creating a new instance of the constant. 236 * set the sub-type of an interval constant. 237 * 238 * @param literalType type of this constant, must be etInterval 239 * @param valueToken value of this constant 240 * @param intervalType sub-type of an interval constant 241 */ 242 public TConstant (ELiteralType literalType, TSourceToken valueToken,EIntervalType intervalType){ 243 this(literalType, valueToken); 244 this.intervalType = intervalType; 245 } 246 247 /** 248 * @deprecated use {@link #getValueToken} instead 249 * 250 * @param stringValue text value of this constant 251 */ 252// public void setStringValue(String stringValue) { 253// this.stringValue = stringValue; 254// } 255 256 /** 257 * 258 * @return text value of this constant without quote characters 259 */ 260 public String getValue(){ 261 //return getStringValue(); 262 String ret; 263 switch (literalType){ 264 case etString: 265 case etNumber: 266 case etFloat: 267 if (valueToken != null){ 268 ret = TBaseType.removeQuoteChar(valueToken.toString()); 269 }else{ 270 ret = TBaseType.removeQuoteChar(toString()); 271 } 272 273 break; 274 default: 275 ret = toString(); 276 break; 277 } 278 279 return ret; 280 } 281 282 /** 283 * @deprecated since 1.8.2.4, use {@link #getValue()} instead. 284 * 285 * @return text value of this constant 286 */ 287 public String getStringValue() { 288 return getValue(); 289 } 290 291 private String stringValue; 292 293 /** 294 * get type of this constant, can be strings, integers, and floating point numbers and more. 295 * Please check {@link gudusoft.gsqlparser.ELiteralType} for more type of constant 296 * 297 * @return type of this constant 298 */ 299 public ELiteralType getLiteralType() { 300 return literalType; 301 } 302 303 public void setStringLiteralSequence(TSourceTokenList stringLiteralSequence) { 304 this.stringLiteralSequence = stringLiteralSequence; 305 } 306 307 /** 308 * String list constant in Hive. 309 * 310 * @return a sequence of source token 311 */ 312 public TSourceTokenList getStringLiteralSequence() { 313 314 return stringLiteralSequence; 315 } 316 317 /** 318 * The '+' or '-' before this constant. Valid only when {@link #getLiteralType} is {@link ELiteralType#etNumber} 319 * 320 * @param sign the '+' or '-' token 321 */ 322 public void setSign(TSourceToken sign) { 323 this.sign = sign; 324 } 325 326 private TSourceToken sign; 327 328 /** 329 * The '+' or '-' before this constant. Valid only when {@link #getLiteralType} is {@link ELiteralType#etNumber} 330 * 331 * @return the '+' or '-' token 332 */ 333 public TSourceToken getSign() { 334 return sign; 335 } 336 337 /** 338 * The value of this constant represented by a source token. 339 * 340 * @return the value of this constant 341 */ 342 public TSourceToken getValueToken(){ 343 return valueToken; 344 } 345 346 public void accept(TParseTreeVisitor v){ 347 v.preVisit(this); 348 v.postVisit(this); 349 } 350 351 public void acceptChildren(TParseTreeVisitor v){ 352 v.preVisit(this); 353 v.postVisit(this); 354 } 355 356 public void init(Object arg1){ 357 literalType = (ELiteralType)arg1; 358 } 359 360 /** 361 * The type of this constant. 362 * <p> 363 * The most used type are: etNumber,etFloat,etString,etTimestamp,etDate,etInterval 364 * @param literalType the type of this constant 365 */ 366 public void setLiteralType(ELiteralType literalType) { 367 this.literalType = literalType; 368 } 369 370 public static TConstant createConstant(ELiteralType literalType, String valueStr){ 371 TConstant constant = new TConstant(literalType); 372 constant.setValueToken(new TSourceToken(valueStr)); 373 return constant; 374 } 375 376 public void init(Object arg1, Object arg2){ 377 init(arg1); 378 switch (literalType){ 379 case integer_et: 380 valueToken = (TSourceToken)arg2; 381 break; 382 case etNumber: 383 valueToken = (TSourceToken)arg2; 384 break; 385 case etFloat: 386 valueToken = (TSourceToken)arg2; 387 break; 388 case etString: 389 valueToken = (TSourceToken)arg2; 390 break; 391 case etTimestamp: 392 valueToken = (TSourceToken)arg2; 393 break; 394 case etDate: 395 valueToken = (TSourceToken)arg2; 396 break; 397 case etInterval: 398 valueToken = (TSourceToken)arg2; 399 break; 400 case etStringLiteralSequence: 401 stringLiteralSequence = (TSourceTokenList)arg2; 402 break; 403 case etStar: 404 valueToken = (TSourceToken)arg2; 405 break; 406 case interval: 407 int64_expression = (TExpression)arg2; 408 break; 409 case etJson: 410 keyValues = (ArrayList<TKeyValueSqlNode>)arg2; 411 break; 412 default: 413 break; 414 } 415 416 if (arg2 instanceof TSourceToken){ 417 this.setStartToken((TSourceToken)arg2); 418 this.setEndToken((TSourceToken)arg2); 419 } 420 421 } 422 423 private TSourceToken bind1; 424 private TSourceToken bind2; 425 private TSourceToken indicator; 426 427 public void setBind1(TSourceToken bind1) { 428 this.bind1 = bind1; 429 } 430 431 public void setBind2(TSourceToken bind2) { 432 this.bind2 = bind2; 433 } 434 435 public void setIndicator(TSourceToken indicator) { 436 this.indicator = indicator; 437 } 438 439 public TSourceToken getBind1() { 440 441 return bind1; 442 } 443 444 public TSourceToken getBind2() { 445 return bind2; 446 } 447 448 public TSourceToken getIndicator() { 449 return indicator; 450 } 451 452 EIntervalType getIntervalTypeByDummy(TDummy dummy){ 453 EIntervalType rtn = EIntervalType.itUnknown; 454 for(EIntervalType t : EIntervalType.values()){ 455 if (t.getValue() == dummy.int1){ 456 rtn = t; 457 break; 458 } 459 } 460 return rtn; 461 } 462 463 private ArrayList<TSourceToken> intervalValueTokens = new ArrayList<>(); 464 465 public ArrayList<TSourceToken> getIntervalValueTokens() { 466 return intervalValueTokens; 467 } 468 469 public ArrayList<EIntervalType> getIntervalTypes() { 470 return intervalTypes; 471 } 472 473 private ArrayList<EIntervalType> intervalTypes = new ArrayList<>(); 474 475 public void addIntervalTypeByDummy(TDummy dummy){ 476 intervalTypes.add( getIntervalTypeByDummy(dummy) ); 477 } 478 479 public void init(Object arg1, Object arg2,Object arg3){ 480 init(arg1); 481 switch (literalType){ 482 case etInterval: 483 valueToken = (TSourceToken)arg2; 484 if (arg3 instanceof TDummy){ // databricks 485 intervalType = getIntervalTypeByDummy((TDummy) arg3); 486 intervalValueTokens.add(valueToken); 487 intervalTypes.add(intervalType); 488 }else{ 489 intervalType = (EIntervalType)arg3; 490 } 491 break; 492 case etBindVar: 493 bind1 = (TSourceToken)arg2; 494 bind2 = (TSourceToken)arg3; 495 break; 496 default: 497 break; 498 } 499 } 500 501 502 public void init(Object arg1, Object arg2,Object arg3,Object arg4){ 503 init(arg1); 504 switch (literalType){ 505 case etBindVar: 506 bind1 = (TSourceToken)arg2; 507 bind2 = (TSourceToken)arg3; 508 indicator = (TSourceToken)arg4; 509 break; 510 default: 511 break; 512 } 513 } 514 515 private TExpression int64_expression; 516 517 /** 518 * BigQuery interval literal int64_expression 519 * 520 * @return BigQuery interval literal int64_expression 521 */ 522 public TExpression getInt64_expression() { 523 return int64_expression; 524 } 525}