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

📄 sqlparser.java

📁 java 数据库 功能强大 效率高 SmallSQL Database is a free DBMS library for the Java(tm) platform. It runs on
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
        if(token.value != SQLTokenizer.PARENTHESIS_L) throw createSyntaxError(token, MISSING_PARENTHESIS_L );
        Loop:
        while(true){
            int offset = token.offset + token.length;
            token = nextToken();
            if(token != null) offset = token.offset;
            previousToken();  
            
            expressions.add( expression(cmd, 0) );
            SQLToken last = lastToken();
            int length = last.offset + last.length - offset;
            columns.add( new String( sql, offset, length ) );

            token = nextToken(MISSING_COMMA_PARENTHESIS);
            switch(token.value){
                case SQLTokenizer.PARENTHESIS_R:
                    break Loop;
                case SQLTokenizer.COMMA:
                    continue;
                default:
                    throw new Error();
            }
        }
    }
    

	/**
	 * Read a complex expression that can be build from multiple atomic expressions.
     * @param cmd is needed to add parameters "?" with addParameter() 
	 * @param previousOperationLevel the level of the left operation.
	 */
    private Expression expression(Command cmd, int previousOperationLevel) throws SQLException{
        SQLToken token = nextToken();
        if(token == null) return null;
        Expression leftExpr;
        switch(token.value){
            case SQLTokenizer.NOT:
            	leftExpr =  new ExpressionArithmetic( expression( cmd, ExpressionArithmetic.NOT      / 10), ExpressionArithmetic.NOT);
            	break;
            case SQLTokenizer.MINUS:
            	leftExpr =  new ExpressionArithmetic( expression( cmd, ExpressionArithmetic.NEGATIVE / 10), ExpressionArithmetic.NEGATIVE);
            	break;
            case SQLTokenizer.TILDE:
            	leftExpr =  new ExpressionArithmetic( expression( cmd, ExpressionArithmetic.BIT_NOT  / 10), ExpressionArithmetic.BIT_NOT);
            	break;
            case SQLTokenizer.PARENTHESIS_L:
                leftExpr = expression( cmd, 0);
                token = nextToken(MISSING_PARENTHESIS_R);
                break;
            default:
                leftExpr = expressionSingle( cmd, token);
        }
        boolean isNot = false;
        while((token = nextToken()) != null){
            Expression rightExpr;
            int operation = ExpressionArithmetic.getOperationFromToken(token.value);
            int level = operation / 10;
            if(previousOperationLevel >= level){
                previousToken();
                return leftExpr;
            }
            switch(token.value){
                case SQLTokenizer.PLUS:
                case SQLTokenizer.MINUS:
                case SQLTokenizer.ASTERISK:
                case SQLTokenizer.SLACH:
                case SQLTokenizer.PERCENT:
                case SQLTokenizer.EQUALS:
                case SQLTokenizer.LESSER:
                case SQLTokenizer.LESSER_EQU:
                case SQLTokenizer.GREATER:
                case SQLTokenizer.GREATER_EQU:
                case SQLTokenizer.UNEQUALS:
                case SQLTokenizer.LIKE:
                case SQLTokenizer.OR:
                case SQLTokenizer.AND:
                case SQLTokenizer.BIT_AND:
                case SQLTokenizer.BIT_OR:
                case SQLTokenizer.BIT_XOR:
                    rightExpr = expression( cmd, level );
                    leftExpr = new ExpressionArithmetic( leftExpr, rightExpr, operation );
                    break;
                case SQLTokenizer.BETWEEN:
                    rightExpr = expression( cmd, ExpressionArithmetic.AND );
                    nextToken( MISSING_AND );
                    Expression rightExpr2 = expression( cmd, level );
                    leftExpr = new ExpressionArithmetic( leftExpr, rightExpr, rightExpr2, operation );
                    break;
                case SQLTokenizer.IN:
            		nextToken(MISSING_PARENTHESIS_L);
                	token = nextToken(MISSING_EXPRESSION);
                	if(token.value == SQLTokenizer.SELECT){
                		CommandSelect cmdSel = select();
						leftExpr = new ExpressionInSelect( con, leftExpr, cmdSel, operation );
						nextToken(MISSING_PARENTHESIS_R);
                	}else{
                		previousToken();
                		Expressions list = expressionParenthesisList( cmd );
                		leftExpr = new ExpressionArithmetic( leftExpr, list, operation );
                	}
                    break;
                case SQLTokenizer.IS:
                	token = nextToken(MISSING_NOT_NULL);
                	if(token.value == SQLTokenizer.NOT){
                		nextToken(MISSING_NULL);
						operation++;
                	}
                	leftExpr = new ExpressionArithmetic( leftExpr, operation );
                	break;
                case SQLTokenizer.NOT:
                	token = nextToken(MISSING_BETWEEN_IN);
                	previousToken();
                	isNot = true;
                	continue;
                default:
                        previousToken();
                        return leftExpr;
            }
            if(isNot){
            	isNot = false;
				leftExpr =  new ExpressionArithmetic( leftExpr, ExpressionArithmetic.NOT);
            }
        }
        previousToken();
        return leftExpr;
    }

    /**
     * parst einen einzelne Expression, wie 12, 'qwert', 0x3F oder column name
     * 
     * @param cmd is needed to add parameters "?" with addParameter() 
     */
    private Expression expressionSingle(Command cmd, SQLToken token) throws SQLException{
        boolean isMinus = false;
        if(token != null){
            switch(token.value){
                case SQLTokenizer.NULL:
                        return new ExpressionValue( null, SQLTokenizer.NULL );
                case SQLTokenizer.STRING:
                        return new ExpressionValue( token.getName(null), SQLTokenizer.VARCHAR );
                case SQLTokenizer.IDENTIFIER:
                        {
                        String name = getIdentifier( token );
                        ExpressionName expr =  new ExpressionName( name );
                        SQLToken token2 = nextToken();
                        if(token2 != null && token2.value == SQLTokenizer.POINT){
                            expr.setNameAfterTableAlias( nextIdentifier() );
                        }else{
                            previousToken();
                        }
                        return expr;
                        }
                case SQLTokenizer.TRUE:
                        return new ExpressionValue( Boolean.TRUE, SQLTokenizer.BOOLEAN );
                case SQLTokenizer.FALSE:
                        return new ExpressionValue( Boolean.FALSE, SQLTokenizer.BOOLEAN );
                case SQLTokenizer.ESCAPE_L:{
                        token = nextToken(COMMANDS_ESCAPE);
                        SQLToken para = nextToken(MISSING_EXPRESSION);
                        Expression expr;
                        switch(token.value){
                            case SQLTokenizer.D: // date escape sequence
                            	expr = new ExpressionValue( DateTime.valueOf(para.getName(sql), SQLTokenizer.DATE), SQLTokenizer.DATE );
                            	break;
                            case SQLTokenizer.T: // time escape sequnce
                                expr = new ExpressionValue( DateTime.valueOf(para.getName(sql), SQLTokenizer.TIME), SQLTokenizer.TIME );
                            	break;
                            case SQLTokenizer.TS: // timestamp escape sequence
                                expr = new ExpressionValue( DateTime.valueOf(para.getName(sql), SQLTokenizer.TIMESTAMP), SQLTokenizer.TIMESTAMP );
                            	break;
                            case SQLTokenizer.FN: // function escape sequence
                            	nextToken(MISSING_PARENTHESIS_L);
                            	expr = function(cmd, para, true);
                            	break;
                            case SQLTokenizer.CALL: // call escape sequence
                                throw new java.lang.UnsupportedOperationException("call escape sequence");
                            default: throw new Error();
                        }
                        token = nextToken( ESCAPE_MISSING_CLOSE );
                        return expr;
                }
                case SQLTokenizer.QUESTION:
                        ExpressionValue param = new ExpressionValue();
                        cmd.addParameter( param );
                        return param;
                case SQLTokenizer.CASE:
                		return caseExpr(cmd);
                case SQLTokenizer.MINUS:
                case SQLTokenizer.PLUS:
                        // Vorzeichenerkennung
                        do{
                            if(token.value == SQLTokenizer.MINUS)
                                    isMinus = !isMinus;
                            token = nextToken();
                            if(token == null) throw createSyntaxError( token, MISSING_EXPRESSION );
                        }while(token.value == SQLTokenizer.MINUS || token.value == SQLTokenizer.PLUS);
                        // kein Break
                default:
                        SQLToken token2 = nextToken();
                        if(token2 != null && token2.value == SQLTokenizer.PARENTHESIS_L){
                            if(isMinus)
                                return new ExpressionArithmetic( function( cmd, token, false ),  ExpressionArithmetic.NEGATIVE );
                            return function( cmd, token, false );
                        }else{
                            // Konstanter Ausdruck oder Identifer
                            char chr1 = sql[ token.offset ];
							if(chr1 == '$'){
								previousToken();
	                            String tok = new String(sql, token.offset+1, token.length-1);
                                if(isMinus) tok = "-" + tok;
								return new ExpressionValue( new Money(Double.parseDouble(tok)), SQLTokenizer.MONEY );
							}
                            String tok = new String(sql, token.offset, token.length);
                            if((chr1 >= '0' && '9' >= chr1) || chr1 == '.'){
                                previousToken();
                                //erstes Zeichen ein digit
                                if(token.length>1 && (sql[ token.offset +1 ] | 0x20) == 'x'){
                                    // bin鋜 Daten als Hex
                                    if(isMinus) throw createSyntaxError( token, "Invalid operator minus for data type varbinary.");
                                    return new ExpressionValue( Utils.hex2bytes( sql, token.offset+2, token.length-2), SQLTokenizer.VARBINARY );
                                }
                                if(isMinus) tok = "-" + tok;
                                if(Utils.indexOf( '.', sql, token.offset, token.length ) >= 0 ||
                                   Utils.indexOf( 'e', sql, token.offset, token.length ) >= 0){
                                    return new ExpressionValue( new Double(tok), SQLTokenizer.DOUBLE );
                                }else{
                                    try{
                                        return new ExpressionValue( new Integer(tok), SQLTokenizer.INT );
                                    }catch(NumberFormatException e){
                                        return new ExpressionValue( new Long(tok), SQLTokenizer.BIGINT );
                                    }
                                }
                            }else{
                                // Bezeichner
                                checkValidIdentifier( tok, token );
                                ExpressionName expr = new ExpressionName(tok);
                                if(token2 != null && token2.value == SQLTokenizer.POINT){
                                    expr.setNameAfterTableAlias( nextIdentifier() );
                                }else{
                                    previousToken();
                                }
                                if(isMinus)
                                    return new ExpressionArithmetic( expr,  ExpressionArithmetic.NEGATIVE );
                                return expr;
                            }
                        }
            }
        }
        return null;
    }
    
    
    ExpressionFunctionCase caseExpr(final Command cmd) throws SQLException{
		ExpressionFunctionCase expr = new ExpressionFunctionCase();
		SQLToken token = nextToken(MISSING_EXPRESSION);
		
		Expression input = null;
		if(token.value != SQLTokenizer.WHEN){
			// simple CASE Syntax
			previousToken();
			input = expression(cmd, 0);
			token = nextToken(MISSING_WHEN_ELSE_END);
		}			
			
		while(true){
			switch(token.value){
				case SQLTokenizer.WHEN:				
					Expression condition = expression(cmd, 0);
					if(input != null){
						// simple CASE Syntax
						condition = new ExpressionArithmetic( input, condition, ExpressionArithmetic.EQUALS);
					}
					nextToken(MISSING_THEN);
					Expression result = expression(cmd, 0);
					expr.addCase(condition, result);
					break;
				case SQLTokenizer.ELSE:
					expr.setElseResult(expression(cmd, 0));
					break;
				case SQLTokenizer.END:
					expr.setEnd();
					return expr;
				default:
					throw new Error();
			}
			token = nextToken(MISSING_WHEN_ELSE_END);
		}
    }
    

    /**
     * Parse any functions. The left parenthesis is already consumed from token list.
     * @param token the SQLToken of the function
     * @param isEscape If the function is a FN ESCAPE sequence
     */ 
    private Expression function( Command cmd, SQLToken token, boolean isEscape ) throws SQLException{
        Expression expr;
        switch(token.value){
        	case SQLTokenizer.CONVERT:{
        		Column col;
        		Expression style = null;
        		if(isEscape){
        			expr = expression( cmd, 0);
					nextToken(MISSING_COMMA);
					col = datatype(isEscape);
        		}else{
	        		col = datatype(isEscape);
	        		nextToken(MISSING_COMMA);
					expr = expression( cmd, 0);
					token = nextToken(MISSING_COMMA_PARENTHESIS);
					if(token.value == SQLTokenizer.COMMA){
						style = expression( cmd, 0);
					}else
						previousToken();
        		}
        		nextToken(MISSING_PARENTHESIS_R);
        		return new ExpressionFunctionConvert( col, expr, style );
        	}
        	case SQLTokenizer.CAST:
        		expr = expression( cmd, 0);
        		nextToken(MISSING_AS);
        		Column col = datatype(false);
        		nextToken(MISSING_PARENTHESIS_R);
        		return new ExpressionFunctionConvert( col, expr, null );
			case SQLTokenizer.TIMESTAMPDIFF:
				token = nextToken(MISSING_INTERVALS);
				nextToken(MISSING_COMMA);
				expr = expression( cmd, 0);
				nextToken(MISSING_COMMA);
				expr = new ExpressionFunctionTimestampDiff( token.value, expr, expression( cmd, 0));
				nextToken(MISSING_PARENTHESIS_R);
				return expr;
			case SQLTokenizer.TIMESTAMPADD:
				token = nextToken(MISSING_INTERVALS);
				nextToken(MISSING_COMMA);
				expr = expression( cmd, 0);
				nextToken(MISSING_COMMA);
				expr = new ExpressionFunctionTimestampAdd( token.value, expr, expression( cmd, 0));
				nextToken(MISSING_PARENTHESIS_R);

⌨️ 快捷键说明

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