提交 94d97acd authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Add token types for all keywords and use them instead of strings

上级 81bb6b2e
......@@ -8,12 +8,44 @@
*/
package org.h2.command;
import static org.h2.util.ParserUtil.ALL;
import static org.h2.util.ParserUtil.CHECK;
import static org.h2.util.ParserUtil.CONSTRAINT;
import static org.h2.util.ParserUtil.CROSS;
import static org.h2.util.ParserUtil.DISTINCT;
import static org.h2.util.ParserUtil.EXCEPT;
import static org.h2.util.ParserUtil.EXISTS;
import static org.h2.util.ParserUtil.FALSE;
import static org.h2.util.ParserUtil.FETCH;
import static org.h2.util.ParserUtil.FOR;
import static org.h2.util.ParserUtil.FOREIGN;
import static org.h2.util.ParserUtil.FROM;
import static org.h2.util.ParserUtil.FULL;
import static org.h2.util.ParserUtil.GROUP;
import static org.h2.util.ParserUtil.HAVING;
import static org.h2.util.ParserUtil.IDENTIFIER;
import static org.h2.util.ParserUtil.INNER;
import static org.h2.util.ParserUtil.INTERSECT;
import static org.h2.util.ParserUtil.IS;
import static org.h2.util.ParserUtil.JOIN;
import static org.h2.util.ParserUtil.KEYWORD;
import static org.h2.util.ParserUtil.LIKE;
import static org.h2.util.ParserUtil.LIMIT;
import static org.h2.util.ParserUtil.MINUS;
import static org.h2.util.ParserUtil.NATURAL;
import static org.h2.util.ParserUtil.NOT;
import static org.h2.util.ParserUtil.NULL;
import static org.h2.util.ParserUtil.OFFSET;
import static org.h2.util.ParserUtil.ON;
import static org.h2.util.ParserUtil.ORDER;
import static org.h2.util.ParserUtil.PRIMARY;
import static org.h2.util.ParserUtil.ROWNUM;
import static org.h2.util.ParserUtil.SELECT;
import static org.h2.util.ParserUtil.TRUE;
import static org.h2.util.ParserUtil.UNION;
import static org.h2.util.ParserUtil.UNIQUE;
import static org.h2.util.ParserUtil.WHERE;
import static org.h2.util.ParserUtil.WITH;
import java.math.BigDecimal;
import java.math.BigInteger;
......@@ -197,13 +229,206 @@ public class Parser {
CHAR_DOLLAR_QUOTED_STRING = 9;
// this are token types, see also types in ParserUtil
private static final int PARAMETER = 10, END = 11, VALUE = 12;
private static final int EQUAL = 13, BIGGER_EQUAL = 14, BIGGER = 15;
private static final int SMALLER = 16, SMALLER_EQUAL = 17, NOT_EQUAL = 18;
private static final int AT = 19;
private static final int MINUS = 20, PLUS = 21, STRING_CONCAT = 22;
private static final int OPEN = 23, CLOSE = 24;
private static final int SPATIAL_INTERSECTS = 25;
/**
* Token with parameter.
*/
private static final int PARAMETER = WITH + 1;
/**
* End of input.
*/
private static final int END = PARAMETER + 1;
/**
* Token with value.
*/
private static final int VALUE = END + 1;
/**
* The token "=".
*/
private static final int EQUAL = VALUE + 1;
/**
* The token ">=".
*/
private static final int BIGGER_EQUAL = EQUAL + 1;
/**
* The token ">".
*/
private static final int BIGGER = BIGGER_EQUAL + 1;
/**
* The token "<".
*/
private static final int SMALLER = BIGGER + 1;
/**
* The token "<=".
*/
private static final int SMALLER_EQUAL = SMALLER + 1;
/**
* The token "<>" or "!=".
*/
private static final int NOT_EQUAL = SMALLER_EQUAL + 1;
/**
* The token "@".
*/
private static final int AT = NOT_EQUAL + 1;
/**
* The token "-".
*/
private static final int MINUS_SIGN = AT + 1;
/**
* The token "+".
*/
private static final int PLUS_SIGN = MINUS_SIGN + 1;
/**
* The token "||".
*/
private static final int STRING_CONCAT = PLUS_SIGN + 1;
/**
* The token "(".
*/
private static final int OPEN_PAREN = STRING_CONCAT + 1;
/**
* The token ")".
*/
private static final int CLOSE_PAREN = OPEN_PAREN + 1;
/**
* The token "&&".
*/
private static final int SPATIAL_INTERSECTS = CLOSE_PAREN + 1;
private static final String[] TOKENS = {
// Unused
null,
// KEYWORD
null,
// IDENTIFIER
null,
// ALL
"ALL",
// CHECK
"CHECK",
// CONSTRAINT
"CONSTRAINT",
// CROSS
"CROSS",
// CURRENT_DATE
"CURRENT_DATE",
// CURRENT_TIME
"CURRENT_TIME",
// CURRENT_TIMESTAMP
"CURRENT_TIMESTAMP",
// DISTINCT
"DISTINCT",
// EXCEPT
"EXCEPT",
// EXISTS
"EXISTS",
// FALSE
"FALSE",
// FETCH
"FETCH",
// FOR
"FOR",
// FOREIGN
"FOREIGN",
// FROM
"FROM",
// FULL
"FULL",
// GROUP
"GROUP",
// HAVING
"HAVING",
// INNER
"INNER",
// INTERSECT
"INTERSECT",
// IS
"IS",
// JOIN
"JOIN",
// LIKE
"LIKE",
// LIMIT
"LIMIT",
// MINUS
"MINUS",
// NATURAL
"NATURAL",
// NOT
"NOT",
// NULL
"NULL",
// OFFSET
"OFFSET",
// ON
"ON",
// ORDER
"ORDER",
// PRIMARY
"PRIMARY",
// ROWNUM
"ROWNUM",
// SELECT
"SELECT",
// TRUE
"TRUE",
// UNION
"UNION",
// UNIQUE
"UNIQUE",
// WHERE
"WHERE",
// WITH
"WITH",
// PARAMETER
"?",
// END
null,
// VALUE
null,
// EQUAL
"=",
// BIGGER_EQUAL
">=",
// BIGGER
">",
// SMALLER
"<",
// SMALLER_EQUAL
"<=",
// NOT_EQUAL
"<>",
// AT
"@",
// MINUS_SIGN
"-",
// PLUS_SIGN
"+",
// STRING_CONCAT
"||",
// OPEN_PAREN
"(",
// CLOSE_PAREN
")",
// SPATIAL_INTERSECTS
"&&",
// End
};
private static final Comparator<TableFilter> TABLE_FILTER_COMPARATOR =
new Comparator<TableFilter>() {
......@@ -354,7 +579,7 @@ public class Parser {
readTerm();
// this is an 'out' parameter - set a dummy value
parameters.get(0).setValue(ValueNull.INSTANCE);
read("=");
read(EQUAL);
read("CALL");
c = parseCall();
break;
......@@ -414,7 +639,7 @@ public class Parser {
break;
case 'f':
case 'F':
if (isToken("FROM")) {
if (isToken(FROM)) {
c = parseSelect();
}
break;
......@@ -464,7 +689,7 @@ public class Parser {
break;
case 's':
case 'S':
if (isToken("SELECT")) {
if (isToken(SELECT)) {
c = parseSelect();
} else if (readIf("SET")) {
c = parseSet();
......@@ -500,7 +725,7 @@ public class Parser {
break;
case 'w':
case 'W':
if (readIf("WITH")) {
if (readIf(WITH)) {
c = parseWithStatementOrQuery();
}
break;
......@@ -646,7 +871,7 @@ public class Parser {
return command;
}
String procedureName = readAliasIdentifier();
if (readIf("(")) {
if (readIf(OPEN_PAREN)) {
ArrayList<Column> list = Utils.newSmallArrayList();
for (int i = 0;; i++) {
Column column = parseColumnForTable("C" + i, true, false);
......@@ -782,13 +1007,13 @@ public class Parser {
private void parseUpdateSetClause(Update command, TableFilter filter, int start) {
read("SET");
if (readIf("(")) {
if (readIf(OPEN_PAREN)) {
ArrayList<Column> columns = Utils.newSmallArrayList();
do {
Column column = readTableColumn(filter);
columns.add(column);
} while (readIfMore(true));
read("=");
read(EQUAL);
Expression expression = readExpression();
if (columns.size() == 1) {
// the expression is parsed as a simple value
......@@ -806,21 +1031,21 @@ public class Parser {
} else {
do {
Column column = readTableColumn(filter);
read("=");
read(EQUAL);
command.setAssignment(column, readExpressionOrDefault());
} while (readIf(","));
}
if (readIf("WHERE")) {
if (readIf(WHERE)) {
Expression condition = readExpression();
command.setCondition(condition);
}
if (readIf("ORDER")) {
if (readIf(ORDER)) {
// for MySQL compatibility
// (this syntax is supported, but ignored)
read("BY");
parseSimpleOrderList();
}
if (readIf("LIMIT")) {
if (readIf(LIMIT)) {
Expression limit = readTerm().optimize(session);
command.setLimit(limit);
}
......@@ -851,9 +1076,9 @@ public class Parser {
}
currentPrepared = command;
int start = lastParseIndex;
if (!readIf("FROM") && database.getMode().getEnum() == ModeEnum.MySQL) {
if (!readIf(FROM) && database.getMode().getEnum() == ModeEnum.MySQL) {
readIdentifierWithSchema();
read("FROM");
read(FROM);
}
TableFilter filter = readSimpleTableFilter(0, null);
command.setTableFilter(filter);
......@@ -862,11 +1087,11 @@ public class Parser {
}
private void parseDeleteGivenTable(Delete command, Expression limit, int start) {
if (readIf("WHERE")) {
if (readIf(WHERE)) {
Expression condition = readExpression();
command.setCondition(condition);
}
if (readIf("LIMIT") && limit == null) {
if (readIf(LIMIT) && limit == null) {
limit = readTerm().optimize(session);
}
command.setLimit(limit);
......@@ -914,7 +1139,7 @@ public class Parser {
private Column[] parseColumnList(Table table) {
ArrayList<Column> columns = Utils.newSmallArrayList();
HashSet<Column> set = new HashSet<>();
if (!readIf(")")) {
if (!readIf(CLOSE_PAREN)) {
do {
Column column = parseColumn(table);
if (!set.add(column)) {
......@@ -944,9 +1169,9 @@ public class Parser {
*/
private boolean readIfMore(boolean strict) {
if (readIf(",")) {
return strict || !readIf(")");
return strict || !readIf(CLOSE_PAREN);
}
read(")");
read(CLOSE_PAREN);
return false;
}
......@@ -998,7 +1223,7 @@ public class Parser {
} else if (readIf("TABLES")) {
// for MySQL compatibility
String schema = Constants.SCHEMA_MAIN;
if (readIf("FROM")) {
if (readIf(FROM)) {
schema = readUniqueIdentifier();
}
buff.append("TABLE_NAME, TABLE_SCHEMA FROM "
......@@ -1007,11 +1232,11 @@ public class Parser {
paramValues.add(ValueString.get(schema));
} else if (readIf("COLUMNS")) {
// for MySQL compatibility
read("FROM");
read(FROM);
String tableName = readIdentifierWithSchema();
String schemaName = getSchema().getName();
paramValues.add(ValueString.get(tableName));
if (readIf("FROM")) {
if (readIf(FROM)) {
schemaName = readUniqueIdentifier();
}
buff.append("C.COLUMN_NAME FIELD, "
......@@ -1059,11 +1284,11 @@ public class Parser {
private boolean isSelect() {
int start = lastParseIndex;
while (readIf("(")) {
while (readIf(OPEN_PAREN)) {
// need to read ahead, it could be a nested union:
// ((select 1) union (select 1))
}
boolean select = isToken("SELECT") || isToken("FROM") || isToken("WITH");
boolean select = isToken(SELECT) || isToken(FROM) || isToken(WITH);
parseIndex = start;
read();
return select;
......@@ -1083,23 +1308,23 @@ public class Parser {
if (readIf("USING")) {
return parseMergeUsing(command, start);
}
if (readIf("(")) {
if (readIf(OPEN_PAREN)) {
if (isSelect()) {
command.setQuery(parseSelect());
read(")");
read(CLOSE_PAREN);
return command;
}
Column[] columns = parseColumnList(table);
command.setColumns(columns);
}
if (readIf("KEY")) {
read("(");
read(OPEN_PAREN);
Column[] keys = parseColumnList(table);
command.setKeys(keys);
}
if (readIf("VALUES")) {
do {
read("(");
read(OPEN_PAREN);
command.addRow(parseValuesForInsert());
} while (readIf(","));
} else {
......@@ -1112,11 +1337,11 @@ public class Parser {
MergeUsing command = new MergeUsing(oldCommand);
currentPrepared = command;
if (readIf("(")) {
if (readIf(OPEN_PAREN)) {
/* a select query is supplied */
if (isSelect()) {
command.setQuery(parseSelect());
read(")");
read(CLOSE_PAREN);
}
String queryAlias = readFromAlias(null, Collections.singletonList("ON"));
if (queryAlias == null) {
......@@ -1153,7 +1378,7 @@ public class Parser {
preparedQuery.init();
command.setQuery(preparedQuery);
}
read("ON");
read(ON);
Expression condition = readExpression();
command.setOnCondition(condition);
......@@ -1215,7 +1440,7 @@ public class Parser {
}
private void parseWhenNotMatched(MergeUsing command) {
read("NOT");
read(NOT);
read("MATCHED");
read("THEN");
if (readIf("INSERT")) {
......@@ -1254,7 +1479,7 @@ public class Parser {
return returnedCommand;
}
if (database.getMode().onDuplicateKeyUpdate) {
if (readIf("ON")) {
if (readIf(ON)) {
read("DUPLICATE");
read("KEY");
read("UPDATE");
......@@ -1277,7 +1502,7 @@ public class Parser {
}
}
Column column = table.getColumn(columnName);
read("=");
read(EQUAL);
command.addAssignmentForDuplicate(column, readExpressionOrDefault());
} while (readIf(","));
}
......@@ -1290,10 +1515,10 @@ public class Parser {
private Insert parseInsertGivenTable(Insert command, Table table) {
Column[] columns = null;
if (readIf("(")) {
if (readIf(OPEN_PAREN)) {
if (isSelect()) {
command.setQuery(parseSelect());
read(")");
read(CLOSE_PAREN);
return command;
}
columns = parseColumnList(table);
......@@ -1310,11 +1535,11 @@ public class Parser {
Expression[] expr = {};
command.addRow(expr);
} else if (readIf("VALUES")) {
read("(");
read(OPEN_PAREN);
do {
command.addRow(parseValuesForInsert());
// the following condition will allow (..),; and (..);
} while (readIf(",") && readIf("("));
} while (readIf(",") && readIf(OPEN_PAREN));
} else if (readIf("SET")) {
if (columns != null) {
throw getSyntaxError();
......@@ -1323,7 +1548,7 @@ public class Parser {
ArrayList<Expression> values = Utils.newSmallArrayList();
do {
columnList.add(parseColumn(table));
read("=");
read(EQUAL);
values.add(readExpressionOrDefault());
} while (readIf(","));
command.setColumns(columnList.toArray(new Column[0]));
......@@ -1343,10 +1568,10 @@ public class Parser {
read("INTO");
Table table = readTableOrView();
command.setTable(table);
if (readIf("(")) {
if (readIf(OPEN_PAREN)) {
if (isSelect()) {
command.setQuery(parseSelect());
read(")");
read(CLOSE_PAREN);
return command;
}
Column[] columns = parseColumnList(table);
......@@ -1354,7 +1579,7 @@ public class Parser {
}
if (readIf("VALUES")) {
do {
read("(");
read(OPEN_PAREN);
command.addRow(parseValuesForInsert());
} while (readIf(","));
} else {
......@@ -1365,7 +1590,7 @@ public class Parser {
private Expression[] parseValuesForInsert() {
ArrayList<Expression> values = Utils.newSmallArrayList();
if (!readIf(")")) {
if (!readIf(CLOSE_PAREN)) {
do {
if (readIf("DEFAULT")) {
values.add(null);
......@@ -1380,10 +1605,10 @@ public class Parser {
private TableFilter readTableFilter() {
Table table;
String alias = null;
label: if (readIf("(")) {
label: if (readIf(OPEN_PAREN)) {
if (isSelect()) {
Query query = parseSelectUnion();
read(")");
read(CLOSE_PAREN);
query.setParameterList(new ArrayList<>(parameters));
query.init();
Session s;
......@@ -1399,7 +1624,7 @@ public class Parser {
TableFilter top;
top = readTableFilter();
top = readJoin(top);
read(")");
read(CLOSE_PAREN);
alias = readFromAlias(null);
if (alias != null) {
top.setAlias(alias);
......@@ -1427,12 +1652,12 @@ public class Parser {
throw DbException.get(ErrorCode.SCHEMA_NOT_FOUND_1, schemaName);
}
}
boolean foundLeftBracket = readIf("(");
boolean foundLeftBracket = readIf(OPEN_PAREN);
if (foundLeftBracket && readIf("INDEX")) {
// Sybase compatibility with
// "select * from test (index table1_index)"
readIdentifierWithSchema(null);
read(")");
read(CLOSE_PAREN);
foundLeftBracket = false;
}
if (foundLeftBracket) {
......@@ -1444,11 +1669,11 @@ public class Parser {
Expression max = readExpression();
if (readIf(",")) {
Expression step = readExpression();
read(")");
read(CLOSE_PAREN);
table = new RangeTable(mainSchema, min, max, step,
false);
} else {
read(")");
read(CLOSE_PAREN);
table = new RangeTable(mainSchema, min, max, false);
}
} else {
......@@ -1503,9 +1728,9 @@ public class Parser {
if (table == null) {
throw getSyntaxError();
}
read("(");
read(OPEN_PAREN);
LinkedHashSet<String> indexNames = new LinkedHashSet<>();
if (!readIf(")")) {
if (!readIf(CLOSE_PAREN)) {
do {
String indexName = readIdentifierWithSchema();
Index index = table.getIndex(indexName);
......@@ -1532,7 +1757,7 @@ public class Parser {
}
private ArrayList<String> readDerivedColumnNames() {
if (readIf("(")) {
if (readIf(OPEN_PAREN)) {
ArrayList<String> derivedColumnNames = new ArrayList<>();
do {
derivedColumnNames.add(readAliasIdentifier());
......@@ -1563,7 +1788,7 @@ public class Parser {
private boolean readIfExists(boolean ifExists) {
if (readIf("IF")) {
read("EXISTS");
read(EXISTS);
ifExists = true;
}
return ifExists;
......@@ -1571,7 +1796,7 @@ public class Parser {
private Prepared parseComment() {
int type = 0;
read("ON");
read(ON);
boolean column = false;
if (readIf("TABLE") || readIf("VIEW")) {
type = DbObject.TABLE_OR_VIEW;
......@@ -1580,7 +1805,7 @@ public class Parser {
type = DbObject.TABLE_OR_VIEW;
} else if (readIf("CONSTANT")) {
type = DbObject.CONSTANT;
} else if (readIf("CONSTRAINT")) {
} else if (readIf(CONSTRAINT)) {
type = DbObject.CONSTRAINT;
} else if (readIf("ALIAS")) {
type = DbObject.FUNCTION_ALIAS;
......@@ -1634,7 +1859,7 @@ public class Parser {
command.setSchemaName(schemaName);
command.setObjectName(objectName);
command.setObjectType(type);
read("IS");
read(IS);
command.setCommentExpression(readExpression());
return command;
}
......@@ -1670,7 +1895,7 @@ public class Parser {
ifExists = readIfExists(ifExists);
command.setIfExists(ifExists);
//Support for MySQL: DROP INDEX index_name ON tbl_name
if (readIf("ON")) {
if (readIf(ON)) {
readIdentifierWithSchema();
}
return command;
......@@ -1745,7 +1970,7 @@ public class Parser {
command.setDropAction(dropAction);
}
return command;
} else if (readIf("ALL")) {
} else if (readIf(ALL)) {
read("OBJECTS");
DropDatabase command = new DropDatabase(session);
command.setDropAllObjects(true);
......@@ -1798,51 +2023,51 @@ public class Parser {
TableFilter join;
if (readIf("RIGHT")) {
readIf("OUTER");
read("JOIN");
read(JOIN);
// the right hand side is the 'inner' table usually
join = readTableFilter();
join = readJoin(join);
Expression on = null;
if (readIf("ON")) {
if (readIf(ON)) {
on = readExpression();
}
addJoin(join, top, true, on);
top = join;
} else if (readIf("LEFT")) {
readIf("OUTER");
read("JOIN");
read(JOIN);
join = readTableFilter();
join = readJoin(join);
Expression on = null;
if (readIf("ON")) {
if (readIf(ON)) {
on = readExpression();
}
addJoin(top, join, true, on);
} else if (readIf("FULL")) {
} else if (readIf(FULL)) {
throw getSyntaxError();
} else if (readIf("INNER")) {
read("JOIN");
} else if (readIf(INNER)) {
read(JOIN);
join = readTableFilter();
top = readJoin(top);
Expression on = null;
if (readIf("ON")) {
if (readIf(ON)) {
on = readExpression();
}
addJoin(top, join, false, on);
} else if (readIf("JOIN")) {
} else if (readIf(JOIN)) {
join = readTableFilter();
top = readJoin(top);
Expression on = null;
if (readIf("ON")) {
if (readIf(ON)) {
on = readExpression();
}
addJoin(top, join, false, on);
} else if (readIf("CROSS")) {
read("JOIN");
} else if (readIf(CROSS)) {
read(JOIN);
join = readTableFilter();
addJoin(top, join, false, null);
} else if (readIf("NATURAL")) {
read("JOIN");
} else if (readIf(NATURAL)) {
read(JOIN);
join = readTableFilter();
Column[] tableCols = last.getTable().getColumns();
Column[] joinCols = join.getTable().getColumns();
......@@ -1912,7 +2137,7 @@ public class Parser {
procedureName);
}
command.setProcedure(p);
if (readIf("(")) {
if (readIf(OPEN_PAREN)) {
for (int i = 0;; i++) {
command.setExpression(i, readExpression());
if (!readIfMore(true)) {
......@@ -1937,10 +2162,10 @@ public class Parser {
command.setExecuteCommand(true);
} else {
if (readIf("PLAN")) {
readIf("FOR");
readIf(FOR);
}
}
if (isToken("SELECT") || isToken("FROM") || isToken("(") || isToken("WITH")) {
if (isToken(SELECT) || isToken(FROM) || isToken(OPEN_PAREN) || isToken(WITH)) {
Query query = parseSelect();
query.setNeverLazy(true);
command.setCommand(query);
......@@ -1996,22 +2221,22 @@ public class Parser {
private Query parseSelectUnionExtension(Query command, int start,
boolean unionOnly) {
while (true) {
if (readIf("UNION")) {
if (readIf(UNION)) {
SelectUnion union = new SelectUnion(session, command);
if (readIf("ALL")) {
if (readIf(ALL)) {
union.setUnionType(SelectUnion.UnionType.UNION_ALL);
} else {
readIf("DISTINCT");
readIf(DISTINCT);
union.setUnionType(SelectUnion.UnionType.UNION);
}
union.setRight(parseSelectSub());
command = union;
} else if (readIf("MINUS") || readIf("EXCEPT")) {
} else if (readIf(MINUS) || readIf(EXCEPT)) {
SelectUnion union = new SelectUnion(session, command);
union.setUnionType(SelectUnion.UnionType.EXCEPT);
union.setRight(parseSelectSub());
command = union;
} else if (readIf("INTERSECT")) {
} else if (readIf(INTERSECT)) {
SelectUnion union = new SelectUnion(session, command);
union.setUnionType(SelectUnion.UnionType.INTERSECT);
union.setRight(parseSelectSub());
......@@ -2028,7 +2253,7 @@ public class Parser {
}
private void parseEndOfQuery(Query command) {
if (readIf("ORDER")) {
if (readIf(ORDER)) {
read("BY");
Select oldSelect = currentSelect;
if (command instanceof Select) {
......@@ -2036,7 +2261,7 @@ public class Parser {
}
ArrayList<SelectOrderBy> orderList = Utils.newSmallArrayList();
do {
boolean canBeNumber = !readIf("=");
boolean canBeNumber = !readIf(EQUAL);
SelectOrderBy order = new SelectOrderBy();
Expression expr = readExpression();
if (canBeNumber && expr instanceof ValueExpression &&
......@@ -2058,13 +2283,13 @@ public class Parser {
Select temp = currentSelect;
currentSelect = null;
// http://sqlpro.developpez.com/SQL2008/
if (readIf("OFFSET")) {
if (readIf(OFFSET)) {
command.setOffset(readExpression().optimize(session));
if (!readIf("ROW")) {
readIf("ROWS");
}
}
if (readIf("FETCH")) {
if (readIf(FETCH)) {
if (!readIf("FIRST")) {
read("NEXT");
}
......@@ -2080,13 +2305,13 @@ public class Parser {
read("ONLY");
}
currentSelect = temp;
if (readIf("LIMIT")) {
if (readIf(LIMIT)) {
temp = currentSelect;
// make sure aggregate functions will not work here
currentSelect = null;
Expression limit = readExpression().optimize(session);
command.setLimit(limit);
if (readIf("OFFSET")) {
if (readIf(OFFSET)) {
Expression offset = readExpression().optimize(session);
command.setOffset(offset);
} else if (readIf(",")) {
......@@ -2102,7 +2327,7 @@ public class Parser {
}
currentSelect = temp;
}
if (readIf("FOR")) {
if (readIf(FOR)) {
if (readIf("UPDATE")) {
if (readIf("OF")) {
do {
......@@ -2112,7 +2337,7 @@ public class Parser {
// TODO parser: select for update nowait: should not wait
}
command.setForUpdate(true);
} else if (readIf("READ") || readIf("FETCH")) {
} else if (readIf("READ") || readIf(FETCH)) {
read("ONLY");
}
}
......@@ -2125,7 +2350,7 @@ public class Parser {
* DB2 isolation clause
*/
private void parseIsolationClause() {
if (readIf("WITH")) {
if (readIf(WITH)) {
if (readIf("RR") || readIf("RS")) {
// concurrent-access-resolution clause
if (readIf("USE")) {
......@@ -2144,12 +2369,12 @@ public class Parser {
}
private Query parseSelectSub() {
if (readIf("(")) {
if (readIf(OPEN_PAREN)) {
Query command = parseSelectUnion();
read(")");
read(CLOSE_PAREN);
return command;
}
if (readIf("WITH")) {
if (readIf(WITH)) {
Query query;
try {
query = (Query) parseWith();
......@@ -2223,17 +2448,17 @@ public class Parser {
// SELECT TOP 1 (+?) AS A FROM TEST
Expression limit = readTerm().optimize(session);
command.setLimit(limit);
} else if (readIf("LIMIT")) {
} else if (readIf(LIMIT)) {
Expression offset = readTerm().optimize(session);
command.setOffset(offset);
Expression limit = readTerm().optimize(session);
command.setLimit(limit);
}
currentSelect = temp;
if (readIf("DISTINCT")) {
if (readIf(DISTINCT)) {
command.setDistinct(true);
} else {
readIf("ALL");
readIf(ALL);
}
ArrayList<Expression> expressions = Utils.newSmallArrayList();
do {
......@@ -2255,9 +2480,9 @@ public class Parser {
private Select parseSelectSimple() {
boolean fromFirst;
if (readIf("SELECT")) {
if (readIf(SELECT)) {
fromFirst = false;
} else if (readIf("FROM")) {
} else if (readIf(FROM)) {
fromFirst = true;
} else {
throw getSyntaxError();
......@@ -2269,11 +2494,11 @@ public class Parser {
currentPrepared = command;
if (fromFirst) {
parseSelectSimpleFromPart(command);
read("SELECT");
read(SELECT);
parseSelectSimpleSelectPart(command);
} else {
parseSelectSimpleSelectPart(command);
if (!readIf("FROM")) {
if (!readIf(FROM)) {
// select without FROM: convert to SELECT ... FROM
// SYSTEM_RANGE(1,1)
Table dual = getDualTable(false);
......@@ -2285,14 +2510,14 @@ public class Parser {
parseSelectSimpleFromPart(command);
}
}
if (readIf("WHERE")) {
if (readIf(WHERE)) {
Expression condition = readExpression();
command.addCondition(condition);
}
// the group by is read for the outer select (or not a select)
// so that columns that are not grouped can be used
currentSelect = oldSelect;
if (readIf("GROUP")) {
if (readIf(GROUP)) {
read("BY");
command.setGroupQuery();
ArrayList<Expression> list = Utils.newSmallArrayList();
......@@ -2303,7 +2528,7 @@ public class Parser {
command.setGroupBy(list);
}
currentSelect = command;
if (readIf("HAVING")) {
if (readIf(HAVING)) {
command.setGroupQuery();
Expression condition = readExpression();
command.setHaving(condition);
......@@ -2352,23 +2577,23 @@ public class Parser {
}
private Expression readCondition() {
if (readIf("NOT")) {
if (readIf(NOT)) {
return new ConditionNot(readCondition());
}
if (readIf("EXISTS")) {
read("(");
if (readIf(EXISTS)) {
read(OPEN_PAREN);
Query query = parseSelect();
// can not reduce expression because it might be a union except
// query with distinct
read(")");
read(CLOSE_PAREN);
return new ConditionExists(query);
}
if (readIf("INTERSECTS")) {
read("(");
read(OPEN_PAREN);
Expression r1 = readConcat();
read(",");
Expression r2 = readConcat();
read(")");
read(CLOSE_PAREN);
return new Comparison(session, Comparison.SPATIAL_INTERSECTS, r1,
r2);
}
......@@ -2378,16 +2603,17 @@ public class Parser {
// TABLE TEST(ID INT DEFAULT 0 NOT NULL))
int backup = parseIndex;
boolean not = false;
if (readIf("NOT")) {
if (readIf(NOT)) {
not = true;
if (isToken("NULL")) {
if (isToken(NULL)) {
// this really only works for NOT NULL!
parseIndex = backup;
currentToken = "NOT";
currentTokenType = NOT;
break;
}
}
if (readIf("LIKE")) {
if (readIf(LIKE)) {
Expression b = readConcat();
Expression esc = null;
if (readIf("ESCAPE")) {
......@@ -2411,23 +2637,23 @@ public class Parser {
Expression b = readConcat();
recompileAlways = true;
r = new CompareLike(database, r, b, null, true);
} else if (readIf("IS")) {
if (readIf("NOT")) {
if (readIf("NULL")) {
} else if (readIf(IS)) {
if (readIf(NOT)) {
if (readIf(NULL)) {
r = new Comparison(session, Comparison.IS_NOT_NULL, r,
null);
} else if (readIf("DISTINCT")) {
read("FROM");
} else if (readIf(DISTINCT)) {
read(FROM);
r = new Comparison(session, Comparison.EQUAL_NULL_SAFE,
r, readConcat());
} else {
r = new Comparison(session,
Comparison.NOT_EQUAL_NULL_SAFE, r, readConcat());
}
} else if (readIf("NULL")) {
} else if (readIf(NULL)) {
r = new Comparison(session, Comparison.IS_NULL, r, null);
} else if (readIf("DISTINCT")) {
read("FROM");
} else if (readIf(DISTINCT)) {
read(FROM);
r = new Comparison(session, Comparison.NOT_EQUAL_NULL_SAFE,
r, readConcat());
} else {
......@@ -2435,8 +2661,8 @@ public class Parser {
readConcat());
}
} else if (readIf("IN")) {
read("(");
if (readIf(")")) {
read(OPEN_PAREN);
if (readIf(CLOSE_PAREN)) {
if (database.getMode().prohibitEmptyInPredicate) {
throw getSyntaxError();
}
......@@ -2466,7 +2692,7 @@ public class Parser {
r = new ConditionIn(database, r, v);
}
}
read(")");
read(CLOSE_PAREN);
}
} else if (readIf("BETWEEN")) {
Expression low = readConcat();
......@@ -2483,14 +2709,14 @@ public class Parser {
break;
}
read();
if (readIf("ALL")) {
read("(");
if (readIf(ALL)) {
read(OPEN_PAREN);
Query query = parseSelect();
r = new ConditionInSelect(database, r, query, true,
compareType);
read(")");
read(CLOSE_PAREN);
} else if (readIf("ANY") || readIf("SOME")) {
read("(");
read(OPEN_PAREN);
if (currentTokenType == PARAMETER && compareType == 0) {
Parameter p = readParameter();
r = new ConditionInParameter(database, r, p);
......@@ -2499,11 +2725,11 @@ public class Parser {
r = new ConditionInSelect(database, r, query, false,
compareType);
}
read(")");
read(CLOSE_PAREN);
} else {
Expression right = readConcat();
if (SysProperties.OLD_STYLE_OUTER_JOIN &&
readIf("(") && readIf("+") && readIf(")")) {
readIf(OPEN_PAREN) && readIf(PLUS_SIGN) && readIf(CLOSE_PAREN)) {
// support for a subset of old-fashioned Oracle outer
// join with (+)
if (r instanceof ExpressionColumn &&
......@@ -2548,7 +2774,7 @@ public class Parser {
private Expression readConcat() {
Expression r = readSum();
while (true) {
if (readIf("||")) {
if (readIf(STRING_CONCAT)) {
r = new Operation(OpType.CONCAT, r, readSum());
} else if (readIf("~")) {
if (readIf("*")) {
......@@ -2578,9 +2804,9 @@ public class Parser {
private Expression readSum() {
Expression r = readFactor();
while (true) {
if (readIf("+")) {
if (readIf(PLUS_SIGN)) {
r = new Operation(OpType.PLUS, r, readFactor());
} else if (readIf("-")) {
} else if (readIf(MINUS_SIGN)) {
r = new Operation(OpType.MINUS, r, readFactor());
} else {
return r;
......@@ -2614,7 +2840,7 @@ public class Parser {
r = new Aggregate(AggregateType.COUNT_ALL, null, currentSelect,
false);
} else {
boolean distinct = readIf("DISTINCT");
boolean distinct = readIf(DISTINCT);
Expression on = readExpression();
if (on instanceof Wildcard && !distinct) {
// PostgreSQL compatibility: count(t.*)
......@@ -2626,12 +2852,12 @@ public class Parser {
}
}
} else if (aggregateType == AggregateType.GROUP_CONCAT) {
boolean distinct = readIf("DISTINCT");
boolean distinct = readIf(DISTINCT);
if (equalsToken("GROUP_CONCAT", aggregateName)) {
r = new Aggregate(AggregateType.GROUP_CONCAT,
readExpression(), currentSelect, distinct);
if (readIf("ORDER")) {
if (readIf(ORDER)) {
read("BY");
r.setOrderByList(parseSimpleOrderList());
}
......@@ -2645,7 +2871,7 @@ public class Parser {
readExpression(), currentSelect, distinct);
read(",");
r.setGroupConcatSeparator(readExpression());
if (readIf("ORDER")) {
if (readIf(ORDER)) {
read("BY");
r.setOrderByList(parseSimpleOrderList());
}
......@@ -2653,20 +2879,20 @@ public class Parser {
r = null;
}
} else if (aggregateType == AggregateType.ARRAY_AGG) {
boolean distinct = readIf("DISTINCT");
boolean distinct = readIf(DISTINCT);
r = new Aggregate(AggregateType.ARRAY_AGG,
readExpression(), currentSelect, distinct);
if (readIf("ORDER")) {
if (readIf(ORDER)) {
read("BY");
r.setOrderByList(parseSimpleOrderList());
}
} else {
boolean distinct = readIf("DISTINCT");
boolean distinct = readIf(DISTINCT);
r = new Aggregate(aggregateType, readExpression(), currentSelect,
distinct);
}
read(")");
read(CLOSE_PAREN);
if (r != null) {
r.setFilterCondition(readFilterCondition());
}
......@@ -2701,7 +2927,7 @@ public class Parser {
}
Expression[] args;
ArrayList<Expression> argList = Utils.newSmallArrayList();
if (!readIf(")")) {
if (!readIf(CLOSE_PAREN)) {
do {
argList.add(readExpression());
} while (readIfMore(true));
......@@ -2711,7 +2937,7 @@ public class Parser {
}
private JavaAggregate readJavaAggregate(UserAggregate aggregate) {
boolean distinct = readIf("DISTINCT");
boolean distinct = readIf(DISTINCT);
ArrayList<Expression> params = Utils.newSmallArrayList();
do {
params.add(readExpression());
......@@ -2725,10 +2951,10 @@ public class Parser {
private Expression readFilterCondition() {
if (readIf("FILTER")) {
read("(");
read("WHERE");
read(OPEN_PAREN);
read(WHERE);
Expression filterCondition = readExpression();
read(")");
read(CLOSE_PAREN);
return filterCondition;
}
return null;
......@@ -2774,7 +3000,7 @@ public class Parser {
read("AS");
Column type = parseColumnWithType(null, false);
function.setDataType(type);
read(")");
read(CLOSE_PAREN);
break;
}
case Function.CONVERT: {
......@@ -2783,13 +3009,13 @@ public class Parser {
function.setDataType(type);
read(",");
function.setParameter(0, readExpression());
read(")");
read(CLOSE_PAREN);
} else {
function.setParameter(0, readExpression());
read(",");
Column type = parseColumnWithType(null, false);
function.setDataType(type);
read(")");
read(CLOSE_PAREN);
}
break;
}
......@@ -2797,9 +3023,9 @@ public class Parser {
function.setParameter(0,
ValueExpression.get(ValueString.get(currentToken)));
read();
read("FROM");
read(FROM);
function.setParameter(1, readExpression());
read(")");
read(CLOSE_PAREN);
break;
}
case Function.DATE_ADD:
......@@ -2815,7 +3041,7 @@ public class Parser {
function.setParameter(1, readExpression());
read(",");
function.setParameter(2, readExpression());
read(")");
read(CLOSE_PAREN);
break;
}
case Function.SUBSTRING: {
......@@ -2826,12 +3052,12 @@ public class Parser {
// SUBSTRING(X FROM 1) -- Postgres
// SUBSTRING(X FOR 1) -- Postgres
function.setParameter(0, readExpression());
if (readIf("FROM")) {
if (readIf(FROM)) {
function.setParameter(1, readExpression());
if (readIf("FOR")) {
if (readIf(FOR)) {
function.setParameter(2, readExpression());
}
} else if (readIf("FOR")) {
} else if (readIf(FOR)) {
function.setParameter(1, ValueExpression.get(ValueInt.get(0)));
function.setParameter(2, readExpression());
} else {
......@@ -2841,7 +3067,7 @@ public class Parser {
function.setParameter(2, readExpression());
}
}
read(")");
read(CLOSE_PAREN);
break;
}
case Function.POSITION: {
......@@ -2851,33 +3077,33 @@ public class Parser {
read("IN");
}
function.setParameter(1, readExpression());
read(")");
read(CLOSE_PAREN);
break;
}
case Function.TRIM: {
Expression space = null;
if (readIf("LEADING")) {
function = Function.getFunction(database, "LTRIM");
if (!readIf("FROM")) {
if (!readIf(FROM)) {
space = readExpression();
read("FROM");
read(FROM);
}
} else if (readIf("TRAILING")) {
function = Function.getFunction(database, "RTRIM");
if (!readIf("FROM")) {
if (!readIf(FROM)) {
space = readExpression();
read("FROM");
read(FROM);
}
} else if (readIf("BOTH")) {
if (!readIf("FROM")) {
if (!readIf(FROM)) {
space = readExpression();
read("FROM");
read(FROM);
}
}
Expression p0 = readExpression();
if (readIf(",")) {
space = readExpression();
} else if (readIf("FROM")) {
} else if (readIf(FROM)) {
space = p0;
p0 = readExpression();
}
......@@ -2885,7 +3111,7 @@ public class Parser {
if (space != null) {
function.setParameter(1, space);
}
read(")");
read(CLOSE_PAREN);
break;
}
case Function.TABLE:
......@@ -2896,7 +3122,7 @@ public class Parser {
String columnName = readAliasIdentifier();
Column column = parseColumnWithType(columnName, false);
columns.add(column);
read("=");
read(EQUAL);
function.setParameter(i, readExpression());
i++;
} while (readIfMore(true));
......@@ -2905,17 +3131,17 @@ public class Parser {
break;
}
case Function.ROW_NUMBER:
read(")");
read(CLOSE_PAREN);
read("OVER");
read("(");
read(")");
read(OPEN_PAREN);
read(CLOSE_PAREN);
if (currentSelect == null && currentPrepared == null) {
throw getSyntaxError();
}
return new Rownum(currentSelect == null ? currentPrepared
: currentSelect);
default:
if (!readIf(")")) {
if (!readIf(CLOSE_PAREN)) {
int i = 0;
do {
function.setParameter(i++, readExpression());
......@@ -2927,8 +3153,8 @@ public class Parser {
}
private Expression readFunctionWithoutParameters(String name) {
if (readIf("(")) {
read(")");
if (readIf(OPEN_PAREN)) {
read(CLOSE_PAREN);
}
if (database.isAllowBuiltinAliasOverride()) {
FunctionAlias functionAlias = database.getSchema(session.getCurrentSchemaName()).findFunction(name);
......@@ -2976,7 +3202,7 @@ public class Parser {
}
String name = readColumnIdentifier();
Schema s = database.findSchema(objectName);
if ((!SysProperties.OLD_STYLE_OUTER_JOIN || s != null) && readIf("(")) {
if ((!SysProperties.OLD_STYLE_OUTER_JOIN || s != null) && readIf(OPEN_PAREN)) {
// only if the token before the dot is a valid schema name,
// otherwise the old style Oracle outer join doesn't work:
// t.x = t2.x(+)
......@@ -2991,7 +3217,7 @@ public class Parser {
return expr;
}
name = readColumnIdentifier();
if (readIf("(")) {
if (readIf(OPEN_PAREN)) {
String databaseName = schema;
if (!equalsToken(database.getShortName(), databaseName)) {
throw DbException.get(ErrorCode.DATABASE_NOT_FOUND_1,
......@@ -3083,19 +3309,18 @@ public class Parser {
case PARAMETER:
r = readParameter();
break;
case KEYWORD:
if (isToken("SELECT") || isToken("FROM") || isToken("WITH")) {
Query query = parseSelect();
r = new Subquery(query);
} else {
throw getSyntaxError();
}
case SELECT:
case FROM:
case WITH:
r = new Subquery(parseSelect());
break;
case KEYWORD:
throw getSyntaxError();
case IDENTIFIER:
String name = currentToken;
if (currentTokenQuoted) {
read();
if (readIf("(")) {
if (readIf(OPEN_PAREN)) {
r = readFunction(null, name);
} else if (readIf(".")) {
r = readTermObjectDot(name);
......@@ -3111,7 +3336,7 @@ public class Parser {
// otherwise CASE(3) would be a function call, which it is
// not
r = readCase();
} else if (readIf("(")) {
} else if (readIf(OPEN_PAREN)) {
r = readFunction(null, name);
} else if (equalsToken("CURRENT_USER", name)) {
r = readFunctionWithoutParameters("USER");
......@@ -3144,7 +3369,7 @@ public class Parser {
r = new ExpressionColumn(database, null, null, name);
}
} else if (equalsToken("NEXT", name) && readIf("VALUE")) {
read("FOR");
read(FOR);
Sequence sequence = readSequence();
r = new SequenceValue(sequence);
} else if (equalsToken("TIME", name)) {
......@@ -3165,7 +3390,7 @@ public class Parser {
r = ValueExpression.get(ValueTime.parse(time));
}
} else if (equalsToken("TIMESTAMP", name)) {
if (readIf("WITH")) {
if (readIf(WITH)) {
read("TIME");
read("ZONE");
if (currentTokenType != VALUE
......@@ -3236,7 +3461,7 @@ public class Parser {
}
}
break;
case MINUS:
case MINUS_SIGN:
read();
if (currentTokenType == VALUE) {
r = ValueExpression.get(currentValue.negate());
......@@ -3257,20 +3482,20 @@ public class Parser {
r = new Operation(OpType.NEGATE, readTerm(), null);
}
break;
case PLUS:
case PLUS_SIGN:
read();
r = readTerm();
break;
case OPEN:
case OPEN_PAREN:
read();
if (readIf(")")) {
if (readIf(CLOSE_PAREN)) {
r = new ExpressionList(new Expression[0]);
} else {
r = readExpression();
if (readIfMore(true)) {
ArrayList<Expression> list = Utils.newSmallArrayList();
list.add(r);
if (!readIf(")")) {
if (!readIf(CLOSE_PAREN)) {
do {
list.add(readExpression());
} while (readIfMore(false));
......@@ -3289,8 +3514,8 @@ public class Parser {
break;
case ROWNUM:
read();
if (readIf("(")) {
read(")");
if (readIf(OPEN_PAREN)) {
read(CLOSE_PAREN);
}
if (currentSelect == null && currentPrepared == null) {
throw getSyntaxError();
......@@ -3407,10 +3632,10 @@ public class Parser {
private int readInt() {
boolean minus = false;
if (currentTokenType == MINUS) {
if (currentTokenType == MINUS_SIGN) {
minus = true;
read();
} else if (currentTokenType == PLUS) {
} else if (currentTokenType == PLUS_SIGN) {
read();
}
if (currentTokenType != VALUE) {
......@@ -3427,10 +3652,10 @@ public class Parser {
private long readLong() {
boolean minus = false;
if (currentTokenType == MINUS) {
if (currentTokenType == MINUS_SIGN) {
minus = true;
read();
} else if (currentTokenType == PLUS) {
} else if (currentTokenType == PLUS_SIGN) {
read();
}
if (currentTokenType != VALUE) {
......@@ -3458,7 +3683,7 @@ public class Parser {
read();
return result;
}
if (readIf("ON")) {
if (readIf(ON)) {
return true;
} else if (readIf("OFF")) {
return false;
......@@ -3539,6 +3764,14 @@ public class Parser {
read();
}
private void read(int tokenType) {
if (tokenType != currentTokenType) {
addExpected(tokenType);
throw getSyntaxError();
}
read();
}
private boolean readIf(String token) {
if (!currentTokenQuoted && equalsToken(token, currentToken)) {
read();
......@@ -3548,6 +3781,15 @@ public class Parser {
return false;
}
private boolean readIf(int tokenType) {
if (tokenType == currentTokenType) {
read();
return true;
}
addExpected(tokenType);
return false;
}
private boolean isToken(String token) {
if (!currentTokenQuoted && equalsToken(token, currentToken)) {
return true;
......@@ -3556,6 +3798,14 @@ public class Parser {
return false;
}
private boolean isToken(int tokenType) {
if (tokenType == currentTokenType) {
return true;
}
addExpected(tokenType);
return false;
}
private boolean equalsToken(String a, String b) {
if (a == null) {
return b == null;
......@@ -3581,6 +3831,12 @@ public class Parser {
}
}
private void addExpected(int tokenType) {
if (expectedList != null) {
expectedList.add(TOKENS[tokenType]);
}
}
private void read() {
currentTokenQuoted = false;
if (expectedList != null) {
......@@ -4085,9 +4341,9 @@ public class Parser {
case '@':
return AT;
case '+':
return PLUS;
return PLUS_SIGN;
case '-':
return MINUS;
return MINUS_SIGN;
case '{':
case '}':
case '*':
......@@ -4101,9 +4357,9 @@ public class Parser {
case '~':
return KEYWORD;
case '(':
return OPEN;
return OPEN_PAREN;
case ')':
return CLOSE;
return CLOSE_PAREN;
case '<':
return SMALLER;
case '>':
......@@ -4242,21 +4498,21 @@ public class Parser {
read("AS");
read("IDENTITY");
long start = 1, increment = 1;
if (readIf("(")) {
if (readIf(OPEN_PAREN)) {
read("START");
readIf("WITH");
readIf(WITH);
start = readLong();
readIf(",");
if (readIf("INCREMENT")) {
readIf("BY");
increment = readLong();
}
read(")");
read(CLOSE_PAREN);
}
column.setPrimaryKey(true);
column.setAutoIncrement(true, start, increment);
}
if (readIf("ON")) {
if (readIf(ON)) {
read("UPDATE");
Expression onUpdateExpression = readExpression();
column.setOnUpdateExpression(session, onUpdateExpression);
......@@ -4292,19 +4548,19 @@ public class Parser {
private void parseAutoIncrement(Column column) {
long start = 1, increment = 1;
if (readIf("(")) {
if (readIf(OPEN_PAREN)) {
start = readLong();
if (readIf(",")) {
increment = readLong();
}
read(")");
read(CLOSE_PAREN);
}
column.setAutoIncrement(true, start, increment);
}
private String readCommentIf() {
if (readIf("COMMENT")) {
readIf("IS");
readIf(IS);
return readString();
}
return null;
......@@ -4327,12 +4583,12 @@ public class Parser {
original += " VARYING";
}
} else if (readIf("TIME")) {
if (readIf("(")) {
if (readIf(OPEN_PAREN)) {
originalScale = readNonNegativeInt();
if (originalScale > ValueTime.MAXIMUM_SCALE) {
throw DbException.get(ErrorCode.INVALID_VALUE_SCALE_PRECISION, Integer.toString(originalScale));
}
read(")");
read(CLOSE_PAREN);
}
if (readIf("WITHOUT")) {
read("TIME");
......@@ -4340,7 +4596,7 @@ public class Parser {
original += " WITHOUT TIME ZONE";
}
} else if (readIf("TIMESTAMP")) {
if (readIf("(")) {
if (readIf(OPEN_PAREN)) {
originalScale = readNonNegativeInt();
// Allow non-standard TIMESTAMP(..., ...) syntax
if (readIf(",")) {
......@@ -4349,9 +4605,9 @@ public class Parser {
if (originalScale > ValueTimestamp.MAXIMUM_SCALE) {
throw DbException.get(ErrorCode.INVALID_VALUE_SCALE_PRECISION, Integer.toString(originalScale));
}
read(")");
read(CLOSE_PAREN);
}
if (readIf("WITH")) {
if (readIf(WITH)) {
read("TIME");
read("ZONE");
original += " WITH TIME ZONE";
......@@ -4431,13 +4687,13 @@ public class Parser {
break;
}
} else if (original.equals("DATETIME") || original.equals("DATETIME2")) {
if (readIf("(")) {
if (readIf(OPEN_PAREN)) {
originalScale = readNonNegativeInt();
if (originalScale > ValueTime.MAXIMUM_SCALE) {
throw DbException.get(ErrorCode.INVALID_VALUE_SCALE_PRECISION,
Integer.toString(originalScale));
}
read(")");
read(CLOSE_PAREN);
scale = originalScale;
original = original + '(' + originalScale + ')';
precision = displaySize = ValueTimestamp.getDisplaySize(originalScale);
......@@ -4446,7 +4702,7 @@ public class Parser {
scale = 0;
precision = displaySize = ValueTimestamp.getDisplaySize(0);
}
} else if (readIf("(")) {
} else if (readIf(OPEN_PAREN)) {
if (!readIf("MAX")) {
long p = readLong();
if (readIf("K")) {
......@@ -4476,12 +4732,12 @@ public class Parser {
displaySize = MathUtils.convertLongToInt(precision);
original += ")";
}
read(")");
read(CLOSE_PAREN);
}
} else if (dataType.type == Value.DOUBLE && original.equals("FLOAT")) {
if (readIf("(")) {
if (readIf(OPEN_PAREN)) {
int p = readNonNegativeInt();
read(")");
read(CLOSE_PAREN);
if (p > 53) {
throw DbException.get(ErrorCode.INVALID_VALUE_SCALE_PRECISION, Integer.toString(p));
}
......@@ -4491,7 +4747,7 @@ public class Parser {
original = original + '(' + p + ')';
}
} else if (dataType.type == Value.ENUM) {
if (readIf("(")) {
if (readIf(OPEN_PAREN)) {
java.util.List<String> enumeratorList = new ArrayList<>();
original += '(';
String enumerator0 = readString();
......@@ -4511,13 +4767,13 @@ public class Parser {
} catch (DbException e) {
throw e.addSQL(original);
}
} else if (readIf("(")) {
} else if (readIf(OPEN_PAREN)) {
// Support for MySQL: INT(11), MEDIUMINT(8) and so on.
// Just ignore the precision.
readNonNegativeInt();
read(")");
read(CLOSE_PAREN);
}
if (readIf("FOR")) {
if (readIf(FOR)) {
read("BIT");
read("DATA");
if (dataType.type == Value.STRING) {
......@@ -4624,19 +4880,19 @@ public class Parser {
String indexName = null;
Schema oldSchema = null;
boolean ifNotExists = false;
if (readIf("PRIMARY")) {
if (readIf(PRIMARY)) {
read("KEY");
if (readIf("HASH")) {
hash = true;
}
primaryKey = true;
if (!isToken("ON")) {
if (!isToken(ON)) {
ifNotExists = readIfNotExists();
indexName = readIdentifierWithSchema(null);
oldSchema = getSchema();
}
} else {
if (readIf("UNIQUE")) {
if (readIf(UNIQUE)) {
unique = true;
}
if (readIf("HASH")) {
......@@ -4646,7 +4902,7 @@ public class Parser {
spatial = true;
}
if (readIf("INDEX")) {
if (!isToken("ON")) {
if (!isToken(ON)) {
ifNotExists = readIfNotExists();
indexName = readIdentifierWithSchema(null);
oldSchema = getSchema();
......@@ -4655,7 +4911,7 @@ public class Parser {
throw getSyntaxError();
}
}
read("ON");
read(ON);
String tableName = readIdentifierWithSchema();
checkSchema(oldSchema);
CreateIndex command = new CreateIndex(session, getSchema());
......@@ -4665,7 +4921,7 @@ public class Parser {
command.setUnique(unique);
command.setIndexName(indexName);
command.setComment(readCommentIf());
read("(");
read(OPEN_PAREN);
command.setIndexColumns(parseIndexColumnList());
if (readIf("USING")) {
......@@ -4696,7 +4952,7 @@ public class Parser {
* @return true if we expect to see a TABLE clause
*/
private boolean addRoleOrRight(GrantRevoke command) {
if (readIf("SELECT")) {
if (readIf(SELECT)) {
command.addRight(Right.SELECT);
return true;
} else if (readIf("DELETE")) {
......@@ -4708,7 +4964,7 @@ public class Parser {
} else if (readIf("UPDATE")) {
command.addRight(Right.UPDATE);
return true;
} else if (readIf("ALL")) {
} else if (readIf(ALL)) {
command.addRight(Right.ALL);
return true;
} else if (readIf("ALTER")) {
......@@ -4741,7 +4997,7 @@ public class Parser {
}
}
if (tableClauseExpected) {
if (readIf("ON")) {
if (readIf(ON)) {
if (readIf("SCHEMA")) {
Schema schema = database.getSchema(readAliasIdentifier());
command.setSchema(schema);
......@@ -4756,7 +5012,7 @@ public class Parser {
if (operationType == CommandInterface.GRANT) {
read("TO");
} else {
read("FROM");
read(FROM);
}
command.setGranteeName(readUniqueIdentifier());
return command;
......@@ -4783,7 +5039,7 @@ public class Parser {
do {
int i = 0;
ArrayList<Expression> row = Utils.newSmallArrayList();
boolean multiColumn = readIf("(");
boolean multiColumn = readIf(OPEN_PAREN);
do {
Expression expr = readExpression();
expr = expr.optimize(session);
......@@ -4874,7 +5130,7 @@ public class Parser {
} else {
command.setAuthorization(session.getUser().getName());
}
if (readIf("WITH")) {
if (readIf(WITH)) {
command.setTableEngineParams(readTableEngineParams());
}
return command;
......@@ -4896,7 +5152,7 @@ public class Parser {
command.setSequenceName(sequenceName);
while (true) {
if (readIf("START")) {
readIf("WITH");
readIf(WITH);
command.setStartWith(readExpression());
} else if (readIf("INCREMENT")) {
readIf("BY");
......@@ -4931,7 +5187,7 @@ public class Parser {
command.setCacheSize(ValueExpression.get(ValueLong.get(1)));
} else if (readIf("BELONGS_TO_TABLE")) {
command.setBelongsToTable(true);
} else if (readIf("ORDER")) {
} else if (readIf(ORDER)) {
// Oracle compatibility
} else {
break;
......@@ -4942,8 +5198,8 @@ public class Parser {
private boolean readIfNotExists() {
if (readIf("IF")) {
read("NOT");
read("EXISTS");
read(NOT);
read(EXISTS);
return true;
}
return false;
......@@ -4983,7 +5239,7 @@ public class Parser {
command.setName(name);
command.setSchema(getSchema());
command.setIfNotExists(ifNotExists);
read("FOR");
read(FOR);
command.setJavaClassMethod(readUniqueIdentifier());
return command;
}
......@@ -4994,7 +5250,7 @@ public class Parser {
command.setTypeName(readUniqueIdentifier());
read("AS");
Column col = parseColumnForTable("VALUE", true, false);
if (readIf("CHECK")) {
if (readIf(CHECK)) {
Expression expr = readExpression();
col.addCheckConstraint(session, expr);
}
......@@ -5030,7 +5286,7 @@ public class Parser {
typeMask |= Trigger.UPDATE;
} else if (readIf("DELETE")) {
typeMask |= Trigger.DELETE;
} else if (readIf("SELECT")) {
} else if (readIf(SELECT)) {
typeMask |= Trigger.SELECT;
} else if (readIf("ROLLBACK")) {
onRollback = true;
......@@ -5040,7 +5296,7 @@ public class Parser {
} while (readIf(",")
|| (database.getMode().getEnum() == ModeEnum.PostgreSQL
&& readIf("OR")));
read("ON");
read(ON);
String tableName = readIdentifierWithSchema();
checkSchema(schema);
CreateTrigger command = new CreateTrigger(session, getSchema());
......@@ -5052,7 +5308,7 @@ public class Parser {
command.setOnRollback(onRollback);
command.setTypeMask(typeMask);
command.setTableName(tableName);
if (readIf("FOR")) {
if (readIf(FOR)) {
read("EACH");
read("ROW");
command.setRowBased(true);
......@@ -5119,7 +5375,7 @@ public class Parser {
if (readIf("AS")) {
command.setSource(readString());
} else {
read("FOR");
read(FOR);
command.setJavaClassMethod(readUniqueIdentifier());
}
return command;
......@@ -5144,7 +5400,7 @@ public class Parser {
// used in setCteCleanups.
Collections.reverse(viewsCreated);
if (isToken("SELECT")) {
if (isToken(SELECT)) {
Query query = parseSelectUnion();
query.setPrepareAlways(true);
query.setNeverLazy(true);
......@@ -5190,7 +5446,7 @@ public class Parser {
// column names are now optional - they can be inferred from the named
// query, if not supplied by user
if (readIf("(")) {
if (readIf(OPEN_PAREN)) {
cols = parseColumnList();
for (String c : cols) {
// we don't really know the type of the column, so STRING will
......@@ -5237,12 +5493,12 @@ public class Parser {
String[] querySQLOutput = {null};
try {
read("AS");
read("(");
read(OPEN_PAREN);
Query withQuery = parseSelect();
if (!isTemporary) {
withQuery.session = session;
}
read(")");
read(CLOSE_PAREN);
columnTemplateList = TableView.createQueryColumnTemplateList(cols, withQuery, querySQLOutput);
} finally {
......@@ -5317,7 +5573,7 @@ public class Parser {
command.setOrReplace(orReplace);
command.setForce(force);
command.setTableExpression(isTableExpression);
if (readIf("(")) {
if (readIf(OPEN_PAREN)) {
String[] cols = parseColumnList();
command.setColumnNames(cols);
}
......@@ -5442,7 +5698,7 @@ public class Parser {
command.setIfExists(ifExists);
while (true) {
if (readIf("RESTART")) {
read("WITH");
read(WITH);
command.setStartWith(readExpression());
} else if (readIf("INCREMENT")) {
read("BY");
......@@ -5511,9 +5767,9 @@ public class Parser {
command.setType(CommandInterface.ALTER_USER_ADMIN);
User user = database.getUser(userName);
command.setUser(user);
if (readIf("TRUE")) {
if (readIf(TRUE)) {
command.setAdmin(true);
} else if (readIf("FALSE")) {
} else if (readIf(FALSE)) {
command.setAdmin(false);
} else {
throw getSyntaxError();
......@@ -5524,13 +5780,13 @@ public class Parser {
}
private void readIfEqualOrTo() {
if (!readIf("=")) {
if (!readIf(EQUAL)) {
readIf("TO");
}
}
private Prepared parseSet() {
if (readIf("@")) {
if (readIf(AT)) {
Set command = new Set(session, SetTypes.VARIABLE);
command.setString(readAliasIdentifier());
readIfEqualOrTo();
......@@ -5612,7 +5868,7 @@ public class Parser {
Set command = new Set(session, SetTypes.ALLOW_LITERALS);
if (readIf("NONE")) {
command.setInt(Constants.ALLOW_LITERALS_NONE);
} else if (readIf("ALL")) {
} else if (readIf(ALL)) {
command.setInt(Constants.ALLOW_LITERALS_ALL);
} else if (readIf("NUMBERS")) {
command.setInt(Constants.ALLOW_LITERALS_NUMBERS);
......@@ -5770,7 +6026,7 @@ public class Parser {
throw DbException.getInvalidValueException("collation", name);
}
if (readIf("STRENGTH")) {
if (readIf("PRIMARY")) {
if (readIf(PRIMARY)) {
command.setInt(Collator.PRIMARY);
} else if (readIf("SECONDARY")) {
command.setInt(Collator.SECONDARY);
......@@ -5804,7 +6060,7 @@ public class Parser {
private RunScriptCommand parseRunScript() {
RunScriptCommand command = new RunScriptCommand(session);
read("FROM");
read(FROM);
command.setFileNameExpr(readExpression());
if (readIf("COMPRESSION")) {
command.setCompressionAlgorithm(readUniqueIdentifier());
......@@ -5988,7 +6244,7 @@ public class Parser {
schema, type, value);
command.setTableName(tableName);
command.setIfTableExists(ifTableExists);
if (readIf("CHECK")) {
if (readIf(CHECK)) {
command.setCheckExisting(true);
} else if (readIf("NOCHECK")) {
command.setCheckExisting(false);
......@@ -6007,7 +6263,7 @@ public class Parser {
String newName = readColumnIdentifier();
command.setNewColumnName(newName);
return command;
} else if (readIf("CONSTRAINT")) {
} else if (readIf(CONSTRAINT)) {
String constraintName = readIdentifierWithSchema(schema.getName());
checkSchema(schema);
read("TO");
......@@ -6030,7 +6286,7 @@ public class Parser {
return command;
}
} else if (readIf("DROP")) {
if (readIf("CONSTRAINT")) {
if (readIf(CONSTRAINT)) {
boolean ifExists = readIfExists(false);
String constraintName = readIdentifierWithSchema(schema.getName());
ifExists = readIfExists(ifExists);
......@@ -6039,7 +6295,7 @@ public class Parser {
session, getSchema(), ifExists);
command.setConstraintName(constraintName);
return commandIfTableExists(schema, tableName, ifTableExists, command);
} else if (readIf("FOREIGN")) {
} else if (readIf(FOREIGN)) {
// MySQL compatibility
read("KEY");
String constraintName = readIdentifierWithSchema(schema.getName());
......@@ -6063,7 +6319,7 @@ public class Parser {
command = dropCommand;
}
return commandIfTableExists(schema, tableName, ifTableExists, command);
} else if (readIf("PRIMARY")) {
} else if (readIf(PRIMARY)) {
read("KEY");
Table table = tableIfTableExists(schema, tableName, ifTableExists);
if (table == null) {
......@@ -6079,7 +6335,7 @@ public class Parser {
ArrayList<Column> columnsToRemove = new ArrayList<>();
Table table = tableIfTableExists(schema, tableName, ifTableExists);
// For Oracle compatibility - open bracket required
boolean openingBracketDetected = readIf("(");
boolean openingBracketDetected = readIf(OPEN_PAREN);
do {
String columnName = readColumnIdentifier();
if (table != null) {
......@@ -6091,7 +6347,7 @@ public class Parser {
} while (readIf(","));
if (openingBracketDetected) {
// For Oracle compatibility - close bracket
read(")");
read(CLOSE_PAREN);
}
if (table == null || columnsToRemove.isEmpty()) {
return new NoOperation(session);
......@@ -6123,7 +6379,7 @@ public class Parser {
// MySQL compatibility (optional)
readIf("COLUMN");
// Oracle specifies (but will not require) an opening parenthesis
boolean hasOpeningBracket = readIf("(");
boolean hasOpeningBracket = readIf(OPEN_PAREN);
String columnName = readColumnIdentifier();
AlterTableAlterColumn command;
NullConstraintType nullConstraint = parseNotNullConstraint();
......@@ -6149,7 +6405,7 @@ public class Parser {
"Internal Error - unhandled case: " + nullConstraint.name());
}
if(hasOpeningBracket) {
read(")");
read(CLOSE_PAREN);
}
return command;
} else if (readIf("ALTER")) {
......@@ -6178,7 +6434,7 @@ public class Parser {
command.setDefaultExpression(null);
return command;
}
if (readIf("ON")) {
if (readIf(ON)) {
read("UPDATE");
AlterTableAlterColumn command = new AlterTableAlterColumn(session, schema);
command.setTableName(tableName);
......@@ -6188,8 +6444,8 @@ public class Parser {
command.setDefaultExpression(null);
return command;
}
read("NOT");
read("NULL");
read(NOT);
read(NULL);
AlterTableAlterColumn command = new AlterTableAlterColumn(
session, schema);
command.setTableName(tableName);
......@@ -6226,7 +6482,7 @@ public class Parser {
Expression defaultExpression = readExpression();
command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_DEFAULT);
command.setDefaultExpression(defaultExpression);
} else if (readIf("ON")) {
} else if (readIf(ON)) {
read("UPDATE");
Expression onUpdateExpression = readExpression();
command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_ON_UPDATE);
......@@ -6245,7 +6501,7 @@ public class Parser {
}
return command;
} else if (readIf("RESTART")) {
readIf("WITH");
readIf(WITH);
Expression start = readExpression();
AlterSequence command = new AlterSequence(session, schema);
command.setColumn(column);
......@@ -6312,7 +6568,7 @@ public class Parser {
command.setType(CommandInterface.ALTER_TABLE_ADD_COLUMN);
command.setTableName(tableName);
command.setIfTableExists(ifTableExists);
if (readIf("(")) {
if (readIf(OPEN_PAREN)) {
command.setIfNotExists(false);
do {
parseTableColumnDefinition(command, schema, tableName);
......@@ -6342,7 +6598,7 @@ public class Parser {
return ConstraintActionType.RESTRICT;
}
read("SET");
if (readIf("NULL")) {
if (readIf(NULL)) {
return ConstraintActionType.SET_NULL;
}
read("DEFAULT");
......@@ -6365,14 +6621,14 @@ public class Parser {
boolean ifNotExists = false;
boolean allowIndexDefinition = database.getMode().indexDefinitionInCreateTable;
boolean allowAffinityKey = database.getMode().allowAffinityKey;
if (readIf("CONSTRAINT")) {
if (readIf(CONSTRAINT)) {
ifNotExists = readIfNotExists();
constraintName = readIdentifierWithSchema(schema.getName());
checkSchema(schema);
comment = readCommentIf();
allowIndexDefinition = true;
}
if (readIf("PRIMARY")) {
if (readIf(PRIMARY)) {
read("KEY");
AlterTableAddConstraint command = new AlterTableAddConstraint(
session, schema, ifNotExists);
......@@ -6384,7 +6640,7 @@ public class Parser {
if (readIf("HASH")) {
command.setPrimaryKeyHash(true);
}
read("(");
read(OPEN_PAREN);
command.setIndexColumns(parseIndexColumnList());
if (readIf("INDEX")) {
String indexName = readIdentifierWithSchema();
......@@ -6406,9 +6662,9 @@ public class Parser {
command.setComment(comment);
command.setTableName(tableName);
command.setIfTableExists(ifTableExists);
if (!readIf("(")) {
if (!readIf(OPEN_PAREN)) {
command.setIndexName(readUniqueIdentifier());
read("(");
read(OPEN_PAREN);
}
command.setIndexColumns(parseIndexColumnList());
// MySQL compatibility
......@@ -6418,24 +6674,24 @@ public class Parser {
return command;
} else if (allowAffinityKey && readIfAffinity()) {
read("KEY");
read("(");
read(OPEN_PAREN);
CreateIndex command = createAffinityIndex(schema, tableName, parseIndexColumnList());
command.setIfTableExists(ifTableExists);
return command;
}
AlterTableAddConstraint command;
if (readIf("CHECK")) {
if (readIf(CHECK)) {
command = new AlterTableAddConstraint(session, schema, ifNotExists);
command.setType(CommandInterface.ALTER_TABLE_ADD_CONSTRAINT_CHECK);
command.setCheckExpression(readExpression());
} else if (readIf("UNIQUE")) {
} else if (readIf(UNIQUE)) {
readIf("KEY");
readIf("INDEX");
command = new AlterTableAddConstraint(session, schema, ifNotExists);
command.setType(CommandInterface.ALTER_TABLE_ADD_CONSTRAINT_UNIQUE);
if (!readIf("(")) {
if (!readIf(OPEN_PAREN)) {
constraintName = readUniqueIdentifier();
read("(");
read(OPEN_PAREN);
}
command.setIndexColumns(parseIndexColumnList());
if (readIf("INDEX")) {
......@@ -6446,11 +6702,11 @@ public class Parser {
if (readIf("USING")) {
read("BTREE");
}
} else if (readIf("FOREIGN")) {
} else if (readIf(FOREIGN)) {
command = new AlterTableAddConstraint(session, schema, ifNotExists);
command.setType(CommandInterface.ALTER_TABLE_ADD_CONSTRAINT_REFERENTIAL);
read("KEY");
read("(");
read(OPEN_PAREN);
command.setIndexColumns(parseIndexColumnList());
if (readIf("INDEX")) {
String indexName = readIdentifierWithSchema();
......@@ -6467,7 +6723,7 @@ public class Parser {
if (readIf("NOCHECK")) {
command.setCheckExisting(false);
} else {
readIf("CHECK");
readIf(CHECK);
command.setCheckExisting(true);
}
command.setTableName(tableName);
......@@ -6479,13 +6735,13 @@ public class Parser {
private void parseReferences(AlterTableAddConstraint command,
Schema schema, String tableName) {
if (readIf("(")) {
if (readIf(OPEN_PAREN)) {
command.setRefTableName(schema, tableName);
command.setRefIndexColumns(parseIndexColumnList());
} else {
String refTableName = readIdentifierWithSchema(schema.getName());
command.setRefTableName(getSchema(), refTableName);
if (readIf("(")) {
if (readIf(OPEN_PAREN)) {
command.setRefIndexColumns(parseIndexColumnList());
}
}
......@@ -6493,7 +6749,7 @@ public class Parser {
String indexName = readIdentifierWithSchema();
command.setRefIndex(getSchema().findIndex(session, indexName));
}
while (readIf("ON")) {
while (readIf(ON)) {
if (readIf("DELETE")) {
command.setDeleteAction(parseAction());
} else {
......@@ -6501,7 +6757,7 @@ public class Parser {
command.setUpdateAction(parseAction());
}
}
if (readIf("NOT")) {
if (readIf(NOT)) {
read("DEFERRABLE");
} else {
readIf("DEFERRABLE");
......@@ -6520,7 +6776,7 @@ public class Parser {
command.setIfNotExists(ifNotExists);
command.setTableName(tableName);
command.setComment(readCommentIf());
read("(");
read(OPEN_PAREN);
command.setDriver(readString());
read(",");
command.setUrl(readString());
......@@ -6535,7 +6791,7 @@ public class Parser {
originalTable = readString();
}
command.setOriginalTable(originalTable);
read(")");
read(CLOSE_PAREN);
if (readIf("EMIT")) {
read("UPDATES");
command.setEmitUpdates(true);
......@@ -6563,8 +6819,8 @@ public class Parser {
command.setIfNotExists(ifNotExists);
command.setTableName(tableName);
command.setComment(readCommentIf());
if (readIf("(")) {
if (!readIf(")")) {
if (readIf(OPEN_PAREN)) {
if (!readIf(CLOSE_PAREN)) {
do {
parseTableColumnDefinition(command, schema, tableName);
} while (readIfMore(false));
......@@ -6572,13 +6828,13 @@ public class Parser {
}
// Allows "COMMENT='comment'" in DDL statements (MySQL syntax)
if (readIf("COMMENT")) {
if (readIf("=")) {
if (readIf(EQUAL)) {
// read the complete string comment, but nothing with it for now
readString();
}
}
if (readIf("ENGINE")) {
if (readIf("=")) {
if (readIf(EQUAL)) {
// map MySQL engine types onto H2 behavior
String tableEngine = readUniqueIdentifier();
if ("InnoDb".equalsIgnoreCase(tableEngine)) {
......@@ -6590,12 +6846,12 @@ public class Parser {
command.setTableEngine(readUniqueIdentifier());
}
}
if (readIf("WITH")) {
if (readIf(WITH)) {
command.setTableEngineParams(readTableEngineParams());
}
// MySQL compatibility
if (readIf("AUTO_INCREMENT")) {
read("=");
read(EQUAL);
if (currentTokenType != VALUE ||
currentValue.getType() != Value.INT) {
throw DbException.getSyntaxError(sqlCommand, parseIndex,
......@@ -6605,13 +6861,13 @@ public class Parser {
}
readIf("DEFAULT");
if (readIf("CHARSET")) {
read("=");
read(EQUAL);
if (!readIf("UTF8")) {
read("UTF8MB4");
}
}
if (temp) {
if (readIf("ON")) {
if (readIf(ON)) {
read("COMMIT");
if (readIf("DROP")) {
command.setOnCommitDrop();
......@@ -6619,7 +6875,7 @@ public class Parser {
read("ROWS");
command.setOnCommitTruncate();
}
} else if (readIf("NOT")) {
} else if (readIf(NOT)) {
if (readIf("PERSISTENT")) {
command.setPersistData(false);
} else {
......@@ -6629,7 +6885,7 @@ public class Parser {
if (readIf("TRANSACTIONAL")) {
command.setTransactional(true);
}
} else if (!persistIndexes && readIf("NOT")) {
} else if (!persistIndexes && readIf(NOT)) {
read("PERSISTENT");
command.setPersistData(false);
}
......@@ -6641,14 +6897,14 @@ public class Parser {
command.setSortedInsertMode(true);
}
command.setQuery(parseSelect());
if (readIf("WITH")) {
if (readIf(WITH)) {
command.setWithNoData(readIf("NO"));
read("DATA");
}
}
// for MySQL compatibility
if (readIf("ROW_FORMAT")) {
if (readIf("=")) {
if (readIf(EQUAL)) {
readColumnIdentifier();
}
}
......@@ -6676,13 +6932,13 @@ public class Parser {
}
command.addColumn(column);
String constraintName = null;
if (readIf("CONSTRAINT")) {
if (readIf(CONSTRAINT)) {
constraintName = readColumnIdentifier();
}
// For compatibility with Apache Ignite.
boolean allowAffinityKey = database.getMode().allowAffinityKey;
boolean affinity = allowAffinityKey && readIfAffinity();
if (readIf("PRIMARY")) {
if (readIf(PRIMARY)) {
read("KEY");
boolean hash = readIf("HASH");
IndexColumn[] cols = { new IndexColumn() };
......@@ -6708,7 +6964,7 @@ public class Parser {
cols[0].columnName = column.getName();
CreateIndex idx = createAffinityIndex(schema, tableName, cols);
command.addConstraintCommand(idx);
} else if (readIf("UNIQUE")) {
} else if (readIf(UNIQUE)) {
AlterTableAddConstraint unique = new AlterTableAddConstraint(
session, schema, false);
unique.setConstraintName(constraintName);
......@@ -6722,7 +6978,7 @@ public class Parser {
if (NullConstraintType.NULL_IS_NOT_ALLOWED == parseNotNullConstraint()) {
column.setNullable(false);
}
if (readIf("CHECK")) {
if (readIf(CHECK)) {
Expression expr = readExpression();
column.addCheckConstraint(session, expr);
}
......@@ -6750,12 +7006,12 @@ public class Parser {
private NullConstraintType parseNotNullConstraint() {
NullConstraintType nullConstraint = NullConstraintType.NO_NULL_CONSTRAINT_FOUND;
if (isToken("NOT") || isToken("NULL")) {
if (readIf("NOT")) {
read("NULL");
if (isToken(NOT) || isToken(NULL)) {
if (readIf(NOT)) {
read(NULL);
nullConstraint = NullConstraintType.NULL_IS_NOT_ALLOWED;
} else {
read("NULL");
read(NULL);
nullConstraint = NullConstraintType.NULL_IS_ALLOWED;
}
if (database.getMode().getEnum() == ModeEnum.Oracle) {
......@@ -6784,7 +7040,7 @@ public class Parser {
boolean ifNotExists = readIfNotExists();
String name = readIdentifierWithSchema();
Schema synonymSchema = getSchema();
read("FOR");
read(FOR);
String tableName = readIdentifierWithSchema();
Schema targetSchema = getSchema();
......
......@@ -18,24 +18,199 @@ public class ParserUtil {
public static final int IDENTIFIER = 2;
/**
* The token "null".
* The token "ALL".
*/
public static final int NULL = 3;
public static final int ALL = IDENTIFIER + 1;
/**
* The token "true".
* The token "CHECK".
*/
public static final int TRUE = 4;
public static final int CHECK = ALL + 1;
/**
* The token "false".
* The token "CONSTRAINT".
*/
public static final int FALSE = 5;
public static final int CONSTRAINT = CHECK + 1;
/**
* The token "rownum".
* The token "CROSS".
*/
public static final int ROWNUM = 6;
public static final int CROSS = CONSTRAINT + 1;
/**
* The token "CURRENT_DATE".
*/
public static final int CURRENT_DATE = CROSS + 1;
/**
* The token "CURRENT_TIME".
*/
public static final int CURRENT_TIME = CURRENT_DATE + 1;
/**
* The token "CURRENT_TIMESTAMP".
*/
public static final int CURRENT_TIMESTAMP = CURRENT_TIME + 1;
/**
* The token "DISTINCT".
*/
public static final int DISTINCT = CURRENT_TIMESTAMP + 1;
/**
* The token "EXCEPT".
*/
public static final int EXCEPT = DISTINCT + 1;
/**
* The token "EXISTS".
*/
public static final int EXISTS = EXCEPT + 1;
/**
* The token "FALSE".
*/
public static final int FALSE = EXISTS + 1;
/**
* The token "FETCH".
*/
public static final int FETCH = FALSE + 1;
/**
* The token "FOR".
*/
public static final int FOR = FETCH + 1;
/**
* The token "FOREIGN".
*/
public static final int FOREIGN = FOR + 1;
/**
* The token "FROM".
*/
public static final int FROM = FOREIGN + 1;
/**
* The token "FULL".
*/
public static final int FULL = FROM + 1;
/**
* The token "GROUP".
*/
public static final int GROUP = FULL + 1;
/**
* The token "HAVING".
*/
public static final int HAVING = GROUP + 1;
/**
* The token "INNER".
*/
public static final int INNER = HAVING + 1;
/**
* The token "INTERSECT".
*/
public static final int INTERSECT = INNER + 1;
/**
* The token "IS".
*/
public static final int IS = INTERSECT + 1;
/**
* The token "JOIN".
*/
public static final int JOIN = IS + 1;
/**
* The token "LIKE".
*/
public static final int LIKE = JOIN + 1;
/**
* The token "LIMIT".
*/
public static final int LIMIT = LIKE + 1;
/**
* The token "MINUS".
*/
public static final int MINUS = LIMIT + 1;
/**
* The token "NATURAL".
*/
public static final int NATURAL = MINUS + 1;
/**
* The token "NOT".
*/
public static final int NOT = NATURAL + 1;
/**
* The token "NULL".
*/
public static final int NULL = NOT + 1;
/**
* The token "OFFSET".
*/
public static final int OFFSET = NULL + 1;
/**
* The token "ON".
*/
public static final int ON = OFFSET + 1;
/**
* The token "ORDER".
*/
public static final int ORDER = ON + 1;
/**
* The token "PRIMARY".
*/
public static final int PRIMARY = ORDER + 1;
/**
* The token "ROWNUM".
*/
public static final int ROWNUM = PRIMARY + 1;
/**
* The token "SELECT".
*/
public static final int SELECT = ROWNUM + 1;
/**
* The token "TRUE".
*/
public static final int TRUE = SELECT + 1;
/**
* The token "UNION".
*/
public static final int UNION = TRUE + 1;
/**
* The token "UNIQUE".
*/
public static final int UNIQUE = UNION + 1;
/**
* The token "WHERE".
*/
public static final int WHERE = UNIQUE + 1;
/**
* The token "WITH".
*/
public static final int WITH = WHERE + 1;
private ParserUtil() {
// utility class
......@@ -95,14 +270,14 @@ public class ParserUtil {
*/
switch (s.charAt(0)) {
case 'A':
return getKeywordOrIdentifier(s, "ALL", KEYWORD);
return getKeywordOrIdentifier(s, "ALL", ALL);
case 'C':
if ("CHECK".equals(s)) {
return KEYWORD;
return CHECK;
} else if ("CONSTRAINT".equals(s)) {
return KEYWORD;
return CONSTRAINT;
} else if ("CROSS".equals(s)) {
return KEYWORD;
return CROSS;
}
if (additionalKeywords) {
if ("CURRENT_DATE".equals(s) || "CURRENT_TIME".equals(s) || "CURRENT_TIMESTAMP".equals(s)) {
......@@ -111,32 +286,36 @@ public class ParserUtil {
}
return IDENTIFIER;
case 'D':
return getKeywordOrIdentifier(s, "DISTINCT", KEYWORD);
return getKeywordOrIdentifier(s, "DISTINCT", DISTINCT);
case 'E':
if ("EXCEPT".equals(s)) {
return KEYWORD;
return EXCEPT;
}
return getKeywordOrIdentifier(s, "EXISTS", KEYWORD);
return getKeywordOrIdentifier(s, "EXISTS", EXISTS);
case 'F':
if ("FETCH".equals(s)) {
return KEYWORD;
return FETCH;
} else if ("FROM".equals(s)) {
return KEYWORD;
return FROM;
} else if ("FOR".equals(s)) {
return KEYWORD;
return FOR;
} else if ("FOREIGN".equals(s)) {
return KEYWORD;
return FOREIGN;
} else if ("FULL".equals(s)) {
return KEYWORD;
return FULL;
}
return getKeywordOrIdentifier(s, "FALSE", FALSE);
case 'G':
return getKeywordOrIdentifier(s, "GROUP", KEYWORD);
return getKeywordOrIdentifier(s, "GROUP", GROUP);
case 'H':
return getKeywordOrIdentifier(s, "HAVING", KEYWORD);
return getKeywordOrIdentifier(s, "HAVING", HAVING);
case 'I':
if ("INNER".equals(s) || "INTERSECT".equals(s) || "IS".equals(s)) {
return KEYWORD;
if ("INNER".equals(s)) {
return INNER;
} else if ("INTERSECT".equals(s)) {
return INTERSECT;
} else if ("IS".equals(s)) {
return IS;
}
if (additionalKeywords) {
if ("INTERSECTS".equals(s)) {
......@@ -145,10 +324,12 @@ public class ParserUtil {
}
return IDENTIFIER;
case 'J':
return getKeywordOrIdentifier(s, "JOIN", KEYWORD);
return getKeywordOrIdentifier(s, "JOIN", JOIN);
case 'L':
if ("LIMIT".equals(s) || "LIKE".equals(s)) {
return KEYWORD;
if ("LIMIT".equals(s)) {
return LIMIT;
} else if ("LIKE".equals(s)) {
return LIKE;
}
if (additionalKeywords) {
if ("LOCALTIME".equals(s) || "LOCALTIMESTAMP".equals(s)) {
......@@ -157,28 +338,28 @@ public class ParserUtil {
}
return IDENTIFIER;
case 'M':
return getKeywordOrIdentifier(s, "MINUS", KEYWORD);
return getKeywordOrIdentifier(s, "MINUS", MINUS);
case 'N':
if ("NOT".equals(s)) {
return KEYWORD;
return NOT;
} else if ("NATURAL".equals(s)) {
return KEYWORD;
return NATURAL;
}
return getKeywordOrIdentifier(s, "NULL", NULL);
case 'O':
if ("OFFSET".equals(s)) {
return KEYWORD;
return OFFSET;
} else if ("ON".equals(s)) {
return KEYWORD;
return ON;
}
return getKeywordOrIdentifier(s, "ORDER", KEYWORD);
return getKeywordOrIdentifier(s, "ORDER", ORDER);
case 'P':
return getKeywordOrIdentifier(s, "PRIMARY", KEYWORD);
return getKeywordOrIdentifier(s, "PRIMARY", PRIMARY);
case 'R':
return getKeywordOrIdentifier(s, "ROWNUM", ROWNUM);
case 'S':
if ("SELECT".equals(s)) {
return KEYWORD;
return SELECT;
}
if (additionalKeywords) {
if ("SYSDATE".equals(s) || "SYSTIME".equals(s) || "SYSTIMESTAMP".equals(s)) {
......@@ -198,14 +379,14 @@ public class ParserUtil {
return IDENTIFIER;
case 'U':
if ("UNIQUE".equals(s)) {
return KEYWORD;
return UNIQUE;
}
return getKeywordOrIdentifier(s, "UNION", KEYWORD);
return getKeywordOrIdentifier(s, "UNION", UNION);
case 'W':
if ("WITH".equals(s)) {
return KEYWORD;
return WITH;
}
return getKeywordOrIdentifier(s, "WHERE", KEYWORD);
return getKeywordOrIdentifier(s, "WHERE", WHERE);
default:
return IDENTIFIER;
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论