📄 expressionarithmetic.java
字号:
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( leftStr, right2.getString() );
case ADD: return Utils.string2boolean(leftStr + rightStr);
}
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:
case BIT_NOT:
return left.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 left.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; //Boolean operations return ever a result ???, but at least ISNULL and ISNOTNULL
case NEGATIVE:
case BIT_NOT:
return left.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 ){
int type = left == null ? right.getDataType() : getDataType(left, right);
return Utils.createSQLException("Unsupported conversion to data type '" +
SQLTokenizer.getKeyWord(dataType) +
"' from data type '" +
SQLTokenizer.getKeyWord(type) +
"' for Operation '" + getKeywordFromOperation(operation)+'\'');
}
void optimize() throws SQLException{
super.optimize();
Expression[] params = getParams();
if(params.length == 1){
return;
}
setParamAt( convertExpressionIfNeeded( params[0], params[1] ), 0 );
for(int p=1; p<params.length; p++){
setParamAt( convertExpressionIfNeeded( params[p], left ), p );
}
}
/**
* This method only for creating an error message. Thats there is no optimizing.
* @param value
* @return
*/
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;
}
}
/**
* Returns the higher level data type from 2 expressions.
*/
static int getDataType(Expression left, Expression right){
int typeLeft = left.getDataType();
int typeRight = right.getDataType();
return getDataType( typeLeft, typeRight);
}
/**
* Return the best data type for a complex number operation. This method return only
* SQLTokenizer.INT,
* SQLTokenizer.BIGINT,
* SQLTokenizer.MONEY,
* SQLTokenizer.DECIMAL or
* SQLTokenizer.DOUBLE.
* @param paramDataType
*/
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;
}
/**
* Returns the higher level data type from 2 data types.
*/
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 ];
}
// value decade is the operation order
static final int OR = 11; // OR
static final int AND = 21; // AND
static final int NOT = 31; // NOT
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; // like Equals but (null = null) --> true
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; // IN
static final int BETWEEN = 62; // BETWEEN
static final int LIKE = 63; // LIKE
static final int ISNULL = 64; // IS NULL
static final int ISNOTNULL = ISNULL+1; // IS NOT NULL
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);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -