Search in sources :

Example 1 with PGTypeCastExpr

use of com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGTypeCastExpr in project druid by alibaba.

the class SQLExprParser method methodRest.

protected SQLExpr methodRest(SQLExpr expr, boolean acceptLPAREN) {
    if (acceptLPAREN) {
        accept(Token.LPAREN);
    }
    boolean distinct = false;
    if (lexer.token == Token.DISTINCT) {
        lexer.nextToken();
        distinct = true;
        if (lexer.token == Token.RPAREN || lexer.token == Token.COMMA) {
            throw new ParserException(lexer.info());
        }
    }
    String methodName = null;
    String aggMethodName = null;
    SQLMethodInvokeExpr methodInvokeExpr;
    SQLExpr owner = null;
    String trimOption = null;
    long hash_lower = 0L;
    if (expr instanceof SQLIdentifierExpr) {
        SQLIdentifierExpr identifierExpr = (SQLIdentifierExpr) expr;
        methodName = identifierExpr.getName();
        hash_lower = identifierExpr.nameHashCode64();
        if (allowIdentifierMethod) {
            if (hash_lower == FnvHash.Constants.TRIM) {
                if (lexer.identifierEquals(FnvHash.Constants.LEADING)) {
                    trimOption = lexer.stringVal();
                    lexer.nextToken();
                } else if (lexer.identifierEquals(FnvHash.Constants.BOTH)) {
                    trimOption = lexer.stringVal();
                    lexer.nextToken();
                } else if (lexer.identifierEquals(FnvHash.Constants.TRAILING)) {
                    trimOption = lexer.stringVal();
                    lexer.nextToken();
                }
            } else if (hash_lower == FnvHash.Constants.MATCH && (DbType.mysql == dbType || DbType.ads == dbType)) {
                return parseMatch();
            } else if (hash_lower == FnvHash.Constants.EXTRACT && DbType.mysql == dbType) {
                return parseExtract();
            } else if (hash_lower == FnvHash.Constants.POSITION && DbType.mysql == dbType) {
                return parsePosition();
            } else if (hash_lower == FnvHash.Constants.TRY_CAST) {
                SQLCastExpr cast = new SQLCastExpr();
                cast.setTry(true);
                cast.setExpr(expr());
                accept(Token.AS);
                cast.setDataType(parseDataType(false));
                accept(Token.RPAREN);
                return cast;
            } else if (hash_lower == FnvHash.Constants.INT4 && DbType.postgresql == dbType) {
                PGTypeCastExpr castExpr = new PGTypeCastExpr();
                castExpr.setExpr(this.expr());
                castExpr.setDataType(new SQLDataTypeImpl(methodName));
                accept(Token.RPAREN);
                return castExpr;
            } else if (hash_lower == FnvHash.Constants.VARBIT && DbType.postgresql == dbType) {
                PGTypeCastExpr castExpr = new PGTypeCastExpr();
                SQLExpr len = this.primary();
                castExpr.setDataType(new SQLDataTypeImpl(methodName, len));
                accept(Token.RPAREN);
                castExpr.setExpr(this.expr());
                return castExpr;
            } else if (hash_lower == FnvHash.Constants.CONVERT && DbType.mysql == dbType) {
                methodInvokeExpr = new SQLMethodInvokeExpr(methodName, hash_lower);
                SQLExpr arg0 = this.expr();
                // Fix for using.
                Object exprUsing = arg0.getAttributes().get("USING");
                if (exprUsing instanceof String) {
                    String charset = (String) exprUsing;
                    methodInvokeExpr.setUsing(new SQLIdentifierExpr(charset));
                    arg0.getAttributes().remove("USING");
                }
                methodInvokeExpr.addArgument(arg0);
                if (lexer.token == Token.COMMA) {
                    lexer.nextToken();
                    SQLDataType dataType = this.parseDataType();
                    SQLDataTypeRefExpr dataTypeRefExpr = new SQLDataTypeRefExpr(dataType);
                    methodInvokeExpr.addArgument(dataTypeRefExpr);
                }
                if (lexer.token == Token.USING || lexer.identifierEquals(FnvHash.Constants.USING)) {
                    lexer.nextToken();
                    SQLExpr using;
                    if (lexer.token == Token.STAR) {
                        lexer.nextToken();
                        using = new SQLAllColumnExpr();
                    } else if (lexer.token == Token.BINARY) {
                        using = new SQLIdentifierExpr(lexer.stringVal());
                        lexer.nextToken();
                    } else {
                        using = this.primary();
                    }
                    methodInvokeExpr.setUsing(using);
                }
                accept(Token.RPAREN);
                return primaryRest(methodInvokeExpr);
            }
        }
        if (distinct) {
            aggMethodName = methodName;
        } else {
            aggMethodName = getAggregateFunction(hash_lower);
        }
    } else if (expr instanceof SQLPropertyExpr) {
        methodName = ((SQLPropertyExpr) expr).getSimpleName();
        aggMethodName = SQLUtils.normalize(methodName);
        hash_lower = FnvHash.fnv1a_64_lower(aggMethodName);
        aggMethodName = getAggregateFunction(hash_lower);
        owner = ((SQLPropertyExpr) expr).getOwner();
    } else if (expr instanceof SQLDefaultExpr) {
        methodName = "DEFAULT";
    } else if (expr instanceof SQLCharExpr) {
        methodName = ((SQLCharExpr) expr).getText();
        if (isAggregateFunction(methodName)) {
            aggMethodName = methodName;
        }
    } else if (expr instanceof SQLDbLinkExpr) {
        SQLDbLinkExpr dbLinkExpr = (SQLDbLinkExpr) expr;
        methodName = dbLinkExpr.toString();
    }
    if (aggMethodName != null) {
        SQLAggregateExpr aggregateExpr = parseAggregateExpr(methodName);
        if (distinct) {
            aggregateExpr.setOption(SQLAggregateOption.DISTINCT);
        }
        if (lexer.token == Token.COLONCOLON) {
            return primaryRest(aggregateExpr);
        }
        return aggregateExpr;
    }
    methodInvokeExpr = new SQLMethodInvokeExpr(methodName, hash_lower);
    if (owner != null) {
        methodInvokeExpr.setOwner(owner);
    }
    if (trimOption != null) {
        methodInvokeExpr.setTrimOption(trimOption);
    }
    Token token = lexer.token;
    if (token != Token.RPAREN && token != Token.FROM) {
        exprList(methodInvokeExpr.getArguments(), methodInvokeExpr);
    }
    if (hash_lower == FnvHash.Constants.EXIST && methodInvokeExpr.getArguments().size() == 1 && methodInvokeExpr.getArguments().get(0) instanceof SQLQueryExpr) {
        throw new ParserException("exists syntax error.");
    }
    if (lexer.token == Token.FROM) {
        lexer.nextToken();
        SQLExpr from = this.expr();
        methodInvokeExpr.setFrom(from);
        if (lexer.token == Token.FOR) {
            lexer.nextToken();
            SQLExpr forExpr = expr();
            methodInvokeExpr.setFor(forExpr);
        }
    }
    if (lexer.token == Token.USING || lexer.identifierEquals(FnvHash.Constants.USING)) {
        lexer.nextToken();
        SQLExpr using;
        if (lexer.token == Token.STAR) {
            lexer.nextToken();
            using = new SQLAllColumnExpr();
        } else if (lexer.token == Token.BINARY) {
            using = new SQLIdentifierExpr(lexer.stringVal());
            lexer.nextToken();
        } else {
            using = this.primary();
        }
        methodInvokeExpr.setUsing(using);
    }
    // mysql
    if (hash_lower == FnvHash.Constants.WEIGHT_STRING) {
        if (lexer.token == Token.AS) {
            lexer.nextToken();
            SQLDataType as = this.parseDataType();
            methodInvokeExpr.putAttribute("as", as);
        }
        if (lexer.identifierEquals(FnvHash.Constants.LEVEL)) {
            lexer.nextToken();
            List<SQLSelectOrderByItem> levels = new ArrayList<SQLSelectOrderByItem>();
            for (; ; ) {
                SQLSelectOrderByItem level = this.parseSelectOrderByItem();
                levels.add(level);
                if (lexer.token == Token.COMMA) {
                    lexer.nextToken();
                    continue;
                }
                break;
            }
            methodInvokeExpr.putAttribute("levels", levels);
        }
        if (lexer.identifierEquals(FnvHash.Constants.REVERSE)) {
            lexer.nextToken();
            methodInvokeExpr.putAttribute("reverse", true);
        }
    }
    SQLAggregateExpr aggregateExpr = null;
    if (lexer.token == Token.ORDER) {
        lexer.nextToken();
        accept(Token.BY);
        aggregateExpr = new SQLAggregateExpr(methodName);
        aggregateExpr.getArguments().addAll(methodInvokeExpr.getArguments());
        SQLOrderBy orderBy = new SQLOrderBy();
        this.orderBy(orderBy.getItems(), orderBy);
        aggregateExpr.setOrderBy(orderBy);
    }
    accept(Token.RPAREN);
    if (lexer.identifierEquals(FnvHash.Constants.USING) && dbType == DbType.odps) {
        lexer.nextToken();
        SQLExpr using = this.primary();
        methodInvokeExpr.setUsing(using);
    }
    if (lexer.identifierEquals(FnvHash.Constants.FILTER)) {
        if (aggregateExpr == null) {
            Lexer.SavePoint mark = lexer.mark();
            lexer.nextToken();
            Token nextToken = lexer.token;
            lexer.reset(mark);
            if (nextToken == Token.LPAREN) {
                aggregateExpr = new SQLAggregateExpr(methodName);
                aggregateExpr.getArguments().addAll(methodInvokeExpr.getArguments());
                filter(aggregateExpr);
            }
        } else {
            filter(aggregateExpr);
        }
    }
    if (lexer.token == Token.OVER) {
        if (aggregateExpr == null) {
            aggregateExpr = new SQLAggregateExpr(methodName);
            aggregateExpr.getArguments().addAll(methodInvokeExpr.getArguments());
        }
        over(aggregateExpr);
    }
    if (aggregateExpr != null) {
        return primaryRest(aggregateExpr);
    }
    if (lexer.token == Token.LPAREN) {
        return methodInvokeExpr;
    }
    return primaryRest(methodInvokeExpr);
// throw new ParserException("not support token:" + lexer.token + ", " + lexer.info());
}
Also used : ArrayList(java.util.ArrayList) PGTypeCastExpr(com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGTypeCastExpr)

Example 2 with PGTypeCastExpr

use of com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGTypeCastExpr in project druid by alibaba.

the class BitsTest method test_timestamp.

public void test_timestamp() throws Exception {
    String sql = "44::bit(10)";
    PGExprParser parser = new PGExprParser(sql);
    PGTypeCastExpr expr = (PGTypeCastExpr) parser.expr();
    System.out.println(expr.toString());
}
Also used : PGExprParser(com.alibaba.druid.sql.dialect.postgresql.parser.PGExprParser) PGTypeCastExpr(com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGTypeCastExpr)

Aggregations

PGTypeCastExpr (com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGTypeCastExpr)2 PGExprParser (com.alibaba.druid.sql.dialect.postgresql.parser.PGExprParser)1 ArrayList (java.util.ArrayList)1