org.apache.calcite.sql.parser.impl.ParseException: Encountered "create"

在用calcite解析oracle的建表语句时报这样的错:

Caused by: org.apache.calcite.sql.parser.impl.ParseException: Encountered "CREATE" at line 3, column 2.
Was expecting one of:
    "SET" ...
    "RESET" ...
    "ALTER" ...
    "WITH" ...
    "+" ...
    "-" ...
    "NOT" ...
    "EXISTS" ...
    <UNSIGNED_INTEGER_LITERAL> ...
    <DECIMAL_NUMERIC_LITERAL> ...
    <APPROX_NUMERIC_LITERAL> ...
    <BINARY_STRING_LITERAL> ...
    <PREFIXED_STRING_LITERAL> ...
    <QUOTED_STRING> ...
    <UNICODE_STRING_LITERAL> ...
    "TRUE" ...
    "FALSE" ...
    "UNKNOWN" ...
    "NULL" ...
    <LBRACE_D> ...
    <LBRACE_T> ...
    <LBRACE_TS> ...
    "DATE" ...
    "TIME" ...
    "TIMESTAMP" ...
    "INTERVAL" ...
    "?" ...
    "CAST" ...
    "EXTRACT" ...
    "POSITION" ...
    "CONVERT" ...
    "TRANSLATE" ...
    "OVERLAY" ...
    "FLOOR" ...
    "CEIL" ...
    "CEILING" ...
    "SUBSTRING" ...
    "TRIM" ...
    "CLASSIFIER" ...
    "MATCH_NUMBER" ...
    "RUNNING" ...
    "PREV" ...
    "NEXT" ...
    "JSON_EXISTS" ...
    "JSON_VALUE" ...
    "JSON_QUERY" ...
    "JSON_OBJECT" ...
    "JSON_OBJECTAGG" ...
    "JSON_ARRAY" ...
    "JSON_ARRAYAGG" ...
    <LBRACE_FN> ...
    "MULTISET" ...
    "ARRAY" ...
    "PERIOD" ...
    "SPECIFIC" ...
    <IDENTIFIER> ...
    <QUOTED_IDENTIFIER> ...
    <BACK_QUOTED_IDENTIFIER> ...
    <BRACKET_QUOTED_IDENTIFIER> ...
    <UNICODE_QUOTED_IDENTIFIER> ...
    "ABS" ...
    "AVG" ...
    "CARDINALITY" ...
    "CHAR_LENGTH" ...
    "CHARACTER_LENGTH" ...
    "COALESCE" ...
    "COLLECT" ...
    "COVAR_POP" ...
    "COVAR_SAMP" ...
    "CUME_DIST" ...
    "COUNT" ...
    "CURRENT_DATE" ...
    "CURRENT_TIME" ...
    "CURRENT_TIMESTAMP" ...
    "DENSE_RANK" ...
    "ELEMENT" ...
    "EXP" ...
    "FIRST_VALUE" ...
    "FUSION" ...
    "GROUPING" ...
    "HOUR" ...
    "LAG" ...
    "LEAD" ...
    "LAST_VALUE" ...
    "LN" ...
    "LOCALTIME" ...
    "LOCALTIMESTAMP" ...
    "LOWER" ...
    "MAX" ...
    "MIN" ...
    "MINUTE" ...
    "MOD" ...
    "MONTH" ...
    "NTH_VALUE" ...
    "NTILE" ...
    "NULLIF" ...
    "OCTET_LENGTH" ...
    "PERCENT_RANK" ...
    "POWER" ...
    "RANK" ...
    "REGR_COUNT" ...
    "REGR_SXX" ...
    "REGR_SYY" ...
    "ROW_NUMBER" ...
    "SECOND" ...
    "SQRT" ...
    "STDDEV_POP" ...
    "STDDEV_SAMP" ...
    "SUM" ...
    "UPPER" ...
    "TRUNCATE" ...
    "USER" ...
    "VAR_POP" ...
    "VAR_SAMP" ...
    "YEAR" ...
    "CURRENT_CATALOG" ...
    "CURRENT_DEFAULT_TRANSFORM_GROUP" ...
    "CURRENT_PATH" ...
    "CURRENT_ROLE" ...
    "CURRENT_SCHEMA" ...
    "CURRENT_USER" ...
    "SESSION_USER" ...
    "SYSTEM_USER" ...
    "NEW" ...
    "CASE" ...
    "CURRENT" ...
    "CURSOR" ...
    "ROW" ...
    "(" ...
    "SELECT" ...
    "VALUES" ...
    "TABLE" ...
    "EXPLAIN" ...
    "DESCRIBE" ...
    "INSERT" ...
    "UPSERT" ...
    "DELETE" ...
    "UPDATE" ...
    "MERGE" ...
    "CALL" ...
    
    at org.apache.calcite.sql.parser.impl.SqlParserImpl.generateParseException(SqlParserImpl.java:25004)
    at org.apache.calcite.sql.parser.impl.SqlParserImpl.jj_consume_token(SqlParserImpl.java:24821)
    at org.apache.calcite.sql.parser.impl.SqlParserImpl.SqlStmt(SqlParserImpl.java:864)
    at org.apache.calcite.sql.parser.impl.SqlParserImpl.SqlStmtEof(SqlParserImpl.java:876)
    at org.apache.calcite.sql.parser.impl.SqlParserImpl.parseSqlStmtEof(SqlParserImpl.java:198)
    at org.apache.calcite.sql.parser.SqlParser.parseQuery(SqlParser.java:148)
    ... 1 more

 

可能的情况:

1、可能是使用了oracle的保留关键字来命名了,这时候需要检查一下报错的语句,

2、如果是在解析DDL操作,比如:CREATE TABLE, ALTER TABLE, DROP TABLE, etc.

那么只引入calcite-core是不够的,

Calcite的核心模块(calcite-core)支持SQL查询(SELECT)和DML操作(INSERT,UPDATE,DELETE,MERGE),但不支持DDL操作,如CREATE SCHEMA或CREATE TABLE。正如我们将要看到的,DDL使存储库的状态模型变得复杂,并且使得解析器更难以扩展,因此我们将DDL留在了核心之外。
  服务器模块(calcite-server)向Calcite添加DDL支持。它扩展了SQL解析器,使用与子项目相同的机制,添加了一些DDL命令:

    • CREATE 和 DROP SCHEMA
    • CREATE 和 DROP FOREIGN SCHEMA
    • CREATE和DROP TABLE(含CREATE TABLE ... AS SELECT)
    • CREATE 和 DROP MATERIALIZED VIEW
    • CREATE 和 DROP VIEW

但是这里没有INDEX相关的DDL,

这时候需要

① 在pom.xml文件中引入服务器包,

        <dependency>
            <groupId>org.apache.calcite</groupId>
            <artifactId>calcite-server</artifactId>
            <version>1.18.0</version>
        </dependency>

② 在解析配置中添加相应的工厂和待解析语句的适配数据库配置,

SqlParser.Config sqlParserConfig = SqlParser.configBuilder()
    .setParserFactory(SqlDdlParserImpl.FACTORY)
    .setConformance(SqlConformanceEnum.MYSQL_5)
    .setLex(Lex.MYSQL)
    .build();

SqlParser parser = SqlParser.create(query, sqlParserConfig);

 

这样就可以解析DDL了,

 

但create table 还是不能正确解析,测试时候建表字段类型中设置的长度是不能被正常识别的,比如 abc varchar(20)这个“(”就会报错,目前2020-5-25 09:20:12还没解决,

posted @ 2020-02-21 15:46  十点  阅读(6443)  评论(0编辑  收藏  举报