1 24 25 package com.mckoi.database; 26 27 import java.util.Date ; 28 import java.util.List ; 29 import java.util.ArrayList ; 30 import java.io.StringReader ; 31 import java.io.IOException ; 32 import java.io.ObjectInputStream ; 33 import java.io.ObjectOutputStream ; 34 import com.mckoi.database.sql.SQL; 35 import com.mckoi.util.BigNumber; 36 37 67 68 public final class Expression implements java.io.Serializable , Cloneable { 69 70 73 static final long serialVersionUID = 6981261114471924028L; 74 75 84 private ArrayList elements = new ArrayList (); 85 86 89 private transient ArrayList eval_stack; 90 91 95 private StringBuffer text; 96 97 98 101 public Expression() { 102 text = new StringBuffer (); 103 } 104 105 108 public Expression(Object ob) { 109 this(); 110 addElement(ob); 111 } 112 113 116 public Expression(Expression exp) { 117 concat(exp); 118 text = new StringBuffer (new String (exp.text)); 119 } 120 121 125 public Expression(Expression exp1, Operator op, Expression exp2) { 126 elements.addAll(exp1.elements); 128 elements.addAll(exp2.elements); 129 elements.add(op); 130 } 131 132 136 public StringBuffer text() { 137 return text; 138 } 139 140 143 public void copyTextFrom(Expression e) { 144 this.text = new StringBuffer (new String (e.text())); 145 } 146 147 155 public static Expression parse(String expression) { 156 synchronized (expression_parser) { 157 try { 158 expression_parser.ReInit(new StringReader (expression)); 159 expression_parser.reset(); 160 Expression exp = expression_parser.parseExpression(); 161 162 exp.text().setLength(0); 163 exp.text().append(expression); 164 return exp; 165 } 166 catch (com.mckoi.database.sql.ParseException e) { 167 throw new RuntimeException (e.getMessage()); 168 } 169 } 170 } 171 172 176 private final static SQL expression_parser = new SQL(new StringReader ("")); 177 178 181 public static Expression simple(Object ob1, Operator op, Object ob2) { 182 Expression exp = new Expression(ob1); 183 exp.addElement(ob2); 184 exp.addElement(op); 185 return exp; 186 } 187 188 189 195 public void addElement(Object ob) { 196 if (ob == null) { 197 elements.add(TObject.nullVal()); 198 } 199 else if (ob instanceof TObject || 200 ob instanceof ParameterSubstitution || 201 ob instanceof CorrelatedVariable || 202 ob instanceof Variable || 203 ob instanceof FunctionDef || 204 ob instanceof Operator || 205 ob instanceof StatementTreeObject 206 ) { 207 elements.add(ob); 208 } 209 else { 210 throw new Error ("Unknown element type added to expression: " + 211 ob.getClass()); 212 } 213 } 214 215 225 public Expression concat(Expression expr) { 226 elements.addAll(expr.elements); 227 return this; 228 } 229 230 236 public void addOperator(Operator op) { 237 elements.add(op); 238 } 239 240 244 public int size() { 245 return elements.size(); 246 } 247 248 252 public Object elementAt(int n) { 253 return elements.get(n); 254 } 255 256 259 public Object last() { 260 return elements.get(size() - 1); 261 } 262 263 264 269 public void setElementAt(int n, Object ob) { 270 elements.set(n, ob); 271 } 272 273 276 private final void push(Object ob) { 277 eval_stack.add(ob); 278 } 279 280 283 private final Object pop() { 284 return eval_stack.remove(eval_stack.size() - 1); 285 } 286 287 288 292 public List allVariables() { 293 ArrayList vars = new ArrayList (); 294 for (int i = 0; i < elements.size(); ++i) { 295 Object ob = elements.get(i); 296 if (ob instanceof Variable) { 297 vars.add(ob); 298 } 299 else if (ob instanceof FunctionDef) { 300 Expression[] params = ((FunctionDef)ob).getParameters(); 301 for (int n = 0; n < params.length; ++n) { 302 vars.addAll(params[n].allVariables()); 303 } 304 } 305 else if (ob instanceof TObject) { 306 TObject tob = (TObject) ob; 307 if (tob.getTType() instanceof TArrayType) { 308 Expression[] exp_list = (Expression[]) tob.getObject(); 309 for (int n = 0; n < exp_list.length; ++n) { 310 vars.addAll(exp_list[n].allVariables()); 311 } 312 } 313 } 314 } 315 return vars; 316 } 317 318 322 public List allElements() { 323 ArrayList elems = new ArrayList (); 324 for (int i = 0; i < elements.size(); ++i) { 325 Object ob = elements.get(i); 326 if (ob instanceof Operator) { 327 } 328 else if (ob instanceof FunctionDef) { 329 Expression[] params = ((FunctionDef) ob).getParameters(); 330 for (int n = 0; n < params.length; ++n) { 331 elems.addAll(params[n].allElements()); 332 } 333 } 334 else if (ob instanceof TObject) { 335 TObject tob = (TObject) ob; 336 if (tob.getTType() instanceof TArrayType) { 337 Expression[] exp_list = (Expression[]) tob.getObject(); 338 for (int n = 0; n < exp_list.length; ++n) { 339 elems.addAll(exp_list[n].allElements()); 340 } 341 } 342 else { 343 elems.add(ob); 344 } 345 } 346 else { 347 elems.add(ob); 348 } 349 } 350 return elems; 351 } 352 353 361 public void prepare(ExpressionPreparer preparer) throws DatabaseException { 362 for (int n = 0; n < elements.size(); ++n) { 363 Object ob = elements.get(n); 364 365 if (preparer.canPrepare(ob)) { 368 elements.set(n, preparer.prepare(ob)); 369 } 370 371 Expression[] exp_list = null; 372 if (ob instanceof FunctionDef) { 373 FunctionDef func = (FunctionDef) ob; 374 exp_list = func.getParameters(); 375 } 376 else if (ob instanceof TObject) { 377 TObject tob = (TObject) ob; 378 if (tob.getTType() instanceof TArrayType) { 379 exp_list = (Expression[]) tob.getObject(); 380 } 381 } 382 else if (ob instanceof StatementTreeObject) { 383 StatementTreeObject stree = (StatementTreeObject) ob; 384 stree.prepareExpressions(preparer); 385 } 386 387 if (exp_list != null) { 388 for (int p = 0; p < exp_list.length; ++p) { 389 exp_list[p].prepare(preparer); 390 } 391 } 392 393 } 394 } 395 396 397 402 public boolean isConstant() { 403 for (int n = 0; n < elements.size(); ++n) { 404 Object ob = elements.get(n); 405 if (ob instanceof TObject) { 406 TObject tob = (TObject) ob; 407 TType ttype = tob.getTType(); 408 if (ttype instanceof TQueryPlanType) { 410 return false; 411 } 412 else if (ttype instanceof TArrayType) { 414 Expression[] exp_list = (Expression[]) tob.getObject(); 415 for (int p = 0; p < exp_list.length; ++p) { 416 if (!exp_list[p].isConstant()) { 417 return false; 418 } 419 } 420 } 421 } 422 else if (ob instanceof Variable) { 423 return false; 424 } 425 else if (ob instanceof FunctionDef) { 426 Expression[] params = ((FunctionDef) ob).getParameters(); 427 for (int p = 0; p < params.length; ++p) { 428 if (!params[p].isConstant()) { 429 return false; 430 } 431 } 432 } 433 } 434 return true; 435 } 436 437 441 public boolean hasSubQuery() { 442 List list = allElements(); 443 int len = list.size(); 444 for (int n = 0; n < len; ++n) { 445 Object ob = list.get(n); 446 if (ob instanceof TObject) { 447 TObject tob = (TObject) ob; 448 if (tob.getTType() instanceof TQueryPlanType) { 449 return true; 450 } 451 } 452 } 453 return false; 454 } 455 456 459 public boolean containsNotOperator() { 460 for (int n = 0; n < elements.size(); ++n) { 461 Object ob = elements.get(n); 462 if (ob instanceof Operator) { 463 if (((Operator) ob).isNot()) { 464 return true; 465 } 466 } 467 } 468 return false; 469 } 470 471 477 public ArrayList discoverCorrelatedVariables(int level, ArrayList list) { 478 List elems = allElements(); 479 int sz = elems.size(); 480 for (int i = 0; i < sz; ++i) { 482 Object ob = elems.get(i); 483 if (ob instanceof CorrelatedVariable) { 484 CorrelatedVariable v = (CorrelatedVariable) ob; 485 if (v.getQueryLevelOffset() == level) { 486 list.add(v); 487 } 488 } 489 else if (ob instanceof TObject) { 490 TObject tob = (TObject) ob; 491 if (tob.getTType() instanceof TQueryPlanType) { 492 QueryPlanNode node = (QueryPlanNode) tob.getObject(); 493 list = node.discoverCorrelatedVariables(level + 1, list); 494 } 495 } 496 } 497 return list; 498 } 499 500 504 public ArrayList discoverTableNames(ArrayList list) { 505 List elems = allElements(); 506 int sz = elems.size(); 507 for (int i = 0; i < sz; ++i) { 509 Object ob = elems.get(i); 510 if (ob instanceof TObject) { 511 TObject tob = (TObject) ob; 512 if (tob.getTType() instanceof TQueryPlanType) { 513 QueryPlanNode node = (QueryPlanNode) tob.getObject(); 514 list = node.discoverTableNames(list); 515 } 516 } 517 } 518 return list; 519 } 520 521 525 public QueryPlanNode getQueryPlanNode() { 526 Object ob = elementAt(0); 527 if (size() == 1 && ob instanceof TObject) { 528 TObject tob = (TObject) ob; 529 if (tob.getTType() instanceof TQueryPlanType) { 530 return (QueryPlanNode) tob.getObject(); 531 } 532 } 533 return null; 534 } 535 536 540 public Variable getVariable() { 541 Object ob = elementAt(0); 542 if (size() == 1 && ob instanceof Variable) { 543 return (Variable) ob; 544 } 545 return null; 546 } 547 548 556 public Expression[] split() { 557 if (size() <= 1) { 558 throw new Error ("Can only split expressions with more than 1 element."); 559 } 560 561 int midpoint = -1; 562 int stack_size = 0; 563 for (int n = 0; n < size() - 1; ++n) { 564 Object ob = elementAt(n); 565 if (ob instanceof Operator) { 566 --stack_size; 567 } 568 else { 569 ++stack_size; 570 } 571 572 if (stack_size == 1) { 573 midpoint = n; 574 } 575 } 576 577 if (midpoint == -1) { 578 throw new Error ("postfix format error: Midpoint not found."); 579 } 580 581 Expression lhs = new Expression(); 582 for (int n = 0; n <= midpoint; ++n) { 583 lhs.addElement(elementAt(n)); 584 } 585 586 Expression rhs = new Expression(); 587 for (int n = midpoint + 1; n < size() - 1; ++n) { 588 rhs.addElement(elementAt(n)); 589 } 590 591 return new Expression[] { lhs, rhs }; 592 } 593 594 606 public Expression getEndExpression() { 607 608 int stack_size = 1; 609 int end = size() - 1; 610 for (int n = end; n > 0; --n) { 611 Object ob = elementAt(n); 612 if (ob instanceof Operator) { 613 ++stack_size; 614 } 615 else { 616 --stack_size; 617 } 618 619 if (stack_size == 0) { 620 Expression new_exp = new Expression(); 622 for (int i = n; i <= end; ++i) { 623 new_exp.addElement(elementAt(i)); 624 } 625 return new_exp; 626 } 627 } 628 629 return new Expression(this); 630 } 631 632 644 public ArrayList breakByOperator(ArrayList list, final String logical_op) { 645 Object ob = last(); 647 if (ob instanceof Operator) { 648 Operator op = (Operator) ob; 649 if (op.is(logical_op)) { 650 Expression[] exps = split(); 652 list = exps[0].breakByOperator(list, logical_op); 653 list = exps[1].breakByOperator(list, logical_op); 654 return list; 655 } 656 } 657 list.add(this); 660 return list; 661 } 662 663 677 public TObject evaluate(GroupResolver group, VariableResolver resolver, 678 QueryContext context) { 679 int element_count = elements.size(); 682 if (element_count == 1) { 683 return (TObject) elementToObject(0, group, resolver, context); 684 } 685 else if (element_count == 3) { 686 TObject o1 = (TObject) elementToObject(0, group, resolver, context); 687 TObject o2 = (TObject) elementToObject(1, group, resolver, context); 688 Operator op = (Operator) elements.get(2); 689 return op.eval(o1, o2, group, resolver, context); 690 } 691 692 if (eval_stack == null) { 693 eval_stack = new ArrayList (); 694 } 695 696 for (int n = 0; n < element_count; ++n) { 697 Object val = elementToObject(n, group, resolver, context); 698 if (val instanceof Operator) { 699 Operator op = (Operator) val; 702 703 TObject v2 = (TObject) pop(); 704 TObject v1 = (TObject) pop(); 705 706 push(op.eval(v1, v2, group, resolver, context)); 707 } 708 else { 709 push(val); 710 } 711 } 712 return (TObject) pop(); 714 } 715 716 719 public TObject evaluate(VariableResolver resolver, QueryContext context) { 720 return evaluate(null, resolver, context); 721 } 722 723 729 private Object elementToObject(int n, GroupResolver group, 730 VariableResolver resolver, QueryContext context) { 731 Object ob = elements.get(n); 732 if (ob instanceof TObject || 733 ob instanceof Operator) { 734 return ob; 735 } 736 else if (ob instanceof Variable) { 737 return resolver.resolve((Variable) ob); 738 } 739 else if (ob instanceof CorrelatedVariable) { 740 return ((CorrelatedVariable) ob).getEvalResult(); 741 } 742 else if (ob instanceof FunctionDef) { 743 Function fun = ((FunctionDef) ob).getFunction(context); 744 return fun.evaluate(group, resolver, context); 745 } 746 else { 747 if (ob == null) { 748 throw new NullPointerException ("Null element in expression"); 749 } 750 throw new Error ("Unknown element type: " + ob.getClass()); 751 } 752 } 753 754 758 public boolean hasAggregateFunction(QueryContext context) { 759 for (int n = 0; n < elements.size(); ++n) { 760 Object ob = elements.get(n); 761 if (ob instanceof FunctionDef) { 762 if (((FunctionDef) ob).isAggregate(context)) { 763 return true; 764 } 765 } 766 else if (ob instanceof TObject) { 767 TObject tob = (TObject) ob; 768 if (tob.getTType() instanceof TArrayType) { 769 Expression[] list = (Expression[]) tob.getObject(); 770 for (int i = 0; i < list.length; ++i) { 771 if (list[i].hasAggregateFunction(context)) { 772 return true; 773 } 774 } 775 } 776 } 777 } 778 return false; 779 } 780 781 788 public TType returnTType(VariableResolver resolver, QueryContext context) { 789 Object ob = elements.get(elements.size() - 1); 790 if (ob instanceof FunctionDef) { 791 Function fun = ((FunctionDef) ob).getFunction(context); 792 return fun.returnTType(resolver, context); 793 } 794 else if (ob instanceof TObject) { 795 return ((TObject)ob).getTType(); 796 } 797 else if (ob instanceof Operator) { 798 Operator op = (Operator) ob; 799 return op.returnTType(); 800 } 801 else if (ob instanceof Variable) { 802 Variable variable = (Variable) ob; 803 return resolver.returnTType(variable); 804 } 805 else if (ob instanceof CorrelatedVariable) { 806 CorrelatedVariable variable = (CorrelatedVariable) ob; 807 return variable.returnTType(); 808 } 809 else { 810 throw new Error ("Unable to determine type for expression."); 811 } 812 } 813 814 818 public Object clone() throws CloneNotSupportedException { 819 Expression v = (Expression) super.clone(); 821 v.eval_stack = null; 822 int size = elements.size(); 824 ArrayList cloned_elements = new ArrayList (size); 825 v.elements = cloned_elements; 826 827 for (int i = 0; i < size; ++i) { 829 Object element = elements.get(i); 830 831 if (element instanceof TObject) { 832 TObject tob = (TObject) element; 834 TType ttype = tob.getTType(); 835 if (ttype instanceof TQueryPlanType) { 837 QueryPlanNode node = (QueryPlanNode) tob.getObject(); 838 node = (QueryPlanNode) node.clone(); 839 element = new TObject(ttype, node); 840 } 841 else if (ttype instanceof TArrayType) { 843 Expression[] arr = (Expression[]) tob.getObject(); 844 arr = (Expression[]) arr.clone(); 845 for (int n = 0; n < arr.length; ++n) { 846 arr[n] = (Expression) arr[n].clone(); 847 } 848 element = new TObject(ttype, arr); 849 } 850 } 851 else if (element instanceof Operator || 852 element instanceof ParameterSubstitution) { 853 } 855 else if (element instanceof CorrelatedVariable) { 856 element = ((CorrelatedVariable) element).clone(); 857 } 858 else if (element instanceof Variable) { 859 element = ((Variable) element).clone(); 860 } 861 else if (element instanceof FunctionDef) { 862 element = ((FunctionDef) element).clone(); 863 } 864 else if (element instanceof StatementTreeObject) { 865 element = ((StatementTreeObject) element).clone(); 866 } 867 else { 868 throw new CloneNotSupportedException (element.getClass().toString()); 869 } 870 cloned_elements.add(element); 871 } 872 873 return v; 874 } 875 876 880 public String toString() { 881 StringBuffer buf = new StringBuffer (); 882 buf.append("[ Expression "); 883 if (text() != null) { 884 buf.append("["); 885 buf.append(text().toString()); 886 buf.append("]"); 887 } 888 buf.append(": "); 889 for (int n = 0; n < elements.size(); ++n) { 890 buf.append(elements.get(n)); 891 if (n < elements.size() - 1) { 892 buf.append(","); 893 } 894 } 895 buf.append(" ]"); 896 return new String (buf); 897 } 898 899 901 906 private void writeObject(ObjectOutputStream out) throws IOException { 907 out.defaultWriteObject(); 908 } 909 910 913 private void readObject(ObjectInputStream in) 914 throws IOException , ClassNotFoundException { 915 in.defaultReadObject(); 916 917 int sz = elements.size(); 920 for (int i = 0; i < sz; ++i) { 921 Object ob = elements.get(i); 922 TObject conv_object = null; 923 if (ob == null || ob instanceof com.mckoi.database.global.NullObject) { 924 conv_object = TObject.nullVal(); 925 } 926 else if (ob instanceof String ) { 927 conv_object = TObject.stringVal((String ) ob); 928 } 929 else if (ob instanceof java.math.BigDecimal ) { 930 conv_object = TObject.bigNumberVal( 931 BigNumber.fromBigDecimal((java.math.BigDecimal ) ob)); 932 } 933 else if (ob instanceof java.util.Date ) { 934 conv_object = TObject.dateVal((java.util.Date ) ob); 935 } 936 else if (ob instanceof Boolean ) { 937 conv_object = TObject.booleanVal(((Boolean ) ob).booleanValue()); 938 } 939 if (conv_object != null) { 940 elements.set(i, conv_object); 941 } 942 } 943 } 944 945 } 946 | Popular Tags |