/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.test.db;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import org.h2.test.TestBase;
/**
* Test recursive queries using WITH.
*/
public class TestRecursiveQueries extends TestBase {
/**
* Run just this test.
*
* @param a ignored
*/
public static void main(String... a) throws Exception {
TestBase.createCaller().init().test();
}
public void test() throws Exception {
testWrongLinkLargeResult();
testSimple();
}
private void testWrongLinkLargeResult() throws Exception {
deleteDb("recursiveQueries");
Connection conn = getConnection("recursiveQueries");
Statement stat;
stat = conn.createStatement();
stat.execute("create table test(parent varchar(255), child varchar(255))");
stat.execute("insert into test values('/', 'a'), ('a', 'b1'), ('a', 'b2'), ('a', 'c'), ('c', 'd1'), ('c', 'd2')");
ResultSet rs = stat.executeQuery("with recursive rec_test(depth, parent, child) as (" +
"select 0, parent, child from test where parent = '/' " +
"union all " +
"select depth+1, r.parent, r.child from test i join rec_test r " +
"on (i.parent = r.child) where depth<9 " +
") select count(*) from rec_test");
rs.next();
assertEquals(29524, rs.getInt(1));
stat.execute("with recursive rec_test(depth, parent, child) as ( "+
"select 0, parent, child from test where parent = '/' "+
"union all "+
"select depth+1, i.parent, i.child from test i join rec_test r "+
"on (r.child = i.parent) where depth<10 "+
") select * from rec_test");
conn.close();
deleteDb("recursiveQueries");
}
private void testSimple() throws Exception {
deleteDb("recursiveQueries");
Connection conn = getConnection("recursiveQueries");
Statement stat;
PreparedStatement prep, prep2;
ResultSet rs;
stat = conn.createStatement();
rs = stat.executeQuery("with recursive t(n) as " +
"(select 1 union all select n+1 from t where n<3) " +
"select * from t");
assertTrue(rs.next());
assertEquals(1, rs.getInt(1));
assertTrue(rs.next());
assertEquals(2, rs.getInt(1));
assertTrue(rs.next());
assertEquals(3, rs.getInt(1));
assertFalse(rs.next());
prep = conn.prepareStatement("with recursive t(n) as " +
"(select 1 union all select n+1 from t where n<3) " +
"select * from t where n>?");
prep.setInt(1, 2);
rs = prep.executeQuery();
assertTrue(rs.next());
assertEquals(3, rs.getInt(1));
assertFalse(rs.next());
prep.setInt(1, 1);
rs = prep.executeQuery();
assertTrue(rs.next());
assertEquals(2, rs.getInt(1));
assertTrue(rs.next());
assertEquals(3, rs.getInt(1));
assertFalse(rs.next());
prep = conn.prepareStatement("with recursive t(n) as " +
"(select @start union all select n+@inc from t where n<@end) " +
"select * from t");
prep2 = conn.prepareStatement("select @start:=?, @inc:=?, @end:=?");
prep2.setInt(1, 10);
prep2.setInt(2, 2);
prep2.setInt(3, 14);
prep2.execute();
rs = prep.executeQuery();
assertTrue(rs.next());
assertEquals(10, rs.getInt(1));
assertTrue(rs.next());
assertEquals(12, rs.getInt(1));
assertTrue(rs.next());
assertEquals(14, rs.getInt(1));
assertFalse(rs.next());
prep2.setInt(1, 100);
prep2.setInt(2, 3);
prep2.setInt(3, 103);
prep2.execute();
rs = prep.executeQuery();
assertTrue(rs.next());
assertEquals(100, rs.getInt(1));
assertTrue(rs.next());
assertEquals(103, rs.getInt(1));
assertFalse(rs.next());
conn.close();
deleteDb("recursiveQueries");
}
}