[
https://issues.apache.org/jira/browse/DRILL-4465?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15178160#comment-15178160
]
ASF GitHub Bot commented on DRILL-4465:
---------------------------------------
Github user jinfengni commented on a diff in the pull request:
https://github.com/apache/drill/pull/401#discussion_r54912629
--- Diff:
exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillSqlParser.java
---
@@ -0,0 +1,349 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.drill.exec.planner.sql;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.calcite.adapter.java.JavaTypeFactory;
+import org.apache.calcite.avatica.util.Casing;
+import org.apache.calcite.avatica.util.Quoting;
+import org.apache.calcite.jdbc.CalciteSchemaImpl;
+import org.apache.calcite.jdbc.JavaTypeFactoryImpl;
+import org.apache.calcite.plan.ConventionTraitDef;
+import org.apache.calcite.plan.RelOptCluster;
+import org.apache.calcite.plan.RelOptCostFactory;
+import org.apache.calcite.plan.RelOptTable;
+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.type.RelDataType;
+import org.apache.calcite.rel.type.RelDataTypeFactory;
+import org.apache.calcite.rel.type.RelDataTypeSystemImpl;
+import org.apache.calcite.rex.RexBuilder;
+import org.apache.calcite.schema.SchemaPlus;
+import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlOperatorTable;
+import org.apache.calcite.sql.parser.SqlParseException;
+import org.apache.calcite.sql.parser.SqlParser;
+import org.apache.calcite.sql.parser.SqlParserImplFactory;
+import org.apache.calcite.sql.parser.SqlParserPos;
+import org.apache.calcite.sql.type.SqlTypeName;
+import org.apache.calcite.sql.util.ChainedSqlOperatorTable;
+import org.apache.calcite.sql.validate.SqlConformance;
+import org.apache.calcite.sql.validate.SqlValidatorCatalogReader;
+import org.apache.calcite.sql.validate.SqlValidatorImpl;
+import org.apache.calcite.sql2rel.RelDecorrelator;
+import org.apache.calcite.sql2rel.SqlToRelConverter;
+import org.apache.drill.common.exceptions.UserException;
+import org.apache.drill.exec.expr.fn.FunctionImplementationRegistry;
+import org.apache.drill.exec.ops.UdfUtilities;
+import org.apache.drill.exec.planner.cost.DrillCostBase;
+import org.apache.drill.exec.planner.logical.DrillConstExecutor;
+import org.apache.drill.exec.planner.physical.DrillDistributionTraitDef;
+import org.apache.drill.exec.planner.physical.PlannerSettings;
+import
org.apache.drill.exec.planner.sql.parser.impl.DrillParserWithCompoundIdConverter;
+
+/**
+ * Class responsible for managing parsing, validation and toRel conversion
for sql statements.
+ */
+public class DrillSqlParser {
+ private static final org.slf4j.Logger logger =
org.slf4j.LoggerFactory.getLogger(DrillSqlParser.class);
+
+ private static DrillTypeSystem DRILL_TYPE_SYSTEM = new DrillTypeSystem();
+
+ private final JavaTypeFactory typeFactory;
+ private final SqlParser.Config parserConfig;
+ private final CalciteCatalogReader catalog;
+ private final PlannerSettings settings;
+ private final SchemaPlus rootSchema;
+ private final SchemaPlus defaultSchema;
+ private final SqlOperatorTable opTab;
+ private final RelOptCostFactory costFactory;
+ private final DrillValidator validator;
+ private final boolean isInnerQuery;
+ private final UdfUtilities util;
+ private final FunctionImplementationRegistry functions;
+
+ private String sql;
+ private VolcanoPlanner planner;
+
+
+ public DrillSqlParser(PlannerSettings settings, SchemaPlus defaultSchema,
+ final SqlOperatorTable operatorTable, UdfUtilities util,
FunctionImplementationRegistry functions) {
+ this.settings = settings;
+ this.util = util;
+ this.functions = functions;
+ this.parserConfig = new ParserConfig();
+ this.isInnerQuery = false;
+ this.typeFactory = new JavaTypeFactoryImpl(DRILL_TYPE_SYSTEM);
+ this.defaultSchema = defaultSchema;
+ this.rootSchema = rootSchema(defaultSchema);
+ this.catalog = new CalciteCatalogReader(
+ CalciteSchemaImpl.from(rootSchema),
+ parserConfig.caseSensitive(),
+ CalciteSchemaImpl.from(defaultSchema).path(null),
+ typeFactory);
+ this.opTab = new ChainedSqlOperatorTable(Arrays.asList(operatorTable,
catalog));
+ this.costFactory = (settings.useDefaultCosting()) ? null : new
DrillCostBase.DrillCostFactory();
+ this.validator = new DrillValidator(opTab, catalog, typeFactory,
SqlConformance.DEFAULT);
+ validator.setIdentifierExpansion(true);
+ }
+
+ private DrillSqlParser(DrillSqlParser parent, SchemaPlus defaultSchema,
SchemaPlus rootSchema,
+ CalciteCatalogReader catalog) {
+ this.parserConfig = parent.parserConfig;
+ this.defaultSchema = defaultSchema;
+ this.functions = parent.functions;
+ this.util = parent.util;
+ this.isInnerQuery = true;
+ this.typeFactory = parent.typeFactory;
+ this.costFactory = parent.costFactory;
+ this.settings = parent.settings;
+ this.rootSchema = rootSchema;
+ this.catalog = catalog;
+ this.opTab = parent.opTab;
+ this.planner = parent.planner;
+ this.validator = new DrillValidator(opTab, catalog, typeFactory,
SqlConformance.DEFAULT);
+ validator.setIdentifierExpansion(true);
+ }
+
+
+ public SqlNode parse(String sql) {
+ try {
+ SqlParser parser = SqlParser.create(sql, parserConfig);
+ return parser.parseStmt();
+ } catch (SqlParseException e) {
+ throw UserException
+ .parseError(e)
+ .message(isInnerQuery ? "Failure parsing a view your query is
dependent upon." : "Failure parsing query.")
+ .addContext("SQL Query", formatSQLParsingError(sql, e.getPos()))
+ .build(logger);
+ }
+
+ }
+
+ public SqlNode validate(final SqlNode parsedNode) {
+ try {
+ SqlNode validatedNode = validator.validate(parsedNode);
+ return validatedNode;
+ } catch (RuntimeException e) {
+ throw UserException
+ .validationError(e)
+ .message(isInnerQuery ?
+ "Failure validating a view your query is dependent upon." :
"Failure validating query.")
+ .addContext("SQL query", sql)
+ .build(logger);
+ }
+ }
+
+ public RelDataType getOutputType(SqlNode validatedNode) {
+ return validator.getValidatedNodeType(validatedNode);
+ }
+
+ public JavaTypeFactory getTypeFactory() {
+ return typeFactory;
+ }
+
+ public SqlOperatorTable getOpTab() {
+ return opTab;
+ }
+
+ public RelOptCostFactory getCostFactory() {
+ return costFactory;
+ }
+
+ public SchemaPlus getRootSchema() {
+ return rootSchema;
+ }
+
+ public SchemaPlus getDefaultSchema() {
+ return defaultSchema;
+ }
+
+ private class DrillValidator extends SqlValidatorImpl {
+ protected DrillValidator(SqlOperatorTable opTab,
SqlValidatorCatalogReader catalogReader,
+ RelDataTypeFactory typeFactory, SqlConformance conformance) {
+ super(opTab, catalogReader, typeFactory, conformance);
+ }
+ }
+
+ private static class DrillTypeSystem extends RelDataTypeSystemImpl {
+
+ @Override
+ public int getDefaultPrecision(SqlTypeName typeName) {
+ switch (typeName) {
+ case CHAR:
+ case BINARY:
+ case VARCHAR:
+ case VARBINARY:
+ return 65536;
+ default:
+ return super.getDefaultPrecision(typeName);
+ }
+ }
+
+ @Override
+ public int getMaxNumericScale() {
+ return 38;
+ }
+
+ @Override
+ public int getMaxNumericPrecision() {
+ return 38;
+ }
+
+ }
+
+ public RelNode toRel(
+ final SqlNode validatedNode) {
+ final RexBuilder rexBuilder = new RexBuilder(typeFactory);
+ if (planner == null) {
+ planner = new VolcanoPlanner(costFactory, settings);
+ planner.setExecutor(new DrillConstExecutor(functions, util,
settings));
+ planner.clearRelTraitDefs();
+ planner.addRelTraitDef(ConventionTraitDef.INSTANCE);
+ planner.addRelTraitDef(DrillDistributionTraitDef.INSTANCE);
+ planner.addRelTraitDef(RelCollationTraitDef.INSTANCE);
+ }
+
+ final RelOptCluster cluster = RelOptCluster.create(planner,
rexBuilder);
+ final SqlToRelConverter sqlToRelConverter =
+ new SqlToRelConverter(new Expander(), validator, catalog, cluster,
DrillConvertletTable.INSTANCE);
+
+ sqlToRelConverter.setTrimUnusedFields(false);
+ sqlToRelConverter.enableTableAccessConversion(false);
+ final RelNode rel = sqlToRelConverter.convertQuery(validatedNode,
false, true);
+ final RelNode rel2 = sqlToRelConverter.flattenTypes(rel, true);
+ final RelNode rel3 = RelDecorrelator.decorrelateQuery(rel2);
+ return rel3;
+
+ }
+
+ private class Expander implements RelOptTable.ViewExpander {
+
+ public Expander() {
+ }
+
+ public RelNode expandView(
+ RelDataType rowType,
+ String queryString,
+ List<String> schemaPath) {
+ DrillSqlParser parser = new DrillSqlParser(DrillSqlParser.this,
defaultSchema, rootSchema,
+ catalog.withSchemaPath(schemaPath));
+ return expandView(queryString, parser);
+ }
+
+ @Override
+ public RelNode expandView(
+ RelDataType rowType,
+ String queryString,
+ SchemaPlus rootSchema, // new root schema
+ List<String> schemaPath) {
+ final CalciteCatalogReader catalogReader = new CalciteCatalogReader(
+ CalciteSchemaImpl.from(rootSchema),
+ parserConfig.caseSensitive(),
+ schemaPath,
+ typeFactory);
+ SchemaPlus schema = rootSchema;
+ for (String s : schemaPath) {
+ schema = schema.getSubSchema(s);
--- End diff --
Is it possible that schema.getSubSchema(s) could return null? In such case,
the next loop iteration will possibly hit NPE.
> Refactor Parsing and Planning to canonicalize planning and parsing
> ------------------------------------------------------------------
>
> Key: DRILL-4465
> URL: https://issues.apache.org/jira/browse/DRILL-4465
> Project: Apache Drill
> Issue Type: Sub-task
> Components: Query Planning & Optimization
> Reporter: Jacques Nadeau
> Assignee: Jinfeng Ni
> Fix For: 1.6.0
>
>
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)