提交 76e61e71 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Add TestKeywords and missing keywords

上级 f69172a5
...@@ -475,13 +475,14 @@ There is a list of keywords that can't be used as identifiers (table names, colu ...@@ -475,13 +475,14 @@ There is a list of keywords that can't be used as identifiers (table names, colu
unless they are quoted (surrounded with double quotes). The list is currently: unless they are quoted (surrounded with double quotes). The list is currently:
</p><p> </p><p>
<code> <code>
ALL, ARRAY, CHECK, CONSTRAINT, CROSS, CURRENT_DATE, CURRENT_TIME, ALL, ARRAY, CASE, CHECK, CONSTRAINT, CROSS, CURRENT_DATE,
CURRENT_TIMESTAMP, DISTINCT, EXCEPT, EXISTS, FALSE, FETCH, FOR, CURRENT_TIME, CURRENT_TIMESTAMP, CURRENT_USER, DISTINCT, EXCEPT,
FOREIGN, FROM, FULL, GROUP, HAVING, INNER, INTERSECT, INTERSECTS, EXISTS, FALSE, FETCH, FOR, FOREIGN, FROM, FULL, GROUP, HAVING,
INTERVAL, IS, JOIN, LIKE, LIMIT, LOCALTIME, LOCALTIMESTAMP, IF, INNER, INTERSECT, INTERSECTS, INTERVAL, IS, JOIN, LIKE,
MINUS, NATURAL, NOT, NULL, OFFSET, ON, ORDER, PRIMARY, ROW, LIMIT, LOCALTIME, LOCALTIMESTAMP, MINUS, NATURAL, NOT, NULL,
ROWNUM, SELECT, SYSDATE, SYSTIME, SYSTIMESTAMP, TODAY, TOP, TRUE, OFFSET, ON, ORDER, PRIMARY, ROW, ROWNUM, SELECT, SYSDATE,
UNION, UNIQUE, WHERE, WINDOW, WITH SYSTIME, SYSTIMESTAMP, TODAY, TOP, TRUE, UNION, UNIQUE, VALUES,
WHERE, WINDOW, WITH
</code> </code>
</p><p> </p><p>
Certain words of this list are keywords because they are functions that can be used without '()', Certain words of this list are keywords because they are functions that can be used without '()',
......
...@@ -10,12 +10,14 @@ package org.h2.command; ...@@ -10,12 +10,14 @@ package org.h2.command;
import static org.h2.util.ParserUtil.ALL; import static org.h2.util.ParserUtil.ALL;
import static org.h2.util.ParserUtil.ARRAY; import static org.h2.util.ParserUtil.ARRAY;
import static org.h2.util.ParserUtil.CASE;
import static org.h2.util.ParserUtil.CHECK; import static org.h2.util.ParserUtil.CHECK;
import static org.h2.util.ParserUtil.CONSTRAINT; import static org.h2.util.ParserUtil.CONSTRAINT;
import static org.h2.util.ParserUtil.CROSS; import static org.h2.util.ParserUtil.CROSS;
import static org.h2.util.ParserUtil.CURRENT_DATE; import static org.h2.util.ParserUtil.CURRENT_DATE;
import static org.h2.util.ParserUtil.CURRENT_TIME; import static org.h2.util.ParserUtil.CURRENT_TIME;
import static org.h2.util.ParserUtil.CURRENT_TIMESTAMP; import static org.h2.util.ParserUtil.CURRENT_TIMESTAMP;
import static org.h2.util.ParserUtil.CURRENT_USER;
import static org.h2.util.ParserUtil.DISTINCT; import static org.h2.util.ParserUtil.DISTINCT;
import static org.h2.util.ParserUtil.EXCEPT; import static org.h2.util.ParserUtil.EXCEPT;
import static org.h2.util.ParserUtil.EXISTS; import static org.h2.util.ParserUtil.EXISTS;
...@@ -28,6 +30,7 @@ import static org.h2.util.ParserUtil.FULL; ...@@ -28,6 +30,7 @@ import static org.h2.util.ParserUtil.FULL;
import static org.h2.util.ParserUtil.GROUP; import static org.h2.util.ParserUtil.GROUP;
import static org.h2.util.ParserUtil.HAVING; import static org.h2.util.ParserUtil.HAVING;
import static org.h2.util.ParserUtil.IDENTIFIER; import static org.h2.util.ParserUtil.IDENTIFIER;
import static org.h2.util.ParserUtil.IF;
import static org.h2.util.ParserUtil.INNER; import static org.h2.util.ParserUtil.INNER;
import static org.h2.util.ParserUtil.INTERSECT; import static org.h2.util.ParserUtil.INTERSECT;
import static org.h2.util.ParserUtil.INTERSECTS; import static org.h2.util.ParserUtil.INTERSECTS;
...@@ -52,6 +55,7 @@ import static org.h2.util.ParserUtil.SELECT; ...@@ -52,6 +55,7 @@ import static org.h2.util.ParserUtil.SELECT;
import static org.h2.util.ParserUtil.TRUE; import static org.h2.util.ParserUtil.TRUE;
import static org.h2.util.ParserUtil.UNION; import static org.h2.util.ParserUtil.UNION;
import static org.h2.util.ParserUtil.UNIQUE; import static org.h2.util.ParserUtil.UNIQUE;
import static org.h2.util.ParserUtil.VALUES;
import static org.h2.util.ParserUtil.WHERE; import static org.h2.util.ParserUtil.WHERE;
import static org.h2.util.ParserUtil.WINDOW; import static org.h2.util.ParserUtil.WINDOW;
import static org.h2.util.ParserUtil.WITH; import static org.h2.util.ParserUtil.WITH;
...@@ -424,6 +428,8 @@ public class Parser { ...@@ -424,6 +428,8 @@ public class Parser {
"ALL", "ALL",
// ARRAY // ARRAY
"ARRAY", "ARRAY",
// CASE
"CASE",
// CHECK // CHECK
"CHECK", "CHECK",
// CONSTRAINT // CONSTRAINT
...@@ -436,6 +442,8 @@ public class Parser { ...@@ -436,6 +442,8 @@ public class Parser {
"CURRENT_TIME", "CURRENT_TIME",
// CURRENT_TIMESTAMP // CURRENT_TIMESTAMP
"CURRENT_TIMESTAMP", "CURRENT_TIMESTAMP",
// CURRENT_USER
"CURRENT_USER",
// DISTINCT // DISTINCT
"DISTINCT", "DISTINCT",
// EXCEPT // EXCEPT
...@@ -458,6 +466,8 @@ public class Parser { ...@@ -458,6 +466,8 @@ public class Parser {
"GROUP", "GROUP",
// HAVING // HAVING
"HAVING", "HAVING",
// IF
"IF",
// INNER // INNER
"INNER", "INNER",
// INTERSECT // INTERSECT
...@@ -506,6 +516,8 @@ public class Parser { ...@@ -506,6 +516,8 @@ public class Parser {
"UNION", "UNION",
// UNIQUE // UNIQUE
"UNIQUE", "UNIQUE",
// VALUES
"VALUES",
// WHERE // WHERE
"WHERE", "WHERE",
// WINDOW // WINDOW
...@@ -735,6 +747,10 @@ public class Parser { ...@@ -735,6 +747,10 @@ public class Parser {
case SELECT: case SELECT:
c = parseSelect(); c = parseSelect();
break; break;
case VALUES:
read();
c = parseValues();
break;
case WITH: case WITH:
read(); read();
c = parseWithStatementOrQuery(); c = parseWithStatementOrQuery();
...@@ -867,11 +883,6 @@ public class Parser { ...@@ -867,11 +883,6 @@ public class Parser {
c = parseUse(); c = parseUse();
} }
break; break;
case 'v':
case 'V':
if (readIf("VALUES")) {
c = parseValues();
}
} }
} }
if (c == null) { if (c == null) {
...@@ -1434,7 +1445,7 @@ public class Parser { ...@@ -1434,7 +1445,7 @@ public class Parser {
private Prepared parseMerge() { private Prepared parseMerge() {
int start = lastParseIndex; int start = lastParseIndex;
read("INTO"); read("INTO");
List<String> excludeIdentifiers = Arrays.asList("USING", "KEY", "VALUES"); List<String> excludeIdentifiers = Arrays.asList("USING", "KEY");
TableFilter targetTableFilter = readSimpleTableFilter(0, excludeIdentifiers); TableFilter targetTableFilter = readSimpleTableFilter(0, excludeIdentifiers);
if (readIf("USING")) { if (readIf("USING")) {
return parseMergeUsing(targetTableFilter, start); return parseMergeUsing(targetTableFilter, start);
...@@ -1457,7 +1468,7 @@ public class Parser { ...@@ -1457,7 +1468,7 @@ public class Parser {
Column[] keys = parseColumnList(table); Column[] keys = parseColumnList(table);
command.setKeys(keys); command.setKeys(keys);
} }
if (readIf("VALUES")) { if (readIf(VALUES)) {
do { do {
read(OPEN_PAREN); read(OPEN_PAREN);
command.addRow(parseValuesForInsert()); command.addRow(parseValuesForInsert());
...@@ -1644,10 +1655,10 @@ public class Parser { ...@@ -1644,10 +1655,10 @@ public class Parser {
command.setSortedInsertMode(true); command.setSortedInsertMode(true);
} }
if (readIf("DEFAULT")) { if (readIf("DEFAULT")) {
read("VALUES"); read(VALUES);
Expression[] expr = {}; Expression[] expr = {};
command.addRow(expr); command.addRow(expr);
} else if (readIf("VALUES")) { } else if (readIf(VALUES)) {
read(OPEN_PAREN); read(OPEN_PAREN);
do { do {
command.addRow(parseValuesForInsert()); command.addRow(parseValuesForInsert());
...@@ -1690,7 +1701,7 @@ public class Parser { ...@@ -1690,7 +1701,7 @@ public class Parser {
Column[] columns = parseColumnList(table); Column[] columns = parseColumnList(table);
command.setColumns(columns); command.setColumns(columns);
} }
if (readIf("VALUES")) { if (readIf(VALUES)) {
do { do {
read(OPEN_PAREN); read(OPEN_PAREN);
command.addRow(parseValuesForInsert()); command.addRow(parseValuesForInsert());
...@@ -1748,7 +1759,7 @@ public class Parser { ...@@ -1748,7 +1759,7 @@ public class Parser {
} }
return top; return top;
} }
} else if (readIf("VALUES")) { } else if (readIf(VALUES)) {
table = parseValuesTable(0).getTable(); table = parseValuesTable(0).getTable();
} else { } else {
String tableName = readIdentifierWithSchema(null); String tableName = readIdentifierWithSchema(null);
...@@ -1927,7 +1938,7 @@ public class Parser { ...@@ -1927,7 +1938,7 @@ public class Parser {
} }
private boolean readIfExists(boolean ifExists) { private boolean readIfExists(boolean ifExists) {
if (readIf("IF")) { if (readIf(IF)) {
read(EXISTS); read(EXISTS);
ifExists = true; ifExists = true;
} }
...@@ -3751,8 +3762,8 @@ public class Parser { ...@@ -3751,8 +3762,8 @@ public class Parser {
break; break;
case IDENTIFIER: case IDENTIFIER:
String name = currentToken; String name = currentToken;
read();
if (currentTokenQuoted) { if (currentTokenQuoted) {
read();
if (readIf(OPEN_PAREN)) { if (readIf(OPEN_PAREN)) {
r = readFunction(null, name); r = readFunction(null, name);
} else if (readIf(DOT)) { } else if (readIf(DOT)) {
...@@ -3761,14 +3772,8 @@ public class Parser { ...@@ -3761,14 +3772,8 @@ public class Parser {
r = new ExpressionColumn(database, null, null, name); r = new ExpressionColumn(database, null, null, name);
} }
} else { } else {
read();
if (readIf(DOT)) { if (readIf(DOT)) {
r = readTermObjectDot(name); r = readTermObjectDot(name);
} else if (equalsToken("CASE", name)) {
// CASE must be processed before (,
// otherwise CASE(3) would be a function call, which it is
// not
r = readCase();
} else if (readIf(OPEN_PAREN)) { } else if (readIf(OPEN_PAREN)) {
r = readFunction(null, name); r = readFunction(null, name);
} else { } else {
...@@ -3879,6 +3884,14 @@ public class Parser { ...@@ -3879,6 +3884,14 @@ public class Parser {
r = ValueExpression.get(currentValue); r = ValueExpression.get(currentValue);
read(); read();
break; break;
case VALUES:
read();
r = readKeywordFunction("VALUES");
break;
case CASE:
read();
r = readCase();
break;
case CURRENT_DATE: case CURRENT_DATE:
read(); read();
r = readKeywordFunction("CURRENT_DATE"); r = readKeywordFunction("CURRENT_DATE");
...@@ -3891,6 +3904,10 @@ public class Parser { ...@@ -3891,6 +3904,10 @@ public class Parser {
read(); read();
r = readKeywordFunction("CURRENT_TIMESTAMP"); r = readKeywordFunction("CURRENT_TIMESTAMP");
break; break;
case CURRENT_USER:
read();
r = readKeywordFunction("USER");
break;
case LOCALTIME: case LOCALTIME:
read(); read();
r = readKeywordFunction("LOCALTIME"); r = readKeywordFunction("LOCALTIME");
...@@ -3946,9 +3963,7 @@ public class Parser { ...@@ -3946,9 +3963,7 @@ public class Parser {
} }
switch (ch) { switch (ch) {
case 'C': case 'C':
if (equalsToken("CURRENT_USER", name)) { if (database.getMode().getEnum() == ModeEnum.DB2 && equalsToken("CURRENT", name)) {
return readFunctionWithoutParameters("USER");
} else if (database.getMode().getEnum() == ModeEnum.DB2 && equalsToken("CURRENT", name)) {
return parseDB2SpecialRegisters(name); return parseDB2SpecialRegisters(name);
} }
break; break;
...@@ -4134,13 +4149,13 @@ public class Parser { ...@@ -4134,13 +4149,13 @@ public class Parser {
private Expression readCase() { private Expression readCase() {
if (readIf("END")) { if (readIf("END")) {
readIf("CASE"); readIf(CASE);
return ValueExpression.getNull(); return ValueExpression.getNull();
} }
if (readIf("ELSE")) { if (readIf("ELSE")) {
Expression elsePart = readExpression().optimize(session); Expression elsePart = readExpression().optimize(session);
read("END"); read("END");
readIf("CASE"); readIf(CASE);
return elsePart; return elsePart;
} }
int i; int i;
...@@ -4157,13 +4172,13 @@ public class Parser { ...@@ -4157,13 +4172,13 @@ public class Parser {
} else { } else {
Expression expr = readExpression(); Expression expr = readExpression();
if (readIf("END")) { if (readIf("END")) {
readIf("CASE"); readIf(CASE);
return ValueExpression.getNull(); return ValueExpression.getNull();
} }
if (readIf("ELSE")) { if (readIf("ELSE")) {
Expression elsePart = readExpression().optimize(session); Expression elsePart = readExpression().optimize(session);
read("END"); read("END");
readIf("CASE"); readIf(CASE);
return elsePart; return elsePart;
} }
function = Function.getFunction(database, "CASE"); function = Function.getFunction(database, "CASE");
...@@ -5879,7 +5894,7 @@ public class Parser { ...@@ -5879,7 +5894,7 @@ public class Parser {
} }
private boolean readIfNotExists() { private boolean readIfNotExists() {
if (readIf("IF")) { if (readIf(IF)) {
read(NOT); read(NOT);
read(EXISTS); read(EXISTS);
return true; return true;
......
...@@ -1547,13 +1547,14 @@ public class JdbcDatabaseMetaData extends TraceObject implements ...@@ -1547,13 +1547,14 @@ public class JdbcDatabaseMetaData extends TraceObject implements
* </pre> * </pre>
* The complete list of keywords (including SQL-2003 keywords) is: * The complete list of keywords (including SQL-2003 keywords) is:
* <pre> * <pre>
* ALL, ARRAY, CHECK, CONSTRAINT, CROSS, CURRENT_DATE, CURRENT_TIME, * ALL, ARRAY, CASE, CHECK, CONSTRAINT, CROSS, CURRENT_DATE,
* CURRENT_TIMESTAMP, DISTINCT, EXCEPT, EXISTS, FALSE, FETCH, FOR, * CURRENT_TIME, CURRENT_TIMESTAMP, CURRENT_USER, DISTINCT, EXCEPT,
* FOREIGN, FROM, FULL, GROUP, HAVING, INNER, INTERSECT, INTERSECTS, * EXISTS, FALSE, FETCH, FOR, FOREIGN, FROM, FULL, GROUP, HAVING,
* INTERVAL, IS, JOIN, LIKE, LIMIT, LOCALTIME, LOCALTIMESTAMP, * IF, INNER, INTERSECT, INTERSECTS, INTERVAL, IS, JOIN, LIKE,
* MINUS, NATURAL, NOT, NULL, OFFSET, ON, ORDER, PRIMARY, ROW, * LIMIT, LOCALTIME, LOCALTIMESTAMP, MINUS, NATURAL, NOT, NULL,
* ROWNUM, SELECT, SYSDATE, SYSTIME, SYSTIMESTAMP, TODAY, TOP, TRUE, * OFFSET, ON, ORDER, PRIMARY, ROW, ROWNUM, SELECT, SYSDATE,
* UNION, UNIQUE, WHERE, WINDOW, WITH * SYSTIME, SYSTIMESTAMP, TODAY, TOP, TRUE, UNION, UNIQUE, VALUES,
* WHERE, WINDOW, WITH
* </pre> * </pre>
* *
* @return a list of additional the keywords * @return a list of additional the keywords
...@@ -1561,7 +1562,7 @@ public class JdbcDatabaseMetaData extends TraceObject implements ...@@ -1561,7 +1562,7 @@ public class JdbcDatabaseMetaData extends TraceObject implements
@Override @Override
public String getSQLKeywords() { public String getSQLKeywords() {
debugCodeCall("getSQLKeywords"); debugCodeCall("getSQLKeywords");
return "INTERSECTS,LIMIT,MINUS,OFFSET,ROWNUM,SYSDATE,SYSTIME,SYSTIMESTAMP,TODAY,TOP"; return "IF,INTERSECTS,LIMIT,MINUS,OFFSET,ROWNUM,SYSDATE,SYSTIME,SYSTIMESTAMP,TODAY,TOP";
} }
/** /**
......
...@@ -27,10 +27,15 @@ public class ParserUtil { ...@@ -27,10 +27,15 @@ public class ParserUtil {
*/ */
public static final int ARRAY = ALL + 1; public static final int ARRAY = ALL + 1;
/**
* The token "CASE".
*/
public static final int CASE = ARRAY + 1;
/** /**
* The token "CHECK". * The token "CHECK".
*/ */
public static final int CHECK = ARRAY + 1; public static final int CHECK = CASE + 1;
/** /**
* The token "CONSTRAINT". * The token "CONSTRAINT".
...@@ -57,10 +62,15 @@ public class ParserUtil { ...@@ -57,10 +62,15 @@ public class ParserUtil {
*/ */
public static final int CURRENT_TIMESTAMP = CURRENT_TIME + 1; public static final int CURRENT_TIMESTAMP = CURRENT_TIME + 1;
/**
* The token "CURRENT_USER".
*/
public static final int CURRENT_USER = CURRENT_TIMESTAMP + 1;
/** /**
* The token "DISTINCT". * The token "DISTINCT".
*/ */
public static final int DISTINCT = CURRENT_TIMESTAMP + 1; public static final int DISTINCT = CURRENT_USER + 1;
/** /**
* The token "EXCEPT". * The token "EXCEPT".
...@@ -112,10 +122,15 @@ public class ParserUtil { ...@@ -112,10 +122,15 @@ public class ParserUtil {
*/ */
public static final int HAVING = GROUP + 1; public static final int HAVING = GROUP + 1;
/**
* The token "IF".
*/
public static final int IF = HAVING + 1;
/** /**
* The token "INNER". * The token "INNER".
*/ */
public static final int INNER = HAVING + 1; public static final int INNER = IF + 1;
/** /**
* The token "INTERSECT". * The token "INTERSECT".
...@@ -232,10 +247,15 @@ public class ParserUtil { ...@@ -232,10 +247,15 @@ public class ParserUtil {
*/ */
public static final int UNIQUE = UNION + 1; public static final int UNIQUE = UNION + 1;
/**
* The token "VALUES".
*/
public static final int VALUES = UNIQUE + 1;
/** /**
* The token "WHERE". * The token "WHERE".
*/ */
public static final int WHERE = UNIQUE + 1; public static final int WHERE = VALUES + 1;
/** /**
* The token "WINDOW". * The token "WINDOW".
...@@ -337,7 +357,9 @@ public class ParserUtil { ...@@ -337,7 +357,9 @@ public class ParserUtil {
} }
return IDENTIFIER; return IDENTIFIER;
case 'C': case 'C':
if (eq("CHECK", s, ignoreCase, start, end)) { if (eq("CASE", s, ignoreCase, start, end)) {
return CASE;
} else if (eq("CHECK", s, ignoreCase, start, end)) {
return CHECK; return CHECK;
} else if (eq("CONSTRAINT", s, ignoreCase, start, end)) { } else if (eq("CONSTRAINT", s, ignoreCase, start, end)) {
return CONSTRAINT; return CONSTRAINT;
...@@ -349,6 +371,8 @@ public class ParserUtil { ...@@ -349,6 +371,8 @@ public class ParserUtil {
return CURRENT_TIME; return CURRENT_TIME;
} else if (eq("CURRENT_TIMESTAMP", s, ignoreCase, start, end)) { } else if (eq("CURRENT_TIMESTAMP", s, ignoreCase, start, end)) {
return CURRENT_TIMESTAMP; return CURRENT_TIMESTAMP;
} else if (eq("CURRENT_USER", s, ignoreCase, start, end)) {
return CURRENT_USER;
} }
return IDENTIFIER; return IDENTIFIER;
case 'D': case 'D':
...@@ -389,7 +413,9 @@ public class ParserUtil { ...@@ -389,7 +413,9 @@ public class ParserUtil {
} }
return IDENTIFIER; return IDENTIFIER;
case 'I': case 'I':
if (eq("INNER", s, ignoreCase, start, end)) { if (eq("IF", s, ignoreCase, start, end)) {
return IF;
} else if (eq("INNER", s, ignoreCase, start, end)) {
return INNER; return INNER;
} else if (eq("INTERSECT", s, ignoreCase, start, end)) { } else if (eq("INTERSECT", s, ignoreCase, start, end)) {
return INTERSECT; return INTERSECT;
...@@ -480,6 +506,11 @@ public class ParserUtil { ...@@ -480,6 +506,11 @@ public class ParserUtil {
return UNION; return UNION;
} }
return IDENTIFIER; return IDENTIFIER;
case 'V':
if (eq("VALUES", s, ignoreCase, start, end)) {
return VALUES;
}
return IDENTIFIER;
case 'W': case 'W':
if (eq("WHERE", s, ignoreCase, start, end)) { if (eq("WHERE", s, ignoreCase, start, end)) {
return WHERE; return WHERE;
......
...@@ -196,6 +196,7 @@ import org.h2.test.unit.TestIntIntHashMap; ...@@ -196,6 +196,7 @@ import org.h2.test.unit.TestIntIntHashMap;
import org.h2.test.unit.TestIntPerfectHash; import org.h2.test.unit.TestIntPerfectHash;
import org.h2.test.unit.TestInterval; import org.h2.test.unit.TestInterval;
import org.h2.test.unit.TestJmx; import org.h2.test.unit.TestJmx;
import org.h2.test.unit.TestKeywords;
import org.h2.test.unit.TestLocalResultFactory; import org.h2.test.unit.TestLocalResultFactory;
import org.h2.test.unit.TestLocale; import org.h2.test.unit.TestLocale;
import org.h2.test.unit.TestMathUtils; import org.h2.test.unit.TestMathUtils;
...@@ -973,6 +974,7 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1` ...@@ -973,6 +974,7 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
addTest(new TestIntArray()); addTest(new TestIntArray());
addTest(new TestIntIntHashMap()); addTest(new TestIntIntHashMap());
addTest(new TestIntPerfectHash()); addTest(new TestIntPerfectHash());
addTest(new TestKeywords());
addTest(new TestMathUtils()); addTest(new TestMathUtils());
addTest(new TestMemoryUnmapper()); addTest(new TestMemoryUnmapper());
addTest(new TestMode()); addTest(new TestMode());
......
...@@ -463,7 +463,7 @@ public class TestMetaData extends TestDb { ...@@ -463,7 +463,7 @@ public class TestMetaData extends TestDb {
assertEquals("schema", meta.getSchemaTerm()); assertEquals("schema", meta.getSchemaTerm());
assertEquals("\\", meta.getSearchStringEscape()); assertEquals("\\", meta.getSearchStringEscape());
assertEquals("INTERSECTS,LIMIT,MINUS,OFFSET,ROWNUM,SYSDATE,SYSTIME,SYSTIMESTAMP,TODAY,TOP", assertEquals("IF,INTERSECTS,LIMIT,MINUS,OFFSET,ROWNUM,SYSDATE,SYSTIME,SYSTIMESTAMP,TODAY,TOP",
meta.getSQLKeywords()); meta.getSQLKeywords());
assertTrue(meta.getURL().startsWith("jdbc:h2:")); assertTrue(meta.getURL().startsWith("jdbc:h2:"));
......
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.test.unit;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.HashSet;
import org.h2.command.Parser;
import org.h2.test.TestBase;
import org.h2.util.ParserUtil;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
/**
* Tests keywords.
*/
public class TestKeywords extends TestBase {
/**
* Run just this test.
*
* @param a
* ignored
*/
public static void main(String... a) throws Exception {
TestBase.createCaller().init().test();
}
@Override
public void test() throws Exception {
final HashSet<String> set = new HashSet<>();
ClassReader r = new ClassReader(Parser.class.getResourceAsStream("Parser.class"));
r.accept(new ClassVisitor(Opcodes.ASM6) {
@Override
public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) {
add(set, value);
return null;
}
@Override
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature,
String[] exceptions) {
return new MethodVisitor(Opcodes.ASM6) {
@Override
public void visitLdcInsn(Object value) {
add(set, value);
}
};
}
void add(HashSet<String> set, Object value) {
if (!(value instanceof String)) {
return;
}
String s = (String) value;
int l = s.length();
if (l == 0 || ParserUtil.getSaveTokenType(s, false, 0, l, true) != ParserUtil.IDENTIFIER) {
return;
}
for (int i = 0; i < l; i++) {
char ch = s.charAt(i);
if ((ch < 'A' || ch > 'Z') && ch != '_') {
return;
}
}
set.add(s);
}
}, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
try (Connection conn = DriverManager.getConnection("jdbc:h2:mem:keywords")) {
Statement stat = conn.createStatement();
for (String s : set) {
// _ROWID_ is a special virtual column
String column = s.equals("_ROWID_") ? "C" : s;
try {
stat.execute("CREATE TABLE " + s + '(' + column + " INT)");
stat.execute("INSERT INTO " + s + '(' + column + ") VALUES (10)");
try (ResultSet rs = stat.executeQuery("SELECT " + column + " FROM " + s)) {
assertTrue(rs.next());
assertEquals(10, rs.getInt(1));
assertFalse(rs.next());
}
} catch (Throwable t) {
throw new AssertionError(s + " cannot be used as identifier.", t);
}
}
}
}
}
...@@ -163,9 +163,6 @@ public class Build extends BuildBase { ...@@ -163,9 +163,6 @@ public class Build extends BuildBase {
downloadUsingMaven("ext/org.jacoco.report-0.8.0.jar", downloadUsingMaven("ext/org.jacoco.report-0.8.0.jar",
"org.jacoco", "org.jacoco.report", "0.8.0", "org.jacoco", "org.jacoco.report", "0.8.0",
"1bcab2a451f5a382bc674857c8f3f6d3fa52151d"); "1bcab2a451f5a382bc674857c8f3f6d3fa52151d");
downloadUsingMaven("ext/asm-6.1.jar",
"org.ow2.asm", "asm", "6.1",
"94a0d17ba8eb24833cd54253ace9b053786a9571");
downloadUsingMaven("ext/asm-commons-6.1.jar", downloadUsingMaven("ext/asm-commons-6.1.jar",
"org.ow2.asm", "asm-commons", "6.1", "org.ow2.asm", "asm-commons", "6.1",
"8a8d242d7ce00fc937a245fae5b65763d13f7cd1"); "8a8d242d7ce00fc937a245fae5b65763d13f7cd1");
...@@ -272,6 +269,7 @@ public class Build extends BuildBase { ...@@ -272,6 +269,7 @@ public class Build extends BuildBase {
File.pathSeparator + "ext/org.osgi.core-4.2.0.jar" + File.pathSeparator + "ext/org.osgi.core-4.2.0.jar" +
File.pathSeparator + "ext/org.osgi.enterprise-4.2.0.jar" + File.pathSeparator + "ext/org.osgi.enterprise-4.2.0.jar" +
File.pathSeparator + "ext/jts-core-1.15.0.jar" + File.pathSeparator + "ext/jts-core-1.15.0.jar" +
File.pathSeparator + "ext/asm-6.1.jar" +
File.pathSeparator + javaToolsJar; File.pathSeparator + javaToolsJar;
FileList files; FileList files;
if (clientOnly) { if (clientOnly) {
...@@ -386,6 +384,9 @@ public class Build extends BuildBase { ...@@ -386,6 +384,9 @@ public class Build extends BuildBase {
downloadOrVerify("ext/junit-4.12.jar", downloadOrVerify("ext/junit-4.12.jar",
"junit", "junit", "4.12", "junit", "junit", "4.12",
"2973d150c0dc1fefe998f834810d68f278ea58ec", offline); "2973d150c0dc1fefe998f834810d68f278ea58ec", offline);
downloadUsingMaven("ext/asm-6.1.jar",
"org.ow2.asm", "asm", "6.1",
"94a0d17ba8eb24833cd54253ace9b053786a9571");
} }
private void downloadOrVerify(String target, String group, String artifact, private void downloadOrVerify(String target, String group, String artifact,
...@@ -962,6 +963,7 @@ public class Build extends BuildBase { ...@@ -962,6 +963,7 @@ public class Build extends BuildBase {
File.pathSeparator + "ext/jts-core-1.15.0.jar" + File.pathSeparator + "ext/jts-core-1.15.0.jar" +
File.pathSeparator + "ext/slf4j-api-1.6.0.jar" + File.pathSeparator + "ext/slf4j-api-1.6.0.jar" +
File.pathSeparator + "ext/slf4j-nop-1.6.0.jar" + File.pathSeparator + "ext/slf4j-nop-1.6.0.jar" +
File.pathSeparator + "ext/asm-6.1.jar" +
File.pathSeparator + javaToolsJar; File.pathSeparator + javaToolsJar;
int version = getJavaVersion(); int version = getJavaVersion();
if (version >= 9) { if (version >= 9) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论