提交 bb06b10c authored 作者: Niklas Mehner's avatar Niklas Mehner

Fix bug in parser when "ALLOW_LITERALS=NONE" is set: parameter indices are not "literals"

上级 78cc4925
...@@ -2812,10 +2812,10 @@ public class Parser { ...@@ -2812,10 +2812,10 @@ public class Parser {
case PARAMETER: case PARAMETER:
// there must be no space between ? and the number // there must be no space between ? and the number
boolean indexed = Character.isDigit(sqlCommandChars[parseIndex]); boolean indexed = Character.isDigit(sqlCommandChars[parseIndex]);
read();
Parameter p; Parameter p;
if (indexed && currentTokenType == VALUE && if (indexed) {
currentValue.getType() == Value.INT) { readParameterIndex();
if (indexedParameterList == null) { if (indexedParameterList == null) {
if (parameters == null) { if (parameters == null) {
// this can occur when parsing expressions only (for // this can occur when parsing expressions only (for
...@@ -2845,6 +2845,7 @@ public class Parser { ...@@ -2845,6 +2845,7 @@ public class Parser {
} }
read(); read();
} else { } else {
read();
if (indexedParameterList != null) { if (indexedParameterList != null) {
throw DbException throw DbException
.get(ErrorCode.CANNOT_MIX_INDEXED_AND_UNINDEXED_PARAMS); .get(ErrorCode.CANNOT_MIX_INDEXED_AND_UNINDEXED_PARAMS);
...@@ -3481,6 +3482,30 @@ public class Parser { ...@@ -3481,6 +3482,30 @@ public class Parser {
} }
} }
private void readParameterIndex() {
int i = parseIndex;
char[] chars = sqlCommandChars;
char c = chars[i++];
long number = c - '0';
while (true) {
c = chars[i];
if (c < '0' || c > '9') {
currentValue = ValueInt.get((int) number);
currentTokenType = VALUE;
currentToken = "0";
parseIndex = i;
break;
}
number = number * 10 + (c - '0');
if (number > Integer.MAX_VALUE) {
throw DbException.getInvalidValueException(
"parameter index", number);
}
i++;
}
}
private void checkLiterals(boolean text) { private void checkLiterals(boolean text) {
if (!session.getAllowLiterals()) { if (!session.getAllowLiterals()) {
int allowed = database.getAllowLiterals(); int allowed = database.getAllowLiterals();
......
...@@ -95,6 +95,7 @@ public class TestPreparedStatement extends TestBase { ...@@ -95,6 +95,7 @@ public class TestPreparedStatement extends TestBase {
testColumnMetaDataWithIn(conn); testColumnMetaDataWithIn(conn);
conn.close(); conn.close();
testPreparedStatementWithLiteralsNone(); testPreparedStatementWithLiteralsNone();
testPreparedStatementWithIndexedParameterAndLiteralsNone();
deleteDb("preparedStatement"); deleteDb("preparedStatement");
} }
...@@ -1420,6 +1421,27 @@ public class TestPreparedStatement extends TestBase { ...@@ -1420,6 +1421,27 @@ public class TestPreparedStatement extends TestBase {
deleteDb("preparedStatement"); deleteDb("preparedStatement");
} }
private void testPreparedStatementWithIndexedParameterAndLiteralsNone() throws SQLException {
// make sure that when the analyze table kicks in,
// it works with ALLOW_LITERALS=NONE
deleteDb("preparedStatement");
Connection conn = getConnection(
"preparedStatement;ANALYZE_AUTO=100");
conn.createStatement().execute(
"SET ALLOW_LITERALS NONE");
conn.prepareStatement("CREATE TABLE test (id INT)").execute();
PreparedStatement ps = conn.prepareStatement(
"INSERT INTO test (id) VALUES (?1)");
ps.setInt(1, 1);
ps.executeUpdate();
conn.close();
deleteDb("preparedStatement");
}
private void checkBigDecimal(ResultSet rs, String[] value) throws SQLException { private void checkBigDecimal(ResultSet rs, String[] value) throws SQLException {
for (String v : value) { for (String v : value) {
assertTrue(rs.next()); assertTrue(rs.next());
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论