1 24 25 package com.mckoi.database; 26 27 import java.lang.reflect.*; 28 import java.math.BigDecimal ; 29 import java.util.ArrayList ; 30 import java.util.HashMap ; 31 import java.util.Date ; 32 import java.util.Calendar ; 33 import java.util.Comparator ; 34 import java.util.Arrays ; 35 import java.util.Locale ; 36 import java.text.*; 37 import java.io.InputStream ; 38 import java.io.IOException ; 39 import com.mckoi.util.Cache; 40 import com.mckoi.database.global.SQLTypes; 41 import com.mckoi.database.global.CastHelper; 42 import com.mckoi.database.global.ByteLongObject; 43 import com.mckoi.database.global.BlobAccessor; 44 import com.mckoi.database.global.StringObject; 45 import com.mckoi.database.global.StringAccessor; 46 import com.mckoi.database.global.ObjectTranslator; 47 import com.mckoi.database.jdbc.SQLQuery; 48 import com.mckoi.util.BigNumber; 49 50 57 58 final class InternalFunctionFactory extends FunctionFactory { 59 60 63 public void init() { 64 65 addFunction("dateob", DateObFunction.class); 67 addFunction("timeob", TimeObFunction.class); 68 addFunction("timestampob", TimeStampObFunction.class); 69 addFunction("dateformat", DateFormatFunction.class); 70 71 addFunction("tonumber", ToNumberFunction.class); 73 addFunction("sql_cast", SQLCastFunction.class); 74 addFunction("lower", LowerFunction.class); 76 addFunction("upper", UpperFunction.class); 77 addFunction("concat", ConcatFunction.class); 78 addFunction("length", LengthFunction.class); 79 addFunction("substring", SubstringFunction.class); 80 addFunction("sql_trim", SQLTrimFunction.class); 81 addFunction("ltrim", LTrimFunction.class); 82 addFunction("rtrim", RTrimFunction.class); 83 addFunction("user", UserFunction.class); 85 addFunction("privgroups", PrivGroupsFunction.class); 86 addFunction("count", CountFunction.class, FunctionInfo.AGGREGATE); 88 addFunction("distinct_count", 89 DistinctCountFunction.class, FunctionInfo.AGGREGATE); 90 addFunction("avg", AvgFunction.class, FunctionInfo.AGGREGATE); 91 addFunction("sum", SumFunction.class, FunctionInfo.AGGREGATE); 92 addFunction("min", MinFunction.class, FunctionInfo.AGGREGATE); 93 addFunction("max", MaxFunction.class, FunctionInfo.AGGREGATE); 94 addFunction("aggor", AggOrFunction.class, FunctionInfo.AGGREGATE); 95 addFunction("abs", AbsFunction.class); 97 addFunction("sign", SignFunction.class); 98 addFunction("mod", ModFunction.class); 99 addFunction("round", RoundFunction.class); 100 addFunction("pow", PowFunction.class); 101 addFunction("sqrt", SqrtFunction.class); 102 addFunction("uniquekey", 104 UniqueKeyFunction.class, FunctionInfo.STATE_BASED); 105 addFunction("nextval", 106 NextValFunction.class, FunctionInfo.STATE_BASED); 107 addFunction("currval", 108 CurrValFunction.class, FunctionInfo.STATE_BASED); 109 addFunction("setval", 110 SetValFunction.class, FunctionInfo.STATE_BASED); 111 addFunction("hextobinary", HexToBinaryFunction.class); 113 addFunction("binarytohex", BinaryToHexFunction.class); 114 addFunction("least", LeastFunction.class); 116 addFunction("greatest", GreatestFunction.class); 117 addFunction("if", IfFunction.class); 119 addFunction("coalesce", CoalesceFunction.class); 120 121 addFunction("_new_JavaObject", JavaObjectInstantiation2.class); 123 124 addFunction("i_frule_convert", ForeignRuleConvert.class); 126 addFunction("i_sql_type", SQLTypeString.class); 127 addFunction("i_view_data", ViewDataConvert.class); 128 addFunction("i_privilege_string", PrivilegeString.class); 129 130 } 131 132 133 135 137 private static class CountFunction extends AbstractFunction { 138 139 public CountFunction(Expression[] params) { 140 super("count", params); 141 setAggregate(true); 142 143 if (parameterCount() != 1) { 144 throw new RuntimeException ("'count' function must have one argument."); 145 } 146 } 147 148 public TObject evaluate(GroupResolver group, VariableResolver resolver, 149 QueryContext context) { 150 if (group == null) { 151 throw new RuntimeException ( 152 "'count' can only be used as an aggregate function."); 153 } 154 155 int size = group.size(); 156 TObject result; 157 if (size == 0 || isGlob()) { 159 result = TObject.intVal(size); 160 } 161 else { 162 165 int total_count = size; 166 167 Expression exp = getParameter(0); 168 for (int i = 0; i < size; ++i) { 169 TObject val = 170 exp.evaluate(null, group.getVariableResolver(i), context); 171 if (val.isNull()) { 172 --total_count; 173 } 174 } 175 176 result = TObject.intVal(total_count); 177 } 178 179 return result; 180 } 181 182 } 183 184 186 private static class DistinctCountFunction extends AbstractFunction { 187 188 public DistinctCountFunction(Expression[] params) { 189 super("distinct_count", params); 190 setAggregate(true); 191 192 if (parameterCount() <= 0) { 193 throw new RuntimeException ( 194 "'distinct_count' function must have at least one argument."); 195 } 196 197 } 198 199 public TObject evaluate(GroupResolver group, VariableResolver resolver, 200 QueryContext context) { 201 213 if (group == null) { 214 throw new RuntimeException ( 215 "'count' can only be used as an aggregate function."); 216 } 217 218 final int rows = group.size(); 219 if (rows <= 1) { 220 return TObject.intVal(rows); 222 } 223 224 final int cols = parameterCount(); 227 final TObject[] group_r = new TObject[rows * cols]; 228 int n = 0; 229 for (int i = 0; i < rows; ++i) { 230 VariableResolver vr = group.getVariableResolver(i); 231 for (int p = 0; p < cols; ++p) { 232 Expression exp = getParameter(p); 233 group_r[n + p] = exp.evaluate(null, vr, context); 234 } 235 n += cols; 236 } 237 238 Comparator c = new Comparator () { 240 public int compare(Object ob1, Object ob2) { 241 int r1 = ((Integer ) ob1).intValue(); 242 int r2 = ((Integer ) ob2).intValue(); 243 244 int index1 = r1 * cols; 246 int index2 = r2 * cols; 247 for (int n = 0; n < cols; ++n) { 248 int v = group_r[index1 + n].compareTo(group_r[index2 + n]); 249 if (v != 0) { 250 return v; 251 } 252 } 253 254 return 0; 256 } 257 }; 258 259 Object [] list = new Object [rows]; 261 for (int i = 0; i < rows; ++i) { 262 list[i] = new Integer (i); 263 } 264 265 Arrays.sort(list, c); 267 268 int distinct_count = 1; 270 for (int i = 1; i < rows; ++i) { 271 int v = c.compare(list[i], list[i - 1]); 272 if (v > 0) { 275 ++distinct_count; 278 } 279 else if (v < 0) { 280 throw new Error ("Assertion failed - the distinct list does not " + 283 "appear to be sorted."); 284 } 285 } 286 287 if (list.length > 0) { 290 int first_entry = ((Integer ) list[0]).intValue(); 291 boolean first_is_null = true; 293 for (int m = 0; m < cols && first_is_null == true; ++m) { 294 TObject val = group_r[(first_entry * cols) + m]; 295 if (!val.isNull()) { 296 first_is_null = false; 298 } 299 } 300 if (first_is_null) { 302 distinct_count = distinct_count - 1; 304 } 305 } 306 307 return TObject.intVal(distinct_count); 308 } 309 310 } 311 312 314 private static class AvgFunction extends AbstractAggregateFunction { 315 316 public AvgFunction(Expression[] params) { 317 super("avg", params); 318 } 319 320 public TObject evalAggregate(GroupResolver group, QueryContext context, 321 TObject ob1, TObject ob2) { 322 if (ob1 != null) { 324 if (ob2.isNull()) { 325 return ob1; 326 } 327 else { 328 if (!ob1.isNull()) { 329 return ob1.operatorAdd(ob2); 330 } 331 else { 332 return ob2; 333 } 334 } 335 } 336 return ob2; 337 } 338 339 public TObject postEvalAggregate(GroupResolver group, QueryContext context, 340 TObject result) { 341 if (result.isNull()) { 343 return result; 344 } 345 return result.operatorDivide(TObject.intVal(group.size())); 346 } 347 348 } 349 350 352 private static class SumFunction extends AbstractAggregateFunction { 353 354 public SumFunction(Expression[] params) { 355 super("sum", params); 356 } 357 358 public TObject evalAggregate(GroupResolver group, QueryContext context, 359 TObject ob1, TObject ob2) { 360 if (ob1 != null) { 362 if (ob2.isNull()) { 363 return ob1; 364 } 365 else { 366 if (!ob1.isNull()) { 367 return ob1.operatorAdd(ob2); 368 } 369 else { 370 return ob2; 371 } 372 } 373 } 374 return ob2; 375 } 376 377 } 378 379 381 private static class MinFunction extends AbstractAggregateFunction { 382 383 public MinFunction(Expression[] params) { 384 super("min", params); 385 } 386 387 public TObject evalAggregate(GroupResolver group, QueryContext context, 388 TObject ob1, TObject ob2) { 389 if (ob1 != null) { 391 if (ob2.isNull()) { 392 return ob1; 393 } 394 else { 395 if (!ob1.isNull() && ob1.compareToNoNulls(ob2) < 0) { 396 return ob1; 397 } 398 else { 399 return ob2; 400 } 401 } 402 } 403 return ob2; 404 } 405 406 public TType returnTType(VariableResolver resolver, QueryContext context) { 407 return getParameter(0).returnTType(resolver, context); 409 } 410 411 } 412 413 415 private static class MaxFunction extends AbstractAggregateFunction { 416 417 public MaxFunction(Expression[] params) { 418 super("max", params); 419 } 420 421 public TObject evalAggregate(GroupResolver group, QueryContext context, 422 TObject ob1, TObject ob2) { 423 if (ob1 != null) { 425 if (ob2.isNull()) { 426 return ob1; 427 } 428 else { 429 if (!ob1.isNull() && ob1.compareToNoNulls(ob2) > 0) { 430 return ob1; 431 } 432 else { 433 return ob2; 434 } 435 } 436 } 437 return ob2; 438 } 439 440 public TType returnTType(VariableResolver resolver, QueryContext context) { 441 return getParameter(0).returnTType(resolver, context); 443 } 444 445 } 446 447 449 private static class AggOrFunction extends AbstractAggregateFunction { 450 451 public AggOrFunction(Expression[] params) { 452 super("aggor", params); 453 } 454 455 public TObject evalAggregate(GroupResolver group, QueryContext context, 456 TObject ob1, TObject ob2) { 457 if (ob1 != null) { 460 if (ob2.isNull()) { 461 return ob1; 462 } 463 else { 464 if (!ob1.isNull()) { 465 return ob1.operatorOr(ob2); 466 } 467 else { 468 return ob2; 469 } 470 } 471 } 472 return ob2; 473 } 474 475 } 476 477 478 479 481 private static class UserFunction extends AbstractFunction { 483 484 public UserFunction(Expression[] params) { 485 super("user", params); 486 487 if (parameterCount() > 0) { 488 throw new RuntimeException ("'user' function must have no arguments."); 489 } 490 } 491 492 public TObject evaluate(GroupResolver group, VariableResolver resolver, 493 QueryContext context) { 494 return TObject.stringVal(context.getUserName()); 495 } 496 497 public TType returnTType() { 498 return TType.STRING_TYPE; 499 } 500 501 } 502 503 private static class PrivGroupsFunction extends AbstractFunction { 505 506 public PrivGroupsFunction(Expression[] params) { 507 super("privgroups", params); 508 509 if (parameterCount() > 0) { 510 throw new RuntimeException ( 511 "'privgroups' function must have no arguments."); 512 } 513 } 514 515 public TObject evaluate(GroupResolver group, VariableResolver resolver, 516 QueryContext context) { 517 throw new RuntimeException ( 518 "'PrivGroups' function currently not working."); 519 } 520 521 public TType returnTType() { 522 return TType.STRING_TYPE; 523 } 524 525 } 526 527 528 529 530 531 532 534 private static class LowerFunction extends AbstractFunction { 535 536 public LowerFunction(Expression[] params) { 537 super("lower", params); 538 539 if (parameterCount() != 1) { 540 throw new RuntimeException ("Lower function must have one argument."); 541 } 542 } 543 544 public TObject evaluate(GroupResolver group, VariableResolver resolver, 545 QueryContext context) { 546 TObject ob = getParameter(0).evaluate(group, resolver, context); 547 if (ob.isNull()) { 548 return ob; 549 } 550 return new TObject(ob.getTType(), 551 ob.getObject().toString().toLowerCase()); 552 } 553 554 public TType returnTType() { 555 return TType.STRING_TYPE; 556 } 557 558 } 559 560 562 private static class UpperFunction extends AbstractFunction { 563 564 public UpperFunction(Expression[] params) { 565 super("upper", params); 566 567 if (parameterCount() != 1) { 568 throw new RuntimeException ("Upper function must have one argument."); 569 } 570 } 571 572 public TObject evaluate(GroupResolver group, VariableResolver resolver, 573 QueryContext context) { 574 TObject ob = getParameter(0).evaluate(group, resolver, context); 575 if (ob.isNull()) { 576 return ob; 577 } 578 return new TObject(ob.getTType(), 579 ob.getObject().toString().toUpperCase()); 580 } 581 582 public TType returnTType() { 583 return TType.STRING_TYPE; 584 } 585 586 } 587 588 590 private static class ConcatFunction extends AbstractFunction { 591 592 public ConcatFunction(Expression[] params) { 593 super("concat", params); 594 595 if (parameterCount() < 1) { 596 throw new RuntimeException ( 597 "Concat function must have at least one argument."); 598 } 599 } 600 601 public TObject evaluate(GroupResolver group, VariableResolver resolver, 602 QueryContext context) { 603 StringBuffer cc = new StringBuffer (); 604 605 Locale str_locale = null; 606 int str_strength = 0; 607 int str_decomposition = 0; 608 for (int i = 0; i < parameterCount(); ++i) { 609 Expression cur_parameter = getParameter(i); 610 TObject ob = cur_parameter.evaluate(group, resolver, context); 611 if (!ob.isNull()) { 612 cc.append(ob.getObject().toString()); 613 TType type = ob.getTType(); 614 if (str_locale == null && type instanceof TStringType) { 615 TStringType str_type = (TStringType) type; 616 str_locale = str_type.getLocale(); 617 str_strength = str_type.getStrength(); 618 str_decomposition = str_type.getDecomposition(); 619 } 620 } 621 else { 622 return ob; 623 } 624 } 625 626 TType type; 629 if (str_locale != null) { 630 type = new TStringType(SQLTypes.VARCHAR, -1, 631 str_locale, str_strength, str_decomposition); 632 } 633 else { 634 type = TType.STRING_TYPE; 635 } 636 637 return new TObject(type, new String (cc)); 638 } 639 640 public TType returnTType(VariableResolver resolver, QueryContext context) { 641 Locale str_locale = null; 643 int str_strength = 0; 644 int str_decomposition = 0; 645 for (int i = 0; i < parameterCount() && str_locale == null; ++i) { 646 TType type = getParameter(i).returnTType(resolver, context); 647 if (type instanceof TStringType) { 648 TStringType str_type = (TStringType) type; 649 str_locale = str_type.getLocale(); 650 str_strength = str_type.getStrength(); 651 str_decomposition = str_type.getDecomposition(); 652 } 653 } 654 655 if (str_locale != null) { 656 return new TStringType(SQLTypes.VARCHAR, -1, 657 str_locale, str_strength, str_decomposition); 658 } 659 else { 660 return TType.STRING_TYPE; 661 } 662 } 663 664 } 665 666 668 private static class LengthFunction extends AbstractFunction { 669 670 public LengthFunction(Expression[] params) { 671 super("length", params); 672 673 if (parameterCount() != 1) { 674 throw new RuntimeException ("Length function must have one argument."); 675 } 676 } 677 678 public TObject evaluate(GroupResolver group, VariableResolver resolver, 679 QueryContext context) { 680 TObject ob = getParameter(0).evaluate(group, resolver, context); 681 if (ob.isNull()) { 682 return ob; 683 } 684 if (ob.getTType() instanceof TBinaryType) { 685 BlobAccessor blob = (BlobAccessor) ob.getObject(); 686 return TObject.intVal(blob.length()); 687 } 688 if (ob.getTType() instanceof TStringType) { 689 StringAccessor str = (StringAccessor) ob.getObject(); 690 return TObject.intVal(str.length()); 691 } 692 return TObject.intVal(ob.getObject().toString().length()); 693 } 694 695 } 696 697 699 private static class SubstringFunction extends AbstractFunction { 700 701 public SubstringFunction(Expression[] params) { 702 super("substring", params); 703 704 if (parameterCount() < 1 || parameterCount() > 3) { 705 throw new RuntimeException ( 706 "Substring function needs one to three arguments."); 707 } 708 } 709 710 public TObject evaluate(GroupResolver group, VariableResolver resolver, 711 QueryContext context) { 712 TObject ob = getParameter(0).evaluate(group, resolver, context); 713 if (ob.isNull()) { 714 return ob; 715 } 716 String str = ob.getObject().toString(); 717 int pcount = parameterCount(); 718 int str_length = str.length(); 719 int arg1 = 1; 720 int arg2 = str_length; 721 if (pcount >= 2) { 722 arg1 = getParameter(1).evaluate(group, resolver, 723 context).toBigNumber().intValue(); 724 } 725 if (pcount >= 3) { 726 arg2 = getParameter(2).evaluate(group, resolver, 727 context).toBigNumber().intValue(); 728 } 731 732 if (arg1 < 1) { 734 arg1 = 1; 735 } 736 if (arg1 > str_length) { 737 return TObject.stringVal(""); 738 } 739 if (arg2 + arg1 > str_length) { 740 arg2 = (str_length - arg1) + 1; 741 } 742 if (arg2 < 1) { 743 return TObject.stringVal(""); 744 } 745 746 return TObject.stringVal(str.substring(arg1 - 1, (arg1 + arg2) - 1)); 747 } 748 749 public TType returnTType() { 750 return TType.STRING_TYPE; 751 } 752 753 } 754 755 757 private static class SQLTrimFunction extends AbstractFunction { 758 759 public SQLTrimFunction(Expression[] params) { 760 super("sql_trim", params); 761 762 if (parameterCount() != 3) { 764 throw new RuntimeException ( 765 "SQL Trim function must have three parameters."); 766 } 767 } 768 769 public TObject evaluate(GroupResolver group, VariableResolver resolver, 770 QueryContext context) { 771 TObject ttype = getParameter(0).evaluate(group, resolver, context); 773 TObject cob = getParameter(1).evaluate(group, resolver, context); 775 if (cob.isNull()) { 776 return cob; 777 } 778 else if (ttype.isNull()) { 779 return TObject.stringVal((StringObject) null); 780 } 781 String characters = cob.getObject().toString(); 782 String ttype_str = ttype.getObject().toString(); 783 TObject ob = getParameter(2).evaluate(group, resolver, context); 785 if (ob.isNull()) { 786 return ob; 787 } 788 String str = ob.getObject().toString(); 789 790 int skip = characters.length(); 791 if (ttype_str.equals("leading") || ttype_str.equals("both")) { 793 int scan = 0; 795 while (scan < str.length() && 796 str.indexOf(characters, scan) == scan) { 797 scan += skip; 798 } 799 str = str.substring(Math.min(scan, str.length())); 800 } 801 if (ttype_str.equals("trailing") || ttype_str.equals("both")) { 802 int scan = str.length() - 1; 804 int i = str.lastIndexOf(characters, scan); 805 while (scan >= 0 && i != -1 && i == scan - skip + 1) { 806 scan -= skip; 807 i = str.lastIndexOf(characters, scan); 808 } 809 str = str.substring(0, Math.max(0, scan + 1)); 810 } 811 812 return TObject.stringVal(str); 813 } 814 815 public TType returnTType(VariableResolver resolver, QueryContext context) { 816 return TType.STRING_TYPE; 817 } 818 819 } 820 821 823 private static class LTrimFunction extends AbstractFunction { 824 825 public LTrimFunction(Expression[] params) { 826 super("ltrim", params); 827 828 if (parameterCount() != 1) { 829 throw new RuntimeException ( 830 "ltrim function may only have 1 parameter."); 831 } 832 } 833 834 public TObject evaluate(GroupResolver group, VariableResolver resolver, 835 QueryContext context) { 836 TObject ob = getParameter(0).evaluate(group, resolver, context); 837 if (ob.isNull()) { 838 return ob; 839 } 840 String str = ob.getObject().toString(); 841 842 int scan = 0; 845 while (scan < str.length() && 846 str.indexOf(' ', scan) == scan) { 847 scan += 1; 848 } 849 str = str.substring(Math.min(scan, str.length())); 850 851 return TObject.stringVal(str); 852 } 853 854 public TType returnTType(VariableResolver resolver, QueryContext context) { 855 return TType.STRING_TYPE; 856 } 857 858 } 859 860 862 private static class RTrimFunction extends AbstractFunction { 863 864 public RTrimFunction(Expression[] params) { 865 super("rtrim", params); 866 867 if (parameterCount() != 1) { 868 throw new RuntimeException ( 869 "rtrim function may only have 1 parameter."); 870 } 871 } 872 873 public TObject evaluate(GroupResolver group, VariableResolver resolver, 874 QueryContext context) { 875 TObject ob = getParameter(0).evaluate(group, resolver, context); 876 if (ob.isNull()) { 877 return ob; 878 } 879 String str = ob.getObject().toString(); 880 881 int scan = str.length() - 1; 884 int i = str.lastIndexOf(" ", scan); 885 while (scan >= 0 && i != -1 && i == scan - 2) { 886 scan -= 1; 887 i = str.lastIndexOf(" ", scan); 888 } 889 str = str.substring(0, Math.max(0, scan + 1)); 890 891 return TObject.stringVal(str); 892 } 893 894 public TType returnTType(VariableResolver resolver, QueryContext context) { 895 return TType.STRING_TYPE; 896 } 897 898 } 899 900 901 902 903 904 905 906 907 909 private static class AbsFunction extends AbstractFunction { 910 911 public AbsFunction(Expression[] params) { 912 super("abs", params); 913 914 if (parameterCount() != 1) { 915 throw new RuntimeException ("Abs function must have one argument."); 916 } 917 } 918 919 public TObject evaluate(GroupResolver group, VariableResolver resolver, 920 QueryContext context) { 921 TObject ob = getParameter(0).evaluate(group, resolver, context); 922 if (ob.isNull()) { 923 return ob; 924 } 925 BigNumber num = ob.toBigNumber(); 926 return TObject.bigNumberVal(num.abs()); 927 } 928 929 } 930 931 933 private static class SignFunction extends AbstractFunction { 934 935 public SignFunction(Expression[] params) { 936 super("sign", params); 937 938 if (parameterCount() != 1) { 939 throw new RuntimeException ("Sign function must have one argument."); 940 } 941 } 942 943 public TObject evaluate(GroupResolver group, VariableResolver resolver, 944 QueryContext context) { 945 TObject ob = getParameter(0).evaluate(group, resolver, context); 946 if (ob.isNull()) { 947 return ob; 948 } 949 BigNumber num = ob.toBigNumber(); 950 return TObject.intVal(num.signum()); 951 } 952 953 } 954 955 957 private static class ModFunction extends AbstractFunction { 958 959 public ModFunction(Expression[] params) { 960 super("mod", params); 961 962 if (parameterCount() != 2) { 963 throw new RuntimeException ("Mod function must have two arguments."); 964 } 965 } 966 967 public TObject evaluate(GroupResolver group, VariableResolver resolver, 968 QueryContext context) { 969 TObject ob1 = getParameter(0).evaluate(group, resolver, context); 970 TObject ob2 = getParameter(1).evaluate(group, resolver, context); 971 if (ob1.isNull()) { 972 return ob1; 973 } 974 else if (ob2.isNull()) { 975 return ob2; 976 } 977 978 double v = ob1.toBigNumber().doubleValue(); 979 double m = ob2.toBigNumber().doubleValue(); 980 return TObject.doubleVal(v % m); 981 } 982 983 } 984 985 987 private static class RoundFunction extends AbstractFunction { 988 989 public RoundFunction(Expression[] params) { 990 super("round", params); 991 992 if (parameterCount() < 1 || parameterCount() > 2) { 993 throw new RuntimeException ( 994 "Round function must have one or two arguments."); 995 } 996 } 997 998 public TObject evaluate(GroupResolver group, VariableResolver resolver, 999 QueryContext context) { 1000 TObject ob1 = getParameter(0).evaluate(group, resolver, context); 1001 if (ob1.isNull()) { 1002 return ob1; 1003 } 1004 1005 BigNumber v = ob1.toBigNumber(); 1006 int d = 0; 1007 if (parameterCount() == 2) { 1008 TObject ob2 = getParameter(1).evaluate(group, resolver, context); 1009 if (ob2.isNull()) { 1010 d = 0; 1011 } 1012 else { 1013 d = ob2.toBigNumber().intValue(); 1014 } 1015 } 1016 return TObject.bigNumberVal(v.setScale(d, BigDecimal.ROUND_HALF_UP)); 1017 } 1018 1019 } 1020 1021 1023 private static class PowFunction extends AbstractFunction { 1024 1025 public PowFunction(Expression[] params) { 1026 super("pow", params); 1027 1028 if (parameterCount() != 2) { 1029 throw new RuntimeException ("Pow function must have two arguments."); 1030 } 1031 } 1032 1033 public TObject evaluate(GroupResolver group, VariableResolver resolver, 1034 QueryContext context) { 1035 TObject ob1 = getParameter(0).evaluate(group, resolver, context); 1036 TObject ob2 = getParameter(1).evaluate(group, resolver, context); 1037 if (ob1.isNull()) { 1038 return ob1; 1039 } 1040 else if (ob2.isNull()) { 1041 return ob2; 1042 } 1043 1044 double v = ob1.toBigNumber().doubleValue(); 1045 double w = ob2.toBigNumber().doubleValue(); 1046 return TObject.doubleVal(Math.pow(v, w)); 1047 } 1048 1049 } 1050 1051 1053 private static class SqrtFunction extends AbstractFunction { 1054 1055 public SqrtFunction(Expression[] params) { 1056 super("sqrt", params); 1057 1058 if (parameterCount() != 1) { 1059 throw new RuntimeException ("Sqrt function must have one argument."); 1060 } 1061 } 1062 1063 public TObject evaluate(GroupResolver group, VariableResolver resolver, 1064 QueryContext context) { 1065 TObject ob = getParameter(0).evaluate(group, resolver, context); 1066 if (ob.isNull()) { 1067 return ob; 1068 } 1069 1070 return TObject.bigNumberVal(ob.toBigNumber().sqrt()); 1071 } 1072 1073 } 1074 1075 1077 private static class LeastFunction extends AbstractFunction { 1078 1079 public LeastFunction(Expression[] params) { 1080 super("least", params); 1081 1082 if (parameterCount() < 1) { 1083 throw new RuntimeException ( 1084 "Least function must have at least 1 argument."); 1085 } 1086 } 1087 1088 public TObject evaluate(GroupResolver group, VariableResolver resolver, 1089 QueryContext context) { 1090 TObject least = null; 1091 for (int i = 0; i < parameterCount(); ++i) { 1092 TObject ob = getParameter(i).evaluate(group, resolver, context); 1093 if (ob.isNull()) { 1094 return ob; 1095 } 1096 if (least == null || ob.compareTo(least) < 0) { 1097 least = ob; 1098 } 1099 } 1100 return least; 1101 } 1102 1103 public TType returnTType(VariableResolver resolver, QueryContext context) { 1104 return getParameter(0).returnTType(resolver, context); 1105 } 1106 1107 } 1108 1109 1111 private static class GreatestFunction extends AbstractFunction { 1112 1113 public GreatestFunction(Expression[] params) { 1114 super("greatest", params); 1115 1116 if (parameterCount() < 1) { 1117 throw new RuntimeException ( 1118 "Greatest function must have at least 1 argument."); 1119 } 1120 } 1121 1122 public TObject evaluate(GroupResolver group, VariableResolver resolver, 1123 QueryContext context) { 1124 TObject great = null; 1125 for (int i = 0; i < parameterCount(); ++i) { 1126 TObject ob = getParameter(i).evaluate(group, resolver, context); 1127 if (ob.isNull()) { 1128 return ob; 1129 } 1130 if (great == null || ob.compareTo(great) > 0) { 1131 great = ob; 1132 } 1133 } 1134 return great; 1135 } 1136 1137 public TType returnTType(VariableResolver resolver, QueryContext context) { 1138 return getParameter(0).returnTType(resolver, context); 1139 } 1140 1141 } 1142 1143 1145 private static class UniqueKeyFunction extends AbstractFunction { 1146 1147 public UniqueKeyFunction(Expression[] params) { 1148 super("uniquekey", params); 1149 1150 if (parameterCount() != 1) { 1153 throw new RuntimeException ( 1154 "'uniquekey' function must have only 1 argument."); 1155 } 1156 } 1157 1158 public TObject evaluate(GroupResolver group, VariableResolver resolver, 1159 QueryContext context) { 1160 String str = getParameter(0).evaluate(group, resolver, 1161 context).getObject().toString(); 1162 long v = context.nextSequenceValue(str); 1163 return TObject.longVal(v); 1164 } 1165 1166 public TType returnTType(VariableResolver resolver, QueryContext context) { 1167 return TType.NUMERIC_TYPE; 1168 } 1169 1170 } 1171 1172 private static class NextValFunction extends AbstractFunction { 1173 1174 public NextValFunction(Expression[] params) { 1175 super("nextval", params); 1176 1177 if (parameterCount() != 1) { 1180 throw new RuntimeException ( 1181 "'nextval' function must have only 1 argument."); 1182 } 1183 } 1184 1185 public TObject evaluate(GroupResolver group, VariableResolver resolver, 1186 QueryContext context) { 1187 String str = getParameter(0).evaluate(group, resolver, 1188 context).getObject().toString(); 1189 long v = context.nextSequenceValue(str); 1190 return TObject.longVal(v); 1191 } 1192 1193 public TType returnTType(VariableResolver resolver, QueryContext context) { 1194 return TType.NUMERIC_TYPE; 1195 } 1196 1197 } 1198 1199 private static class CurrValFunction extends AbstractFunction { 1200 1201 public CurrValFunction(Expression[] params) { 1202 super("currval", params); 1203 1204 if (parameterCount() != 1) { 1207 throw new RuntimeException ( 1208 "'currval' function must have only 1 argument."); 1209 } 1210 } 1211 1212 public TObject evaluate(GroupResolver group, VariableResolver resolver, 1213 QueryContext context) { 1214 String str = getParameter(0).evaluate(group, resolver, 1215 context).getObject().toString(); 1216 long v = context.currentSequenceValue(str); 1217 return TObject.longVal(v); 1218 } 1219 1220 public TType returnTType(VariableResolver resolver, QueryContext context) { 1221 return TType.NUMERIC_TYPE; 1222 } 1223 1224 } 1225 1226 private static class SetValFunction extends AbstractFunction { 1227 1228 public SetValFunction(Expression[] params) { 1229 super("setval", params); 1230 1231 if (parameterCount() != 2) { 1234 throw new RuntimeException ( 1235 "'setval' function must have 2 arguments."); 1236 } 1237 } 1238 1239 public TObject evaluate(GroupResolver group, VariableResolver resolver, 1240 QueryContext context) { 1241 String str = getParameter(0).evaluate(group, resolver, 1242 context).getObject().toString(); 1243 BigNumber num = getParameter(1).evaluate(group, resolver, 1244 context).toBigNumber(); 1245 long v = num.longValue(); 1246 context.setSequenceValue(str, v); 1247 return TObject.longVal(v); 1248 } 1249 1250 public TType returnTType(VariableResolver resolver, QueryContext context) { 1251 return TType.NUMERIC_TYPE; 1252 } 1253 1254 } 1255 1256 1257 1258 1259 1261 private static class HexToBinaryFunction extends AbstractFunction { 1262 1263 public HexToBinaryFunction(Expression[] params) { 1264 super("hextobinary", params); 1265 1266 if (parameterCount() != 1) { 1268 throw new RuntimeException ( 1269 "'hextobinary' function must have only 1 argument."); 1270 } 1271 } 1272 1273 public TObject evaluate(GroupResolver group, VariableResolver resolver, 1274 QueryContext context) { 1275 String str = getParameter(0).evaluate(group, resolver, 1276 context).getObject().toString(); 1277 1278 int str_len = str.length(); 1279 if (str_len == 0) { 1280 return new TObject(TType.BINARY_TYPE, new ByteLongObject(new byte[0])); 1281 } 1282 byte[] buf = new byte[(str_len + 1) / 2]; 1284 int index = 0; 1285 if (buf.length * 2 != str_len) { 1286 buf[0] = (byte) Character.digit(str.charAt(0), 16); 1287 ++index; 1288 } 1289 int v = 0; 1290 for (int i = index; i < str_len; i += 2) { 1291 v = (Character.digit(str.charAt(i), 16) << 4) | 1292 (Character.digit(str.charAt(i + 1), 16)); 1293 buf[index] = (byte) (v & 0x0FF); 1294 ++index; 1295 } 1296 1297 return new TObject(TType.BINARY_TYPE, new ByteLongObject(buf)); 1298 } 1299 1300 public TType returnTType(VariableResolver resolver, QueryContext context) { 1301 return TType.BINARY_TYPE; 1302 } 1303 1304 } 1305 1306 1308 private static class BinaryToHexFunction extends AbstractFunction { 1309 1310 final static char[] digits = { 1311 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 1312 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 1313 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 1314 'u', 'v', 'w', 'x', 'y', 'z' 1315 }; 1316 1317 public BinaryToHexFunction(Expression[] params) { 1318 super("binarytohex", params); 1319 1320 if (parameterCount() != 1) { 1322 throw new RuntimeException ( 1323 "'binarytohex' function must have only 1 argument."); 1324 } 1325 } 1326 1327 public TObject evaluate(GroupResolver group, VariableResolver resolver, 1328 QueryContext context) { 1329 TObject ob = getParameter(0).evaluate(group, resolver, context); 1330 if (ob.isNull()) { 1331 return ob; 1332 } 1333 else if (ob.getTType() instanceof TBinaryType) { 1334 StringBuffer buf = new StringBuffer (); 1335 BlobAccessor blob = (BlobAccessor) ob.getObject(); 1336 InputStream bin = blob.getInputStream(); 1337 try { 1338 int bval = bin.read(); 1339 while (bval != -1) { 1340 buf.append(digits[((bval >> 4) & 0x0F)]); 1341 buf.append(digits[(bval & 0x0F)]); 1342 bval = bin.read(); 1343 } 1344 } 1345 catch (IOException e) { 1346 e.printStackTrace(); 1347 throw new RuntimeException ("IO Error: " + e.getMessage()); 1348 } 1349 1350 return TObject.stringVal(buf.toString()); 1355 } 1356 else { 1357 throw new RuntimeException ( 1358 "'binarytohex' parameter type is not a binary object."); 1359 } 1360 1361 } 1362 1363 public TType returnTType(VariableResolver resolver, QueryContext context) { 1364 return TType.STRING_TYPE; 1365 } 1366 1367 } 1368 1369 1371 static class SQLCastFunction extends AbstractFunction { 1372 1373 private TType cast_to_type; 1374 1375 public SQLCastFunction(Expression[] params) { 1376 super("sql_cast", params); 1377 1378 if (parameterCount() != 2) { 1380 throw new RuntimeException ( 1381 "'sql_cast' function must have only 2 arguments."); 1382 } 1383 1384 Expression exp = params[1]; 1388 if (exp.size() != 1) { 1389 throw new RuntimeException ( 1390 "'sql_cast' function must have simple second parameter."); 1391 } 1392 1393 Object vob = params[1].last(); 1394 if (vob instanceof TObject) { 1395 TObject ob = (TObject) vob; 1396 String encoded_type = ob.getObject().toString(); 1397 cast_to_type = TType.decodeString(encoded_type); 1398 } 1399 else { 1400 throw new RuntimeException ( 1401 "'sql_cast' function must have simple second parameter."); 1402 } 1403 } 1404 1405 public TObject evaluate(GroupResolver group, VariableResolver resolver, 1406 QueryContext context) { 1407 1408 TObject ob = getParameter(0).evaluate(group, resolver, context); 1409 if (ob.getTType().getSQLType() == cast_to_type.getSQLType()) { 1412 return ob; 1413 } 1414 Object casted_ob = TType.castObjectToTType(ob.getObject(), cast_to_type); 1416 return new TObject(cast_to_type, casted_ob); 1417 1418 } 1419 1420 public TType returnTType(VariableResolver resolver, QueryContext context) { 1421 return cast_to_type; 1422 } 1423 1424 } 1425 1426 1428 static class DateObFunction extends AbstractFunction { 1429 1430 private final static TType DATE_TYPE = new TDateType(SQLTypes.DATE); 1431 1432 1438 private final static DateFormat date_format_sho; 1439 private final static DateFormat date_format_sql; 1440 private final static DateFormat date_format_med; 1441 private final static DateFormat date_format_lon; 1442 private final static DateFormat date_format_ful; 1443 1444 static { 1445 date_format_med = DateFormat.getDateInstance(DateFormat.MEDIUM); 1446 date_format_sho = DateFormat.getDateInstance(DateFormat.SHORT); 1447 date_format_lon = DateFormat.getDateInstance(DateFormat.LONG); 1448 date_format_ful = DateFormat.getDateInstance(DateFormat.FULL); 1449 1450 date_format_sql = new SimpleDateFormat("yyyy-MM-dd"); 1452 } 1453 1454 private static TObject dateVal(Date d) { 1455 return new TObject(DATE_TYPE, d); 1456 } 1457 1458 public DateObFunction(Expression[] params) { 1459 super("dateob", params); 1460 1461 if (parameterCount() > 1) { 1462 throw new RuntimeException ( 1463 "'dateob' function must have only one or zero parameters."); 1464 } 1465 } 1466 1467 public TObject evaluate(GroupResolver group, VariableResolver resolver, 1468 QueryContext context) { 1469 1470 if (parameterCount() == 0) { 1472 return dateVal(new Date ()); 1473 } 1474 1475 TObject exp_res = getParameter(0).evaluate(group, resolver, context); 1476 if (exp_res.isNull()) { 1478 return dateVal(new Date ()); 1479 } 1480 else if (exp_res.getTType() instanceof TNumericType) { 1483 BigNumber num = (BigNumber) exp_res.getObject(); 1484 return dateVal(new Date (num.longValue())); 1485 } 1486 1487 String date_str = exp_res.getObject().toString(); 1488 1489 synchronized (date_format_sho) { 1492 try { 1494 return dateVal(date_format_sql.parse(date_str)); 1495 } 1496 catch (ParseException e) {} 1497 try { 1498 return dateVal(date_format_sho.parse(date_str)); 1499 } 1500 catch (ParseException e) {} 1501 try { 1502 return dateVal(date_format_med.parse(date_str)); 1503 } 1504 catch (ParseException e) {} 1505 try { 1506 return dateVal(date_format_lon.parse(date_str)); 1507 } 1508 catch (ParseException e) {} 1509 try { 1510 return dateVal(date_format_ful.parse(date_str)); 1511 } 1512 catch (ParseException e) {} 1513 1514 throw new RuntimeException ( 1515 "Unable to parse date string '" + date_str + "'"); 1516 } 1517 1518 } 1519 1520 public TType returnTType(VariableResolver resolver, QueryContext context) { 1521 return DATE_TYPE; 1522 } 1523 1524 } 1525 1526 1528 static class TimeObFunction extends AbstractFunction { 1529 1530 private final static TType TIME_TYPE = new TDateType(SQLTypes.TIME); 1531 1532 public TimeObFunction(Expression[] params) { 1533 super("timeob", params); 1534 1535 if (parameterCount() > 1) { 1536 throw new RuntimeException ( 1537 "'timeob' function must have only one or zero parameters."); 1538 } 1539 } 1540 1541 private TObject timeNow() { 1542 Calendar c = Calendar.getInstance(); 1543 c.setLenient(false); 1544 int hour = c.get(Calendar.HOUR_OF_DAY); 1545 int minute = c.get(Calendar.MINUTE); 1546 int second = c.get(Calendar.SECOND); 1547 int millisecond = c.get(Calendar.MILLISECOND); 1548 1549 c.set(1970, 0, 1); 1550 return new TObject(TIME_TYPE, c.getTime()); 1551 } 1552 1553 public TObject evaluate(GroupResolver group, VariableResolver resolver, 1554 QueryContext context) { 1555 1556 if (parameterCount() == 0) { 1558 return timeNow(); 1559 } 1560 1561 TObject exp_res = getParameter(0).evaluate(group, resolver, context); 1562 if (exp_res.isNull()) { 1564 return timeNow(); 1565 } 1566 1567 String date_str = exp_res.getObject().toString(); 1568 1569 return new TObject(TIME_TYPE, CastHelper.toTime(date_str)); 1570 1571 } 1572 1573 public TType returnTType(VariableResolver resolver, QueryContext context) { 1574 return TIME_TYPE; 1575 } 1576 1577 } 1578 1579 1581 static class TimeStampObFunction extends AbstractFunction { 1582 1583 private final static TType TIMESTAMP_TYPE = 1584 new TDateType(SQLTypes.TIMESTAMP); 1585 1586 public TimeStampObFunction(Expression[] params) { 1587 super("timestampob", params); 1588 1589 if (parameterCount() > 1) { 1590 throw new RuntimeException ( 1591 "'timestampob' function must have only one or zero parameters."); 1592 } 1593 } 1594 1595 public TObject evaluate(GroupResolver group, VariableResolver resolver, 1596 QueryContext context) { 1597 1598 if (parameterCount() == 0) { 1600 return new TObject(TIMESTAMP_TYPE, new Date ()); 1601 } 1602 1603 TObject exp_res = getParameter(0).evaluate(group, resolver, context); 1604 if (exp_res.isNull()) { 1606 return new TObject(TIMESTAMP_TYPE, new Date ()); 1607 } 1608 1609 String date_str = exp_res.getObject().toString(); 1610 1611 return new TObject(TIMESTAMP_TYPE, CastHelper.toTimeStamp(date_str)); 1612 1613 } 1614 1615 public TType returnTType(VariableResolver resolver, QueryContext context) { 1616 return TIMESTAMP_TYPE; 1617 } 1618 1619 } 1620 1621 1623 1626 static class DateFormatFunction extends AbstractFunction { 1627 1628 final static Cache formatter_cache = new Cache(127, 90, 10); 1629 1630 public DateFormatFunction(Expression[] params) { 1631 super("dateformat", params); 1632 1633 if (parameterCount() != 2) { 1634 throw new RuntimeException ( 1635 "'dateformat' function must have exactly two parameters."); 1636 } 1637 } 1638 1639 public TObject evaluate(GroupResolver group, VariableResolver resolver, 1640 QueryContext context) { 1641 1642 TObject datein = getParameter(0).evaluate(group, resolver, context); 1643 TObject format = getParameter(1).evaluate(group, resolver, context); 1644 if (datein.isNull()) { 1646 return datein; 1647 } 1648 1649 Date d; 1650 if (!(datein.getTType() instanceof TDateType)) { 1651 throw new RuntimeException ( 1652 "Date to format must be DATE, TIME or TIMESTAMP"); 1653 } 1654 else { 1655 d = (Date ) datein.getObject(); 1656 } 1657 1658 String format_string = format.toString(); 1659 synchronized(formatter_cache) { 1660 SimpleDateFormat formatter = 1661 (SimpleDateFormat) formatter_cache.get(format_string); 1662 if (formatter == null) { 1663 formatter = new SimpleDateFormat(format_string); 1664 formatter_cache.put(format_string, formatter); 1665 } 1666 return TObject.stringVal(formatter.format(d)); 1667 } 1668 } 1669 1670 public TType returnTType(VariableResolver resolver, QueryContext context) { 1671 return TType.STRING_TYPE; 1672 } 1673 1674 } 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1686 private static class ToNumberFunction extends AbstractFunction { 1689 1690 public ToNumberFunction(Expression[] params) { 1691 super("tonumber", params); 1692 1693 if (parameterCount() != 1) { 1694 throw new RuntimeException ("TONUMBER function must have one argument."); 1695 } 1696 } 1697 1698 public TObject evaluate(GroupResolver group, VariableResolver resolver, 1699 QueryContext context) { 1700 return getParameter(0).evaluate(group, resolver, 1702 context).castTo(TType.NUMERIC_TYPE); 1703 } 1704 1705 } 1706 1707 1709 private static class IfFunction extends AbstractFunction { 1711 1712 public IfFunction(Expression[] params) { 1713 super("if", params); 1714 if (parameterCount() != 3) { 1715 throw new RuntimeException ( 1716 "IF function must have exactly three arguments."); 1717 } 1718 } 1719 1720 public TObject evaluate(GroupResolver group, VariableResolver resolver, 1721 QueryContext context) { 1722 TObject res = getParameter(0).evaluate(group, resolver, context); 1723 if (res.getTType() instanceof TBooleanType) { 1724 if (res.compareTo(TObject.booleanVal(true)) == 0) { 1726 return getParameter(1).evaluate(group, resolver, context); 1728 } 1729 else { 1730 return getParameter(2).evaluate(group, resolver, context); 1733 } 1734 } 1735 return TObject.nullVal(); 1737 } 1738 1739 public TType returnTType(VariableResolver resolver, QueryContext context) { 1740 1745 TType t1 = getParameter(1).returnTType(resolver, context); 1747 if (t1 instanceof TNullType) { 1751 return getParameter(2).returnTType(resolver, context); 1752 } 1753 return t1; 1754 } 1755 1756 } 1757 1758 1760 private static class CoalesceFunction extends AbstractFunction { 1762 1763 public CoalesceFunction(Expression[] params) { 1764 super("coalesce", params); 1765 if (parameterCount() < 1) { 1766 throw new RuntimeException ( 1767 "COALESCE function must have at least 1 parameter."); 1768 } 1769 } 1770 1771 public TObject evaluate(GroupResolver group, VariableResolver resolver, 1772 QueryContext context) { 1773 int count = parameterCount(); 1774 for (int i = 0; i < count - 1; ++i) { 1775 TObject res = getParameter(i).evaluate(group, resolver, context); 1776 if (!res.isNull()) { 1777 return res; 1778 } 1779 } 1780 return getParameter(count - 1).evaluate(group, resolver, context); 1781 } 1782 1783 public TType returnTType(VariableResolver resolver, QueryContext context) { 1784 1789 int count = parameterCount(); 1792 for (int i = 0; i < count; ++i) { 1793 TType t = getParameter(i).returnTType(resolver, context); 1794 if (!(t instanceof TNullType)) { 1795 return t; 1796 } 1797 } 1798 return TType.NULL_TYPE; 1800 } 1801 1802 } 1803 1804 1805 1806 1808 private static class JavaObjectInstantiation extends AbstractFunction { 1810 1811 public JavaObjectInstantiation(Expression[] params) { 1812 super("_new_JavaObject", params); 1813 1814 if (parameterCount() < 1) { 1815 throw new RuntimeException ( 1816 "_new_JavaObject function must have one argument."); 1817 } 1818 } 1819 1820 public TObject evaluate(GroupResolver group, VariableResolver resolver, 1821 QueryContext context) { 1822 final int arg_len = parameterCount() - 1; 1824 Object [] args = new Object [arg_len]; 1825 for (int i = 0; i < args.length; ++i) { 1826 args[i] = getParameter(i + 1).evaluate(group, resolver, 1827 context).getObject(); 1828 } 1829 Object [] casted_args = new Object [arg_len]; 1830 1831 try { 1832 String clazz = getParameter(0).evaluate(null, resolver, 1833 context).getObject().toString(); 1834 Class c = Class.forName(clazz); 1835 1836 Constructor[] constructs = c.getConstructors(); 1837 search_constructs: 1840 for (int i = 0; i < constructs.length; ++i) { 1841 Class [] construct_args = constructs[i].getParameterTypes(); 1842 if (construct_args.length == arg_len) { 1843 for (int n = 0; n < arg_len; ++n) { 1844 if (construct_args[n].isPrimitive()) { 1846 String class_name = construct_args[n].getName(); 1847 if (args[n] instanceof Number ) { 1849 Number num = (Number ) args[n]; 1850 if (class_name.equals("byte")) { 1851 casted_args[n] = new Byte (num.byteValue()); 1852 } 1853 else if (class_name.equals("char")) { 1854 casted_args[n] = new Character ((char) num.intValue()); 1855 } 1856 else if (class_name.equals("double")) { 1857 casted_args[n] = new Double (num.doubleValue()); 1858 } 1859 else if (class_name.equals("float")) { 1860 casted_args[n] = new Float (num.floatValue()); 1861 } 1862 else if (class_name.equals("int")) { 1863 casted_args[n] = new Integer (num.intValue()); 1864 } 1865 else if (class_name.equals("long")) { 1866 casted_args[n] = new Long (num.longValue()); 1867 } 1868 else if (class_name.equals("short")) { 1869 casted_args[n] = new Short (num.shortValue()); 1870 } 1871 else { 1872 break search_constructs; 1874 } 1875 1876 } 1877 else if (args[n] instanceof Boolean ) { 1879 if (class_name.equals("boolean")) { 1881 casted_args[n] = args[n]; 1882 } 1883 else { 1884 break search_constructs; 1885 } 1886 } 1887 else { 1889 break search_constructs; 1890 } 1891 1892 } 1893 else { 1895 if (construct_args[n].isInstance(args[n])) { 1897 casted_args[n] = args[n]; 1898 } 1899 else { 1900 break search_constructs; 1901 } 1902 } 1903 } Object ob = constructs[i].newInstance(casted_args); 1906 ByteLongObject serialized_ob = ObjectTranslator.serialize(ob); 1907 return new TObject(new TJavaObjectType(clazz), serialized_ob); 1908 } 1909 } 1910 1911 throw new RuntimeException ( 1912 "Unable to find a constructor for '" + clazz + 1913 "' that matches given arguments."); 1914 1915 } 1916 catch (ClassNotFoundException e) { 1917 throw new RuntimeException ("Class not found: " + e.getMessage()); 1918 } 1919 catch (InstantiationException e) { 1920 throw new RuntimeException ("Instantiation Error: " + e.getMessage()); 1921 } 1922 catch (IllegalAccessException e) { 1923 throw new RuntimeException ("Illegal Access Error: " + e.getMessage()); 1924 } 1925 catch (IllegalArgumentException e) { 1926 throw new RuntimeException ( 1927 "Illegal Argument Error: " + e.getMessage()); 1928 } 1929 catch (InvocationTargetException e) { 1930 throw new RuntimeException ( 1931 "Invocation Target Error: " + e.getMessage()); 1932 } 1933 1934 } 1935 1936 public TType returnTType(VariableResolver resolver, QueryContext context) { 1937 String clazz = getParameter(0).evaluate(null, resolver, 1938 context).getObject().toString(); 1939 return new TJavaObjectType(clazz); 1940 } 1941 1942 } 1943 1944 private static class JavaObjectInstantiation2 extends AbstractFunction { 1947 1948 public JavaObjectInstantiation2(Expression[] params) { 1949 super("_new_JavaObject", params); 1950 1951 if (parameterCount() < 1) { 1952 throw new RuntimeException ( 1953 "_new_JavaObject function must have one argument."); 1954 } 1955 } 1956 1957 public TObject evaluate(GroupResolver group, VariableResolver resolver, 1958 QueryContext context) { 1959 final int arg_len = parameterCount() - 1; 1961 TObject[] args = new TObject[arg_len]; 1962 for (int i = 0; i < args.length; ++i) { 1963 args[i] = getParameter(i + 1).evaluate(group, resolver, context); 1964 } 1965 Caster.deserializeJavaObjects(args); 1966 1967 try { 1968 String clazz = getParameter(0).evaluate(null, resolver, 1970 context).getObject().toString(); 1971 Class c = Class.forName(clazz); 1972 Constructor[] constructs = c.getConstructors(); 1973 1974 Constructor bestConstructor = 1975 Caster.findBestConstructor(constructs, args); 1976 if (bestConstructor == null) { 1977 String argTypes = Caster.getArgTypesString(args); 1980 throw new RuntimeException ( 1981 "Unable to find a constructor for '" + clazz + 1982 "' that matches given arguments: " + argTypes); 1983 } 1984 Object [] casted_args = 1985 Caster.castArgsToConstructor(args, bestConstructor); 1986 Object ob = bestConstructor.newInstance(casted_args); 1988 ByteLongObject serialized_ob = ObjectTranslator.serialize(ob); 1989 return new TObject(new TJavaObjectType(clazz), serialized_ob); 1990 1991 } 1992 catch (ClassNotFoundException e) { 1993 throw new RuntimeException ("Class not found: " + e.getMessage()); 1994 } 1995 catch (InstantiationException e) { 1996 throw new RuntimeException ("Instantiation Error: " + e.getMessage()); 1997 } 1998 catch (IllegalAccessException e) { 1999 throw new RuntimeException ("Illegal Access Error: " + e.getMessage()); 2000 } 2001 catch (IllegalArgumentException e) { 2002 throw new RuntimeException ( 2003 "Illegal Argument Error: " + e.getMessage()); 2004 } 2005 catch (InvocationTargetException e) { 2006 String msg = e.getMessage(); 2007 if (msg == null) { 2008 Throwable th = e.getTargetException(); 2009 if (th != null) { 2010 msg = th.getClass().getName() + ": " + th.getMessage(); 2011 } 2012 } 2013 throw new RuntimeException ("Invocation Target Error: " + msg); 2014 } 2015 2016 } 2017 2018 public TType returnTType(VariableResolver resolver, QueryContext context) { 2019 String clazz = getParameter(0).evaluate(null, resolver, 2020 context).getObject().toString(); 2021 return new TJavaObjectType(clazz); 2022 } 2023 2024 } 2025 2026 2028 private static class ForeignRuleConvert extends AbstractFunction { 2031 2032 public ForeignRuleConvert(Expression[] params) { 2033 super("i_frule_convert", params); 2034 2035 if (parameterCount() != 1) { 2036 throw new RuntimeException ( 2037 "i_frule_convert function must have one argument."); 2038 } 2039 } 2040 2041 public TObject evaluate(GroupResolver group, VariableResolver resolver, 2042 QueryContext context) { 2043 TObject ob = getParameter(0).evaluate(group, resolver, context); 2045 String str = null; 2046 if (!ob.isNull()) { 2047 str = ob.getObject().toString(); 2048 } 2049 int v; 2050 if (str == null || str.equals("") || str.equals("NO ACTION")) { 2051 v = java.sql.DatabaseMetaData.importedKeyNoAction; 2052 } 2053 else if (str.equals("CASCADE")) { 2054 v = java.sql.DatabaseMetaData.importedKeyCascade; 2055 } 2056 else if (str.equals("SET NULL")) { 2057 v = java.sql.DatabaseMetaData.importedKeySetNull; 2058 } 2059 else if (str.equals("SET DEFAULT")) { 2060 v = java.sql.DatabaseMetaData.importedKeySetDefault; 2061 } 2062 else if (str.equals("RESTRICT")) { 2063 v = java.sql.DatabaseMetaData.importedKeyRestrict; 2064 } 2065 else { 2066 throw new Error ("Unrecognised foreign key rule: " + str); 2067 } 2068 return TObject.intVal(v); 2070 } 2071 2072 } 2073 2074 2076 private static class SQLTypeString extends AbstractFunction { 2079 2080 public SQLTypeString(Expression[] params) { 2081 super("i_sql_type", params); 2082 2083 if (parameterCount() != 3) { 2084 throw new RuntimeException ( 2085 "i_sql_type function must have three arguments."); 2086 } 2087 } 2088 2089 public TObject evaluate(GroupResolver group, VariableResolver resolver, 2090 QueryContext context) { 2091 TObject type_string = getParameter(0).evaluate(group, resolver, context); 2093 TObject type_size = getParameter(1).evaluate(group, resolver, context); 2094 TObject type_scale = getParameter(2).evaluate(group, resolver, context); 2095 2096 StringBuffer result_str = new StringBuffer (); 2097 result_str.append(type_string.toString()); 2098 long size = -1; 2099 long scale = -1; 2100 if (!type_size.isNull()) { 2101 size = type_size.toBigNumber().longValue(); 2102 } 2103 if (!type_scale.isNull()) { 2104 scale = type_scale.toBigNumber().longValue(); 2105 } 2106 2107 if (size != -1) { 2108 result_str.append('('); 2109 result_str.append(size); 2110 if (scale != -1) { 2111 result_str.append(','); 2112 result_str.append(scale); 2113 } 2114 result_str.append(')'); 2115 } 2116 2117 return TObject.stringVal(new String (result_str)); 2118 } 2119 2120 public TType returnTType(VariableResolver resolver, QueryContext context) { 2121 return TType.STRING_TYPE; 2122 } 2123 2124 } 2125 2126 2128 2131 private static class ViewDataConvert extends AbstractFunction { 2132 2133 public ViewDataConvert(Expression[] params) { 2134 super("i_view_data", params); 2135 2136 if (parameterCount() != 2) { 2137 throw new RuntimeException ( 2138 "i_sql_type function must have two arguments."); 2139 } 2140 } 2141 2142 public TObject evaluate(GroupResolver group, VariableResolver resolver, 2143 QueryContext context) { 2144 TObject command = getParameter(0).evaluate(group, resolver, context); 2148 TObject data = getParameter(1).evaluate(group, resolver, context); 2149 2150 String command_str = command.getObject().toString(); 2151 ByteLongObject blob = (ByteLongObject) data.getObject(); 2152 2153 if (command_str.equalsIgnoreCase("referenced tables")) { 2154 ViewDef view_def = ViewDef.deserializeFromBlob(blob); 2155 QueryPlanNode node = view_def.getQueryPlanNode(); 2156 ArrayList touched_tables = node.discoverTableNames(new ArrayList ()); 2157 StringBuffer buf = new StringBuffer (); 2158 int sz = touched_tables.size(); 2159 for (int i = 0; i < sz; ++i) { 2160 buf.append(touched_tables.get(i)); 2161 if (i < sz - 1) { 2162 buf.append(", "); 2163 } 2164 } 2165 return TObject.stringVal(new String (buf)); 2166 } 2167 else if (command_str.equalsIgnoreCase("plan dump")) { 2168 ViewDef view_def = ViewDef.deserializeFromBlob(blob); 2169 QueryPlanNode node = view_def.getQueryPlanNode(); 2170 StringBuffer buf = new StringBuffer (); 2171 node.debugString(0, buf); 2172 return TObject.stringVal(new String (buf)); 2173 } 2174 else if (command_str.equalsIgnoreCase("query string")) { 2175 SQLQuery query = SQLQuery.deserializeFromBlob(blob); 2176 return TObject.stringVal(query.toString()); 2177 } 2178 2179 return TObject.nullVal(); 2180 2181 } 2182 2183 public TType returnTType(VariableResolver resolver, QueryContext context) { 2184 return TType.STRING_TYPE; 2185 } 2186 2187 } 2188 2189 2191 2194 private static class PrivilegeString extends AbstractFunction { 2195 2196 public PrivilegeString(Expression[] params) { 2197 super("i_privilege_string", params); 2198 2199 if (parameterCount() != 1) { 2200 throw new RuntimeException ( 2201 "i_privilege_string function must have one argument."); 2202 } 2203 } 2204 2205 public TObject evaluate(GroupResolver group, VariableResolver resolver, 2206 QueryContext context) { 2207 TObject priv_bit_ob = getParameter(0).evaluate(group, resolver, context); 2208 int priv_bit = ((BigNumber) priv_bit_ob.getObject()).intValue(); 2209 Privileges privs = new Privileges(); 2210 privs = privs.add(priv_bit); 2211 return TObject.stringVal(privs.toString()); 2212 } 2213 2214 public TType returnTType(VariableResolver resolver, QueryContext context) { 2215 return TType.STRING_TYPE; 2216 } 2217 2218 } 2219 2220 2221 2222} 2223 | Popular Tags |