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

📄 expressionarithmetic.java

📁 java 数据库 功能强大 效率高 SmallSQL Database is a free DBMS library for the Java(tm) platform. It runs on
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
                    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 + -