package org.apache.calcite.adapter.jdbc;

import io.pivotal.beach.calcite.programs.ForcedRulesProgram;
import io.pivotal.beach.calcite.programs.SequenceProgram;
import org.apache.calcite.runtime.Hook;
import org.apache.calcite.test.CalciteAssert;
import org.junit.BeforeClass;
import org.junit.Test;

public class JournalledSelectRuleIntegrationTest {
	@BeforeClass
	public static void rebuildTestDatabase() throws Exception {
		TargetDatabase.rebuild();
	}

	@Test
	public void testSelectRewriting() {
		CalciteAssert
				.model(TargetDatabase.JOURNALLED_MODEL)
				.query("SELECT \"empid\" FROM \"hr\".\"emps\"")
				.withHook(Hook.PROGRAM, SequenceProgram.prepend(new ForcedRulesProgram(
						new JournalledSelectRule()
				)))
				.explainContains("PLAN=JdbcToEnumerableConverter\n" +
						"  JdbcProject(empid=[CAST($0):INTEGER])\n" +
						"    JdbcFilter(condition=[AND(=($1, $3), IS NULL($2))])\n" +
						"      JdbcProject(empid=[$0], version_number=[$2], subsequent_version_number=[$3], $f6=[MAX($2) OVER (PARTITION BY $0 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)])\n" +
						"        JdbcTableScan(table=[[hr, emps_journal]])\n")
				.runs()
				.planHasSql("SELECT CAST(\"empid\" AS INTEGER) AS \"empid\"\n" +
						"FROM (SELECT \"empid\", \"version_number\", \"subsequent_version_number\", MAX(\"version_number\") OVER (PARTITION BY \"empid\" ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS \"$f6\"\n" +
						"FROM \"calcite_sql_rewriter_integration_test\".\"emps_journal\") AS \"t\"\n" +
						"WHERE \"version_number\" = \"$f6\" AND \"subsequent_version_number\" IS NULL");
	}
}

@@ -35,16 +35,56 @@
 .jdbc;%0A%0A
+import com.google.common.base.Function;%0A
 import i
@@ -132,24 +132,24 @@
 lesProgram;%0A
-
 import io.pi
@@ -280,16 +280,96 @@
 Assert;%0A
+import org.apache.calcite.tools.Program;%0Aimport org.apache.calcite.util.Holder;%0A
 import o
@@ -465,16 +465,152 @@
 nTest %7B%0A
+%0A%09private Function%3CHolder%3CProgram%3E, Void%3E program = SequenceProgram.prepend(%0A%09%09%09new ForcedRulesProgram(new JournalledSelectRule())%0A%09);%0A%0A
 %09@Before
@@ -896,95 +896,15 @@
 AM, 
-SequenceProgram.prepend(new ForcedRulesProgram(%0A%09%09%09%09%09%09new JournalledSelectRule()%0A%09%09%09%09))
+program
 )%0A%09%09
@@ -1791,15 +1791,566 @@
 S NULL%22)
-;%0A%09%7D
+%0A%09%09%09%09.returns(%22empid=1%5Cn%22 +%0A%09%09%09%09%09%09%22empid=2%5Cn%22 +%0A%09%09%09%09%09%09%22empid=3%5Cn%22 +%0A%09%09%09%09%09%09%22empid=4%5Cn%22 +%0A%09%09%09%09%09%09%22empid=5%5Cn%22 +%0A%09%09%09%09%09%09%22empid=6%5Cn%22);%0A%09%7D%0A%0A%09@Test%0A%09public void testComplexSelectRewriting() %7B%0A%09%09CalciteAssert%0A%09%09%09%09.model(TargetDatabase.JOURNALLED_MODEL)%0A%09%09%09%09.query(%22SELECT %5C%22d%5C%22.%5C%22deptno%5C%22%5Cn%22 +%0A%09%09%09%09%09%09%22FROM %5C%22hr%5C%22.%5C%22emps%5C%22 AS %5C%22e%5C%22%5Cn%22 +%0A%09%09%09%09%09%09%22JOIN %5C%22hr%5C%22.%5C%22depts%5C%22 AS %5C%22d%5C%22 ON %5C%22e%5C%22.%5C%22deptno%5C%22 = %5C%22d%5C%22.%5C%22deptno%5C%22%5Cn%22 +%0A%09%09%09%09%09%09%22GROUP BY %5C%22d%5C%22.%5C%22deptno%5C%22%5Cn%22 +%0A%09%09%09%09%09%09%22HAVING COUNT(*) %3E 1%22)%0A%09%09%09%09.withHook(Hook.PROGRAM, program)%0A%09%09%09%09.runs()%0A%09%09%09%09.returns(%22deptno=2%5Cn%22);%0A%09%7D%0A
 %0A%7D%0A

Extend integration tests to check database results, more complex query