diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java index 98814ff80c..3bc8debde3 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java @@ -145,8 +145,8 @@ public class OracleExprParser extends SQLExprParser { // ; } - - public SQLDataType parseDataType() { + + public SQLDataType parseDataType(boolean restrict) { if (lexer.token() == Token.CONSTRAINT || lexer.token() == Token.COMMA) { return null; @@ -240,12 +240,12 @@ public class OracleExprParser extends SQLExprParser { if (isCharType(typeName)) { SQLCharacterDataType charType = new SQLCharacterDataType(typeName); - + if (lexer.token() == Token.LPAREN) { lexer.nextToken(); - + charType.addArgument(this.expr()); - + if (identifierEquals("CHAR")) { lexer.nextToken(); charType.setCharType(SQLCharacterDataType.CHAR_TYPE_CHAR); @@ -253,8 +253,10 @@ public class OracleExprParser extends SQLExprParser { lexer.nextToken(); charType.setCharType(SQLCharacterDataType.CHAR_TYPE_BYTE); } - + accept(Token.RPAREN); + } else if (restrict) { + accept(Token.LPAREN); } return parseCharTypeRest(charType); @@ -272,7 +274,6 @@ public class OracleExprParser extends SQLExprParser { throw new ParserException("syntax error : " + lexer.token() + " " + lexer.stringVal()); } } - SQLDataType dataType = new SQLDataTypeImpl(typeName); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java index aff55dc242..987cd718a9 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java @@ -1626,7 +1626,7 @@ public class OracleStatementParser extends SQLStatementParser { parameter.setConstant(true); } - dataType = this.exprParser.parseDataType(); + dataType = this.exprParser.parseDataType(false); if (lexer.token() == Token.COLONEQ) { lexer.nextToken(); diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java index 0ca06aad23..357c886eac 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java @@ -1781,6 +1781,10 @@ public class SQLExprParser extends SQLParser { } public SQLDataType parseDataType() { + return parseDataType(true); + } + + public SQLDataType parseDataType(boolean restrict) { if (lexer.token() == Token.DEFAULT || lexer.token() == Token.NOT || lexer.token() == Token.NULL) { return null; diff --git a/src/main/resources/META-INF/druid/parser/mysql/keywords b/src/main/resources/META-INF/druid/parser/mysql/keywords index b974301b79..18da15607a 100644 --- a/src/main/resources/META-INF/druid/parser/mysql/keywords +++ b/src/main/resources/META-INF/druid/parser/mysql/keywords @@ -1,11 +1,8 @@ accessible -account -action add after against aggregate -algorithm all alter always @@ -18,7 +15,6 @@ asc ascii asensitive at -autoextend_size auto_increment avg avg_row_length @@ -43,7 +39,6 @@ call cascade cascaded case -catalog_name chain change changed @@ -54,17 +49,12 @@ charset check checksum cipher -class_origin -client close coalesce -code collate collation column columns -column_format -column_name comment commit committed @@ -77,9 +67,6 @@ condition connection consistent constraint -constraint_catalog -constraint_name -constraint_schema contains context continue @@ -94,31 +81,21 @@ current_time current_timestamp current_user cursor -cursor_name -data database databases -datafile date datetime day -day_hour -day_microsecond -day_minute -day_second deallocate dec decimal declare default -default_auth definer delayed -delay_key_write delete desc describe -des_key_file deterministic diagnostics directory @@ -158,7 +135,6 @@ execute exists exit expansion -expire explain export extended @@ -168,8 +144,6 @@ fast faults fetch fields -file -file_block_size filter first fixed @@ -177,7 +151,6 @@ float float4 float8 flush -follows for force foreign @@ -192,16 +165,12 @@ generated geometry geometrycollection get -get_format -global grant grants group group_replication handler -hash having -help high_priority host hosts @@ -212,20 +181,16 @@ hour_second identified if ignore -ignore_server_ids import in index indexes infile -initial_size inner inout insensitive insert -insert_method install -instance int int1 int2 @@ -235,7 +200,6 @@ int8 integer interval into -invoker io io_after_gtids io_before_gtids @@ -249,16 +213,12 @@ join json key keys -key_block_size kill -language -last leading leave leaves left less -level like limit linear @@ -278,32 +238,7 @@ longblob longtext loop low_priority -master -master_auto_position -master_bind -master_connect_retry -master_delay -master_heartbeat_period -master_host -master_log_file -master_log_pos -master_password -master_port -master_retry_count -master_server_id -master_ssl -master_ssl_ca -master_ssl_capath -master_ssl_cert -master_ssl_cipher -master_ssl_crl -master_ssl_crlpath -master_ssl_key -master_ssl_verify_server_cert -master_tls_version -master_user match -maxvalue max_connections_per_hour max_queries_per_hour max_rows @@ -315,18 +250,14 @@ medium mediumblob mediumint mediumtext -memory merge -message_text microsecond middleint migrate minute minute_microsecond minute_second -min_rows mod -mode modifies modify month @@ -335,8 +266,6 @@ multipoint multipolygon mutex mysql_errno -name -names national natural nchar @@ -357,7 +286,6 @@ number numeric nvarchar offset -old_password on one only @@ -372,7 +300,6 @@ order out outer outfile -owner pack_keys page parser @@ -386,9 +313,7 @@ phase plugin plugins plugin_dir -point polygon -port precedes precision prepare @@ -398,14 +323,9 @@ primary privileges procedure processlist -profile -profiles -proxy purge quarter query -quick -range read reads read_only @@ -466,7 +386,6 @@ savepoint schedule schema schemas -schema_name second second_microsecond security @@ -483,23 +402,19 @@ show shutdown signal signed -simple slave slow smallint snapshot -socket some soname sounds source spatial specific -sql sqlexception sqlstate sqlwarning -sql_after_gtids sql_after_mts_gaps sql_before_gtids sql_big_result @@ -508,31 +423,19 @@ sql_cache sql_calc_found_rows sql_no_cache sql_small_result -sql_thread -sql_tsi_day -sql_tsi_hour -sql_tsi_minute -sql_tsi_month -sql_tsi_quarter -sql_tsi_second -sql_tsi_week -sql_tsi_year ssl stacked -start starting starts stats_auto_recalc stats_persistent stats_sample_pages -status stop storage stored straight_join string subclass_origin -subject subpartition subpartitions super @@ -542,8 +445,6 @@ switches table tables tablespace -table_checksum -table_name temporary temptable terminated @@ -584,14 +485,12 @@ upgrade usage use user -user_resources use_frm using utc_date utc_time utc_timestamp validation -value values varbinary varchar @@ -614,9 +513,7 @@ wrapper write x509 xa -xid xml xor -year year_month zerofill diff --git a/src/main/resources/META-INF/druid/parser/oracle/builtin_functions b/src/main/resources/META-INF/druid/parser/oracle/builtin_functions index 0c5632cc28..433e3f2ad9 100644 --- a/src/main/resources/META-INF/druid/parser/oracle/builtin_functions +++ b/src/main/resources/META-INF/druid/parser/oracle/builtin_functions @@ -56,6 +56,7 @@ NLS_CHARSET_NAME ASCII INSTR +INSTRB LENGTH LENGTHB REGEXP_INSTR diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTableTest_error_0.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTableTest_error_0.java new file mode 100644 index 0000000000..17123dcb65 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateTableTest_error_0.java @@ -0,0 +1,37 @@ +/* + * Copyright 1999-2017 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.druid.bvt.sql.oracle.create; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.parser.ParserException; +import com.alibaba.druid.util.JdbcConstants; + +import java.util.List; + +public class OracleCreateTableTest_error_0 extends OracleTest { + + public void test_types() throws Exception { + Throwable error = null; + try { + SQLUtils.parseStatements("create table t (fid varchar2);", JdbcConstants.ORACLE); + } catch (ParserException ex) { + error = ex; + } + assertNotNull(error); + } +}