1 33 package smallsql.database; 34 35 import java.sql.*; 36 37 38 public class ExpressionArithmetic extends Expression { 39 40 private Expression left; 41 private Expression right; 42 private Expression right2; 43 private Expression[] inList; 44 final private int operation; 45 46 49 ExpressionArithmetic( Expression right, int operation){ 50 super(FUNCTION); 51 this.right = right; 52 this.operation = operation; 53 super.setParams( new Expression[]{ right }); 54 } 55 56 ExpressionArithmetic( Expression left, Expression right, int operation){ 57 super(FUNCTION); 58 this.left = left; 59 this.right = right; 60 this.operation = operation; 61 super.setParams( new Expression[]{ left, right }); 62 } 63 64 67 ExpressionArithmetic( Expression left, Expression right, Expression right2, int operation){ 68 super(FUNCTION); 69 this.left = left; 70 this.right = right; 71 this.right2 = right2; 72 this.operation = operation; 73 super.setParams( new Expression[]{ left, right, right2 }); 74 } 75 76 79 ExpressionArithmetic( Expression left, Expressions inList, int operation){ 80 super(FUNCTION); 81 this.left = left; 82 this.operation = operation; 83 Expression[] params; 84 if(inList != null){ 85 this.inList = inList.toArray(); 86 params = new Expression[this.inList.length+1]; 87 params[0] = left; 88 System.arraycopy(this.inList, 0, params, 1, this.inList.length); 89 }else{ 90 params = new Expression[]{ left }; 91 } 92 super.setParams( params ); 93 } 94 95 96 final void setParamAt( Expression param, int idx){ 97 switch(idx){ 98 case 0: 99 left = param; 100 break; 101 case 1: 102 right = param; 103 break; 104 case 2: 105 right2 = param; 106 break; 107 } 108 if(inList != null && idx>0 && idx<=inList.length){ 109 inList[idx+1] = param; 110 } 111 super.setParamAt( param, idx ); 112 } 113 114 115 118 public boolean equals(Object expr){ 119 if(!super.equals(expr)) return false; 120 if(!(expr instanceof ExpressionArithmetic)) return false; 121 if( ((ExpressionArithmetic)expr).operation != operation) return false; 122 return true; 123 } 124 125 126 127 int getInt() throws java.lang.Exception { 128 if(isNull()) return 0; 129 int dataType = getDataType(); 130 switch(dataType){ 131 case SQLTokenizer.BIT: 132 case SQLTokenizer.BOOLEAN: 133 return getBoolean() ? 1 : 0; 134 case SQLTokenizer.TINYINT: 135 case SQLTokenizer.SMALLINT: 136 case SQLTokenizer.INT: 137 return getIntImpl(); 138 case SQLTokenizer.BIGINT: 139 return (int)getLongImpl(); 140 case SQLTokenizer.REAL: 141 return (int)getFloatImpl(); 142 case SQLTokenizer.FLOAT: 143 case SQLTokenizer.DOUBLE: 144 case SQLTokenizer.MONEY: 145 case SQLTokenizer.SMALLMONEY: 146 case SQLTokenizer.NUMERIC: 147 case SQLTokenizer.DECIMAL: 148 return (int)getDoubleImpl(); 149 } 150 throw createUnspportedConversion( SQLTokenizer.INT); 151 } 152 153 154 private int getIntImpl() throws java.lang.Exception { 155 switch(operation){ 156 case ADD: return left.getInt() + right.getInt(); 157 case SUB: return left.getInt() - right.getInt(); 158 case MUL: return left.getInt() * right.getInt(); 159 case DIV: return left.getInt() / right.getInt(); 160 case NEGATIVE: return - right.getInt(); 161 case MOD: return left.getInt() % right.getInt(); 162 case BIT_NOT: return ~ right.getInt(); 163 } 164 throw createUnspportedConversion( SQLTokenizer.INT); 165 } 166 167 168 long getLong() throws java.lang.Exception { 169 if(isNull()) return 0; 170 int dataType = getDataType(); 171 switch(dataType){ 172 case SQLTokenizer.BIT: 173 case SQLTokenizer.BOOLEAN: 174 return getBoolean() ? 1 : 0; 175 case SQLTokenizer.TINYINT: 176 case SQLTokenizer.SMALLINT: 177 case SQLTokenizer.INT: 178 return getIntImpl(); 179 case SQLTokenizer.BIGINT: 180 return getLongImpl(); 181 case SQLTokenizer.REAL: 182 return (long)getFloatImpl(); 183 case SQLTokenizer.FLOAT: 184 case SQLTokenizer.DOUBLE: 185 case SQLTokenizer.MONEY: 186 case SQLTokenizer.SMALLMONEY: 187 case SQLTokenizer.NUMERIC: 188 case SQLTokenizer.DECIMAL: 189 return (long)getDoubleImpl(); 190 } 191 throw createUnspportedConversion( SQLTokenizer.LONG); 192 } 193 194 195 private long getLongImpl() throws java.lang.Exception { 196 if(isNull()) return 0; 197 switch(operation){ 198 case ADD: return left.getLong() + right.getLong(); 199 case SUB: return left.getLong() - right.getLong(); 200 case MUL: return left.getLong() * right.getLong(); 201 case DIV: return left.getLong() / right.getLong(); 202 case NEGATIVE: return - right.getLong(); 203 case MOD: return left.getLong() % right.getLong(); 204 case BIT_NOT: return ~ right.getInt(); 205 } 206 throw createUnspportedConversion( SQLTokenizer.LONG); 207 } 208 209 210 double getDouble() throws java.lang.Exception { 211 if(isNull()) return 0; 212 int dataType = getDataType(); 213 switch(dataType){ 214 case SQLTokenizer.BIT: 215 case SQLTokenizer.BOOLEAN: 216 return getBoolean() ? 1 : 0; 217 case SQLTokenizer.TINYINT: 218 case SQLTokenizer.SMALLINT: 219 case SQLTokenizer.INT: 220 return getIntImpl(); 221 case SQLTokenizer.BIGINT: 222 return getLongImpl(); 223 case SQLTokenizer.REAL: 224 return getFloatImpl(); 225 case SQLTokenizer.FLOAT: 226 case SQLTokenizer.DOUBLE: 227 case SQLTokenizer.MONEY: 228 case SQLTokenizer.SMALLMONEY: 229 case SQLTokenizer.NUMERIC: 230 case SQLTokenizer.DECIMAL: 231 return getDoubleImpl(); 232 } 233 throw createUnspportedConversion( SQLTokenizer.DOUBLE); 234 } 235 236 237 private double getDoubleImpl() throws java.lang.Exception { 238 if(operation == NEGATIVE) 239 return getDoubleImpl(0, right.getDouble()); 240 return getDoubleImpl(left.getDouble(), right.getDouble()); 241 } 242 243 244 private double getDoubleImpl( double lVal, double rVal) throws java.lang.Exception { 245 switch(operation){ 246 case ADD: return lVal + rVal; 247 case SUB: return lVal - rVal; 248 case MUL: return lVal * rVal; 249 case DIV: return lVal / rVal; 250 case NEGATIVE: return - rVal; 251 case MOD: return lVal % rVal; 252 } 253 throw createUnspportedConversion( SQLTokenizer.DOUBLE); 254 } 255 256 257 float getFloat() throws java.lang.Exception { 258 if(isNull()) return 0; 259 int dataType = getDataType(); 260 switch(dataType){ 261 case SQLTokenizer.BIT: 262 case SQLTokenizer.BOOLEAN: 263 return getBoolean() ? 1 : 0; 264 case SQLTokenizer.TINYINT: 265 case SQLTokenizer.SMALLINT: 266 case SQLTokenizer.INT: 267 return getIntImpl(); 268 case SQLTokenizer.BIGINT: 269 return getLongImpl(); 270 case SQLTokenizer.REAL: 271 return getFloatImpl(); 272 case SQLTokenizer.FLOAT: 273 case SQLTokenizer.DOUBLE: 274 case SQLTokenizer.MONEY: 275 case SQLTokenizer.SMALLMONEY: 276 case SQLTokenizer.NUMERIC: 277 case SQLTokenizer.DECIMAL: 278 return (float)getDoubleImpl(); 279 } 280 throw createUnspportedConversion( SQLTokenizer.DOUBLE); 281 } 282 283 284 private float getFloatImpl() throws java.lang.Exception { 285 switch(operation){ 286 case ADD: return left.getFloat() + right.getFloat(); 287 case SUB: return left.getFloat() - right.getFloat(); 288 case MUL: return left.getFloat() * right.getFloat(); 289 case DIV: return left.getFloat() / right.getFloat(); 290 case NEGATIVE: return - right.getFloat(); 291 case MOD: return left.getFloat() % right.getFloat(); 292 } 293 throw createUnspportedConversion( SQLTokenizer.REAL ); 294 } 295 296 297 long getMoney() throws java.lang.Exception { 298 if(isNull()) return 0; 299 int dataType = getDataType(); 300 switch(dataType){ 301 case SQLTokenizer.BIT: 302 case SQLTokenizer.BOOLEAN: 303 return getBoolean() ? 10000 : 0; 304 case SQLTokenizer.TINYINT: 305 case SQLTokenizer.SMALLINT: 306 case SQLTokenizer.INT: 307 return getIntImpl() * 10000; 308 case SQLTokenizer.BIGINT: 309 return getLongImpl() * 10000; 310 case SQLTokenizer.REAL: 311 return Utils.doubleToMoney( getFloatImpl() ); 312 case SQLTokenizer.FLOAT: 313 case SQLTokenizer.DOUBLE: 314 case SQLTokenizer.NUMERIC: 315 case SQLTokenizer.DECIMAL: 316 return Utils.doubleToMoney( getDoubleImpl() ); 317 case SQLTokenizer.MONEY: 318 case SQLTokenizer.SMALLMONEY: 319 return getMoneyImpl(); 320 } 321 throw createUnspportedConversion( SQLTokenizer.DOUBLE); 322 } 323 324 325 private long getMoneyImpl() throws java.lang.Exception { 326 switch(operation){ 327 case ADD: return left.getMoney() + right.getMoney(); 328 case SUB: return left.getMoney() - right.getMoney(); 329 case MUL: return left.getMoney() * right.getMoney() / 10000; 330 case DIV: return left.getMoney() * 10000 / right.getMoney(); 331 case NEGATIVE: return - right.getMoney(); 332 } 333 throw createUnspportedConversion( SQLTokenizer.MONEY ); 334 } 335 336 337 MutableNumeric getNumeric() throws java.lang.Exception { 338 if(isNull()) return null; 339 int dataType = getDataType(); 340 switch(dataType){ 341 case SQLTokenizer.BIT: 342 case SQLTokenizer.BOOLEAN: 343 return new MutableNumeric(getBoolean() ? 1 : 0); 344 case SQLTokenizer.TINYINT: 345 case SQLTokenizer.SMALLINT: 346 case SQLTokenizer.INT: 347 return new MutableNumeric(getIntImpl()); 348 case SQLTokenizer.BIGINT: 349 return new MutableNumeric(getLongImpl()); 350 case SQLTokenizer.REAL: 351 return new MutableNumeric(getFloatImpl()); 352 case SQLTokenizer.FLOAT: 353 case SQLTokenizer.DOUBLE: 354 return new MutableNumeric( getDoubleImpl() ); 355 case SQLTokenizer.NUMERIC: 356 case SQLTokenizer.DECIMAL: 357 return getNumericImpl(); 358 case SQLTokenizer.MONEY: 359 case SQLTokenizer.SMALLMONEY: 360 return new MutableNumeric(getMoneyImpl(),4); 361 } 362 throw createUnspportedConversion( SQLTokenizer.DOUBLE); 363 } 364 365 366 private MutableNumeric getNumericImpl() throws java.lang.Exception { 367 switch(operation){ 368 case ADD: 369 { 370 MutableNumeric num = left.getNumeric(); 371 num.add( right.getNumeric() ); 372 return num; 373 } 374 case SUB: 375 { 376 MutableNumeric num = left.getNumeric(); 377 num.sub( right.getNumeric() ); 378 return num; 379 } 380 case MUL: 381 if(getDataType(right.getDataType(), SQLTokenizer.INT) == SQLTokenizer.INT){ 382 MutableNumeric num = left.getNumeric(); 383 num.mul(right.getInt()); 384 return num; 385 }else 386 if(getDataType(left.getDataType(), SQLTokenizer.INT) == SQLTokenizer.INT){ 387 MutableNumeric num = right.getNumeric(); 388 num.mul(left.getInt()); 389 return num; 390 }else{ 391 MutableNumeric num = left.getNumeric(); 392 num.mul( right.getNumeric() ); 393 return num; 394 } 395 case DIV: 396 { 397 MutableNumeric num = left.getNumeric(); 398 if(getDataType(right.getDataType(), SQLTokenizer.INT) == SQLTokenizer.INT) 399 num.div( right.getInt() ); 400 else 401 num.div( right.getNumeric() ); 402 return num; 403 } 404 case NEGATIVE: 405 { 406 MutableNumeric num = right.getNumeric(); 407 num.setSignum(-num.getSignum()); 408 return num; 409 } 410 case MOD: 411 { 412 if(getDataType(getDataType(), SQLTokenizer.INT) == SQLTokenizer.INT) 413 return new MutableNumeric(getInt()); 414 MutableNumeric num = left.getNumeric(); 415 num.mod( right.getNumeric() ); 416 return num; 417 } 418 default: throw createUnspportedConversion( SQLTokenizer.NUMERIC ); 419 } 420 } 421 422 423 Object getObject() throws java.lang.Exception { 424 if(isNull()) return null; 425 int dataType = getDataType(); 426 switch(dataType){ 427 case SQLTokenizer.BIT: 428 case SQLTokenizer.BOOLEAN: 429 return getBoolean() ? Boolean.TRUE : Boolean.FALSE; 430 case SQLTokenizer.BINARY: 431 case SQLTokenizer.VARBINARY: 432 return getBytes(); 433 case SQLTokenizer.TINYINT: 434 case SQLTokenizer.SMALLINT: 435 case SQLTokenizer.INT: 436 return new Integer ( getInt() ); 437 case SQLTokenizer.BIGINT: 438 return new Long ( getLong() ); 439 case SQLTokenizer.REAL: 440 return new Float ( getFloat() ); 441 case SQLTokenizer.FLOAT: 442 case SQLTokenizer.DOUBLE: 443 return new Double ( getDouble() ); 444 case SQLTokenizer.MONEY: 445 case SQLTokenizer.SMALLMONEY: 446 return Money.createFromUnscaledValue( getMoney() ); 447 case SQLTokenizer.NUMERIC: 448 case SQLTokenizer.DECIMAL: 449 return getNumeric(); 450 case SQLTokenizer.CHAR: 451 case SQLTokenizer.NCHAR: 452 case SQLTokenizer.VARCHAR: 453 case SQLTokenizer.NVARCHAR: 454 case SQLTokenizer.LONGNVARCHAR: 455 case SQLTokenizer.LONGVARCHAR: 456 return getString( left.getString(), right.getString() ); 457 case SQLTokenizer.JAVA_OBJECT: 458 Object lObj = left.getObject(); 459 Object rObj = right.getObject(); 461 if(lObj instanceof Number && rObj instanceof Number ) 462 return new Double ( getDoubleImpl( ((Number )lObj).doubleValue(), ((Number )rObj).doubleValue() ) ); 463 else 464 return getString( lObj.toString(), rObj.toString() ); 465 case SQLTokenizer.LONGVARBINARY: 466 return getBytes(); 467 case SQLTokenizer.DATE: 468 case SQLTokenizer.TIME: 469 case SQLTokenizer.TIMESTAMP: 470 case SQLTokenizer.SMALLDATETIME: 471 return new DateTime( getLong(), dataType ); 472 case SQLTokenizer.UNIQUEIDENTIFIER: 473 return getBytes(); 474 default: throw createUnspportedDataType(); 475 } 476 } 477 478 479 boolean getBoolean() throws java.lang.Exception { 480 switch(operation){ 481 case OR: return left.getBoolean() || right.getBoolean(); 482 case AND: return left.getBoolean() && right.getBoolean(); 483 case NOT: return !right.getBoolean(); 484 case LIKE: return Utils.like( left.getString(), right.getString()); 485 case ISNULL:return right.isNull(); 486 case ISNOTNULL: return !right.isNull(); 487 case IN: if(right == null) 488 return isInList(); 489 break; 490 } 491 final boolean rightIsNull = right.isNull(); 492 int dataType; 493 if(operation == NEGATIVE || operation == BIT_NOT){ 494 if(rightIsNull) return false; 495 dataType = right.getDataType(); 496 }else{ 497 final boolean leftIsNull = left.isNull(); 498 if(operation == EQUALS_NULL && leftIsNull && rightIsNull) return true; 499 if(leftIsNull || rightIsNull) return false; 500 dataType = getDataType(left, right); 501 } 502 switch(dataType){ 503 case SQLTokenizer.BOOLEAN: 504 switch(operation){ 505 case IN: 506 case EQUALS_NULL: 507 case EQUALS: return left.getBoolean() == right.getBoolean(); 508 case UNEQUALS: return left.getBoolean() != right.getBoolean(); 509 } 510 case SQLTokenizer.TINYINT: 512 case SQLTokenizer.SMALLINT: 513 case SQLTokenizer.INT: 514 case SQLTokenizer.BIT: 515 switch(operation){ 516 case IN: 517 case EQUALS_NULL: 518 case EQUALS: return left.getInt() == right.getInt(); 519 case GREATER: return left.getInt() > right.getInt(); 520 case GRE_EQU: return left.getInt() >= right.getInt(); 521 case LESSER: return left.getInt() < right.getInt(); 522 case LES_EQU: return left.getInt() <= right.getInt(); 523 case UNEQUALS: return left.getInt() != right.getInt(); 524 case BETWEEN: 525 int _left = left.getInt(); 526 return _left >= right.getInt() && right2.getInt() >= _left; 527 default: 528 return getInt() != 0; 529 } 530 case SQLTokenizer.BIGINT: 531 case SQLTokenizer.TIMESTAMP: 532 case SQLTokenizer.TIME: 533 case SQLTokenizer.DATE: 534 case SQLTokenizer.SMALLDATETIME: 535 switch(operation){ 536 case IN: 537 case EQUALS_NULL: 538 case EQUALS: return left.getLong() == right.getLong(); 539 case GREATER: return left.getLong() > right.getLong(); 540 case GRE_EQU: return left.getLong() >= right.getLong(); 541 case LESSER: return left.getLong() < right.getLong(); 542 case LES_EQU: return left.getLong() <= right.getLong(); 543 case UNEQUALS: return left.getLong() != right.getLong(); 544 case BETWEEN: 545 long _left = left.getLong(); 546 return _left >= right.getLong() && right2.getLong() >= _left; 547 default: 548 return getLong() != 0; 549 } 550 case SQLTokenizer.REAL: 551 switch(operation){ 552 case IN: 553 case EQUALS_NULL: 554 case EQUALS: return left.getFloat() == right.getFloat(); 555 case GREATER: return left.getFloat() > right.getFloat(); 556 case GRE_EQU: return left.getFloat() >= right.getFloat(); 557 case LESSER: return left.getFloat() < right.getFloat(); 558 case LES_EQU: return left.getFloat() <= right.getFloat(); 559 case UNEQUALS: return left.getFloat() != right.getFloat(); 560 case BETWEEN: 561 float _left = left.getFloat(); 562 return _left >= right.getFloat() && right2.getFloat() >= _left; 563 default: 564 return getFloat() != 0; 565 } 566 case SQLTokenizer.FLOAT: 567 case SQLTokenizer.DOUBLE: 568 switch(operation){ 569 case IN: 570 case EQUALS_NULL: 571 case EQUALS: return left.getDouble() == right.getDouble(); 572 case GREATER: return left.getDouble() > right.getDouble(); 573 case GRE_EQU: return left.getDouble() >= right.getDouble(); 574 case LESSER: return left.getDouble() < right.getDouble(); 575 case LES_EQU: return left.getDouble() <= right.getDouble(); 576 case UNEQUALS: return left.getDouble() != right.getDouble(); 577 case BETWEEN: 578 double _left = left.getDouble(); 579 return _left >= right.getDouble() && right2.getDouble() >= _left; 580 default: 581 return getDouble() != 0; 582 } 583 case SQLTokenizer.MONEY: 584 case SQLTokenizer.SMALLMONEY: 585 switch(operation){ 586 case IN: 587 case EQUALS_NULL: 588 case EQUALS: return left.getMoney() == right.getMoney(); 589 case GREATER: return left.getMoney() > right.getMoney(); 590 case GRE_EQU: return left.getMoney() >= right.getMoney(); 591 case LESSER: return left.getMoney() < right.getMoney(); 592 case LES_EQU: return left.getMoney() <= right.getMoney(); 593 case UNEQUALS: return left.getMoney() != right.getMoney(); 594 case BETWEEN: 595 long _left = left.getMoney(); 596 return _left >= right.getMoney() && right2.getMoney() >= _left; 597 default: 598 return getMoney() != 0; 599 } 600 case SQLTokenizer.DECIMAL: 601 case SQLTokenizer.NUMERIC:{ 602 if(operation == NEGATIVE) 603 return right.getNumeric().getSignum() != 0; 604 int comp = left.getNumeric().compareTo( right.getNumeric() ); 605 switch(operation){ 606 case IN: 607 case EQUALS_NULL: 608 case EQUALS: return comp == 0; 609 case GREATER: return comp > 0; 610 case GRE_EQU: return comp >= 0; 611 case LESSER: return comp < 0; 612 case LES_EQU: return comp <= 0; 613 case UNEQUALS: return comp != 0; 614 case BETWEEN: 615 return comp >= 0 && 0 >= left.getNumeric().compareTo( right2.getNumeric() ); 616 default: 617 return getNumeric().getSignum() != 0; 618 } 619 } 620 case SQLTokenizer.VARCHAR: 621 case SQLTokenizer.NVARCHAR: 622 case SQLTokenizer.CHAR: 623 case SQLTokenizer.NCHAR: 624 case SQLTokenizer.LONGVARCHAR: 625 case SQLTokenizer.LONGNVARCHAR: 626 case SQLTokenizer.CLOB:{ 627 int comp = String.CASE_INSENSITIVE_ORDER.compare( left.getString(), right.getString() ); 628 switch(operation){ 629 case IN: 630 case EQUALS_NULL: 631 case EQUALS: return comp == 0; 632 case GREATER: return comp > 0; 633 case GRE_EQU: return comp >= 0; 634 case LESSER: return comp < 0; 635 case LES_EQU: return comp <= 0; 636 case UNEQUALS: return comp != 0; 637 case BETWEEN: 638 return comp >= 0 && 0 >= String.CASE_INSENSITIVE_ORDER.compare( left.getString(), right2.getString() ); 639 case ADD: return Utils.string2boolean(left.getString() + right.getString()); 640 } 641 break;} 642 case SQLTokenizer.BINARY: 643 case SQLTokenizer.VARBINARY: 644 case SQLTokenizer.LONGVARBINARY: 645 case SQLTokenizer.BLOB: 646 case SQLTokenizer.UNIQUEIDENTIFIER:{ 647 byte[] leftBytes = left.getBytes(); 648 byte[] rightBytes= right.getBytes(); 649 int comp = Utils.compareBytes( leftBytes, rightBytes); 650 switch(operation){ 651 case IN: 652 case EQUALS_NULL: 653 case EQUALS: return comp == 0; 654 case GREATER: return comp > 0; 655 case GRE_EQU: return comp >= 0; 656 case LESSER: return comp < 0; 657 case LES_EQU: return comp <= 0; 658 case UNEQUALS: return comp != 0; 659 case BETWEEN: 660 return comp >= 0 && 0 >= Utils.compareBytes( leftBytes, right2.getBytes() ); 661 } 662 break;} 663 } 664 throw createUnspportedDataType(); 665 } 666 667 668 String getString() throws java.lang.Exception { 669 if(isNull()) return null; 670 return getObject().toString(); 671 } 672 673 674 final private String getString( String lVal, String rVal ) throws java.lang.Exception { 675 switch(operation){ 676 case ADD: return lVal + rVal; 677 } 678 throw createUnspportedConversion( SQLTokenizer.VARCHAR ); 679 } 680 681 682 int getDataType() { 683 switch(operation){ 684 case NEGATIVE: 685 case BIT_NOT: 686 return right.getDataType(); 687 case EQUALS: 688 case EQUALS_NULL: 689 case GREATER: 690 case GRE_EQU: 691 case LESSER: 692 case LES_EQU: 693 case UNEQUALS: 694 case BETWEEN: 695 case OR: 696 case AND: 697 case NOT: 698 case LIKE: 699 case ISNULL: 700 case ISNOTNULL: 701 return SQLTokenizer.BOOLEAN; 702 default: 703 return getDataType(left, right); 704 } 705 } 706 707 708 int getScale(){ 709 int dataType = getDataType(); 710 switch(dataType){ 711 case SQLTokenizer.DECIMAL: 712 case SQLTokenizer.NUMERIC: 713 switch(operation){ 714 case ADD: 715 case SUB: 716 return Math.max(left.getScale(), right.getScale()); 717 case MUL: 718 return left.getScale() + right.getScale(); 719 case DIV: 720 return Math.max(left.getScale()+5, right.getScale()+4); 721 case NEGATIVE: 722 return right.getScale(); 723 case MOD: 724 return 0; 725 } 726 } 727 return getScale(dataType); 728 } 729 730 731 boolean isNull() throws Exception { 732 switch(operation){ 733 case OR: 734 case AND: 735 case NOT: 736 case LIKE: 737 case ISNULL: 738 case ISNOTNULL: 739 case IN: 740 return false; case NEGATIVE: 742 case BIT_NOT: 743 return right.isNull(); 744 default: return left.isNull() || right.isNull(); 745 } 746 } 747 748 749 byte[] getBytes() throws java.lang.Exception { 750 throw createUnspportedConversion( SQLTokenizer.BINARY ); 751 } 752 753 754 boolean isInList() throws Exception { 755 if(left.isNull()) return false; 756 try{ 757 for(int i=0; i<inList.length; i++){ 758 right = inList[i]; 759 if(getBoolean()) return true; 760 } 761 }finally{ 762 right = null; 763 } 764 return false; 765 } 766 767 768 SQLException createUnspportedDataType(){ 769 return Utils.createSQLException("Unsupported data type '" + 770 SQLTokenizer.getKeyWord(getDataType(left, right)) + 771 "' for Operation '" + getKeywordFromOperation(operation)+'\''); 772 } 773 774 775 SQLException createUnspportedConversion( int dataType ){ 776 int type = left == null ? right.getDataType() : getDataType(left, right); 777 return Utils.createSQLException("Unsupported conversion to data type '" + 778 SQLTokenizer.getKeyWord(dataType) + 779 "' from data type '" + 780 SQLTokenizer.getKeyWord(type) + 781 "' for Operation '" + getKeywordFromOperation(operation)+'\''); 782 } 783 784 785 790 private static String getKeywordFromOperation(int operation){ 791 int token = 0; 792 for(int i=1; i<1000; i++){ 793 if(getOperationFromToken(i) == operation){ 794 token = i; 795 break; 796 } 797 } 798 if(operation == NEGATIVE) token = SQLTokenizer.MINUS; 799 if(operation == ISNOTNULL) token = SQLTokenizer.IS; 800 String keyword = SQLTokenizer.getKeyWord(token); 801 if(keyword == null) keyword = "" + (char)token; 802 return keyword; 803 } 804 805 806 static int getOperationFromToken( int value ){ 807 switch(value){ 808 case SQLTokenizer.PLUS: return ADD; 809 case SQLTokenizer.MINUS: return SUB; 810 case SQLTokenizer.ASTERISK: return MUL; 811 case SQLTokenizer.SLACH: return DIV; 812 case SQLTokenizer.PERCENT: return MOD; 813 case SQLTokenizer.EQUALS: return EQUALS; 814 case SQLTokenizer.GREATER: return GREATER; 815 case SQLTokenizer.GREATER_EQU: return GRE_EQU; 816 case SQLTokenizer.LESSER: return LESSER; 817 case SQLTokenizer.LESSER_EQU: return LES_EQU; 818 case SQLTokenizer.UNEQUALS: return UNEQUALS; 819 case SQLTokenizer.BETWEEN: return BETWEEN; 820 case SQLTokenizer.LIKE: return LIKE; 821 case SQLTokenizer.IN: return IN; 822 case SQLTokenizer.IS: return ISNULL; 823 case SQLTokenizer.OR: return OR; 824 case SQLTokenizer.AND: return AND; 825 case SQLTokenizer.NOT: return NOT; 826 case SQLTokenizer.BIT_OR: return BIT_OR; 827 case SQLTokenizer.BIT_AND: return BIT_AND; 828 case SQLTokenizer.BIT_XOR: return BIT_XOR; 829 case SQLTokenizer.TILDE: return BIT_NOT; 830 default: return 0; 831 } 832 } 833 834 835 838 static int getDataType(Expression left, Expression right){ 839 int typeLeft = left.getDataType(); 840 int typeRight = right.getDataType(); 841 return getDataType( typeLeft, typeRight); 842 } 843 844 845 854 static int getBestNumberDataType(int paramDataType){ 855 int dataTypeIdx = Utils.indexOf( paramDataType, DatatypeRange); 856 if(dataTypeIdx >= NVARCHAR_IDX) 857 return SQLTokenizer.DOUBLE; 858 if(dataTypeIdx >= INT_IDX) 859 return SQLTokenizer.INT; 860 if(dataTypeIdx >= BIGINT_IDX) 861 return SQLTokenizer.BIGINT; 862 if(dataTypeIdx >= MONEY_IDX) 863 return SQLTokenizer.MONEY; 864 if(dataTypeIdx >= DECIMAL_IDX) 865 return SQLTokenizer.DECIMAL; 866 return SQLTokenizer.DOUBLE; 867 } 868 869 872 static int getDataType(int typeLeft, int typeRight){ 873 if(typeLeft == typeRight) return typeLeft; 874 875 int dataTypeIdx = Math.min( Utils.indexOf( typeLeft, DatatypeRange), Utils.indexOf( typeRight, DatatypeRange) ); 876 if(dataTypeIdx < 0) throw new Error ("getDataType(): "+typeLeft+", "+typeRight); 877 return DatatypeRange[ dataTypeIdx ]; 878 } 879 880 881 static final int OR = 11; static final int AND = 21; static final int NOT = 31; static final int BIT_OR = 41; static final int BIT_AND = 42; static final int BIT_XOR = 43; static final int EQUALS = 51; static final int EQUALS_NULL= 52; static final int GREATER = 53; static final int GRE_EQU = 54; static final int LESSER = 55; static final int LES_EQU = 56; static final int UNEQUALS = 57; static final int IN = 61; static final int BETWEEN = 62; static final int LIKE = 63; static final int ISNULL = 64; static final int ISNOTNULL = ISNULL+1; static final int ADD = 71; static final int SUB = 72; static final int MUL = 81; static final int DIV = 82; static final int MOD = 83; static final int BIT_NOT = 91; static final int NEGATIVE =101; 908 private static final int[] DatatypeRange = { 909 SQLTokenizer.TIMESTAMP, 910 SQLTokenizer.SMALLDATETIME, 911 SQLTokenizer.DATE, 912 SQLTokenizer.TIME, 913 SQLTokenizer.DOUBLE, 914 SQLTokenizer.FLOAT, 915 SQLTokenizer.REAL, 916 SQLTokenizer.DECIMAL, 917 SQLTokenizer.NUMERIC, 918 SQLTokenizer.MONEY, 919 SQLTokenizer.SMALLMONEY, 920 SQLTokenizer.BIGINT, 921 SQLTokenizer.INT, 922 SQLTokenizer.SMALLINT, 923 SQLTokenizer.TINYINT, 924 SQLTokenizer.BIT, 925 SQLTokenizer.BOOLEAN, 926 SQLTokenizer.LONGNVARCHAR, 927 SQLTokenizer.UNIQUEIDENTIFIER, 928 SQLTokenizer.NVARCHAR, 929 SQLTokenizer.NCHAR, 930 SQLTokenizer.VARCHAR, 931 SQLTokenizer.CHAR, 932 SQLTokenizer.LONGVARCHAR, 933 SQLTokenizer.CLOB, 934 SQLTokenizer.VARBINARY, 935 SQLTokenizer.BINARY, 936 SQLTokenizer.LONGVARBINARY, 937 SQLTokenizer.BLOB, 938 SQLTokenizer.NULL}; 939 940 941 private static int NVARCHAR_IDX = Utils.indexOf( SQLTokenizer.NVARCHAR, DatatypeRange); 942 private static int INT_IDX = Utils.indexOf( SQLTokenizer.INT, DatatypeRange); 943 private static int BIGINT_IDX = Utils.indexOf( SQLTokenizer.BIGINT, DatatypeRange); 944 private static int MONEY_IDX = Utils.indexOf( SQLTokenizer.MONEY, DatatypeRange); 945 private static int DECIMAL_IDX = Utils.indexOf( SQLTokenizer.DECIMAL, DatatypeRange); 946 } | Popular Tags |