⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 expression.java

📁 一个可以在applet窗体上持行sql语句并显示返回结果的程序
💻 JAVA
字号:
/*
 * Expression.java
 */

package org.hsql;
import java.sql.*;
import java.util.*;

class Expression {
  // leaf types
  final static int VALUE=1,COLUMN=2,QUERY=3,TRUE=4,VALUELIST=5,ASTERIX=6,
  FUNCTION=7;

  // operations
  final static int NEGATE=9,ADD=10,SUBTRACT=11,MULTIPLY=12,DIVIDE=14,CONCAT=15;

  // logical operations
  final static int NOT=20,EQUAL=21,BIGGER_EQUAL=22,BIGGER=23,SMALLER=24,
  SMALLER_EQUAL=25,NOT_EQUAL=26,LIKE=27,AND=28,OR=29,IN=30,EXISTS=31;

  // aggregate functions
  final static int COUNT=40,SUM=41,MIN=42,MAX=43,AVG=44;

  // system functions
  final static int IFNULL=60,CONVERT=61,CASEWHEN=62;

  // temporary used during paring
  final static int PLUS=100,OPEN=101,CLOSE=102,SELECT=103,COMMA=104,
  STRINGCONCAT=105,BETWEEN=106,CAST=107,END=108;

  private int iType;

  // nodes
  private Expression eArg,eArg2;

  // VALUE
  private Object oData;
  private int iDataType;

  // VALUELIST
  private Hashtable hList;

  // QUERY (correlated subquery)
  private Select sSelect;

  // FUNCTION
  private Function fFunction;

  // LIKE
  private char cLikeEscape;

  // COLUMN
  private String sTable,sColumn;
  private TableFilter tFilter;   // null if not yet resolved
  private int iColumn;
  private String sAlias;          // if it is a column of a select column list
  private boolean bDescending;    // if it is a column in a order by

