在用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还没解决,