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

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

......@@ -2812,10 +2812,10 @@ public class Parser {
case PARAMETER:
// there must be no space between ? and the number
boolean indexed = Character.isDigit(sqlCommandChars[parseIndex]);
read();
Parameter p;
if (indexed && currentTokenType == VALUE &&
currentValue.getType() == Value.INT) {
if (indexed) {
readParameterIndex();
if (indexedParameterList == null) {
if (parameters == null) {
// this can occur when parsing expressions only (for
......@@ -2845,6 +2845,7 @@ public class Parser {
}
read();
} else {
read();
if (indexedParameterList != null) {
throw DbException
.get(ErrorCode.CANNOT_MIX_INDEXED_AND_UNINDEXED_PARAMS);
......@@ -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) {
if (!session.getAllowLiterals()) {
int allowed = database.getAllowLiterals();
......
......@@ -95,6 +95,7 @@ public class TestPreparedStatement extends TestBase {
testColumnMetaDataWithIn(conn);
conn.close();
testPreparedStatementWithLiteralsNone();
testPreparedStatementWithIndexedParameterAndLiteralsNone();
deleteDb("preparedStatement");
}
......@@ -1420,6 +1421,27 @@ public class TestPreparedStatement extends TestBase {
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 {
for (String v : value) {
assertTrue(rs.next());
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论