OmniSciDB  8a228a1076
MapDPlanner.java
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to you under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 package org.apache.calcite.prepare;
18 
20 
21 import org.apache.calcite.config.CalciteConnectionConfig;
22 import org.apache.calcite.config.CalciteConnectionConfigImpl;
23 import org.apache.calcite.config.CalciteConnectionProperty;
24 import org.apache.calcite.jdbc.CalciteSchema;
25 import org.apache.calcite.linq4j.function.Functions;
26 import org.apache.calcite.plan.Context;
27 import org.apache.calcite.plan.RelOptCostImpl;
28 import org.apache.calcite.plan.hep.HepPlanner;
29 import org.apache.calcite.plan.hep.HepProgram;
30 import org.apache.calcite.rel.RelNode;
31 import org.apache.calcite.rel.RelRoot;
32 import org.apache.calcite.rel.core.RelFactories;
34 import org.apache.calcite.rel.rules.FilterJoinRule;
37 import org.apache.calcite.schema.SchemaPlus;
38 import org.apache.calcite.sql.SqlNode;
39 import org.apache.calcite.sql.advise.SqlAdvisor;
40 import org.apache.calcite.sql.advise.SqlAdvisorValidator;
41 import org.apache.calcite.sql.parser.SqlParseException;
42 import org.apache.calcite.sql.validate.SqlConformance;
43 import org.apache.calcite.sql.validate.SqlConformanceEnum;
44 import org.apache.calcite.sql.validate.SqlMoniker;
45 import org.apache.calcite.sql.validate.SqlValidator;
46 import org.apache.calcite.tools.FrameworkConfig;
47 import org.apache.calcite.tools.RelConversionException;
48 
49 import java.lang.reflect.InvocationTargetException;
50 import java.lang.reflect.Method;
51 import java.util.ArrayList;
52 import java.util.List;
53 import java.util.Properties;
54 
61 public class MapDPlanner extends PlannerImpl {
62  FrameworkConfig config;
64  new ArrayList<>();
65 
66  public MapDPlanner(FrameworkConfig config) {
67  super(config);
68  this.config = config;
69  }
70 
71  private static SchemaPlus rootSchema(SchemaPlus schema) {
72  for (;;) {
73  if (schema.getParentSchema() == null) {
74  return schema;
75  }
76  schema = schema.getParentSchema();
77  }
78  }
79 
80  public static class CompletionResult {
81  public List<SqlMoniker> hints;
82  public String replaced;
83 
84  CompletionResult(final List<SqlMoniker> hints, final String replaced) {
85  this.hints = hints;
86  this.replaced = replaced;
87  }
88  }
89 
90  private CalciteCatalogReader createCatalogReader() {
91  final SchemaPlus rootSchema = rootSchema(config.getDefaultSchema());
92  final Context context = config.getContext();
93  final CalciteConnectionConfig connectionConfig;
94 
95  if (context != null) {
96  connectionConfig = context.unwrap(CalciteConnectionConfig.class);
97  } else {
98  Properties properties = new Properties();
99  properties.setProperty(CalciteConnectionProperty.CASE_SENSITIVE.camelName(),
100  String.valueOf(config.getParserConfig().caseSensitive()));
101  connectionConfig = new CalciteConnectionConfigImpl(properties);
102  }
103 
104  return new CalciteCatalogReader(CalciteSchema.from(rootSchema),
105  CalciteSchema.from(config.getDefaultSchema()).path(null),
106  getTypeFactory(),
107  connectionConfig);
108  }
109 
110  public void advanceToValidate() {
111  try {
112  String dummySql = "SELECT 1";
113  super.parse(dummySql);
114  } catch (SqlParseException e) {
115  throw new RuntimeException(e);
116  }
117  }
118 
119  public void ready() {
120  // need to call ready on the super class, but that method is marked private
121  // circumventing via reflection for now
122  try {
123  Method readyMethod = getClass().getSuperclass().getDeclaredMethod("ready");
124  readyMethod.setAccessible(true);
125  readyMethod.invoke(this);
126  } catch (InvocationTargetException e) {
127  if (e.getCause() instanceof RuntimeException) {
128  throw(RuntimeException) e.getCause();
129  } else {
130  throw new RuntimeException(e.getCause());
131  }
132  } catch (Exception e) {
133  throw new RuntimeException(e);
134  }
135  }
136 
138  final String sql, final int cursor, final List<String> visibleTables) {
139  ready();
140 
141  SqlValidator.Config validatorConfig = SqlValidator.Config.DEFAULT;
142  validatorConfig = validatorConfig.withSqlConformance(SqlConformanceEnum.LENIENT);
143 
144  MapDSqlAdvisorValidator advisor_validator = new MapDSqlAdvisorValidator(visibleTables,
145  config.getOperatorTable(),
147  getTypeFactory(),
148  validatorConfig);
149  SqlAdvisor advisor = new MapDSqlAdvisor(advisor_validator);
150  String[] replaced = new String[1];
151  int adjusted_cursor = cursor < 0 ? sql.length() : cursor;
152  java.util.List<SqlMoniker> hints =
153  advisor.getCompletionHints(sql, adjusted_cursor, replaced);
154  return new CompletionResult(hints, replaced[0]);
155  }
156 
157  @Override
158  public RelRoot rel(SqlNode sql) {
159  RelRoot root = super.rel(sql);
160  root = applyQueryOptimizationRules(root);
161  root = applyFilterPushdown(root);
162  return root;
163  }
164 
165  private RelRoot applyFilterPushdown(RelRoot root) {
166  if (filterPushDownInfo.isEmpty()) {
167  return root;
168  }
169  final DynamicFilterJoinRule dynamicFilterJoinRule = new DynamicFilterJoinRule(true,
170  RelFactories.LOGICAL_BUILDER,
171  FilterJoinRule.TRUE_PREDICATE,
173  final HepProgram program =
174  HepProgram.builder().addRuleInstance(dynamicFilterJoinRule).build();
175  HepPlanner prePlanner = new HepPlanner(program);
176  prePlanner.setRoot(root.rel);
177  final RelNode rootRelNode = prePlanner.findBestExp();
178  filterPushDownInfo.clear();
179  return root.withRel(rootRelNode);
180  }
181 
182  private RelRoot applyQueryOptimizationRules(RelRoot root) {
183  QueryOptimizationRules outerJoinOptRule =
184  new OuterJoinOptViaNullRejectionRule(RelFactories.LOGICAL_BUILDER);
185 
186  HepProgram opt_program =
187  HepProgram.builder().addRuleInstance(outerJoinOptRule).build();
188  HepPlanner prePlanner = new HepPlanner(
189  opt_program, null, true, Functions.ignore2(), RelOptCostImpl.FACTORY);
190  prePlanner.setRoot(root.rel);
191  final RelNode rootRelNode = prePlanner.findBestExp();
192  return root.withRel(rootRelNode);
193  }
194 
196  final List<MapDParserOptions.FilterPushDownInfo> filterPushDownInfo) {
197  this.filterPushDownInfo = filterPushDownInfo;
198  }
199 }
200 
201 // End MapDPlanner.java
RelRoot applyQueryOptimizationRules(RelRoot root)
static SchemaPlus rootSchema(SchemaPlus schema)
CalciteCatalogReader createCatalogReader()
List< MapDParserOptions.FilterPushDownInfo > filterPushDownInfo
CompletionResult(final List< SqlMoniker > hints, final String replaced)
void setFilterPushDownInfo(final List< MapDParserOptions.FilterPushDownInfo > filterPushDownInfo)
CompletionResult getCompletionHints(final String sql, final int cursor, final List< String > visibleTables)
MapDPlanner(FrameworkConfig config)
RelRoot applyFilterPushdown(RelRoot root)