Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
94d97acd
提交
94d97acd
authored
6 年前
作者:
Evgenij Ryazanov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add token types for all keywords and use them instead of strings
上级
81bb6b2e
显示空白字符变更
内嵌
并排
正在显示
2 个修改的文件
包含
795 行增加
和
358 行删除
+795
-358
Parser.java
h2/src/main/org/h2/command/Parser.java
+575
-319
ParserUtil.java
h2/src/main/org/h2/util/ParserUtil.java
+220
-39
没有找到文件。
h2/src/main/org/h2/command/Parser.java
浏览文件 @
94d97acd
...
...
@@ -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
SELECT:
case
FROM:
case
WITH:
r
=
new
Subquery
(
parseSelect
());
break
;
case
KEYWORD:
if
(
isToken
(
"SELECT"
)
||
isToken
(
"FROM"
)
||
isToken
(
"WITH"
))
{
Query
query
=
parseSelect
();
r
=
new
Subquery
(
query
);
}
else
{
throw
getSyntaxError
();
}
break
;
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
();
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/util/ParserUtil.java
浏览文件 @
94d97acd
...
...
@@ -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
;
}
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论