  Expression(Function f) {
    iType=FUNCTION;
    fFunction=f;
  }
  Expression(Expression e) {
    iType=e.iType;
    iDataType=e.iDataType;
    eArg=e.eArg;
    eArg2=e.eArg2;
    cLikeEscape=e.cLikeEscape;
    sSelect=e.sSelect;
    fFunction=e.fFunction;
  }
  Expression(Select s) {
    iType=QUERY;
    sSelect=s;
  }
  Expression(Vector v) {
    iType=VALUELIST;
    int len=v.size();
    hList=new Hashtable(len);
    for(int i=0;i<len;i++) {
      Object o=v.elementAt(i);
      if(o!=null) {
        hList.put(o,this); // todo: don't use such dummy objects
      }
    }
  }
  Expression(int type,Expression e,Expression e2) {
    iType=type;
    eArg=e;
    eArg2=e2;
  }
  Expression(String table,String column) {
    sTable=table;
    if(column==null) {
      iType=ASTERIX;
    } else {
      iType=COLUMN;
      sColumn=column;
    }
  }
  Expression(int datatype,Object o) {
    iType=VALUE;
    iDataType=datatype;
    oData=o;
  }
  void setLikeEscape(char c) {
    cLikeEscape=c;
  }
  void setDataType(int type) {
    iDataType=type;
  }
  void setTrue() {
    iType=TRUE;
  }
  boolean isAggregate() {
    if(iType==COUNT || iType==MAX || iType==MIN || iType==SUM || iType==AVG) {
      return true;
    }
    // todo: recurse eArg and eArg2; maybe they are grouped.
    // grouping 'correctly' would be quite complex
    return false;
  }
  void setDescending() {
    bDescending=true;
  }
  boolean isDescending() {
    return bDescending;
  }
  void setAlias(String s) {
    sAlias=s;
  }
  String getAlias() {
    if(sAlias!=null) {
      return sAlias;
    }
    if(iType==VALUE) {
      return "";
    }
    if(iType==COLUMN) {
      return sColumn;
    }
    // todo
    return "";
  }
  int getType() {
    return iType;
  }
  int getColumnNr() {
    return iColumn;
  }
  Expression getArg() {
    return eArg;
  }
  Expression getArg2() {
    return eArg2;
  }
  TableFilter getFilter() {
    return tFilter;
  }
  void checkResolved() throws SQLException {
    Trace.check(iType!=COLUMN || tFilter!=null,Trace.COLUMN_NOT_FOUND,sColumn);
    if(eArg!=null) {
      eArg.checkResolved();
    }
    if(eArg2!=null) {
      eArg2.checkResolved();
    }
    if(sSelect!=null) {
      sSelect.checkResolved();
    }
    if(fFunction!=null) {
      fFunction.checkResolved();
    }
  }
  void resolve(TableFilter f) throws SQLException {
    if(f!=null && iType==COLUMN) {
      if(sTable==null || f.getName().equals(sTable)) {
        int i=f.getTable().searchColumn(sColumn);
        if(i!=-1) {
          // todo: other error message: multiple tables are possible
          Trace.check(tFilter==null||tFilter==f,Trace.COLUMN_NOT_FOUND,sColumn);
          tFilter=f;
          iColumn=i;
          sTable=f.getName();
          iDataType=f.getTable().getColumnType(i);
        }
      }
    }
    // currently sets only data type
    // todo: calculate fixed expressions if possible
    if(eArg!=null) {
      eArg.resolve(f);
    }
    if(eArg2!=null) {
      eArg2.resolve(f);
    }
    if(sSelect!=null) {
      sSelect.resolve(f,false);
      sSelect.resolve();
    }
    if(fFunction!=null) {
      fFunction.resolve(f);
    }
    if(iDataType!=0) {
      return;
    }
    switch(iType) {
    case FUNCTION:
      iDataType=fFunction.getReturnType();
      break;
    case QUERY:
      iDataType=sSelect.eColumn[0].iDataType;
      break;
    case NEGATE:
      iDataType=eArg.iDataType;
      break;
    case ADD:
    case SUBTRACT:
    case MULTIPLY:
    case DIVIDE:
      iDataType=eArg.iDataType;
      break;
    case CONCAT:
      iDataType=Column.VARCHAR;
      break;
    case NOT:
    case EQUAL:
    case BIGGER_EQUAL:
    case BIGGER:
    case SMALLER:
    case SMALLER_EQUAL:
    case NOT_EQUAL:
    case LIKE:
    case AND:
    case OR:
    case IN:
    case EXISTS:
      iDataType=Column.BIT;
      break;
    case COUNT:
      iDataType=Column.INTEGER;
      break;
    case MAX:
    case MIN:
    case SUM:
    case AVG:
      iDataType=eArg.iDataType;
      break;
    case CONVERT:
      // it is already set
      break;
    case IFNULL:
    case CASEWHEN:
      iDataType=eArg2.iDataType;
      break;
    }
  }
  boolean isResolved() {
    if(iType==VALUE)  {
      return true;
    }
    if(iType==COLUMN) {
      return tFilter!=null;
    }
    // todo: could recurse here, but never miss a 'false'!
    return false;
  }
  static boolean isCompare(int i) {
    switch(i) {
    case EQUAL:
    case BIGGER_EQUAL:
    case BIGGER:
    case SMALLER:
    case SMALLER_EQUAL:
    case NOT_EQUAL:
      return true;
    }
    return false;
  }
  String getTableName() {
    if(iType==ASTERIX) {
      return sTable;
    }
    if(iType==COLUMN) {
      if(tFilter==null) {
        return sTable;
      } else {
        return tFilter.getTable().getName();
      }
    }
    // todo
    return "";
  }
  String getColumnName() {
    if(iType==COLUMN) {
      if(tFilter==null) {
        return sColumn;
      } else {
        return tFilter.getTable().getColumnName(iColumn);
      }
    }
    return getAlias();
  }
  void swapCondition() throws SQLException {
    int i=EQUAL;
    switch(iType) {
    case BIGGER_EQUAL:
      i=SMALLER_EQUAL;
      break;
    case SMALLER_EQUAL:
      i=BIGGER_EQUAL;
      break;
    case SMALLER:
      i=BIGGER;
      break;
    case BIGGER:
      i=SMALLER;
      break;
    case EQUAL:
      break;
    default:
      Trace.assert(false,"Expression.swapCondition");
    }
    iType=i;
    Expression e=eArg;
    eArg=eArg2;
    eArg2=e;
  }
  Object getValue(int type) throws SQLException {
    Object o=getValue();
    if(o==null || iDataType==type) {
      return o;
    }
    String s=Column.convertObject(o);
    return Column.convertString(s,type);
  }
  int getDataType() {
    return iDataType;
  }
  Object getValue() throws SQLException {
    switch(iType) {
    case VALUE:
      return oData;
    case COLUMN:
      try {
        return tFilter.oCurrentData[iColumn];
      } catch(NullPointerException e) {
        throw Trace.error(Trace.COLUMN_NOT_FOUND,sColumn);
      }
    case FUNCTION:
      return fFunction.getValue();
    case QUERY:
      return sSelect.getValue(iDataType);
    case NEGATE:
      return Column.negate(eArg.getValue(iDataType),iDataType);
    case COUNT:
      // count(*): sum(1); count(col): sum(col<>null)
      if(eArg.iType==ASTERIX || eArg.getValue()!=null) {
        return new Integer(1);
      }
      return new Integer(0);
    case MAX:
    case MIN:
    case SUM:
    case AVG:
      return eArg.getValue();
    case EXISTS:
      return new Boolean(test());
    case CONVERT:
      return eArg.getValue(iDataType);
    case CASEWHEN:
      if(eArg.test()) {
        return eArg2.eArg.getValue();
      } else {
        return eArg2.eArg2.getValue();
      }
    }
    // todo: simplify this
    Object a=null,b=null;
    if(eArg!=null) {
      a=eArg.getValue(iDataType);
    }
    if(eArg2!=null) {
      b=eArg2.getValue(iDataType);
    }
    switch(iType) {
    case ADD:
      return Column.add(a,b,iDataType);
    case SUBTRACT:
      return Column.subtract(a,b,iDataType);
    case MULTIPLY:
      return Column.multiply(a,b,iDataType);
    case DIVIDE:
      return Column.divide(a,b,iDataType);
    case CONCAT:
      return Column.concat(a,b);
    case IFNULL:
      return a==null ? b : a;
    default:
      // must be comparisation
      // todo: make sure it is
      return new Boolean(test());
    }
  }
  private boolean testValueList(String s) throws SQLException {
    if(iType==VALUELIST) {
      return hList.containsKey(s);
    } else if(iType==QUERY) {
      // todo: convert to valuelist before if everything is resolvable
      Hashtable h=new Hashtable();
      Result r=sSelect.getResult(0);
      Record n=r.rRoot;
      int type=r.iType[0];
      while(n!=null) {
        Object o=Column.createString(n.data[0],type);
        if(o!=null) {
          h.put(o,this);
        }
        n=n.next;
      }
      return h.containsKey(s);
    }
    throw Trace.error(Trace.WRONG_DATA_TYPE);
  }
  boolean test() throws SQLException {
    switch(iType) {
    case TRUE:
      return true;
    case NOT:
      Trace.assert(eArg2==null,"Expression.test");
      return !eArg.test();
    case AND:
      return eArg.test() && eArg2.test();
    case OR:
      return eArg.test() || eArg2.test();
    case LIKE:
      // todo: now for all tests a new 'like' object required!
      String s=(String)eArg2.getValue(Column.VARCHAR);
      Like l=new Like(s,cLikeEscape);
      String c=(String)eArg.getValue(Column.VARCHAR);
      return l.compare(c);
    case IN:
      String t=(String)eArg.getValue(Column.VARCHAR);
      return eArg2.testValueList(t);
    case EXISTS:
      Result r=eArg.sSelect.getResult(1); // 1 is already enough
      return r.rRoot!=null;
    }
    Trace.check(eArg!=null,Trace.GENERAL_ERROR);
    Object o=eArg.getValue();
    int type=eArg.iDataType;
    Trace.check(eArg2!=null,Trace.GENERAL_ERROR);
    Object o2=eArg2.getValue(type);
    int result=Column.compare(o,o2,type);
    switch(iType) {
    case EQUAL:
      return result==0;
    case BIGGER:
      return result>0;
    case BIGGER_EQUAL:
      return result>=0;
    case SMALLER_EQUAL:
      return result<=0;
    case SMALLER:
      return result<0;
    case NOT_EQUAL:
      return result!=0;
    }
    Trace.assert(false,"Expression.test2");
    return false;
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -