提交 0d91aa36 authored 作者: S.Vladykin's avatar S.Vladykin

Sub-query cache is getting dropped in Session.prepareLocal now + more tests.

上级 48942c18
...@@ -483,6 +483,8 @@ public class Session extends SessionWithState { ...@@ -483,6 +483,8 @@ public class Session extends SessionWithState {
} }
Parser parser = new Parser(this); Parser parser = new Parser(this);
command = parser.prepareCommand(sql); command = parser.prepareCommand(sql);
// we can't reuse view indexes from sub-queries, so just drop the cache
subQueryIndexCache = null;
if (queryCache != null) { if (queryCache != null) {
if (command.isCacheable()) { if (command.isCacheable()) {
queryCache.put(sql, command); queryCache.put(sql, command);
...@@ -1319,8 +1321,8 @@ public class Session extends SessionWithState { ...@@ -1319,8 +1321,8 @@ public class Session extends SessionWithState {
public Map<Object, ViewIndex> getViewIndexCache(boolean subQuery) { public Map<Object, ViewIndex> getViewIndexCache(boolean subQuery) {
if (subQuery) { if (subQuery) {
// for sub-queries we don't need to use LRU because it should not grow too large // for sub-queries we don't need to use LRU because the cache should not
// for a single query and by the end of the statement we will drop the whole cache // grow too large for a single query (we drop the whole cache in the end of prepareLocal)
if (subQueryIndexCache == null) { if (subQueryIndexCache == null) {
subQueryIndexCache = New.hashMap(); subQueryIndexCache = New.hashMap();
} }
...@@ -1510,7 +1512,6 @@ public class Session extends SessionWithState { ...@@ -1510,7 +1512,6 @@ public class Session extends SessionWithState {
*/ */
public void endStatement() { public void endStatement() {
startStatement = -1; startStatement = -1;
subQueryIndexCache = null;
closeTemporaryResults(); closeTemporaryResults();
} }
......
...@@ -10,8 +10,9 @@ import java.sql.PreparedStatement; ...@@ -10,8 +10,9 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.engine.Session;
import org.h2.jdbc.JdbcConnection;
import org.h2.test.TestBase; import org.h2.test.TestBase;
/** /**
...@@ -33,7 +34,7 @@ public class TestView extends TestBase { ...@@ -33,7 +34,7 @@ public class TestView extends TestBase {
@Override @Override
public void test() throws SQLException { public void test() throws SQLException {
deleteDb("view"); deleteDb("view");
testSubQueryViewIndexCache();
testInnerSelectWithRownum(); testInnerSelectWithRownum();
testInnerSelectWithRange(); testInnerSelectWithRange();
testEmptyColumn(); testEmptyColumn();
...@@ -51,6 +52,53 @@ public class TestView extends TestBase { ...@@ -51,6 +52,53 @@ public class TestView extends TestBase {
deleteDb("view"); deleteDb("view");
} }
public void testSubQueryViewIndexCache() throws SQLException {
if (config.networked) {
return;
}
Connection conn = getConnection("view");
Statement stat = conn.createStatement();
stat.execute("drop table test if exists");
stat.execute("create table test(id int primary key, name varchar(25) unique, age int unique)");
// check that initial cache size is empty
Session s = (Session) ((JdbcConnection) conn).getSession();
s.clearViewIndexCache();
assertTrue(s.getViewIndexCache(true).isEmpty());
assertTrue(s.getViewIndexCache(false).isEmpty());
// create view command should not affect caches
stat.execute("create view v as select * from test");
assertTrue(s.getViewIndexCache(true).isEmpty());
assertTrue(s.getViewIndexCache(false).isEmpty());
// check view index cache
stat.executeQuery("select * from v where id > 0").next();
int size1 = s.getViewIndexCache(false).size();
assertTrue(size1 > 0);
assertTrue(s.getViewIndexCache(true).isEmpty());
stat.executeQuery("select * from v where name = 'xyz'").next();
int size2 = s.getViewIndexCache(false).size();
assertTrue(size2 > size1);
assertTrue(s.getViewIndexCache(true).isEmpty());
// check we did not add anything to view cache if we run a sub-query
stat.executeQuery("select * from (select * from test) where age = 17").next();
int size3 = s.getViewIndexCache(false).size();
assertEquals(size2, size3);
assertTrue(s.getViewIndexCache(true).isEmpty());
// check clear works
s.clearViewIndexCache();
assertTrue(s.getViewIndexCache(false).isEmpty());
assertTrue(s.getViewIndexCache(true).isEmpty());
// drop everything
stat.execute("drop view v");
stat.execute("drop table test");
conn.close();
}
private void testInnerSelectWithRownum() throws SQLException { private void testInnerSelectWithRownum() throws SQLException {
Connection conn = getConnection("view"); Connection conn = getConnection("view");
Statement stat = conn.createStatement(); Statement stat = conn.createStatement();
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论