|                                                                                                              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                                                                                                                                                                                              |