package foodmart;
import org.apache.calcite.DataContext;
import org.apache.calcite.adapter.enumerable.EnumerableConvention;
import org.apache.calcite.adapter.enumerable.EnumerableInterpretable;
import org.apache.calcite.adapter.enumerable.EnumerableRel;
import org.apache.calcite.adapter.enumerable.EnumerableRules;
import org.apache.calcite.adapter.java.JavaTypeFactory;
import org.apache.calcite.adapter.java.ReflectiveSchema;
import org.apache.calcite.config.CalciteConnectionConfig;
import org.apache.calcite.config.CalciteConnectionConfigImpl;
import org.apache.calcite.config.CalciteConnectionProperty;
import org.apache.calcite.interpreter.BindableConvention;
import org.apache.calcite.interpreter.Bindables;
import org.apache.calcite.jdbc.CalciteSchema;
import org.apache.calcite.jdbc.JavaTypeFactoryImpl;
import org.apache.calcite.linq4j.QueryProvider;
import org.apache.calcite.plan.*;
import org.apache.calcite.plan.volcano.VolcanoPlanner;
import org.apache.calcite.prepare.CalciteCatalogReader;
import org.apache.calcite.rel.RelCollationTraitDef;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.RelRoot;
import org.apache.calcite.rel.rules.CoreRules;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.rex.RexBuilder;
import org.apache.calcite.runtime.Bindable;
import org.apache.calcite.schema.SchemaPlus;
import org.apache.calcite.sql.SqlExplainFormat;
import org.apache.calcite.sql.SqlExplainLevel;
import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.sql.parser.SqlParser;
import org.apache.calcite.sql.validate.SqlValidator;
import org.apache.calcite.sql.validate.SqlValidatorUtil;
import org.apache.calcite.sql2rel.SqlToRelConverter;
import org.apache.calcite.sql2rel.StandardConvertletTable;
import org.junit.Test;
import java.util.*;
public class EndToFIlterEndExample {
public static class Author {
public final int id;
public final String fname;
public final String lname;
public Author(final int id, final String firstname, final String lastname) {
this.id = id;
this.fname = firstname;
this.lname = lastname;
}
}
public static class Book {
public final int id;
public final String title;
public final int year;
public final Author author;
public Book(final int id, final String title, final int year, final Author author) {
this.id = id;
this.title = title;
this.year = year;
this.author = author;
}
}
public static class BookStore {
public final Author[] author = new Author[]{
new Author(1, "Victor", "Hugo"),
new Author(2, "Alexandre", "Dumas")
};
public final Book[] book = new Book[]{
new Book(1, "Les Miserables", 1862, author[0]),
new Book(2, "The Hunchback of Notre-Dame", 1829, author[0]),
new Book(3, "The Last Day of a Condemned Man", 1829, author[0]),
new Book(4, "The three Musketeers", 1844, author[1]),
new Book(5, "The Count of Monte Cristo", 1884, author[1])
};
}
@Test
public void example() throws Exception {
CalciteSchema schema = CalciteSchema.createRootSchema(true);
schema.add("bs", new ReflectiveSchema(new BookStore()));
RelDataTypeFactory typeFactory = new JavaTypeFactoryImpl();
SqlParser parser = SqlParser.create(
"SELECT b.id, b.title, b.\"year\" "
+ "FROM Book b\n"
+" where b.id = 1"
+ "LIMIT 5");
SqlNode sqlNode = parser.parseQuery();
Properties props = new Properties();
props.setProperty(CalciteConnectionProperty.CASE_SENSITIVE.camelName(), "false");
CalciteConnectionConfig config = new CalciteConnectionConfigImpl(props);
CalciteCatalogReader catalogReader = new CalciteCatalogReader(schema,
Collections.singletonList("bs"),
typeFactory, config);
SqlValidator validator = SqlValidatorUtil.newValidator(SqlStdOperatorTable.instance(),
catalogReader, typeFactory,
SqlValidator.Config.DEFAULT);
SqlNode validNode = validator.validate(sqlNode);
RelOptCluster cluster = newCluster(typeFactory);
SqlToRelConverter relConverter = new SqlToRelConverter(
NOOP_EXPANDER,
validator,
catalogReader,
cluster,
StandardConvertletTable.INSTANCE,
SqlToRelConverter.config());
RelNode logPlan = relConverter.convertQuery(validNode, false, true).rel;
System.out.println(
RelOptUtil.dumpPlan("[Logical plan]", logPlan, SqlExplainFormat.TEXT,
SqlExplainLevel.NON_COST_ATTRIBUTES));
RelOptPlanner planner = cluster.getPlanner();
Bindables.RULES.forEach(r->planner.addRule(r));
logPlan = planner.changeTraits(logPlan,
cluster.traitSet().replace(BindableConvention.INSTANCE));
planner.setRoot(logPlan);
RelNode phyPlan = planner.findBestExp();
System.out.println("pulledUpPredicates");
System.out.println(phyPlan.getCluster().getMetadataQuery().getPulledUpPredicates(phyPlan));
System.out.println("allPredicates");
System.out.println(phyPlan.getCluster().getMetadataQuery().getAllPredicates(phyPlan));
System.out.println(
RelOptUtil.dumpPlan("[Physical plan]", phyPlan, SqlExplainFormat.TEXT,
SqlExplainLevel.NON_COST_ATTRIBUTES));
}
private static RelOptCluster newCluster(RelDataTypeFactory factory) {
RelOptPlanner planner = new VolcanoPlanner();
planner.addRelTraitDef(ConventionTraitDef.INSTANCE);
planner.addRelTraitDef(RelCollationTraitDef.INSTANCE);
return RelOptCluster.create(planner, new RexBuilder(factory));
}
private static final RelOptTable.ViewExpander NOOP_EXPANDER = new RelOptTable.ViewExpander() {
@Override public RelRoot expandView(final RelDataType rowType, final String queryString,
final List<String> schemaPath,
final List<String> viewPath) {
return null;
}
};
private static final class SchemaOnlyDataContext implements DataContext {
private final SchemaPlus schema;
SchemaOnlyDataContext(CalciteSchema calciteSchema) {
this.schema = calciteSchema.plus();
}
@Override public SchemaPlus getRootSchema() {
return schema;
}
@Override public JavaTypeFactory getTypeFactory() {
return null;
}
@Override public QueryProvider getQueryProvider() {
return null;
}
@Override public Object get(final String name) {
return null;
}
}
}