提交 347ad336 authored 作者: noelgrandin's avatar noelgrandin

Fix bug with ALLOW_LITERALS=NONE, where the periodic analyze table on insert…

Fix bug with ALLOW_LITERALS=NONE, where the periodic analyze table on insert would throw an exception.
上级 ddbfdbc4
......@@ -76,6 +76,7 @@ Change Log
</li><li>Fix to org.h2.util.ScriptReader when handling unclosed block comments.
</li><li>Make org.h2.util.ScriptReader throw a better exception when handling broken scripts which generate
extremely large statements.
</li><li>Fix bug with ALLOW_LITERALS=NONE, where the periodic analyze table on insert would throw an exception.
</li></ul>
<h2>Version 1.3.173 (2013-07-28)</h2>
......
......@@ -1680,7 +1680,8 @@ public class Parser {
command.setLimit(limit);
}
if (readIf("SAMPLE_SIZE")) {
command.setSampleSize(getPositiveInt());
Expression sampleSize = readExpression().optimize(session);
command.setSampleSize(sampleSize);
}
currentSelect = temp;
}
......
......@@ -6,16 +6,20 @@
*/
package org.h2.command.ddl;
import java.util.ArrayList;
import org.h2.command.CommandInterface;
import org.h2.command.Prepared;
import org.h2.engine.Database;
import org.h2.engine.Right;
import org.h2.engine.Session;
import org.h2.expression.Parameter;
import org.h2.result.ResultInterface;
import org.h2.table.Column;
import org.h2.table.Table;
import org.h2.util.New;
import org.h2.util.StatementBuilder;
import org.h2.value.Value;
import org.h2.value.ValueInt;
/**
* This class represents the statement
......@@ -80,6 +84,8 @@ public class Analyze extends DefineCommand {
}
Database db = session.getDatabase();
StatementBuilder buff = new StatementBuilder("SELECT ");
ArrayList<Parameter> parameters = New.arrayList();
int parameterIndex = 0;
Column[] columns = table.getColumns();
for (Column col : columns) {
buff.appendExceptFirst(", ");
......@@ -94,10 +100,17 @@ public class Analyze extends DefineCommand {
}
buff.append(" FROM ").append(table.getSQL());
if (sample > 0) {
buff.append(" LIMIT 1 SAMPLE_SIZE ").append(sample);
buff.append(" LIMIT ? SAMPLE_SIZE ? ");
Parameter p = new Parameter(parameterIndex++);
p.setValue(ValueInt.get(1));
parameters.add(p);
p = new Parameter(parameterIndex++);
p.setValue(ValueInt.get(sample));
parameters.add(p);
}
String sql = buff.toString();
Prepared command = session.prepare(sql);
command.setParameterList(parameters);
ResultInterface result = command.query(0);
result.next();
for (int j = 0; j < columns.length; j++) {
......
......@@ -46,9 +46,9 @@ public abstract class Query extends Prepared {
protected Expression offsetExpr;
/**
* The sample size
* The sample size expression as specified in the SAMPLE_SIZE clause.
*/
protected int sampleSize;
protected Expression sampleSizeExpr;
/**
* Whether the result must only contain distinct rows.
......@@ -509,8 +509,19 @@ public abstract class Query extends Prepared {
parameters.add(param);
}
public void setSampleSize(int sampleSize) {
this.sampleSize = sampleSize;
public void setSampleSize(Expression sampleSize) {
this.sampleSizeExpr = sampleSize;
}
protected final int getSampleSizeValue(Session session) {
if (sampleSizeExpr == null) {
return 0;
}
Value v = sampleSizeExpr.getValue(session);
if (v == ValueNull.INSTANCE) {
return 0;
}
return v.getInt();
}
public final long getMaxDataModificationId() {
......
......@@ -315,6 +315,7 @@ public class Select extends Query {
setCurrentRowNumber(0);
currentGroup = null;
ValueArray defaultGroup = ValueArray.get(new Value[0]);
int sampleSize = getSampleSizeValue(session);
while (topTableFilter.next()) {
setCurrentRowNumber(rowNumber + 1);
if (condition == null || Boolean.TRUE.equals(condition.getBooleanValue(session))) {
......@@ -477,6 +478,7 @@ public class Select extends Query {
Index index = topTableFilter.getIndex();
SearchRow first = null;
int columnIndex = index.getColumns()[0].getColumnId();
int sampleSize = getSampleSizeValue(session);
while (true) {
setCurrentRowNumber(rowNumber + 1);
Cursor cursor = index.findNext(session, first, null);
......@@ -517,6 +519,7 @@ public class Select extends Query {
if (isForUpdateMvcc) {
forUpdateRows = New.arrayList();
}
int sampleSize = getSampleSizeValue(session);
while (topTableFilter.next()) {
setCurrentRowNumber(rowNumber + 1);
if (condition == null || Boolean.TRUE.equals(condition.getBooleanValue(session))) {
......@@ -1066,8 +1069,8 @@ public class Select extends Query {
buff.append(" OFFSET ").append(StringUtils.unEnclose(offsetExpr.getSQL()));
}
}
if (sampleSize != 0) {
buff.append("\nSAMPLE_SIZE ").append(sampleSize);
if (sampleSizeExpr != null) {
buff.append("\nSAMPLE_SIZE ").append(StringUtils.unEnclose(sampleSizeExpr.getSQL()));
}
if (isForUpdate) {
buff.append("\nFOR UPDATE");
......
......@@ -393,8 +393,8 @@ public class SelectUnion extends Query {
buff.append("\nOFFSET ").append(StringUtils.unEnclose(offsetExpr.getSQL()));
}
}
if (sampleSize != 0) {
buff.append("\nSAMPLE_SIZE ").append(sampleSize);
if (sampleSizeExpr != null) {
buff.append("\nSAMPLE_SIZE ").append(StringUtils.unEnclose(sampleSizeExpr.getSQL()));
}
if (isForUpdate) {
buff.append("\nFOR UPDATE");
......
......@@ -87,6 +87,7 @@ public class TestPreparedStatement extends TestBase {
testClob(conn);
testParameterMetaData(conn);
conn.close();
testPreparedStatementWithLiteralsNone();
deleteDb("preparedStatement");
}
......@@ -1168,6 +1169,21 @@ public class TestPreparedStatement extends TestBase {
assertTrue(conn == prep.getConnection());
}
private void testPreparedStatementWithLiteralsNone() 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 (?)");
for(int i = 0; i < 200; i++) {
ps.setInt(1, i);
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 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论