// Path: journalled-sql-rewriter/src/main/java/org/apache/calcite/adapter/jdbc/programs/ForcedRulesProgram.java
// public class ForcedRulesProgram implements Program {
// 	private static final Logger logger = LoggerFactory.getLogger(ForcedRulesProgram.class);
// 
// 	private final JdbcRelBuilderFactoryFactory relBuilderFactoryFactory;
// 
// 	private final ForcedRule[] rules;
// 
// 	public ForcedRulesProgram(JdbcRelBuilderFactoryFactory relBuilderFactoryFactory, ForcedRule... rules) {
// 		this.relBuilderFactoryFactory = relBuilderFactoryFactory;
// 		this.rules = rules;
// 	}
// 
// 	@Override
// 	public RelNode run(RelOptPlanner relOptPlanner,
// 			RelNode relNode,
// 			RelTraitSet relTraitSet,
// 			List<RelOptMaterialization> relOptMaterializationList,
// 			List<RelOptLattice> list1) {
// 
// 		logger.debug("Running forced rules on:\n" + RelOptUtil.toString(relNode));
// 
// 		return replace(relNode, rules, relBuilderFactoryFactory.create(relOptPlanner.getContext()));
// 	}
// 
// 	private RelNode replace(RelNode original, ForcedRule[] rules, JdbcRelBuilderFactory relBuilderFactory) {
// 		RelNode p = original;
// 		for (ForcedRule rule : rules) {
// 			RelNode updated = rule.apply(p, relBuilderFactory);
// 			if (updated != null) {
// 				logger.trace("Rule: " + rule.toString() +
// 						"\nReplacing:\n" + RelOptUtil.toString(p) +
// 						"\nWith:\n" + RelOptUtil.toString(updated)
// 				);
// 				// Must maintain row types so that nothing explodes
// 				RelOptUtil.equal(
// 						"RowType of original", p.getRowType(),
// 						"RowType of replaced", updated.getRowType(),
// 						Litmus.THROW
// 				);
// 				p = updated;
// 				break;
// 			}
// 		}
// 
// 		List<RelNode> oldInputs = p.getInputs();
// 		for (int i = 0; i < oldInputs.size(); i++) {
// 			RelNode originalInput = oldInputs.get(i);
// 			RelNode replacedInput = replace(originalInput, rules, relBuilderFactory);
// 			if (replacedInput != originalInput) {
// 				p.replaceInput(i, replacedInput);
// 			}
// 		}
// 		return p;
// 	}
// }
// 
// Path: journalled-sql-rewriter/src/main/java/org/apache/calcite/adapter/jdbc/programs/SequenceProgram.java
// @SuppressWarnings("WeakerAccess") // Public API
// public class SequenceProgram implements Program {
// 	private static final Logger logger = LoggerFactory.getLogger(SequenceProgram.class);
// 
// 	private final ImmutableList<Program> programs;
// 
// 	public SequenceProgram(Program... programs) {
// 		this.programs = ImmutableList.copyOf(programs);
// 	}
// 
// 	// Use with Hook.PROGRAM.add
// 	@SuppressWarnings("Guava") // Must conform to Calcite's API
// 	public static Function<Holder<Program>, Void> prepend(Program program) {
// 		return (holder) -> {
// 			if (holder == null) {
// 				throw new IllegalStateException("No program holder");
// 			}
// 			Program chain = holder.get();
// 			if (chain == null) {
// 				chain = Programs.standard();
// 			}
// 			holder.set(new SequenceProgram(program, chain));
// 			return null;
// 		};
// 	}
// 
// 	public ImmutableList<Program> getPrograms() {
// 		return programs;
// 	}
// 
// 	@Override
// 	public RelNode run(RelOptPlanner relOptPlanner,
// 			RelNode relNode,
// 			RelTraitSet relTraitSet,
// 			List<RelOptMaterialization> relOptMaterializationList,
// 			List<RelOptLattice> relOptLatticeList) {
// 		for (Program program : programs) {
// 			relNode = program.run(relOptPlanner, relNode, relTraitSet, relOptMaterializationList, relOptLatticeList);
// 			logger.debug("After running " + program + ":\n" + RelOptUtil.toString(relNode));
// 		}
// 		return relNode;
// 	}
// 
// }


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.apache.calcite.adapter.jdbc.programs.ForcedRulesProgram;
import org.apache.calcite.adapter.jdbc.programs.SequenceProgram;
import org.apache.calcite.runtime.Hook;
import org.apache.calcite.schema.Schema;
import org.apache.calcite.schema.Table;
import org.apache.calcite.tools.Program;
import org.apache.calcite.util.Holder;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.Mockito;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
	}

	@Test
	public void testGetTableConvertsMatchingTables() {
		JournalledJdbcSchema schema = makeSchema();
		Table table = schema.getTable("MY_TABLE");
		Assert.assertNotNull(table);
		Assert.assertTrue(table instanceof JournalledJdbcTable);
		JournalledJdbcTable journalTable = (JournalledJdbcTable) table;
		Assert.assertEquals(journalTable.getVersionField(), "myvfield");
		Assert.assertEquals(journalTable.getSubsequentVersionField(), "mysvfield");
		Assert.assertNotNull(journalTable.getJournalTable());
	}

	@Test
	public void testGetTablePassesThroughNonMatchingTables() {
		JournalledJdbcSchema schema = makeSchema();
		Table table = schema.getTable("OTHER_TABLE");
		Assert.assertNotNull(table);
		Assert.assertFalse(table instanceof JournalledJdbcTable);
	}

	@Test
	public void testGetTableSurvivesNulls() {
		JournalledJdbcSchema schema = makeSchema();
		Table table = schema.getTable("NOT_HERE");
		Assert.assertNull(table);
	}

	@Test
// Path: journalled-sql-rewriter/src/main/java/org/apache/calcite/adapter/jdbc/programs/ForcedRulesProgram.java
// public class ForcedRulesProgram implements Program {
// 	private static final Logger logger = LoggerFactory.getLogger(ForcedRulesProgram.class);
// 
// 	private final JdbcRelBuilderFactoryFactory relBuilderFactoryFactory;
// 
// 	private final ForcedRule[] rules;
// 
// 	public ForcedRulesProgram(JdbcRelBuilderFactoryFactory relBuilderFactoryFactory, ForcedRule... rules) {
// 		this.relBuilderFactoryFactory = relBuilderFactoryFactory;
// 		this.rules = rules;
// 	}
// 
// 	@Override
// 	public RelNode run(RelOptPlanner relOptPlanner,
// 			RelNode relNode,
// 			RelTraitSet relTraitSet,
// 			List<RelOptMaterialization> relOptMaterializationList,
// 			List<RelOptLattice> list1) {
// 
// 		logger.debug("Running forced rules on:\n" + RelOptUtil.toString(relNode));
// 
// 		return replace(relNode, rules, relBuilderFactoryFactory.create(relOptPlanner.getContext()));
// 	}
// 
// 	private RelNode replace(RelNode original, ForcedRule[] rules, JdbcRelBuilderFactory relBuilderFactory) {
// 		RelNode p = original;
// 		for (ForcedRule rule : rules) {
// 			RelNode updated = rule.apply(p, relBuilderFactory);
// 			if (updated != null) {
// 				logger.trace("Rule: " + rule.toString() +
// 						"\nReplacing:\n" + RelOptUtil.toString(p) +
// 						"\nWith:\n" + RelOptUtil.toString(updated)
// 				);
// 				// Must maintain row types so that nothing explodes
// 				RelOptUtil.equal(
// 						"RowType of original", p.getRowType(),
// 						"RowType of replaced", updated.getRowType(),
// 						Litmus.THROW
// 				);
// 				p = updated;
// 				break;
// 			}
// 		}
// 
// 		List<RelNode> oldInputs = p.getInputs();
// 		for (int i = 0; i < oldInputs.size(); i++) {
// 			RelNode originalInput = oldInputs.get(i);
// 			RelNode replacedInput = replace(originalInput, rules, relBuilderFactory);
// 			if (replacedInput != originalInput) {
// 				p.replaceInput(i, replacedInput);
// 			}
// 		}
// 		return p;
// 	}
// }
// 
// Path: journalled-sql-rewriter/src/main/java/org/apache/calcite/adapter/jdbc/programs/SequenceProgram.java
// @SuppressWarnings("WeakerAccess") // Public API
// public class SequenceProgram implements Program {
// 	private static final Logger logger = LoggerFactory.getLogger(SequenceProgram.class);
// 
// 	private final ImmutableList<Program> programs;
// 
// 	public SequenceProgram(Program... programs) {
// 		this.programs = ImmutableList.copyOf(programs);
// 	}
// 
// 	// Use with Hook.PROGRAM.add
// 	@SuppressWarnings("Guava") // Must conform to Calcite's API
// 	public static Function<Holder<Program>, Void> prepend(Program program) {
// 		return (holder) -> {
// 			if (holder == null) {
// 				throw new IllegalStateException("No program holder");
// 			}
// 			Program chain = holder.get();
// 			if (chain == null) {
// 				chain = Programs.standard();
// 			}
// 			holder.set(new SequenceProgram(program, chain));
// 			return null;
// 		};
// 	}
// 
// 	public ImmutableList<Program> getPrograms() {
// 		return programs;
// 	}
// 
// 	@Override
// 	public RelNode run(RelOptPlanner relOptPlanner,
// 			RelNode relNode,
// 			RelTraitSet relTraitSet,
// 			List<RelOptMaterialization> relOptMaterializationList,
// 			List<RelOptLattice> relOptLatticeList) {
// 		for (Program program : programs) {
// 			relNode = program.run(relOptPlanner, relNode, relTraitSet, relOptMaterializationList, relOptLatticeList);
// 			logger.debug("After running " + program + ":\n" + RelOptUtil.toString(relNode));
// 		}
// 		return relNode;
// 	}
// 
// }


// Path: journalled-sql-rewriter/src/test/java/org/apache/calcite/adapter/jdbc/JournalledJdbcSchemaTest.java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.apache.calcite.adapter.jdbc.programs.ForcedRulesProgram;
import org.apache.calcite.adapter.jdbc.programs.SequenceProgram;
import org.apache.calcite.runtime.Hook;
import org.apache.calcite.schema.Schema;
import org.apache.calcite.schema.Table;
import org.apache.calcite.tools.Program;
import org.apache.calcite.util.Holder;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.Mockito;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;

	}

	@Test
	public void testGetTableConvertsMatchingTables() {
		JournalledJdbcSchema schema = makeSchema();
		Table table = schema.getTable("MY_TABLE");
		Assert.assertNotNull(table);
		Assert.assertTrue(table instanceof JournalledJdbcTable);
		JournalledJdbcTable journalTable = (JournalledJdbcTable) table;
		Assert.assertEquals(journalTable.getVersionField(), "myvfield");
		Assert.assertEquals(journalTable.getSubsequentVersionField(), "mysvfield");
		Assert.assertNotNull(journalTable.getJournalTable());
	}

	@Test
	public void testGetTablePassesThroughNonMatchingTables() {
		JournalledJdbcSchema schema = makeSchema();
		Table table = schema.getTable("OTHER_TABLE");
		Assert.assertNotNull(table);
		Assert.assertFalse(table instanceof JournalledJdbcTable);
	}

	@Test
	public void testGetTableSurvivesNulls() {
		JournalledJdbcSchema schema = makeSchema();
		Table table = schema.getTable("NOT_HERE");
		Assert.assertNull(table);
	}

	@Test
	public void testListsOfKeysAreLoaded() {