package railo.runtime.db; import java.sql.Types; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import railo.commons.lang.CFTypes; import railo.commons.lang.StringUtil; import railo.commons.math.MathUtil; import railo.runtime.PageContext; import railo.runtime.exp.DatabaseException; import railo.runtime.exp.PageException; import railo.runtime.op.Caster; import railo.runtime.op.Operator; import railo.runtime.sql.Select; import railo.runtime.sql.SelectParser; import railo.runtime.sql.Selects; import railo.runtime.sql.exp.BracketExpression; import railo.runtime.sql.exp.Column; import railo.runtime.sql.exp.ColumnExpression; import railo.runtime.sql.exp.Expression; import railo.runtime.sql.exp.op.Operation; import railo.runtime.sql.exp.op.Operation1; import railo.runtime.sql.exp.op.Operation2; import railo.runtime.sql.exp.op.Operation3; import railo.runtime.sql.exp.op.OperationN; import railo.runtime.sql.exp.value.Value; import railo.runtime.sql.exp.value.ValueNumber; import railo.runtime.type.ArrayImpl; import railo.runtime.type.Collection; import railo.runtime.type.Collection.Key; import railo.runtime.type.Query; import railo.runtime.type.QueryColumn; import railo.runtime.type.QueryImpl; /** * */ public final class QoQ { public Query execute(PageContext pc,SQL sql,int maxrows) throws PageException { try { SelectParser parser=new SelectParser(); Selects selects = parser.parse(sql.getSQLString()); return execute(pc,sql,selects,maxrows); } catch(Throwable t) { throw Caster.toPageException(t); } } /** * execute a SQL Statement against CFML Scopes */ public Query execute(PageContext pc,SQL sql, Selects selects,int maxrows) throws PageException { Column[] orders=selects.getOrderbys(); Select[] arrSelects = selects.getSelects(); QueryImpl target=new QueryImpl(new Collection.Key[0],0,"query"); target.setSql(sql); for(int i=0;i<arrSelects.length;i++) { arrSelects[i].getFroms(); Column[] froms = arrSelects[i].getFroms(); if(froms.length>1) throw new DatabaseException("can only work with single tables yet",null,sql,null); executeSingle(pc,arrSelects[i],getSingleTable(pc, froms[0]),target,arrSelects.length>1?-1:maxrows,sql, orders.length>0); } // Order By if(orders.length>0) { order(target,orders); if(maxrows>-1) target.cutRowsTo(maxrows); } // Distinct if(selects.isDistinct()) { order(target,selects.getDistincts()); // order to filter //print.e(selects.getDistincts()); Key[] _keys = target.getColumnNames(); QueryColumn[] columns=new QueryColumn[_keys.length]; for(int i=0;i<columns.length;i++) { columns[i]=target.getColumn(_keys[i]); } int i; Object l,r; outer:for(int row=target.getRecordcount();row>1;row--) { for(i=0;i<columns.length;i++) { l=columns[i].get(row,null); r=columns[i].get(row-1,null); if(l==null || r==null) { if(l!=r)continue outer; } else if(!Operator.equals(l,r,true)) continue outer; } target.removeRow(row); } } order(target,orders); return target; } private static void order(Query qry, Column[] columns) throws PageException { Column col; for(int i=columns.length-1;i>=0;i--) { col = columns[i]; qry.sort(col.getColumn(),col.isDirectionBackward()?Query.ORDER_DESC:Query.ORDER_ASC); } } private void executeSingle(PageContext pc, Select select, Query qr, QueryImpl target, int maxrows, SQL sql,boolean hasOrders) throws PageException { ValueNumber oTop = select.getTop(); if(oTop!=null) { int top=(int)oTop.getValueAsDouble(); if(maxrows==-1 || maxrows>top) maxrows=top; } int recCount=qr.getRecordcount(); Expression[] expSelects = select.getSelects(); int selCount=expSelects.length; Map<Collection.Key,Object> selects=new HashMap<Collection.Key,Object>(); Iterator<Key> it; Key k; // headers for(int i=0;i<selCount;i++) { Expression expSelect = expSelects[i]; if(expSelect.getAlias().equals("*")) { it = qr.keyIterator(); while(it.hasNext()){ k = it.next(); selects.put(k,k); queryAddColumn( target, k, qr.getColumn( k ).getType() ); } } else { Key alias = Caster.toKey(expSelect.getAlias()); selects.put(alias,expSelect); int type = Types.OTHER; if ( expSelect instanceof ColumnExpression ) type = qr.getColumn( Caster.toKey( ((ColumnExpression)expSelect).getColumnName() ) ).getType(); queryAddColumn( target, alias, type ); } } Collection.Key[] headers = selects.keySet().toArray(new Collection.Key[selects.size()]); //QueryImpl rtn=new QueryImpl(headers,0,"query"); //rtn.setSql(sql); // loop records //Column[] orders = select.getOrderbys(); Operation where = select.getWhere(); boolean hasMaxrow=maxrows>-1 && !hasOrders; // get target columns QueryColumn[] trgColumns=new QueryColumn[headers.length]; Object[] trgValues=new Object[headers.length]; for(int cell=0;cell<headers.length;cell++){ trgColumns[cell]=target.getColumn(headers[cell]); trgValues[cell]=selects.get(headers[cell]); } for(int row=1;row<=recCount;row++) { sql.setPosition(0); if(hasMaxrow && maxrows<=target.getRecordcount())break; boolean useRow=where==null || Caster.toBooleanValue(executeExp(pc,sql,qr, where, row)); if(useRow) { target.addRow(1); for(int cell=0;cell<headers.length;cell++){ //Object value = selects.get(headers[cell]); trgColumns[cell].set(target.getRecordcount(), getValue(pc,sql,qr,row,headers[cell],trgValues[cell])); /*target.setAt( headers[cell], target.getRecordcount(), getValue(pc,sql,qr,row,headers[cell],trgValues[cell]) );*/ } } } // Group By if(select.getGroupbys().length>0) throw new DatabaseException("group by are not supported at the moment",null,sql,null); if(select.getHaving()!=null) throw new DatabaseException("having is not supported at the moment",null,sql,null); } private void queryAddColumn(QueryImpl query, Collection.Key column, int type) throws PageException { if(!query.containsKey(column)) { query.addColumn( column, new ArrayImpl(), type ); } } /*private Array array(String value, int recordcount) { Array array = new ArrayImpl(); if(recordcount==0) return array; for(int i=0;i<recordcount;i++) { array.appendEL(value); } return array; }*/ /*private QueryImpl execute2(PageContext pc,SQL sql, Query qr, Select select,Column[] orders,int maxrows) throws PageException { int recCount=qr.getRecordcount(); Expression[] expSelects = select.getSelects(); int selCount=expSelects.length; Map selects=new HashTable(); boolean isSMS=false; Key[] keys; // headers for(int i=0;i<selCount;i++) { Expression expSelect = expSelects[i]; if(expSelect.getAlias().equals("*")) { keys = qr.keys(); for(int y=0;y<keys.length;y++){ selects.put(keys[y].getLowerString(),keys[y].getLowerString()); } } else { String alias=expSelect.getAlias(); alias=alias.toLowerCase(); selects.put(alias,expSelect); } } String[] headers = (String[])selects.keySet().toArray(new String[selects.size()]); QueryImpl rtn=new QueryImpl(headers,0,"query"); rtn.setSql(sql); // loop records Operation where = select.getWhere(); boolean hasMaxrow=maxrows>-1 && (orders==null || orders.length==0); for(int row=1;row<=recCount;row++) { sql.setPosition(0); if(hasMaxrow && maxrows<=rtn.getRecordcount())break; boolean useRow=where==null || Caster.toBooleanValue(executeExp(pc,sql,qr, where, row)); if(useRow) { rtn.addRow(1); for(int cell=0;cell<headers.length;cell++){ Object value = selects.get(headers[cell]); rtn.setAt( headers[cell], rtn.getRecordcount(), getValue(pc,sql,qr,row,headers[cell],value) ); } } } // Group By if(select.getGroupbys().length>0) throw new DatabaseException("group by are not supported at the moment",null,sql); if(select.getHaving()!=null) throw new DatabaseException("having is not supported at the moment",null,sql); // Order By if(orders.length>0) { for(int i=orders.length-1;i>=0;i--) { Column order = orders[i]; rtn.sort(order.getColumn().toLowerCase(),order.isDirectionBackward()?Query.ORDER_DESC:Query.ORDER_ASC); } if(maxrows>-1) { rtn.cutRowsTo(maxrows); } } // Distinct if(select.isDistinct()) { String[] _keys=rtn.getColumns(); QueryColumn[] columns=new QueryColumn[_keys.length]; for(int i=0;i<columns.length;i++) { columns[i]=rtn.getColumn(_keys[i]); } int i; outer:for(int row=rtn.getRecordcount();row>1;row--) { for(i=0;i<columns.length;i++) { if(!Operator.equals(columns[i].get(row),columns[i].get(row-1),true)) continue outer; } rtn.removeRow(row); } } return rtn; }*/ /** * return value * @param sql * @param querySource * @param row * @param key * @param value * @return value * @throws PageException */ private Object getValue(PageContext pc,SQL sql,Query querySource, int row, Collection.Key key, Object value) throws PageException { if(value instanceof Expression)return executeExp(pc,sql,querySource, ((Expression)value),row); return querySource.getAt(key,row,null); } /** * @param pc Page Context of the Request * @param table ZQLQuery * @return Railo Query * @throws PageException */ private Query getSingleTable(PageContext pc, Column table) throws PageException { return Caster.toQuery(pc.getVariable(table.getFullName())); } /** * Executes a ZEXp * @param sql * @param qr Query Result * @param exp expression to execute * @param row current row of resultset * @return result * @throws PageException */ private Object executeExp(PageContext pc,SQL sql,Query qr, Expression exp, int row) throws PageException { //print.e("name:"+exp.getClass().getName()); if(exp instanceof Value) return ((Value)exp).getValue();//executeConstant(sql,qr, (Value)exp, row); if(exp instanceof Column) return executeColumn(sql,qr, (Column)exp, row); if(exp instanceof Operation) return executeOperation(pc,sql,qr, (Operation)exp, row); if(exp instanceof BracketExpression) return executeBracked(pc,sql,qr, (BracketExpression)exp, row); throw new DatabaseException("unsupported sql statement ["+exp+"]",null,sql,null); } private Object executeExp(PageContext pc,SQL sql,Query qr, Expression exp, int row, Object columnDefault) throws PageException { //print.o(exp.getClass().getName()); if(exp instanceof Value) return ((Value)exp).getValue();//executeConstant(sql,qr, (Value)exp, row); if(exp instanceof Column) return executeColumn(sql,qr, (Column)exp, row,columnDefault); if(exp instanceof Operation) return executeOperation(pc,sql,qr, (Operation)exp, row); if(exp instanceof BracketExpression) return executeBracked(pc,sql,qr, (BracketExpression)exp, row); throw new DatabaseException("unsupported sql statement ["+exp+"]",null,sql,null); } private Object executeOperation(PageContext pc,SQL sql,Query qr, Operation operation, int row) throws PageException { if(operation instanceof Operation2) { Operation2 op2=(Operation2) operation; switch(op2.getOperator()){ case Operation.OPERATION2_AND: return executeAnd(pc,sql,qr,op2,row); case Operation.OPERATION2_OR: return executeOr(pc,sql,qr,op2,row); case Operation.OPERATION2_XOR: return executeXor(pc,sql,qr,op2,row); case Operation.OPERATION2_EQ: return executeEQ(pc,sql,qr,op2,row); case Operation.OPERATION2_NEQ: return executeNEQ(pc,sql,qr,op2,row); case Operation.OPERATION2_LTGT: return executeNEQ(pc,sql,qr,op2,row); case Operation.OPERATION2_LT: return executeLT(pc,sql,qr,op2,row); case Operation.OPERATION2_LTE: return executeLTE(pc,sql,qr,op2,row); case Operation.OPERATION2_GT: return executeGT(pc,sql,qr,op2,row); case Operation.OPERATION2_GTE: return executeGTE(pc,sql,qr,op2,row); case Operation.OPERATION2_MINUS: return executeMinus(pc,sql,qr,op2,row); case Operation.OPERATION2_PLUS: return executePlus(pc,sql,qr,op2,row); case Operation.OPERATION2_DIVIDE: return executeDivide(pc,sql,qr,op2,row); case Operation.OPERATION2_MULTIPLY: return executeMultiply(pc,sql,qr,op2,row); case Operation.OPERATION2_EXP: return executeExponent(pc,sql,qr,op2,row); case Operation.OPERATION2_LIKE: return Caster.toBoolean(executeLike(pc,sql,qr,op2,row)); case Operation.OPERATION2_NOT_LIKE: return Caster.toBoolean(!executeLike(pc,sql,qr,op2,row)); case Operation.OPERATION2_MOD: return executeMod(pc,sql,qr,op2,row); } } if(operation instanceof Operation1) { Operation1 op1=(Operation1) operation; int o = op1.getOperator(); if(o==Operation.OPERATION1_IS_NULL) { Object value = executeExp( pc,sql,qr,op1.getExp(),row,null); return Caster.toBoolean(value==null); } if(o==Operation.OPERATION1_IS_NOT_NULL) { Object value = executeExp( pc,sql,qr,op1.getExp(),row,null); return Caster.toBoolean(value!=null); } Object value = executeExp( pc,sql,qr,op1.getExp(),row); if(o==Operation.OPERATION1_MINUS) return Caster.toDouble(-Caster.toDoubleValue(value)); if(o==Operation.OPERATION1_PLUS) return Caster.toDouble(value); if(o==Operation.OPERATION1_NOT) return Caster.toBoolean(!Caster.toBooleanValue(value)); } if(operation instanceof Operation3) { Operation3 op3=(Operation3) operation; int o = op3.getOperator(); if(o==Operation.OPERATION3_BETWEEN) return executeBetween(pc,sql,qr,op3,row); if(o==Operation.OPERATION3_LIKE) return executeLike(pc,sql,qr,op3,row); } if(!(operation instanceof OperationN)) throw new DatabaseException("invalid syntax for SQL Statement",null,sql,null); OperationN opn=(OperationN) operation; String op=StringUtil.toLowerCase(opn.getOperator()); Expression[] operators = opn.getOperants(); /*if(count==0 && op.equals("?")) { int pos=sql.getPosition(); if(sql.getItems().length<=pos) throw new DatabaseException("invalid syntax for SQL Statement",null,sql); sql.setPosition(pos+1); return sql.getItems()[pos].getValueForCF(); }*/ // 11111111111111111111111111111111111111111111111111111 if(operators.length==1) { Object value = executeExp( pc,sql,qr,operators[0],row); // Functions switch(op.charAt(0)) { case 'a': if(op.equals("abs")) return new Double(MathUtil.abs(Caster.toDoubleValue(value))); if(op.equals("acos")) return new Double(Math.acos(Caster.toDoubleValue(value))); if(op.equals("asin")) return new Double(Math.asin(Caster.toDoubleValue(value))); if(op.equals("atan")) return new Double(Math.atan(Caster.toDoubleValue(value))); break; case 'c': if(op.equals("ceiling"))return new Double(Math.ceil(Caster.toDoubleValue(value))); if(op.equals("cos")) return new Double(Math.cos(Caster.toDoubleValue(value))); if(op.equals("cast")) return Caster.castTo(pc, CFTypes.toShort(operators[0].getAlias(),true,CFTypes.TYPE_UNKNOW),operators[0].getAlias(), value); break; case 'e': if(op.equals("exp")) return new Double(Math.exp(Caster.toDoubleValue(value))); break; case 'f': if(op.equals("floor")) return new Double(Math.floor(Caster.toDoubleValue(value))); break; case 'u': if(op.equals("upper") || op.equals("ucase")) return Caster.toString(value).toUpperCase(); break; case 'l': if(op.equals("lower")|| op.equals("lcase")) return Caster.toString(value).toLowerCase(); if(op.equals("ltrim")) return StringUtil.ltrim(Caster.toString(value),null); if(op.equals("length")) return new Double(Caster.toString(value).length()); break; case 'r': if(op.equals("rtrim")) return StringUtil.rtrim(Caster.toString(value),null); break; case 's': if(op.equals("sign")) return new Double(MathUtil.sgn(Caster.toDoubleValue(value))); if(op.equals("sin")) return new Double(Math.sin(Caster.toDoubleValue(value))); if(op.equals("soundex"))return StringUtil.soundex(Caster.toString(value)); if(op.equals("sin")) return new Double(Math.sqrt(Caster.toDoubleValue(value))); break; case 't': if(op.equals("tan")) return new Double(Math.tan(Caster.toDoubleValue(value))); if(op.equals("trim")) return Caster.toString(value).trim(); break; } } // 22222222222222222222222222222222222222222222222222222 else if(operators.length==2) { //if(op.equals("=") || op.equals("in")) return executeEQ(pc,sql,qr,expression,row); Object left = executeExp(pc,sql,qr,operators[0],row); Object right = executeExp(pc,sql,qr,operators[1],row); // Functions switch(op.charAt(0)) { case 'a': if(op.equals("atan2")) return new Double(Math.atan2(Caster.toDoubleValue(left),Caster.toDoubleValue(right))); break; case 'b': if(op.equals("bitand")) return new Double(Operator.bitand(Caster.toDoubleValue(left),Caster.toDoubleValue(right))); if(op.equals("bitor")) return new Double(Operator.bitor(Caster.toDoubleValue(left),Caster.toDoubleValue(right))); break; case 'c': if(op.equals("concat")) return Caster.toString(left).concat(Caster.toString(right)); break; case 'm': if(op.equals("mod")) return new Double(Operator.modulus(Caster.toDoubleValue(left),Caster.toDoubleValue(right))); break; } //throw new DatabaseException("unsopprted sql statement ["+op+"]",null,sql); } // 3333333333333333333333333333333333333333333333333333333333333333333 if(op.equals("in")) return executeIn(pc,sql,qr,opn,row,false); if(op.equals("not_in")) return executeIn(pc,sql,qr,opn,row,true); /* addCustomFunction("cot",1); addCustomFunction("degrees",1); addCustomFunction("log",1); addCustomFunction("log10",1); addCustomFunction("pi",0); addCustomFunction("power",2); addCustomFunction("radians",1); addCustomFunction("rand",0); addCustomFunction("round",2); addCustomFunction("roundmagic",1); addCustomFunction("truncate",2); addCustomFunction("ascii",1); addCustomFunction("bit_length",1); addCustomFunction("char",1); addCustomFunction("char_length",1); addCustomFunction("difference",2); addCustomFunction("hextoraw",1); addCustomFunction("insert",4); addCustomFunction("left",2); addCustomFunction("locate",3); addCustomFunction("octet_length",1); addCustomFunction("rawtohex",1); addCustomFunction("repeat",2); addCustomFunction("replace",3); addCustomFunction("right",2); addCustomFunction("space",1); addCustomFunction("substr",3); addCustomFunction("substring",3); addCustomFunction("curdate",0); addCustomFunction("curtime",0); addCustomFunction("datediff",3); addCustomFunction("dayname",1); addCustomFunction("dayofmonth",1); addCustomFunction("dayofweek",1); addCustomFunction("dayofyear",1); addCustomFunction("hour",1); addCustomFunction("minute",1); addCustomFunction("month",1); addCustomFunction("monthname",1); addCustomFunction("now",0); addCustomFunction("quarter",1); addCustomFunction("second",1); addCustomFunction("week",1); addCustomFunction("year",1); addCustomFunction("current_date",1); addCustomFunction("current_time",1); addCustomFunction("current_timestamp",1); addCustomFunction("database",0); addCustomFunction("user",0); addCustomFunction("current_user",0); addCustomFunction("identity",0); addCustomFunction("ifnull",2); addCustomFunction("casewhen",3); addCustomFunction("convert",2); //addCustomFunction("cast",1); addCustomFunction("coalesce",1000); addCustomFunction("nullif",2); addCustomFunction("extract",1); addCustomFunction("position",1); */ //print(expression); throw new DatabaseException( "unsopprted sql statement ("+op+") ",null,sql,null); } /* * * @param expression * / private void print(ZExpression expression) { print.ln("Operator:"+expression.getOperator().toLowerCase()); int len=expression.nbOperands(); for(int i=0;i<len;i++) { print.ln(" ["+i+"]= "+expression.getOperand(i)); } }/* /** * * execute a and operation * @param qr QueryResult to execute on it * @param expression * @param row row of resultset to execute * @return * @throws PageException */ private Object executeAnd(PageContext pc,SQL sql,Query qr, Operation2 expression, int row) throws PageException { //print.out("("+expression.getLeft().toString(true)+" AND "+expression.getRight().toString(true)+")"); boolean rtn=Caster.toBooleanValue(executeExp(pc,sql,qr,expression.getLeft(),row)); if(!rtn) return Boolean.FALSE; return Caster.toBoolean(executeExp(pc,sql,qr,expression.getRight(),row)); } private Object executeBracked(PageContext pc, SQL sql, Query qr, BracketExpression expression, int row) throws PageException { return executeExp(pc,sql,qr,expression.getExp(),row); } /** * * execute a and operation * @param sql * @param qr QueryResult to execute on it * @param expression * @param row row of resultset to execute * @return result * @throws PageException */ private Object executeOr(PageContext pc,SQL sql,Query qr, Operation2 expression, int row) throws PageException { //print.out("("+expression.getLeft().toString(true)+" OR "+expression.getRight().toString(true)+")"); boolean rtn=Caster.toBooleanValue(executeExp(pc,sql,qr,expression.getLeft(),row)); if(rtn) return Boolean.TRUE; Boolean rtn2 = Caster.toBoolean(executeExp(pc,sql,qr,expression.getRight(),row)); //print.out(rtn+ " or "+rtn2); return rtn2; } private Object executeXor(PageContext pc,SQL sql,Query qr, Operation2 expression, int row) throws PageException { return Caster.toBooleanValue(executeExp(pc,sql,qr,expression.getLeft(),row)) ^ Caster.toBooleanValue(executeExp(pc,sql,qr,expression.getRight(),row))? Boolean.TRUE:Boolean.FALSE; } /** * * execute a equal operation * @param sql * @param qr QueryResult to execute on it * @param expression * @param row row of resultset to execute * @return result * @throws PageException */ private Object executeEQ(PageContext pc,SQL sql,Query qr, Operation2 expression, int row) throws PageException { return (executeCompare(pc,sql,qr, expression, row)==0)?Boolean.TRUE:Boolean.FALSE; } /** * * execute a not equal operation * @param sql * @param qr QueryResult to execute on it * @param expression * @param row row of resultset to execute * @return result * @throws PageException */ private Object executeNEQ(PageContext pc,SQL sql,Query qr, Operation2 expression, int row) throws PageException { return (executeCompare(pc,sql,qr, expression, row)!=0)?Boolean.TRUE:Boolean.FALSE; } /** * * execute a less than operation * @param sql * @param qr QueryResult to execute on it * @param expression * @param row row of resultset to execute * @return result * @throws PageException */ private Object executeLT(PageContext pc,SQL sql,Query qr, Operation2 expression, int row) throws PageException { return (executeCompare(pc,sql,qr, expression, row)<0)?Boolean.TRUE:Boolean.FALSE; } /** * * execute a less than or equal operation * @param sql * @param qr QueryResult to execute on it * @param expression * @param row row of resultset to execute * @return result * @throws PageException */ private Object executeLTE(PageContext pc,SQL sql,Query qr, Operation2 expression, int row) throws PageException { return (executeCompare(pc,sql,qr, expression, row)<=0)?Boolean.TRUE:Boolean.FALSE; } /** * * execute a greater than operation * @param sql * @param qr QueryResult to execute on it * @param expression * @param row row of resultset to execute * @return result * @throws PageException */ private Object executeGT(PageContext pc,SQL sql,Query qr, Operation2 expression, int row) throws PageException { return (executeCompare(pc,sql,qr, expression, row)>0)?Boolean.TRUE:Boolean.FALSE; } /** * * execute a greater than or equal operation * @param sql * @param qr QueryResult to execute on it * @param expression * @param row row of resultset to execute * @return result * @throws PageException */ private Object executeGTE(PageContext pc,SQL sql,Query qr, Operation2 expression, int row) throws PageException { return (executeCompare(pc,sql,qr, expression, row)>=0)?Boolean.TRUE:Boolean.FALSE; } /** * * execute a equal operation * @param sql * @param qr QueryResult to execute on it * @param op * @param row row of resultset to execute * @return result * @throws PageException */ private int executeCompare(PageContext pc, SQL sql, Query qr, Operation2 op, int row) throws PageException { //print.e(op.getLeft().getClass().getName()); return Operator.compare(executeExp(pc,sql,qr,op.getLeft(),row),executeExp(pc,sql,qr,op.getRight(),row)); } private Object executeMod(PageContext pc,SQL sql,Query qr, Operation2 expression, int row) throws PageException { return Caster.toDouble( Caster.toDoubleValue(executeExp(pc,sql,qr,expression.getLeft(),row))% Caster.toDoubleValue(executeExp(pc,sql,qr,expression.getRight(),row))); } /** * * execute a greater than or equal operation * @param sql * @param qr QueryResult to execute on it * @param expression * @param row row of resultset to execute * @return result * @throws PageException */ private Boolean executeIn(PageContext pc,SQL sql,Query qr, OperationN expression, int row, boolean isNot) throws PageException { Expression[] operators = expression.getOperants(); Object left=executeExp(pc,sql,qr,operators[0],row); for(int i=1;i<operators.length;i++) { if(Operator.compare(left,executeExp(pc,sql,qr,operators[i],row))==0) return isNot?Boolean.FALSE:Boolean.TRUE; } return isNot?Boolean.TRUE:Boolean.FALSE; } /** * * execute a minus operation * @param sql * @param qr QueryResult to execute on it * @param expression * @param row row of resultset to execute * @return result * @throws PageException */ private Object executeMinus(PageContext pc,SQL sql,Query qr, Operation2 expression, int row) throws PageException { return new Double( Caster.toDoubleValue(executeExp(pc,sql,qr,expression.getLeft(),row)) - Caster.toDoubleValue(executeExp(pc,sql,qr,expression.getRight(),row)) ); } /** * * execute a divide operation * @param sql * @param qr QueryResult to execute on it * @param expression * @param row row of resultset to execute * @return result * @throws PageException */ private Object executeDivide(PageContext pc,SQL sql,Query qr, Operation2 expression, int row) throws PageException { return new Double( Caster.toDoubleValue(executeExp(pc,sql,qr,expression.getLeft(),row)) / Caster.toDoubleValue(executeExp(pc,sql,qr,expression.getRight(),row)) ); } /** * * execute a multiply operation * @param sql * @param qr QueryResult to execute on it * @param expression * @param row row of resultset to execute * @return result * @throws PageException */ private Object executeMultiply(PageContext pc,SQL sql,Query qr, Operation2 expression, int row) throws PageException { return new Double( Caster.toDoubleValue(executeExp(pc,sql,qr,expression.getLeft(),row)) * Caster.toDoubleValue(executeExp(pc,sql,qr,expression.getRight(),row)) ); } /** * * execute a multiply operation * @param sql * @param qr QueryResult to execute on it * @param expression * @param row row of resultset to execute * @return result * @throws PageException */ private Object executeExponent(PageContext pc,SQL sql,Query qr, Operation2 expression, int row) throws PageException { return Integer.valueOf( Caster.toIntValue(executeExp(pc,sql,qr,expression.getLeft(),row)) ^ Caster.toIntValue(executeExp(pc,sql,qr,expression.getRight(),row)) ); } /** * * execute a plus operation * @param sql * @param qr QueryResult to execute on it * @param expression * @param row row of resultset to execute * @return result * @throws PageException */ private Object executePlus(PageContext pc,SQL sql,Query qr, Operation2 expression, int row) throws PageException { Object left=executeExp(pc,sql,qr,expression.getLeft(),row); Object right=executeExp(pc,sql,qr,expression.getRight(),row); try { return new Double(Caster.toDoubleValue(left)+Caster.toDoubleValue(right)); } catch (PageException e) { return Caster.toString(left)+Caster.toString(right); } } /** * * execute a between operation * @param sql * @param qr QueryResult to execute on it * @param expression * @param row row of resultset to execute * @return result * @throws PageException */ private Object executeBetween(PageContext pc,SQL sql,Query qr, Operation3 expression, int row) throws PageException { Object left=executeExp(pc,sql,qr,expression.getExp(),row); Object right1=executeExp(pc,sql,qr,expression.getLeft(),row); Object right2=executeExp(pc,sql,qr,expression.getRight(),row); //print.out(left+" between "+right1+" and "+right2 // +" = "+((Operator.compare(left,right1)>=0)+" && "+(Operator.compare(left,right2)<=0))); return ( (Operator.compare(left,right1)>=0) && (Operator.compare(left,right2)<=0) )?Boolean.TRUE:Boolean.FALSE; } private Object executeLike(PageContext pc,SQL sql,Query qr, Operation3 expression, int row) throws PageException { return LikeCompare.like(sql, Caster.toString(executeExp(pc,sql,qr,expression.getExp(),row)), Caster.toString(executeExp(pc,sql,qr,expression.getLeft(),row)), Caster.toString(executeExp(pc,sql,qr,expression.getRight(),row)))?Boolean.TRUE:Boolean.FALSE; } private boolean executeLike(PageContext pc,SQL sql,Query qr, Operation2 expression, int row) throws PageException { return LikeCompare.like(sql, Caster.toString(executeExp(pc,sql,qr,expression.getLeft(),row)), Caster.toString(executeExp(pc,sql,qr,expression.getRight(),row))); } /** * Executes a constant value * @param sql * @param qr * @param column * @param row * @return result * @throws PageException */ private Object executeColumn(SQL sql, Query qr, Column column, int row) throws PageException { if(column.getColumn().equals("?")) { int pos=column.getColumnIndex(); if(sql.getItems().length<=pos) throw new DatabaseException("invalid syntax for SQL Statement",null,sql,null); return sql.getItems()[pos].getValueForCF(); } return column.getValue(qr, row); //return qr.getAt(column.getColumn(),row); } private Object executeColumn(SQL sql,Query qr, Column column, int row, Object defaultValue) throws PageException { if(column.getColumn().equals("?")) { int pos=column.getColumnIndex(); if(sql.getItems().length<=pos) throw new DatabaseException("invalid syntax for SQL Statement",null,sql,null); return sql.getItems()[pos].getValueForCF(); } return column.getValue(qr, row,defaultValue); } }