*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
* ---------------
* ExpressionArithmethic.java
* ---------------
* Author: Volker Berlin
*
*/
package smallsql.database;
import java.sql.*;
public class ExpressionArithmetic extends Expression {
private Expression left;
private Expression right;
private Expression right2;
private Expression[] inList;
final private int operation;
ExpressionArithmetic( Expression right, int operation){
super(FUNCTION);
this.right = right;
this.operation = operation;
super.setParams( new Expression[]{ right });
}
ExpressionArithmetic( Expression left, Expression right, int operation){
super(FUNCTION);
this.left = left;
this.right = right;
this.operation = operation;
super.setParams( new Expression[]{ left, right });
}
ExpressionArithmetic( Expression left, Expression right, Expression right2, int operation){
super(FUNCTION);
this.left = left;
this.right = right;
this.right2 = right2;
this.operation = operation;
super.setParams( new Expression[]{ left, right, right2 });
}
ExpressionArithmetic( Expression left, Expressions inList, int operation){
super(FUNCTION);
this.left = left;
this.operation = operation;
Expression[] params;
if(inList != null){
this.inList = inList.toArray();
params = new Expression[this.inList.length+1];
params[0] = left;
System.arraycopy(this.inList, 0, params, 1, this.inList.length);
}else{
params = new Expression[]{ left };
}
super.setParams( params );
}
final void setParamAt( Expression param, int idx){
switch(idx){
case 0:
left = param;
break;
case 1:
right = param;
break;
case 2:
right2 = param;
break;
}
if(inList != null && idx>0 && idx<=inList.length){
inList[idx+1] = param;
}
super.setParamAt( param, idx );
}
public boolean equals(Object expr){
if(!super.equals(expr)) return false;
if(!(expr instanceof ExpressionArithmetic)) return false;
if( ((ExpressionArithmetic)expr).operation != operation) return false;
return true;
}
int getInt() throws java.lang.Exception {
if(isNull()) return 0;
int dataType = getDataType();
switch(dataType){
case SQLTokenizer.BIT:
case SQLTokenizer.BOOLEAN:
return getBoolean() ? 1 : 0;
case SQLTokenizer.TINYINT:
case SQLTokenizer.SMALLINT:
case SQLTokenizer.INT:
return getIntImpl();
case SQLTokenizer.BIGINT:
return (int)getLongImpl();
case SQLTokenizer.REAL:
return (int)getFloatImpl();
case SQLTokenizer.FLOAT:
case SQLTokenizer.DOUBLE:
case SQLTokenizer.MONEY:
case SQLTokenizer.SMALLMONEY:
case SQLTokenizer.NUMERIC:
case SQLTokenizer.DECIMAL:
return (int)getDoubleImpl();
}
throw createUnspportedConversion( SQLTokenizer.INT);
}
private int getIntImpl() throws java.lang.Exception {
switch(operation){
case ADD: return left.getInt() + right.getInt();
case SUB: return left.getInt() - right.getInt();
case MUL: return left.getInt() * right.getInt();
case DIV: return left.getInt() / right.getInt();
case NEGATIVE: return - right.getInt();
case MOD: return left.getInt() % right.getInt();
}
throw createUnspportedConversion( SQLTokenizer.INT);
}
long getLong() throws java.lang.Exception {
if(isNull()) return 0;
int dataType = getDataType();
switch(dataType){
case SQLTokenizer.BIT:
case SQLTokenizer.BOOLEAN:
return getBoolean() ? 1 : 0;
case SQLTokenizer.TINYINT:
case SQLTokenizer.SMALLINT:
case SQLTokenizer.INT:
return getIntImpl();
case SQLTokenizer.BIGINT:
return getLongImpl();
case SQLTokenizer.REAL:
return (long)getFloatImpl();
case SQLTokenizer.FLOAT:
case SQLTokenizer.DOUBLE:
case SQLTokenizer.MONEY:
case SQLTokenizer.SMALLMONEY:
case SQLTokenizer.NUMERIC:
case SQLTokenizer.DECIMAL:
return (long)getDoubleImpl();
}
throw createUnspportedConversion( SQLTokenizer.LONG);
}
private long getLongImpl() throws java.lang.Exception {
if(isNull()) return 0;
switch(operation){
case ADD: return left.getLong() + right.getLong();
case SUB: return left.getLong() - right.getLong();
case MUL: return left.getLong() * right.getLong();
case DIV: return left.getLong() / right.getLong();
case NEGATIVE: return - right.getLong();
case MOD: return left.getLong() % right.getLong();
}
throw createUnspportedConversion( SQLTokenizer.LONG);
}
double getDouble() throws java.lang.Exception {
if(isNull()) return 0;
int dataType = getDataType();
switch(dataType){
case SQLTokenizer.BIT:
case SQLTokenizer.BOOLEAN:
return getBoolean() ? 1 : 0;
case SQLTokenizer.TINYINT:
case SQLTokenizer.SMALLINT:
case SQLTokenizer.INT:
return getIntImpl();
case SQLTokenizer.BIGINT:
return getLongImpl();
case SQLTokenizer.REAL:
return getFloatImpl();
case SQLTokenizer.FLOAT:
case SQLTokenizer.DOUBLE:
case SQLTokenizer.MONEY:
case SQLTokenizer.SMALLMONEY:
case SQLTokenizer.NUMERIC:
case SQLTokenizer.DECIMAL:
return getDoubleImpl();
}
throw createUnspportedConversion( SQLTokenizer.DOUBLE);
}
private double getDoubleImpl() throws java.lang.Exception{
if(operation == NEGATIVE)
return getDoubleImpl(0, right.getDouble());
return getDoubleImpl(left.getDouble(), right.getDouble());
}
private double getDoubleImpl( double lVal, double rVal) throws java.lang.Exception{
switch(operation){
case ADD: return lVal + rVal;
case SUB: return lVal - rVal;
case MUL: return lVal * rVal;
case DIV: return lVal / rVal;
case NEGATIVE: return - rVal;
case MOD: return lVal % rVal;
}
throw createUnspportedConversion( SQLTokenizer.DOUBLE);
}
float getFloat() throws java.lang.Exception {
if(isNull()) return 0;
int dataType = getDataType();
switch(dataType){
case SQLTokenizer.BIT:
case SQLTokenizer.BOOLEAN:
return getBoolean() ? 1 : 0;
case SQLTokenizer.TINYINT:
case SQLTokenizer.SMALLINT:
case SQLTokenizer.INT:
return getIntImpl();
case SQLTokenizer.BIGINT:
return getLongImpl();
case SQLTokenizer.REAL:
return getFloatImpl();
case SQLTokenizer.FLOAT:
case SQLTokenizer.DOUBLE:
case SQLTokenizer.MONEY:
case SQLTokenizer.SMALLMONEY:
case SQLTokenizer.NUMERIC:
case SQLTokenizer.DECIMAL:
return (float)getDoubleImpl();
}
throw createUnspportedConversion( SQLTokenizer.DOUBLE);
}
private float getFloatImpl() throws java.lang.Exception {
switch(operation){
case ADD: return left.getFloat() + right.getFloat();
case SUB: return left.getFloat() - right.getFloat();
case MUL: return left.getFloat() * right.getFloat();
case DIV: return left.getFloat() / right.getFloat();
case NEGATIVE: return - right.getFloat();
case MOD: return left.getFloat() % right.getFloat();
}
throw createUnspportedConversion( SQLTokenizer.REAL );
}
long getMoney() throws java.lang.Exception {
if(isNull()) return 0;
int dataType = getDataType();
switch(dataType){
case SQLTokenizer.BIT:
case SQLTokenizer.BOOLEAN:
return getBoolean() ? 10000 : 0;
case SQLTokenizer.TINYINT:
case SQLTokenizer.SMALLINT:
case SQLTokenizer.INT:
return getIntImpl() * 10000;
case SQLTokenizer.BIGINT:
return getLongImpl() * 10000;
case SQLTokenizer.REAL:
return Utils.doubleToMoney( getFloatImpl() );
case SQLTokenizer.FLOAT:
case SQLTokenizer.DOUBLE:
case SQLTokenizer.NUMERIC:
case SQLTokenizer.DECIMAL:
return Utils.doubleToMoney( getDoubleImpl() );
case SQLTokenizer.MONEY:
case SQLTokenizer.SMALLMONEY:
return getMoneyImpl();
}
throw createUnspportedConversion( SQLTokenizer.DOUBLE);
}
private long getMoneyImpl() throws java.lang.Exception {
switch(operation){
case ADD: return left.getMoney() + right.getMoney();
case SUB: return left.getMoney() - right.getMoney();
case MUL: return left.getMoney() * right.getMoney() / 10000;
case DIV: return left.getMoney() * 10000 / right.getMoney();
case NEGATIVE: return - right.getMoney();
}
throw createUnspportedConversion( SQLTokenizer.MONEY );
}
MutableNumeric getNumeric() throws java.lang.Exception {
if(isNull()) return null;
int dataType = getDataType();
switch(dataType){
case SQLTokenizer.BIT:
case SQLTokenizer.BOOLEAN:
return new MutableNumeric(getBoolean() ? 1 : 0);
case SQLTokenizer.TINYINT:
case SQLTokenizer.SMALLINT:
case SQLTokenizer.INT:
return new MutableNumeric(getIntImpl());
case SQLTokenizer.BIGINT:
return new MutableNumeric(getLongImpl());
case SQLTokenizer.REAL:
return new MutableNumeric(getFloatImpl());
case SQLTokenizer.FLOAT:
case SQLTokenizer.DOUBLE:
return new MutableNumeric( getDoubleImpl() );
case SQLTokenizer.NUMERIC:
case SQLTokenizer.DECIMAL:
return getNumericImpl();
case SQLTokenizer.MONEY:
case SQLTokenizer.SMALLMONEY:
return new MutableNumeric(getMoneyImpl(),4);
}
throw createUnspportedConversion( SQLTokenizer.DOUBLE);
}
private MutableNumeric getNumericImpl() throws java.lang.Exception {
switch(operation){
case ADD:
{
MutableNumeric num = left.getNumeric();
num.add( right.getNumeric() );
return num;
}
case SUB:
{
MutableNumeric num = left.getNumeric();
num.sub( right.getNumeric() );
return num;
}
case MUL:
if(getDataType(right.getDataType(), SQLTokenizer.INT) == SQLTokenizer.INT){
MutableNumeric num = left.getNumeric();
num.mul(right.getInt());
return num;
}else
if(getDataType(left.getDataType(), SQLTokenizer.INT) == SQLTokenizer.INT){
MutableNumeric num = right.getNumeric();
num.mul(left.getInt());
return num;
}else{
MutableNumeric num = left.getNumeric();
num.mul( right.getNumeric() );
return num;
}
case DIV:
{
MutableNumeric num = left.getNumeric();
if(getDataType(right.getDataType(), SQLTokenizer.INT) == SQLTokenizer.INT)
num.div( right.getInt() );
else
num.div( right.getNumeric() );
return num;
}
case NEGATIVE:
{
MutableNumeric num = right.getNumeric();
num.signum = -num.signum;
return num;
}
case MOD:
{
if(getDataType(getDataType(), SQLTokenizer.INT) == SQLTokenizer.INT)
return new MutableNumeric(getInt());
MutableNumeric num = left.getNumeric();
num.mod( right.getNumeric() );
return num;
}
default: throw createUnspportedConversion( SQLTokenizer.NUMERIC );
}
}
Object getObject() throws java.lang.Exception {
if(isNull()) return null;
int dataType = getDataType();
switch(dataType){
case SQLTokenizer.BIT:
case SQLTokenizer.BOOLEAN:
return getBoolean() ? Boolean.TRUE : Boolean.FALSE;
case SQLTokenizer.BINARY:
case SQLTokenizer.VARBINARY:
return getBytes();
case SQLTokenizer.TINYINT:
case SQLTokenizer.SMALLINT:
case SQLTokenizer.INT:
return new Integer( getInt() );
case SQLTokenizer.BIGINT:
return new Long( getLong() );
case SQLTokenizer.REAL:
return new Float( getFloat() );
case SQLTokenizer.FLOAT:
case SQLTokenizer.DOUBLE:
return new Double( getDouble() );
case SQLTokenizer.MONEY:
case SQLTokenizer.SMALLMONEY:
return Money.createFromUnscaledValue( getMoney() );
case SQLTokenizer.NUMERIC:
case SQLTokenizer.DECIMAL:
return getNumeric();
case SQLTokenizer.CHAR:
case SQLTokenizer.NCHAR:
case SQLTokenizer.VARCHAR:
case SQLTokenizer.NVARCHAR:
case SQLTokenizer.LONGNVARCHAR:
case SQLTokenizer.LONGVARCHAR:
return getString( left.getString(), right.getString() );
case SQLTokenizer.JAVA_OBJECT:
Object lObj = left.getObject();
Object rObj = right.getObject();
if(lObj instanceof Number && rObj instanceof Number)
return new Double( getDoubleImpl( ((Number)lObj).doubleValue(), ((Number)rObj).doubleValue() ) );
else
return getString( lObj.toString(), rObj.toString() );
case SQLTokenizer.LONGVARBINARY:
return getBytes();
case SQLTokenizer.DATE:
return DateTime.getDate( getLong() );
case SQLTokenizer.TIME:
return DateTime.getTime( getLong() );
case SQLTokenizer.TIMESTAMP:
case SQLTokenizer.SMALLDATETIME:
return DateTime.getTimestamp( getLong() );
case SQLTokenizer.UNIQUEIDENTIFIER:
return getBytes();
default: throw createUnspportedDataType();
}
}
boolean getBoolean() throws java.lang.Exception {
switch(operation){
case OR: return left.getBoolean() || right.getBoolean();
case AND: return left.getBoolean() && right.getBoolean();
case NOT: return !right.getBoolean();
case LIKE: return Utils.like( left.getString(), right.getString());
case ISNULL:return right.isNull();
case ISNOTNULL: return !right.isNull();
case IN: if(right == null)
return isInList();
break;
}
final boolean rightIsNull = right.isNull();
int dataType;
if(operation == NEGATIVE){
if(rightIsNull) return false;
dataType = right.getDataType();
}else{
final boolean leftIsNull = left.isNull();
if(operation == EQUALS_NULL && leftIsNull && rightIsNull) return true;
if(leftIsNull || rightIsNull) return false;
dataType = getDataType(left, right);
}
switch(dataType){
case SQLTokenizer.BOOLEAN:
switch(operation){
case IN:
case EQUALS_NULL:
case EQUALS: return left.getBoolean() == right.getBoolean();
case UNEQUALS: return left.getBoolean() != right.getBoolean();
}
case SQLTokenizer.TINYINT:
case SQLTokenizer.SMALLINT:
case SQLTokenizer.INT:
case SQLTokenizer.BIT:
switch(operation){
case IN:
case EQUALS_NULL:
case EQUALS: return left.getInt() == right.getInt();
case GREATER: return left.getInt() > right.getInt();
case GRE_EQU: return left.getInt() >= right.getInt();
case LESSER: return left.getInt() < right.getInt();
case LES_EQU: return left.getInt() <= right.getInt();
case UNEQUALS: return left.getInt() != right.getInt();
case BETWEEN:
int _left = left.getInt();
return _left >= right.getInt() && right2.getInt() >= _left;
default:
return getInt() != 0;
}
case SQLTokenizer.BIGINT:
case SQLTokenizer.TIMESTAMP:
case SQLTokenizer.TIME:
case SQLTokenizer.DATE:
case SQLTokenizer.SMALLDATETIME:
switch(operation){
case IN:
case EQUALS_NULL:
case EQUALS: return left.getLong() == right.getLong();
case GREATER: return left.getLong() > right.getLong();
case GRE_EQU: return left.getLong() >= right.getLong();
case LESSER: return left.getLong() < right.getLong();
case LES_EQU: return left.getLong() <= right.getLong();
case UNEQUALS: return left.getLong() != right.getLong();
case BETWEEN:
long _left = left.getLong();
return _left >= right.getLong() && right2.getLong() >= _left;
default:
return getLong() != 0;
}
case SQLTokenizer.REAL:
switch(operation){
case IN:
case EQUALS_NULL:
case EQUALS: return left.getFloat() == right.getFloat();
case GREATER: return left.getFloat() > right.getFloat();
case GRE_EQU: return left.getFloat() >= right.getFloat();
case LESSER: return left.getFloat() < right.getFloat();
case LES_EQU: return left.getFloat() <= right.getFloat();
case UNEQUALS: return left.getFloat() != right.getFloat();
case BETWEEN:
float _left = left.getFloat();
return _left >= right.getFloat() && right2.getFloat() >= _left;
default:
return getFloat() != 0;
}
case SQLTokenizer.FLOAT:
case SQLTokenizer.DOUBLE:
switch(operation){
case IN:
case EQUALS_NULL:
case EQUALS: return left.getDouble() == right.getDouble();
case GREATER: return left.getDouble() > right.getDouble();
case GRE_EQU: return left.getDouble() >= right.getDouble();
case LESSER: return left.getDouble() < right.getDouble();
case LES_EQU: return left.getDouble() <= right.getDouble();
case UNEQUALS: return left.getDouble() != right.getDouble();
case BETWEEN:
double _left = left.getDouble();
return _left >= right.getDouble() && right2.getDouble() >= _left;
default:
return getDouble() != 0;
}
case SQLTokenizer.MONEY:
case SQLTokenizer.SMALLMONEY:
switch(operation){
case IN:
case EQUALS_NULL:
case EQUALS: return left.getMoney() == right.getMoney();
case GREATER: return left.getMoney() > right.getMoney();
case GRE_EQU: return left.getMoney() >= right.getMoney();
case LESSER: return left.getMoney() < right.getMoney();
case LES_EQU: return left.getMoney() <= right.getMoney();
case UNEQUALS: return left.getMoney() != right.getMoney();
case BETWEEN:
long _left = left.getMoney();
return _left >= right.getMoney() && right2.getMoney() >= _left;
default:
return getMoney() != 0;
}
case SQLTokenizer.DECIMAL:
case SQLTokenizer.NUMERIC:{
if(operation == NEGATIVE)
return right.getNumeric().signum != 0;
int comp = left.getNumeric().compareTo( right.getNumeric() );
switch(operation){
case IN:
case EQUALS_NULL:
case EQUALS: return comp == 0;
case GREATER: return comp > 0;
case GRE_EQU: return comp >= 0;
case LESSER: return comp < 0;
case LES_EQU: return comp <= 0;
case UNEQUALS: return comp != 0;
case BETWEEN:
return comp >= 0 && 0 >= left.getNumeric().compareTo( right2.getNumeric() );
default:
return getNumeric().signum != 0;
}
}
case SQLTokenizer.VARCHAR:
case SQLTokenizer.NVARCHAR:
case SQLTokenizer.CHAR:
case SQLTokenizer.NCHAR:
case SQLTokenizer.LONGVARCHAR:
case SQLTokenizer.LONGNVARCHAR:
case SQLTokenizer.CLOB:{
int comp = String.CASE_INSENSITIVE_ORDER.compare( left.getString(), right.getString() );
switch(operation){
case IN:
case EQUALS_NULL:
case EQUALS: return comp == 0;
case GREATER: return comp > 0;
case GRE_EQU: return comp >= 0;
case LESSER: return comp < 0;
case LES_EQU: return comp <= 0;
case UNEQUALS: return comp != 0;
case BETWEEN:
return comp >= 0 && 0 >= String.CASE_INSENSITIVE_ORDER.compare( left.getString(), right2.getString() );
}
break;}
case SQLTokenizer.BINARY:
case SQLTokenizer.VARBINARY:
case SQLTokenizer.LONGVARBINARY:
case SQLTokenizer.BLOB:
case SQLTokenizer.UNIQUEIDENTIFIER:{
byte[] leftBytes = left.getBytes();
byte[] rightBytes= right.getBytes();
int comp = Utils.compareBytes( leftBytes, rightBytes);
switch(operation){
case IN:
case EQUALS_NULL:
case EQUALS: return comp == 0;
case GREATER: return comp > 0;
case GRE_EQU: return comp >= 0;
case LESSER: return comp < 0;
case LES_EQU: return comp <= 0;
case UNEQUALS: return comp != 0;
case BETWEEN:
return comp >= 0 && 0 >= Utils.compareBytes( leftBytes, right2.getBytes() );
}
break;}
}
throw createUnspportedDataType();
}
String getString() throws java.lang.Exception {
if(isNull()) return null;
return getObject().toString();
}
final private String getString( String lVal, String rVal ) throws java.lang.Exception {
switch(operation){
case ADD: return lVal + rVal;
}
throw createUnspportedConversion( SQLTokenizer.VARCHAR );
}
int getDataType() {
switch(operation){
case NEGATIVE:
return right.getDataType();
case EQUALS:
case EQUALS_NULL:
case GREATER:
case GRE_EQU:
case LESSER:
case LES_EQU:
case UNEQUALS:
case BETWEEN:
case OR:
case AND:
case NOT:
case LIKE:
case ISNULL:
case ISNOTNULL:
return SQLTokenizer.BOOLEAN;
default:
return getDataType(left, right);
}
}
int getScale(){
int dataType = getDataType();
switch(dataType){
case SQLTokenizer.DECIMAL:
case SQLTokenizer.NUMERIC:
switch(operation){
case ADD:
case SUB:
return Math.max(left.getScale(), right.getScale());
case MUL:
return left.getScale() + right.getScale();
case DIV:
return Math.max(left.getScale()+5, right.getScale()+4);
case NEGATIVE:
return right.getScale();
case MOD:
return 0;
}
}
return getScale(dataType);
}
boolean isNull() throws Exception{
switch(operation){
case OR:
case AND:
case NOT:
case LIKE:
case ISNULL:
case ISNOTNULL:
case IN:
return false; case NEGATIVE: return right.isNull();
default: return left.isNull() || right.isNull();
}
}
byte[] getBytes() throws java.lang.Exception {
throw createUnspportedConversion( SQLTokenizer.BINARY );
}
boolean isInList() throws Exception{
if(left.isNull()) return false;
try{
for(int i=0; i<inList.length; i++){
right = inList[i];
if(getBoolean()) return true;
}
}finally{
right = null;
}
return false;
}
SQLException createUnspportedDataType(){
return Utils.createSQLException("Unsupported data type '" +
SQLTokenizer.getKeyWord(getDataType(left, right)) +
"' for Operation '" + getKeywordFromOperation(operation)+'\'');
}
SQLException createUnspportedConversion( int dataType ){
return Utils.createSQLException("Unsupported conversion to data type '" +
SQLTokenizer.getKeyWord(dataType) +
"' from data type '" +
SQLTokenizer.getKeyWord(getDataType(left, right)) +
"' for Operation '" + getKeywordFromOperation(operation)+'\'');
}
private static String getKeywordFromOperation(int operation){
int token = 0;
for(int i=1; i<1000; i++){
if(getOperationFromToken(i) == operation){
token = i;
break;
}
}
if(operation == NEGATIVE) token = SQLTokenizer.MINUS;
if(operation == ISNOTNULL) token = SQLTokenizer.IS;
String keyword = SQLTokenizer.getKeyWord(token);
if(keyword == null) keyword = "" + (char)token;
return keyword;
}
static int getOperationFromToken( int value ){
switch(value){
case SQLTokenizer.PLUS: return ADD;
case SQLTokenizer.MINUS: return SUB;
case SQLTokenizer.ASTERISK: return MUL;
case SQLTokenizer.SLACH: return DIV;
case SQLTokenizer.PERCENT: return MOD;
case SQLTokenizer.EQUALS: return EQUALS;
case SQLTokenizer.GREATER: return GREATER;
case SQLTokenizer.GREATER_EQU: return GRE_EQU;
case SQLTokenizer.LESSER: return LESSER;
case SQLTokenizer.LESSER_EQU: return LES_EQU;
case SQLTokenizer.UNEQUALS: return UNEQUALS;
case SQLTokenizer.BETWEEN: return BETWEEN;
case SQLTokenizer.LIKE: return LIKE;
case SQLTokenizer.IN: return IN;
case SQLTokenizer.IS: return ISNULL;
case SQLTokenizer.OR: return OR;
case SQLTokenizer.AND: return AND;
case SQLTokenizer.NOT: return NOT;
case SQLTokenizer.BIT_OR: return BIT_OR;
case SQLTokenizer.BIT_AND: return BIT_AND;
case SQLTokenizer.BIT_XOR: return BIT_XOR;
case SQLTokenizer.TILDE: return BIT_NOT;
default: return 0;
}
}
static int getDataType(Expression left, Expression right){
int typeLeft = left.getDataType();
int typeRight = right.getDataType();
return getDataType( typeLeft, typeRight);
}
static int getBestNumberDataType(int paramDataType){
int dataTypeIdx = Utils.indexOf( paramDataType, DatatypeRange);
if(dataTypeIdx >= NVARCHAR_IDX)
return SQLTokenizer.DOUBLE;
if(dataTypeIdx >= INT_IDX)
return SQLTokenizer.INT;
if(dataTypeIdx >= BIGINT_IDX)
return SQLTokenizer.BIGINT;
if(dataTypeIdx >= MONEY_IDX)
return SQLTokenizer.MONEY;
if(dataTypeIdx >= DECIMAL_IDX)
return SQLTokenizer.DECIMAL;
return SQLTokenizer.DOUBLE;
}
static int getDataType(int typeLeft, int typeRight){
if(typeLeft == typeRight) return typeLeft;
int dataTypeIdx = Math.min( Utils.indexOf( typeLeft, DatatypeRange), Utils.indexOf( typeRight, DatatypeRange) );
if(dataTypeIdx < 0) throw new Error("getDataType(): "+typeLeft+", "+typeRight);
return DatatypeRange[ dataTypeIdx ];
}
static final int OR = 11; static final int AND = 21; static final int NOT = 31; static final int BIT_OR = 41; static final int BIT_AND = 42; static final int BIT_XOR = 43; static final int EQUALS = 51; static final int EQUALS_NULL= 52; static final int GREATER = 53; static final int GRE_EQU = 54; static final int LESSER = 55; static final int LES_EQU = 56; static final int UNEQUALS = 57; static final int IN = 61; static final int BETWEEN = 62; static final int LIKE = 63; static final int ISNULL = 64; static final int ISNOTNULL = ISNULL+1; static final int ADD = 71; static final int SUB = 72; static final int MUL = 81; static final int DIV = 82; static final int MOD = 83; static final int BIT_NOT = 91; static final int NEGATIVE =101;
private static final int[] DatatypeRange = {
SQLTokenizer.TIMESTAMP,
SQLTokenizer.SMALLDATETIME,
SQLTokenizer.DATE,
SQLTokenizer.TIME,
SQLTokenizer.DOUBLE,
SQLTokenizer.FLOAT,
SQLTokenizer.REAL,
SQLTokenizer.DECIMAL,
SQLTokenizer.NUMERIC,
SQLTokenizer.MONEY,
SQLTokenizer.SMALLMONEY,
SQLTokenizer.BIGINT,
SQLTokenizer.INT,
SQLTokenizer.SMALLINT,
SQLTokenizer.TINYINT,
SQLTokenizer.BIT,
SQLTokenizer.BOOLEAN,
SQLTokenizer.LONGNVARCHAR,
SQLTokenizer.UNIQUEIDENTIFIER,
SQLTokenizer.NVARCHAR,
SQLTokenizer.NCHAR,
SQLTokenizer.VARCHAR,
SQLTokenizer.CHAR,
SQLTokenizer.LONGVARCHAR,
SQLTokenizer.CLOB,
SQLTokenizer.VARBINARY,
SQLTokenizer.BINARY,
SQLTokenizer.LONGVARBINARY,
SQLTokenizer.BLOB,
SQLTokenizer.NULL};
private static int NVARCHAR_IDX = Utils.indexOf( SQLTokenizer.NVARCHAR, DatatypeRange);
private static int INT_IDX = Utils.indexOf( SQLTokenizer.INT, DatatypeRange);
private static int BIGINT_IDX = Utils.indexOf( SQLTokenizer.BIGINT, DatatypeRange);
private static int MONEY_IDX = Utils.indexOf( SQLTokenizer.MONEY, DatatypeRange);
private static int DECIMAL_IDX = Utils.indexOf( SQLTokenizer.DECIMAL, DatatypeRange);
}