use of org.apache.calcite.schema.Table in project calcite by apache.
the class ScannableTableTest method testPrepared2.
/**
* Test case for
* <a href="https://issues.apache.org/jira/browse/CALCITE-1031">[CALCITE-1031]
* In prepared statement, CsvScannableTable.scan is called twice</a>.
*/
@Test
public void testPrepared2() throws SQLException {
final Properties properties = new Properties();
properties.setProperty("caseSensitive", "true");
try (final Connection connection = DriverManager.getConnection("jdbc:calcite:", properties)) {
final CalciteConnection calciteConnection = connection.unwrap(CalciteConnection.class);
final AtomicInteger scanCount = new AtomicInteger();
final AtomicInteger enumerateCount = new AtomicInteger();
final Schema schema = new AbstractSchema() {
@Override
protected Map<String, Table> getTableMap() {
return ImmutableMap.<String, Table>of("TENS", new SimpleTable() {
private Enumerable<Object[]> superScan(DataContext root) {
return super.scan(root);
}
@Override
public Enumerable<Object[]> scan(final DataContext root) {
scanCount.incrementAndGet();
return new AbstractEnumerable<Object[]>() {
public Enumerator<Object[]> enumerator() {
enumerateCount.incrementAndGet();
return superScan(root).enumerator();
}
};
}
});
}
};
calciteConnection.getRootSchema().add("TEST", schema);
final String sql = "select * from \"TEST\".\"TENS\" where \"i\" < ?";
final PreparedStatement statement = calciteConnection.prepareStatement(sql);
assertThat(scanCount.get(), is(0));
assertThat(enumerateCount.get(), is(0));
// First execute
statement.setInt(1, 20);
assertThat(scanCount.get(), is(0));
ResultSet resultSet = statement.executeQuery();
assertThat(scanCount.get(), is(1));
assertThat(enumerateCount.get(), is(1));
assertThat(resultSet, Matchers.returnsUnordered("i=0", "i=10"));
assertThat(scanCount.get(), is(1));
assertThat(enumerateCount.get(), is(1));
// Second execute
resultSet = statement.executeQuery();
assertThat(scanCount.get(), is(2));
assertThat(resultSet, Matchers.returnsUnordered("i=0", "i=10"));
assertThat(scanCount.get(), is(2));
// Third execute
statement.setInt(1, 30);
resultSet = statement.executeQuery();
assertThat(scanCount.get(), is(3));
assertThat(resultSet, Matchers.returnsUnordered("i=0", "i=10", "i=20"));
assertThat(scanCount.get(), is(3));
}
}
use of org.apache.calcite.schema.Table in project calcite by apache.
the class ScannableTableTest method testFilterableTableNonCooperative.
/**
* A filter on a {@link FilterableTable} with two columns (noncooperative).
*/
@Test
public void testFilterableTableNonCooperative() throws Exception {
final StringBuilder buf = new StringBuilder();
final Table table = new BeatlesFilterableTable(buf, false);
final String explain = "PLAN=" + "EnumerableInterpreter\n" + " BindableTableScan(table=[[s, beatles2]], filters=[[=($0, 4)]])";
CalciteAssert.that().with(newSchema("s", "beatles2", table)).query("select * from \"s\".\"beatles2\" where \"i\" = 4").explainContains(explain).returnsUnordered("i=4; j=John; k=1940", "i=4; j=Paul; k=1942");
assertThat(buf.toString(), is("returnCount=4"));
}
use of org.apache.calcite.schema.Table in project calcite by apache.
the class ScannableTableTest method testPFPushDownProjectFilterAggregateGroup.
@Test
public void testPFPushDownProjectFilterAggregateGroup() {
final String sql = "select \"i\", count(*) as c\n" + "from \"s\".\"beatles\"\n" + "where \"k\" > 1900\n" + "group by \"i\"";
final StringBuilder buf = new StringBuilder();
final Table table = new BeatlesProjectableFilterableTable(buf, false);
final String explain = "PLAN=" + "EnumerableAggregate(group=[{0}], C=[COUNT()])\n" + " EnumerableInterpreter\n" + " BindableTableScan(table=[[s, beatles]], filters=[[>($2, 1900)]], " + "projects=[[0]])";
CalciteAssert.that().with(newSchema("s", "beatles", table)).query(sql).explainContains(explain).returnsUnordered("i=4; C=2", "i=5; C=1", "i=6; C=1");
}
use of org.apache.calcite.schema.Table in project calcite by apache.
the class RelOptMaterialization method tryUseStar.
/**
* Converts a relational expression to one that uses a
* {@link org.apache.calcite.schema.impl.StarTable}.
*
* <p>The relational expression is already in leaf-join-form, per
* {@link #toLeafJoinForm(org.apache.calcite.rel.RelNode)}.
*
* @return Rewritten expression, or null if expression cannot be rewritten
* to use the star
*/
public static RelNode tryUseStar(RelNode rel, final RelOptTable starRelOptTable) {
final StarTable starTable = starRelOptTable.unwrap(StarTable.class);
assert starTable != null;
RelNode rel2 = rel.accept(new RelShuttleImpl() {
@Override
public RelNode visit(TableScan scan) {
RelOptTable relOptTable = scan.getTable();
final Table table = relOptTable.unwrap(Table.class);
if (table.equals(starTable.tables.get(0))) {
Mappings.TargetMapping mapping = Mappings.createShiftMapping(starRelOptTable.getRowType().getFieldCount(), 0, 0, relOptTable.getRowType().getFieldCount());
final RelOptCluster cluster = scan.getCluster();
final RelNode scan2 = starRelOptTable.toRel(RelOptUtil.getContext(cluster));
return RelOptUtil.createProject(scan2, Mappings.asList(mapping.inverse()));
}
return scan;
}
@Override
public RelNode visit(LogicalJoin join) {
for (; ; ) {
RelNode rel = super.visit(join);
if (rel == join || !(rel instanceof LogicalJoin)) {
return rel;
}
join = (LogicalJoin) rel;
final ProjectFilterTable left = ProjectFilterTable.of(join.getLeft());
if (left != null) {
final ProjectFilterTable right = ProjectFilterTable.of(join.getRight());
if (right != null) {
try {
match(left, right, join.getCluster());
} catch (Util.FoundOne e) {
return (RelNode) e.getNode();
}
}
}
}
}
/**
* Throws a {@link org.apache.calcite.util.Util.FoundOne} containing
* a {@link org.apache.calcite.rel.logical.LogicalTableScan} on
* success. (Yes, an exception for normal operation.)
*/
private void match(ProjectFilterTable left, ProjectFilterTable right, RelOptCluster cluster) {
final Mappings.TargetMapping leftMapping = left.mapping();
final Mappings.TargetMapping rightMapping = right.mapping();
final RelOptTable leftRelOptTable = left.getTable();
final Table leftTable = leftRelOptTable.unwrap(Table.class);
final int leftCount = leftRelOptTable.getRowType().getFieldCount();
final RelOptTable rightRelOptTable = right.getTable();
final Table rightTable = rightRelOptTable.unwrap(Table.class);
if (leftTable instanceof StarTable && ((StarTable) leftTable).tables.contains(rightTable)) {
final int offset = ((StarTable) leftTable).columnOffset(rightTable);
Mappings.TargetMapping mapping = Mappings.merge(leftMapping, Mappings.offsetTarget(Mappings.offsetSource(rightMapping, offset), leftMapping.getTargetCount()));
final RelNode project = RelOptUtil.createProject(LogicalTableScan.create(cluster, leftRelOptTable), Mappings.asList(mapping.inverse()));
final List<RexNode> conditions = Lists.newArrayList();
if (left.condition != null) {
conditions.add(left.condition);
}
if (right.condition != null) {
conditions.add(RexUtil.apply(mapping, RexUtil.shift(right.condition, offset)));
}
final RelNode filter = RelOptUtil.createFilter(project, conditions);
throw new Util.FoundOne(filter);
}
if (rightTable instanceof StarTable && ((StarTable) rightTable).tables.contains(leftTable)) {
final int offset = ((StarTable) rightTable).columnOffset(leftTable);
Mappings.TargetMapping mapping = Mappings.merge(Mappings.offsetSource(leftMapping, offset), Mappings.offsetTarget(rightMapping, leftCount));
final RelNode project = RelOptUtil.createProject(LogicalTableScan.create(cluster, rightRelOptTable), Mappings.asList(mapping.inverse()));
final List<RexNode> conditions = Lists.newArrayList();
if (left.condition != null) {
conditions.add(RexUtil.apply(mapping, RexUtil.shift(left.condition, offset)));
}
if (right.condition != null) {
conditions.add(RexUtil.apply(mapping, right.condition));
}
final RelNode filter = RelOptUtil.createFilter(project, conditions);
throw new Util.FoundOne(filter);
}
}
});
if (rel2 == rel) {
// No rewrite happened.
return null;
}
final Program program = Programs.hep(ImmutableList.of(ProjectFilterTransposeRule.INSTANCE, AggregateProjectMergeRule.INSTANCE, AggregateFilterTransposeRule.INSTANCE), false, DefaultRelMetadataProvider.INSTANCE);
return program.run(null, rel2, null, ImmutableList.<RelOptMaterialization>of(), ImmutableList.<RelOptLattice>of());
}
use of org.apache.calcite.schema.Table in project calcite by apache.
the class MaterializationService method defineMaterialization.
/**
* Defines a new materialization. Returns its key.
*/
public MaterializationKey defineMaterialization(final CalciteSchema schema, TileKey tileKey, String viewSql, List<String> viewSchemaPath, String suggestedTableName, TableFactory tableFactory, boolean create, boolean existing) {
final MaterializationActor.QueryKey queryKey = new MaterializationActor.QueryKey(viewSql, schema, viewSchemaPath);
final MaterializationKey existingKey = actor.keyBySql.get(queryKey);
if (existingKey != null) {
return existingKey;
}
if (!create) {
return null;
}
final CalciteConnection connection = CalciteMetaImpl.connect(schema.root(), null);
CalciteSchema.TableEntry tableEntry;
// with the name and if none can be found, lookup a view in the schema
if (existing) {
tableEntry = schema.getTable(suggestedTableName, true);
if (tableEntry == null) {
tableEntry = schema.getTableBasedOnNullaryFunction(suggestedTableName, true);
}
} else {
tableEntry = null;
}
if (tableEntry == null) {
tableEntry = schema.getTableBySql(viewSql);
}
RelDataType rowType = null;
if (tableEntry == null) {
Table table = tableFactory.createTable(schema, viewSql, viewSchemaPath);
final String tableName = Schemas.uniqueTableName(schema, Util.first(suggestedTableName, "m"));
tableEntry = schema.add(tableName, table, ImmutableList.of(viewSql));
Hook.CREATE_MATERIALIZATION.run(tableName);
rowType = table.getRowType(connection.getTypeFactory());
}
if (rowType == null) {
// If we didn't validate the SQL by populating a table, validate it now.
final CalcitePrepare.ParseResult parse = Schemas.parse(connection, schema, viewSchemaPath, viewSql);
rowType = parse.rowType;
}
final MaterializationKey key = new MaterializationKey();
final MaterializationActor.Materialization materialization = new MaterializationActor.Materialization(key, schema.root(), tableEntry, viewSql, rowType, viewSchemaPath);
actor.keyMap.put(materialization.key, materialization);
actor.keyBySql.put(queryKey, materialization.key);
if (tileKey != null) {
actor.keyByTile.put(tileKey, materialization.key);
}
return key;
}
Aggregations