/* * 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.synth; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import org.h2.test.TestBase; import org.h2.test.synth.sql.RandomGen; /** * A test that runs random operations against a table to test the various index * implementations. */ public class TestSimpleIndex extends TestBase { private Connection conn; private Statement stat; private RandomGen random; /** * Run just this test. * * @param a ignored */ public static void main(String... a) throws Exception { TestBase.createCaller().init().test(); } public void test() throws SQLException { deleteDb("simpleIndex"); conn = getConnection("simpleIndex"); random = new RandomGen(); stat = conn.createStatement(); for (int i = 0; i < 10000; i++) { testIndex(i); } } private void testIndex(int seed) throws SQLException { random.setSeed(seed); String unique = random.nextBoolean() ? "UNIQUE " : ""; int len = random.getInt(2) + 1; StringBuilder buff = new StringBuilder(); for (int i = 0; i < len; i++) { if (i > 0) { buff.append(", "); } buff.append((char) ('A' + random.getInt(3))); } String cols = buff.toString(); execute("CREATE MEMORY TABLE TEST_M(A INT, B INT, C INT, DATA VARCHAR(255))"); execute("CREATE CACHED TABLE TEST_D(A INT, B INT, C INT, DATA VARCHAR(255))"); execute("CREATE MEMORY TABLE TEST_MI(A INT, B INT, C INT, DATA VARCHAR(255))"); execute("CREATE CACHED TABLE TEST_DI(A INT, B INT, C INT, DATA VARCHAR(255))"); execute("CREATE " + unique + "INDEX M ON TEST_MI(" + cols + ")"); execute("CREATE " + unique + "INDEX D ON TEST_DI(" + cols + ")"); for (int i = 0; i < 100; i++) { println("i=" + i); testRows(); } execute("DROP INDEX M"); execute("DROP INDEX D"); execute("DROP TABLE TEST_M"); execute("DROP TABLE TEST_D"); execute("DROP TABLE TEST_MI"); execute("DROP TABLE TEST_DI"); } private void testRows() throws SQLException { String a = randomValue(), b = randomValue(), c = randomValue(); String data = a + "/" + b + "/" + c; String sql = "VALUES(" + a + ", " + b + ", " + c + ", '" + data + "')"; boolean em, ed; // if(id==73) { // print("halt"); // } try { execute("INSERT INTO TEST_MI " + sql); em = false; } catch (SQLException e) { em = true; } try { execute("INSERT INTO TEST_DI " + sql); ed = false; } catch (SQLException e) { ed = true; } if (em != ed) { fail("different result: "); } if (!em) { execute("INSERT INTO TEST_M " + sql); execute("INSERT INTO TEST_D " + sql); } StringBuilder buff = new StringBuilder("WHERE 1=1"); int len = random.getLog(10); for (int i = 0; i < len; i++) { buff.append(" AND "); buff.append('A' + random.getInt(3)); switch (random.getInt(10)) { case 0: buff.append("<"); buff.append(random.getInt(100) - 50); break; case 1: buff.append("<="); buff.append(random.getInt(100) - 50); break; case 2: buff.append(">"); buff.append(random.getInt(100) - 50); break; case 3: buff.append(">="); buff.append(random.getInt(100) - 50); break; case 4: buff.append("<>"); buff.append(random.getInt(100) - 50); break; case 5: buff.append(" IS NULL"); break; case 6: buff.append(" IS NOT NULL"); break; default: buff.append("="); buff.append(random.getInt(100) - 50); } } String where = buff.toString(); String r1 = getResult("SELECT DATA FROM TEST_M " + where + " ORDER BY DATA"); String r2 = getResult("SELECT DATA FROM TEST_D " + where + " ORDER BY DATA"); String r3 = getResult("SELECT DATA FROM TEST_MI " + where + " ORDER BY DATA"); String r4 = getResult("SELECT DATA FROM TEST_DI " + where + " ORDER BY DATA"); assertEquals(r1, r2); assertEquals(r1, r3); assertEquals(r1, r4); } private String getResult(String sql) throws SQLException { ResultSet rs = stat.executeQuery(sql); StringBuilder buff = new StringBuilder(); while (rs.next()) { buff.append(rs.getString(1)); buff.append("; "); } rs.close(); return buff.toString(); } private String randomValue() { return random.getInt(10) == 0 ? "NULL" : "" + (random.getInt(100) - 50); } private void execute(String sql) throws SQLException { try { println(sql + ";"); stat.execute(sql); println("> update count: 1"); } catch (SQLException e) { println("> exception"); throw e; } } }