提交 06b00eda authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Check database settings in JdbcStatement.isSimpleIdentifier()

上级 6178c2ed
...@@ -8106,7 +8106,7 @@ public class Parser { ...@@ -8106,7 +8106,7 @@ public class Parser {
if (s == null) { if (s == null) {
return "\"\""; return "\"\"";
} }
if (ParserUtil.isSimpleIdentifier(s)) { if (ParserUtil.isSimpleIdentifier(s, true, false)) {
return s; return s;
} }
return StringUtils.quoteIdentifier(s); return StringUtils.quoteIdentifier(s);
...@@ -8124,7 +8124,7 @@ public class Parser { ...@@ -8124,7 +8124,7 @@ public class Parser {
if (s == null) { if (s == null) {
return builder.append("\"\""); return builder.append("\"\"");
} }
if (ParserUtil.isSimpleIdentifier(s)) { if (ParserUtil.isSimpleIdentifier(s, true, false)) {
return builder.append(s); return builder.append(s);
} }
return StringUtils.quoteIdentifier(builder, s); return StringUtils.quoteIdentifier(builder, s);
......
...@@ -1403,7 +1403,8 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme ...@@ -1403,7 +1403,8 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
*/ */
@Override @Override
public boolean isSimpleIdentifier(String identifier) throws SQLException { public boolean isSimpleIdentifier(String identifier) throws SQLException {
return ParserUtil.isSimpleIdentifier(identifier); JdbcConnection.Settings settings = conn.getSettings();
return ParserUtil.isSimpleIdentifier(identifier, settings.databaseToUpper, settings.databaseToLower);
} }
/** /**
......
...@@ -284,7 +284,6 @@ public class ParserUtil { ...@@ -284,7 +284,6 @@ public class ParserUtil {
private static final int UPPER_OR_OTHER_LETTER = private static final int UPPER_OR_OTHER_LETTER =
1 << Character.UPPERCASE_LETTER 1 << Character.UPPERCASE_LETTER
| 1 << Character.TITLECASE_LETTER
| 1 << Character.MODIFIER_LETTER | 1 << Character.MODIFIER_LETTER
| 1 << Character.OTHER_LETTER; | 1 << Character.OTHER_LETTER;
...@@ -292,6 +291,26 @@ public class ParserUtil { ...@@ -292,6 +291,26 @@ public class ParserUtil {
UPPER_OR_OTHER_LETTER UPPER_OR_OTHER_LETTER
| 1 << Character.DECIMAL_DIGIT_NUMBER; | 1 << Character.DECIMAL_DIGIT_NUMBER;
private static final int LOWER_OR_OTHER_LETTER =
1 << Character.LOWERCASE_LETTER
| 1 << Character.MODIFIER_LETTER
| 1 << Character.OTHER_LETTER;
private static final int LOWER_OR_OTHER_LETTER_OR_DIGIT =
LOWER_OR_OTHER_LETTER
| 1 << Character.DECIMAL_DIGIT_NUMBER;
private static final int LETTER =
1 << Character.UPPERCASE_LETTER
| 1 << Character.LOWERCASE_LETTER
| 1 << Character.TITLECASE_LETTER
| 1 << Character.MODIFIER_LETTER
| 1 << Character.OTHER_LETTER;
private static final int LETTER_OR_DIGIT =
LETTER
| 1 << Character.DECIMAL_DIGIT_NUMBER;
private ParserUtil() { private ParserUtil() {
// utility class // utility class
} }
...@@ -316,26 +335,44 @@ public class ParserUtil { ...@@ -316,26 +335,44 @@ public class ParserUtil {
* Is this a simple identifier (in the JDBC specification sense). * Is this a simple identifier (in the JDBC specification sense).
* *
* @param s identifier to check * @param s identifier to check
* @param databaseToUpper whether unquoted identifiers are converted to upper case
* @param databaseToLower whether unquoted identifiers are converted to lower case
* @return is specified identifier may be used without quotes * @return is specified identifier may be used without quotes
* @throws NullPointerException if s is {@code null} * @throws NullPointerException if s is {@code null}
*/ */
public static boolean isSimpleIdentifier(String s) { public static boolean isSimpleIdentifier(String s, boolean databaseToUpper, boolean databaseToLower) {
int length = s.length(); int length = s.length();
if (length == 0) { if (length == 0) {
return false; return false;
} }
int startFlags, partFlags;
if (databaseToUpper) {
if (databaseToLower) {
throw new IllegalArgumentException("databaseToUpper && databaseToLower");
} else {
startFlags = UPPER_OR_OTHER_LETTER;
partFlags = UPPER_OR_OTHER_LETTER_OR_DIGIT;
}
} else {
if (databaseToLower) {
startFlags = LOWER_OR_OTHER_LETTER;
partFlags = LOWER_OR_OTHER_LETTER_OR_DIGIT;
} else {
startFlags = LETTER;
partFlags = LETTER_OR_DIGIT;
}
}
char c = s.charAt(0); char c = s.charAt(0);
// lowercase a-z is quoted as well if ((startFlags >>> Character.getType(c) & 1) == 0 && c != '_') {
if ((UPPER_OR_OTHER_LETTER >>> Character.getType(c) & 1) == 0 && c != '_') {
return false; return false;
} }
for (int i = 1; i < length; i++) { for (int i = 1; i < length; i++) {
c = s.charAt(i); c = s.charAt(i);
if ((UPPER_OR_OTHER_LETTER_OR_DIGIT >>> Character.getType(c) & 1) == 0 && c != '_') { if ((partFlags >>> Character.getType(c) & 1) == 0 && c != '_') {
return false; return false;
} }
} }
return getSaveTokenType(s, false, 0, length, true) == IDENTIFIER; return getSaveTokenType(s, !databaseToUpper, 0, length, true) == IDENTIFIER;
} }
/** /**
......
...@@ -53,6 +53,7 @@ public class TestStatement extends TestDb { ...@@ -53,6 +53,7 @@ public class TestStatement extends TestDb {
testIdentityMerge(); testIdentityMerge();
testIdentity(); testIdentity();
conn.close(); conn.close();
testIdentifiers();
deleteDb("statement"); deleteDb("statement");
} }
...@@ -330,23 +331,6 @@ public class TestStatement extends TestDb { ...@@ -330,23 +331,6 @@ public class TestStatement extends TestDb {
assertNull(stat.getWarnings()); assertNull(stat.getWarnings());
assertTrue(conn == stat.getConnection()); assertTrue(conn == stat.getConnection());
assertEquals("SOME_ID", statBC.enquoteIdentifier("SOME_ID", false));
assertEquals("\"SOME ID\"", statBC.enquoteIdentifier("SOME ID", false));
assertEquals("\"SOME_ID\"", statBC.enquoteIdentifier("SOME_ID", true));
assertEquals("\"FROM\"", statBC.enquoteIdentifier("FROM", false));
assertEquals("\"Test\"", statBC.enquoteIdentifier("Test", false));
assertEquals("\"TODAY\"", statBC.enquoteIdentifier("TODAY", false));
// Other lower case characters don't have upper case mappings
assertEquals("\u02B0", statBC.enquoteIdentifier("\u02B0", false));
assertTrue(statBC.isSimpleIdentifier("SOME_ID"));
assertFalse(statBC.isSimpleIdentifier("SOME ID"));
assertFalse(statBC.isSimpleIdentifier("FROM"));
assertFalse(statBC.isSimpleIdentifier("Test"));
assertFalse(statBC.isSimpleIdentifier("TODAY"));
// Other lower case characters don't have upper case mappings
assertTrue(statBC.isSimpleIdentifier("\u02B0"));
stat.close(); stat.close();
} }
...@@ -489,4 +473,75 @@ public class TestStatement extends TestDb { ...@@ -489,4 +473,75 @@ public class TestStatement extends TestDb {
stat.execute("drop table test"); stat.execute("drop table test");
} }
private void testIdentifiers() throws SQLException {
Connection conn = getConnection("statement");
JdbcStatement stat = (JdbcStatement) conn.createStatement();
assertEquals("SOME_ID", stat.enquoteIdentifier("SOME_ID", false));
assertEquals("\"SOME ID\"", stat.enquoteIdentifier("SOME ID", false));
assertEquals("\"SOME_ID\"", stat.enquoteIdentifier("SOME_ID", true));
assertEquals("\"FROM\"", stat.enquoteIdentifier("FROM", false));
assertEquals("\"Test\"", stat.enquoteIdentifier("Test", false));
assertEquals("\"test\"", stat.enquoteIdentifier("test", false));
assertEquals("\"TODAY\"", stat.enquoteIdentifier("TODAY", false));
// Other lower case characters don't have upper case mappings
assertEquals("\u02B0", stat.enquoteIdentifier("\u02B0", false));
assertTrue(stat.isSimpleIdentifier("SOME_ID"));
assertFalse(stat.isSimpleIdentifier("SOME ID"));
assertFalse(stat.isSimpleIdentifier("FROM"));
assertFalse(stat.isSimpleIdentifier("Test"));
assertFalse(stat.isSimpleIdentifier("test"));
assertFalse(stat.isSimpleIdentifier("TODAY"));
// Other lower case characters don't have upper case mappings
assertTrue(stat.isSimpleIdentifier("\u02B0"));
conn.close();
conn = getConnection("statement;DATABASE_TO_LOWER=TRUE");
stat = (JdbcStatement) conn.createStatement();
assertEquals("some_id", stat.enquoteIdentifier("some_id", false));
assertEquals("\"some id\"", stat.enquoteIdentifier("some id", false));
assertEquals("\"some_id\"", stat.enquoteIdentifier("some_id", true));
assertEquals("\"from\"", stat.enquoteIdentifier("from", false));
assertEquals("\"Test\"", stat.enquoteIdentifier("Test", false));
assertEquals("\"TEST\"", stat.enquoteIdentifier("TEST", false));
assertEquals("\"today\"", stat.enquoteIdentifier("today", false));
assertTrue(stat.isSimpleIdentifier("some_id"));
assertFalse(stat.isSimpleIdentifier("some id"));
assertFalse(stat.isSimpleIdentifier("from"));
assertFalse(stat.isSimpleIdentifier("Test"));
assertFalse(stat.isSimpleIdentifier("TEST"));
assertFalse(stat.isSimpleIdentifier("today"));
conn.close();
conn = getConnection("statement;DATABASE_TO_UPPER=FALSE");
stat = (JdbcStatement) conn.createStatement();
assertEquals("SOME_ID", stat.enquoteIdentifier("SOME_ID", false));
assertEquals("some_id", stat.enquoteIdentifier("some_id", false));
assertEquals("\"SOME ID\"", stat.enquoteIdentifier("SOME ID", false));
assertEquals("\"some id\"", stat.enquoteIdentifier("some id", false));
assertEquals("\"SOME_ID\"", stat.enquoteIdentifier("SOME_ID", true));
assertEquals("\"some_id\"", stat.enquoteIdentifier("some_id", true));
assertEquals("\"FROM\"", stat.enquoteIdentifier("FROM", false));
assertEquals("\"from\"", stat.enquoteIdentifier("from", false));
assertEquals("Test", stat.enquoteIdentifier("Test", false));
assertEquals("\"TODAY\"", stat.enquoteIdentifier("TODAY", false));
assertEquals("\"today\"", stat.enquoteIdentifier("today", false));
assertTrue(stat.isSimpleIdentifier("SOME_ID"));
assertTrue(stat.isSimpleIdentifier("some_id"));
assertFalse(stat.isSimpleIdentifier("SOME ID"));
assertFalse(stat.isSimpleIdentifier("some id"));
assertFalse(stat.isSimpleIdentifier("FROM"));
assertFalse(stat.isSimpleIdentifier("from"));
assertTrue(stat.isSimpleIdentifier("Test"));
assertFalse(stat.isSimpleIdentifier("TODAY"));
assertFalse(stat.isSimpleIdentifier("today"));
conn.close();
}
} }
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论