You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hive.apache.org by vg...@apache.org on 2019/12/14 05:41:45 UTC
[hive] branch master updated: HIVE-22637: Avoid cost based rules
during generating expressions from AST (Vineet Garg,
reviewed by Ashutosh Chauhan)
This is an automated email from the ASF dual-hosted git repository.
vgarg pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hive.git
The following commit(s) were added to refs/heads/master by this push:
new f378aa4 HIVE-22637: Avoid cost based rules during generating expressions from AST (Vineet Garg, reviewed by Ashutosh Chauhan)
f378aa4 is described below
commit f378aa42688cb1a8e0b9fdfd525107a1679cddae
Author: Vineet Garg <vg...@apache.org>
AuthorDate: Sat Dec 14 11:11:18 2019 +0530
HIVE-22637: Avoid cost based rules during generating expressions from AST (Vineet Garg, reviewed by Ashutosh Chauhan)
---
.../hadoop/hive/ql/lib/CostLessRuleDispatcher.java | 69 +++++
.../hadoop/hive/ql/parse/TypeCheckProcFactory.java | 287 +++++++++++----------
2 files changed, 214 insertions(+), 142 deletions(-)
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/lib/CostLessRuleDispatcher.java b/ql/src/java/org/apache/hadoop/hive/ql/lib/CostLessRuleDispatcher.java
new file mode 100644
index 0000000..a67044e
--- /dev/null
+++ b/ql/src/java/org/apache/hadoop/hive/ql/lib/CostLessRuleDispatcher.java
@@ -0,0 +1,69 @@
+/*
+ * 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.hadoop.hive.ql.lib;
+
+import java.util.Stack;
+
+import com.google.common.collect.SetMultimap;
+import org.apache.hadoop.hive.ql.parse.SemanticException;
+import org.apache.hadoop.hive.ql.parse.ASTNode;
+
+/**
+ * Dispatches calls to relevant method in processor. The user registers various
+ * rules with the dispatcher, and the processor corresponding to the type of node
+ */
+public class CostLessRuleDispatcher implements Dispatcher {
+
+ private final SetMultimap<Integer, NodeProcessor> procRules;
+ private final NodeProcessorCtx procCtx;
+ private final NodeProcessor defaultProc;
+
+ /**
+ * Constructor.
+ *
+ * @param defaultProc default processor to be fired if no rule matches
+ * @param rules Map mapping the node's type to processor
+ * @param procCtx operator processor context, which is opaque to the dispatcher
+ */
+ public CostLessRuleDispatcher(NodeProcessor defaultProc, SetMultimap<Integer, NodeProcessor> rules,
+ NodeProcessorCtx procCtx) {
+ this.defaultProc = defaultProc;
+ procRules = rules;
+ this.procCtx = procCtx;
+ }
+
+ /**
+ * Dispatcher function.
+ *
+ * @param nd operator to process
+ * @param ndStack the operators encountered so far
+ * @throws SemanticException
+ */
+ @Override public Object dispatch(Node nd, Stack<Node> ndStack, Object... nodeOutputs)
+ throws SemanticException {
+
+ int nodeType = ((ASTNode) nd).getType();
+ NodeProcessor processor = this.defaultProc;
+ if (this.procRules.containsKey(nodeType)) {
+ processor = this.procRules.get(((ASTNode) nd).getType()).iterator().next();
+ }
+ return processor.process(nd, ndStack, procCtx, nodeOutputs);
+ }
+}
+
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/parse/TypeCheckProcFactory.java b/ql/src/java/org/apache/hadoop/hive/ql/parse/TypeCheckProcFactory.java
index e45276f..e0f4826 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/parse/TypeCheckProcFactory.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/parse/TypeCheckProcFactory.java
@@ -47,15 +47,13 @@ import org.apache.hadoop.hive.ql.exec.FunctionRegistry;
import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException;
-import org.apache.hadoop.hive.ql.lib.DefaultRuleDispatcher;
+import org.apache.hadoop.hive.ql.lib.CostLessRuleDispatcher;
import org.apache.hadoop.hive.ql.lib.Dispatcher;
-import org.apache.hadoop.hive.ql.lib.SubqueryExpressionWalker;
import org.apache.hadoop.hive.ql.lib.GraphWalker;
import org.apache.hadoop.hive.ql.lib.Node;
import org.apache.hadoop.hive.ql.lib.NodeProcessor;
import org.apache.hadoop.hive.ql.lib.NodeProcessorCtx;
-import org.apache.hadoop.hive.ql.lib.Rule;
-import org.apache.hadoop.hive.ql.lib.RuleRegExp;
+import org.apache.hadoop.hive.ql.lib.SubqueryExpressionWalker;
import org.apache.hadoop.hive.ql.metadata.Hive;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.optimizer.ConstantPropagateProcFactory;
@@ -108,8 +106,9 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.HashMultimap;
import com.google.common.collect.Lists;
-
+import com.google.common.collect.SetMultimap;
/**
* The Factory for creating typecheck processors. The typecheck processors are
@@ -172,7 +171,7 @@ public class TypeCheckProcFactory {
// try outer row resolver
RowResolver outerRR = ctx.getOuterRR();
if(colInfo == null && outerRR != null) {
- colInfo = outerRR.getExpression(expr);
+ colInfo = outerRR.getExpression(expr);
}
if (colInfo != null) {
desc = new ExprNodeColumnDesc(colInfo);
@@ -196,46 +195,52 @@ public class TypeCheckProcFactory {
// create a walker which walks the tree in a DFS manner while maintaining
// the operator stack. The dispatcher
// generates the plan from the operator tree
- Map<Rule, NodeProcessor> opRules = new LinkedHashMap<Rule, NodeProcessor>();
-
- opRules.put(new RuleRegExp("R1", HiveParser.TOK_NULL + "%"),
- tf.getNullExprProcessor());
- opRules.put(new RuleRegExp("R2", HiveParser.Number + "%|" +
- HiveParser.IntegralLiteral + "%|" +
- HiveParser.NumberLiteral + "%"),
- tf.getNumExprProcessor());
- opRules
- .put(new RuleRegExp("R3", HiveParser.Identifier + "%|"
- + HiveParser.StringLiteral + "%|" + HiveParser.TOK_CHARSETLITERAL + "%|"
- + HiveParser.TOK_STRINGLITERALSEQUENCE + "%|"
- + "%|" + HiveParser.KW_IF + "%|" + HiveParser.KW_CASE + "%|"
- + HiveParser.KW_WHEN + "%|" + HiveParser.KW_IN + "%|"
- + HiveParser.KW_ARRAY + "%|" + HiveParser.KW_MAP + "%|"
- + HiveParser.KW_STRUCT + "%|" + HiveParser.KW_EXISTS + "%|"
- + HiveParser.TOK_SUBQUERY_OP_NOTIN + "%"),
- tf.getStrExprProcessor());
- opRules.put(new RuleRegExp("R4", HiveParser.KW_TRUE + "%|"
- + HiveParser.KW_FALSE + "%"), tf.getBoolExprProcessor());
- opRules.put(new RuleRegExp("R5", HiveParser.TOK_DATELITERAL + "%|"
- + HiveParser.TOK_TIMESTAMPLITERAL + "%|"
- + HiveParser.TOK_TIMESTAMPLOCALTZLITERAL + "%"), tf.getDateTimeExprProcessor());
- opRules.put(new RuleRegExp("R6", HiveParser.TOK_INTERVAL_YEAR_MONTH_LITERAL + "%|"
- + HiveParser.TOK_INTERVAL_DAY_TIME_LITERAL + "%|"
- + HiveParser.TOK_INTERVAL_YEAR_LITERAL + "%|"
- + HiveParser.TOK_INTERVAL_MONTH_LITERAL + "%|"
- + HiveParser.TOK_INTERVAL_DAY_LITERAL + "%|"
- + HiveParser.TOK_INTERVAL_HOUR_LITERAL + "%|"
- + HiveParser.TOK_INTERVAL_MINUTE_LITERAL + "%|"
- + HiveParser.TOK_INTERVAL_SECOND_LITERAL + "%"), tf.getIntervalExprProcessor());
- opRules.put(new RuleRegExp("R7", HiveParser.TOK_TABLE_OR_COL + "%"),
- tf.getColumnExprProcessor());
- opRules.put(new RuleRegExp("R8", HiveParser.TOK_SUBQUERY_EXPR + "%"),
- tf.getSubQueryExprProcessor());
+
+ SetMultimap<Integer, NodeProcessor> astNodeToProcessor = HashMultimap.create();
+ astNodeToProcessor.put(HiveParser.TOK_NULL, tf.getNullExprProcessor());
+
+ astNodeToProcessor.put(HiveParser.Number, tf.getNumExprProcessor());
+ astNodeToProcessor.put(HiveParser.IntegralLiteral, tf.getNumExprProcessor());
+ astNodeToProcessor.put(HiveParser.NumberLiteral, tf.getNumExprProcessor());
+
+ astNodeToProcessor.put(HiveParser.Identifier, tf.getStrExprProcessor());
+ astNodeToProcessor.put(HiveParser.StringLiteral, tf.getStrExprProcessor());
+ astNodeToProcessor.put(HiveParser.TOK_CHARSETLITERAL, tf.getStrExprProcessor());
+ astNodeToProcessor.put(HiveParser.TOK_STRINGLITERALSEQUENCE, tf.getStrExprProcessor());
+ astNodeToProcessor.put(HiveParser.KW_IF, tf.getStrExprProcessor());
+ astNodeToProcessor.put(HiveParser.KW_CASE, tf.getStrExprProcessor());
+ astNodeToProcessor.put(HiveParser.KW_WHEN, tf.getStrExprProcessor());
+ astNodeToProcessor.put(HiveParser.KW_IN, tf.getStrExprProcessor());
+ astNodeToProcessor.put(HiveParser.KW_ARRAY, tf.getStrExprProcessor());
+ astNodeToProcessor.put(HiveParser.KW_MAP, tf.getStrExprProcessor());
+ astNodeToProcessor.put(HiveParser.KW_STRUCT, tf.getStrExprProcessor());
+ astNodeToProcessor.put(HiveParser.KW_EXISTS, tf.getStrExprProcessor());
+ astNodeToProcessor.put(HiveParser.TOK_SUBQUERY_OP_NOTIN, tf.getStrExprProcessor());
+
+ astNodeToProcessor.put(HiveParser.KW_TRUE, tf.getBoolExprProcessor());
+ astNodeToProcessor.put(HiveParser.KW_FALSE, tf.getBoolExprProcessor());
+
+ astNodeToProcessor.put(HiveParser.TOK_DATELITERAL, tf.getDateTimeExprProcessor());
+ astNodeToProcessor.put(HiveParser.TOK_TIMESTAMPLITERAL, tf.getDateTimeExprProcessor());
+ astNodeToProcessor.put(HiveParser.TOK_TIMESTAMPLOCALTZLITERAL, tf.getDateTimeExprProcessor());
+
+ astNodeToProcessor.put(HiveParser.TOK_INTERVAL_YEAR_MONTH_LITERAL, tf.getIntervalExprProcessor());
+ astNodeToProcessor.put(HiveParser.TOK_INTERVAL_DAY_TIME_LITERAL, tf.getIntervalExprProcessor());
+ astNodeToProcessor.put(HiveParser.TOK_INTERVAL_YEAR_LITERAL, tf.getIntervalExprProcessor());
+ astNodeToProcessor.put(HiveParser.TOK_INTERVAL_MONTH_LITERAL, tf.getIntervalExprProcessor());
+ astNodeToProcessor.put(HiveParser.TOK_INTERVAL_DAY_LITERAL, tf.getIntervalExprProcessor());
+ astNodeToProcessor.put(HiveParser.TOK_INTERVAL_HOUR_LITERAL, tf.getIntervalExprProcessor());
+ astNodeToProcessor.put(HiveParser.TOK_INTERVAL_MINUTE_LITERAL, tf.getIntervalExprProcessor());
+ astNodeToProcessor.put(HiveParser.TOK_INTERVAL_SECOND_LITERAL, tf.getIntervalExprProcessor());
+
+ astNodeToProcessor.put(HiveParser.TOK_TABLE_OR_COL, tf.getColumnExprProcessor());
+
+ astNodeToProcessor.put(HiveParser.TOK_SUBQUERY_EXPR, tf.getSubQueryExprProcessor());
// The dispatcher fires the processor corresponding to the closest matching
// rule and passes the context along
- Dispatcher disp = new DefaultRuleDispatcher(tf.getDefaultExprProcessor(),
- opRules, tcCtx);
+ Dispatcher disp = new CostLessRuleDispatcher(tf.getDefaultExprProcessor(),
+ astNodeToProcessor, tcCtx);
GraphWalker ogw = new SubqueryExpressionWalker(disp);
// Create a list of top nodes
@@ -279,7 +284,8 @@ public class TypeCheckProcFactory {
return desc;
}
- return new ExprNodeConstantDesc(TypeInfoFactory.getPrimitiveTypeInfoFromPrimitiveWritable(NullWritable.class), null);
+ return new ExprNodeConstantDesc(TypeInfoFactory.
+ getPrimitiveTypeInfoFromPrimitiveWritable(NullWritable.class), null);
}
}
@@ -574,36 +580,36 @@ public class TypeCheckProcFactory {
// Get the string value and convert to a Interval value.
try {
switch (expr.getType()) {
- case HiveParser.TOK_INTERVAL_YEAR_MONTH_LITERAL:
- return new ExprNodeConstantDesc(TypeInfoFactory.intervalYearMonthTypeInfo,
- HiveIntervalYearMonth.valueOf(intervalString));
- case HiveParser.TOK_INTERVAL_DAY_TIME_LITERAL:
- return new ExprNodeConstantDesc(TypeInfoFactory.intervalDayTimeTypeInfo,
- HiveIntervalDayTime.valueOf(intervalString));
- case HiveParser.TOK_INTERVAL_YEAR_LITERAL:
- return new ExprNodeConstantDesc(TypeInfoFactory.intervalYearMonthTypeInfo,
- new HiveIntervalYearMonth(Integer.parseInt(intervalString), 0));
- case HiveParser.TOK_INTERVAL_MONTH_LITERAL:
- return new ExprNodeConstantDesc(TypeInfoFactory.intervalYearMonthTypeInfo,
- new HiveIntervalYearMonth(0, Integer.parseInt(intervalString)));
- case HiveParser.TOK_INTERVAL_DAY_LITERAL:
- return new ExprNodeConstantDesc(TypeInfoFactory.intervalDayTimeTypeInfo,
- new HiveIntervalDayTime(Integer.parseInt(intervalString), 0, 0, 0, 0));
- case HiveParser.TOK_INTERVAL_HOUR_LITERAL:
- return new ExprNodeConstantDesc(TypeInfoFactory.intervalDayTimeTypeInfo,
- new HiveIntervalDayTime(0, Integer.parseInt(intervalString), 0, 0, 0));
- case HiveParser.TOK_INTERVAL_MINUTE_LITERAL:
- return new ExprNodeConstantDesc(TypeInfoFactory.intervalDayTimeTypeInfo,
- new HiveIntervalDayTime(0, 0, Integer.parseInt(intervalString), 0, 0));
- case HiveParser.TOK_INTERVAL_SECOND_LITERAL:
- BigDecimal bd = new BigDecimal(intervalString);
- BigDecimal bdSeconds = new BigDecimal(bd.toBigInteger());
- BigDecimal bdNanos = bd.subtract(bdSeconds);
- return new ExprNodeConstantDesc(TypeInfoFactory.intervalDayTimeTypeInfo,
- new HiveIntervalDayTime(0, 0, 0, bdSeconds.intValueExact(),
- bdNanos.multiply(NANOS_PER_SEC_BD).intValue()));
- default:
- throw new IllegalArgumentException("Invalid time literal type " + expr.getType());
+ case HiveParser.TOK_INTERVAL_YEAR_MONTH_LITERAL:
+ return new ExprNodeConstantDesc(TypeInfoFactory.intervalYearMonthTypeInfo,
+ HiveIntervalYearMonth.valueOf(intervalString));
+ case HiveParser.TOK_INTERVAL_DAY_TIME_LITERAL:
+ return new ExprNodeConstantDesc(TypeInfoFactory.intervalDayTimeTypeInfo,
+ HiveIntervalDayTime.valueOf(intervalString));
+ case HiveParser.TOK_INTERVAL_YEAR_LITERAL:
+ return new ExprNodeConstantDesc(TypeInfoFactory.intervalYearMonthTypeInfo,
+ new HiveIntervalYearMonth(Integer.parseInt(intervalString), 0));
+ case HiveParser.TOK_INTERVAL_MONTH_LITERAL:
+ return new ExprNodeConstantDesc(TypeInfoFactory.intervalYearMonthTypeInfo,
+ new HiveIntervalYearMonth(0, Integer.parseInt(intervalString)));
+ case HiveParser.TOK_INTERVAL_DAY_LITERAL:
+ return new ExprNodeConstantDesc(TypeInfoFactory.intervalDayTimeTypeInfo,
+ new HiveIntervalDayTime(Integer.parseInt(intervalString), 0, 0, 0, 0));
+ case HiveParser.TOK_INTERVAL_HOUR_LITERAL:
+ return new ExprNodeConstantDesc(TypeInfoFactory.intervalDayTimeTypeInfo,
+ new HiveIntervalDayTime(0, Integer.parseInt(intervalString), 0, 0, 0));
+ case HiveParser.TOK_INTERVAL_MINUTE_LITERAL:
+ return new ExprNodeConstantDesc(TypeInfoFactory.intervalDayTimeTypeInfo,
+ new HiveIntervalDayTime(0, 0, Integer.parseInt(intervalString), 0, 0));
+ case HiveParser.TOK_INTERVAL_SECOND_LITERAL:
+ BigDecimal bd = new BigDecimal(intervalString);
+ BigDecimal bdSeconds = new BigDecimal(bd.toBigInteger());
+ BigDecimal bdNanos = bd.subtract(bdSeconds);
+ return new ExprNodeConstantDesc(TypeInfoFactory.intervalDayTimeTypeInfo,
+ new HiveIntervalDayTime(0, 0, 0, bdSeconds.intValueExact(),
+ bdNanos.multiply(NANOS_PER_SEC_BD).intValue()));
+ default:
+ throw new IllegalArgumentException("Invalid time literal type " + expr.getType());
}
} catch (Exception err) {
throw new SemanticException(
@@ -792,7 +798,7 @@ public class TypeCheckProcFactory {
ObjectInspector keyOI, ObjectInspector valueOI) {
PrimitiveObjectInspector keyPoi = (PrimitiveObjectInspector)keyOI;
PrimitiveObjectInspector valuePoi = (PrimitiveObjectInspector)valueOI;
- Map<?,?> values = (Map<?,?>)((ConstantObjectInspector) inspector).getWritableConstantValue();
+ Map<?, ?> values = (Map<?, ?>)((ConstantObjectInspector) inspector).getWritableConstantValue();
Map<Object, Object> constant = new LinkedHashMap<Object, Object>();
for (Map.Entry<?, ?> e : values.entrySet()) {
constant.put(keyPoi.getPrimitiveJavaObject(e.getKey()), valuePoi.getPrimitiveJavaObject(e.getValue()));
@@ -813,7 +819,6 @@ public class TypeCheckProcFactory {
PrimitiveObjectInspector fieldPoi = (PrimitiveObjectInspector) fields.get(i).getFieldObjectInspector();
constant.add(fieldPoi.getPrimitiveJavaObject(value));
}
-
ExprNodeConstantDesc constantExpr = new ExprNodeConstantDesc(colInfo.getType(), constant);
constantExpr.setFoldedFromCol(colInfo.getInternalName());
constantExpr.setFoldedFromTab(colInfo.getTabAlias());
@@ -1017,8 +1022,8 @@ public class TypeCheckProcFactory {
// to cast the first operand to string
if (funcText.equals("substring") || funcText.equals("concat")){
if(children.size() > 0 && !ExprNodeDescUtils.isStringType(children.get(0))) {
- ExprNodeDesc newColumn = ParseUtils.createConversionCast(children.get(0), TypeInfoFactory.stringTypeInfo);
- children.set(0, newColumn);
+ ExprNodeDesc newColumn = ParseUtils.createConversionCast(children.get(0), TypeInfoFactory.stringTypeInfo);
+ children.set(0, newColumn);
}
}
}
@@ -1078,7 +1083,7 @@ public class TypeCheckProcFactory {
if (!TypeInfoUtils.implicitConvertible(children.get(1).getTypeInfo(),
TypeInfoFactory.intTypeInfo)) {
throw new SemanticException(SemanticAnalyzer.generateErrorMessage(
- expr, ErrorMsg.INVALID_ARRAYINDEX_TYPE.getMsg()));
+ expr, ErrorMsg.INVALID_ARRAYINDEX_TYPE.getMsg()));
}
// Calculate TypeInfo
@@ -1121,41 +1126,41 @@ public class TypeCheckProcFactory {
if (isFunction) {
ASTNode funcNameNode = (ASTNode)expr.getChild(0);
switch (funcNameNode.getType()) {
- case HiveParser.TOK_CHAR:
- // Add type params
- CharTypeInfo charTypeInfo = ParseUtils.getCharTypeInfo(funcNameNode);
- if (genericUDF != null) {
- ((SettableUDF)genericUDF).setTypeInfo(charTypeInfo);
- }
- break;
- case HiveParser.TOK_VARCHAR:
- VarcharTypeInfo varcharTypeInfo = ParseUtils.getVarcharTypeInfo(funcNameNode);
- if (genericUDF != null) {
- ((SettableUDF)genericUDF).setTypeInfo(varcharTypeInfo);
- }
- break;
- case HiveParser.TOK_TIMESTAMPLOCALTZ:
- TimestampLocalTZTypeInfo timestampLocalTZTypeInfo = new TimestampLocalTZTypeInfo();
- HiveConf conf;
- try {
- conf = Hive.get().getConf();
- } catch (HiveException e) {
- throw new SemanticException(e);
- }
- timestampLocalTZTypeInfo.setTimeZone(conf.getLocalTimeZone());
- if (genericUDF != null) {
- ((SettableUDF)genericUDF).setTypeInfo(timestampLocalTZTypeInfo);
- }
- break;
- case HiveParser.TOK_DECIMAL:
- DecimalTypeInfo decTypeInfo = ParseUtils.getDecimalTypeTypeInfo(funcNameNode);
- if (genericUDF != null) {
- ((SettableUDF)genericUDF).setTypeInfo(decTypeInfo);
- }
- break;
- default:
- // Do nothing
- break;
+ case HiveParser.TOK_CHAR:
+ // Add type params
+ CharTypeInfo charTypeInfo = ParseUtils.getCharTypeInfo(funcNameNode);
+ if (genericUDF != null) {
+ ((SettableUDF)genericUDF).setTypeInfo(charTypeInfo);
+ }
+ break;
+ case HiveParser.TOK_VARCHAR:
+ VarcharTypeInfo varcharTypeInfo = ParseUtils.getVarcharTypeInfo(funcNameNode);
+ if (genericUDF != null) {
+ ((SettableUDF)genericUDF).setTypeInfo(varcharTypeInfo);
+ }
+ break;
+ case HiveParser.TOK_TIMESTAMPLOCALTZ:
+ TimestampLocalTZTypeInfo timestampLocalTZTypeInfo = new TimestampLocalTZTypeInfo();
+ HiveConf conf;
+ try {
+ conf = Hive.get().getConf();
+ } catch (HiveException e) {
+ throw new SemanticException(e);
+ }
+ timestampLocalTZTypeInfo.setTimeZone(conf.getLocalTimeZone());
+ if (genericUDF != null) {
+ ((SettableUDF)genericUDF).setTypeInfo(timestampLocalTZTypeInfo);
+ }
+ break;
+ case HiveParser.TOK_DECIMAL:
+ DecimalTypeInfo decTypeInfo = ParseUtils.getDecimalTypeTypeInfo(funcNameNode);
+ if (genericUDF != null) {
+ ((SettableUDF)genericUDF).setTypeInfo(decTypeInfo);
+ }
+ break;
+ default:
+ // Do nothing
+ break;
}
}
@@ -1168,9 +1173,9 @@ public class TypeCheckProcFactory {
if (genericUDF instanceof GenericUDFBaseCompare
&& children.size() == 2
&& ((children.get(0) instanceof ExprNodeConstantDesc
- && children.get(1) instanceof ExprNodeColumnDesc)
- || (children.get(0) instanceof ExprNodeColumnDesc
- && children.get(1) instanceof ExprNodeConstantDesc))) {
+ && children.get(1) instanceof ExprNodeColumnDesc)
+ || (children.get(0) instanceof ExprNodeColumnDesc
+ && children.get(1) instanceof ExprNodeConstantDesc))) {
int constIdx = children.get(0) instanceof ExprNodeConstantDesc ? 0 : 1;
@@ -1229,7 +1234,7 @@ public class TypeCheckProcFactory {
} catch (HiveException e) {
throw new SemanticException(e);
}
- if( children.size() <= HiveConf.getIntVar(conf, HiveConf.ConfVars.HIVEOPT_TRANSFORM_IN_MAXNODES)) {
+ if(children.size() <= HiveConf.getIntVar(conf, HiveConf.ConfVars.HIVEOPT_TRANSFORM_IN_MAXNODES)) {
ArrayList<ExprNodeDesc> orOperands = TypeCheckProcFactoryUtils.rewriteInToOR(children);
if (orOperands != null) {
if (orOperands.size() == 1) {
@@ -1278,10 +1283,10 @@ public class TypeCheckProcFactory {
} else if (ctx.isFoldExpr() && canConvertIntoCoalesce(genericUDF, children)) {
// Rewrite CASE into COALESCE
desc = ExprNodeGenericFuncDesc.newInstance(new GenericUDFCoalesce(),
- Lists.newArrayList(children.get(0), new ExprNodeConstantDesc(false)));
+ Lists.newArrayList(children.get(0), new ExprNodeConstantDesc(false)));
if (Boolean.FALSE.equals(((ExprNodeConstantDesc) children.get(1)).getValue())) {
desc = ExprNodeGenericFuncDesc.newInstance(new GenericUDFOPNot(),
- Lists.newArrayList(desc));
+ Lists.newArrayList(desc));
}
} else {
desc = ExprNodeGenericFuncDesc.newInstance(genericUDF, funcText,
@@ -1291,8 +1296,8 @@ public class TypeCheckProcFactory {
// If the function is deterministic and the children are constants,
// we try to fold the expression to remove e.g. cast on constant
if (ctx.isFoldExpr() && desc instanceof ExprNodeGenericFuncDesc &&
- FunctionRegistry.isConsistentWithinQuery(genericUDF) &&
- ExprNodeDescUtils.isAllConstants(children)) {
+ FunctionRegistry.isConsistentWithinQuery(genericUDF) &&
+ ExprNodeDescUtils.isAllConstants(children)) {
ExprNodeDesc constantExpr = ConstantPropagateProcFactory.foldExpr((ExprNodeGenericFuncDesc)desc);
if (constantExpr != null) {
desc = constantExpr;
@@ -1474,8 +1479,8 @@ public class TypeCheckProcFactory {
private boolean canConvertIntoCoalesce(GenericUDF genericUDF, ArrayList<ExprNodeDesc> children) {
if (genericUDF instanceof GenericUDFWhen && children.size() == 3 &&
- children.get(1) instanceof ExprNodeConstantDesc &&
- children.get(2) instanceof ExprNodeConstantDesc) {
+ children.get(1) instanceof ExprNodeConstantDesc &&
+ children.get(2) instanceof ExprNodeConstantDesc) {
ExprNodeConstantDesc constThen = (ExprNodeConstantDesc) children.get(1);
ExprNodeConstantDesc constElse = (ExprNodeConstantDesc) children.get(2);
Object thenVal = constThen.getValue();
@@ -1749,7 +1754,7 @@ public class TypeCheckProcFactory {
if (!ctx.getallowSubQueryExpr()) {
throw new CalciteSubquerySemanticException(SemanticAnalyzer.generateErrorMessage(sqNode,
ErrorMsg.UNSUPPORTED_SUBQUERY_EXPRESSION.getMsg("Currently SubQuery expressions are only allowed as " +
- "Where and Having Clause predicates")));
+ "Where and Having Clause predicates")));
}
ExprNodeDesc desc = TypeCheckProcFactory.processGByExpr(nd, procCtx);
@@ -1765,12 +1770,12 @@ public class TypeCheckProcFactory {
ASTNode subqueryOp = (ASTNode) expr.getChild(0);
boolean isIN = (subqueryOp.getChildCount() > 0) && (subqueryOp.getChild(0).getType() == HiveParser.KW_IN
- || subqueryOp.getChild(0).getType() == HiveParser.TOK_SUBQUERY_OP_NOTIN);
+ || subqueryOp.getChild(0).getType() == HiveParser.TOK_SUBQUERY_OP_NOTIN);
boolean isEXISTS = (subqueryOp.getChildCount() > 0) && (subqueryOp.getChild(0).getType() == HiveParser.KW_EXISTS
- || subqueryOp.getChild(0).getType() == HiveParser.TOK_SUBQUERY_OP_NOTEXISTS);
+ || subqueryOp.getChild(0).getType() == HiveParser.TOK_SUBQUERY_OP_NOTEXISTS);
boolean isSOME = (subqueryOp.getChildCount() > 0) && (subqueryOp.getChild(0).getType() == HiveParser.KW_SOME);
boolean isALL = (subqueryOp.getChildCount() > 0) && (subqueryOp.getChild(0).getType() == HiveParser.KW_ALL);
- boolean isScalar = subqueryOp.getChildCount() == 0 ;
+ boolean isScalar = subqueryOp.getChildCount() == 0;
// subqueryToRelNode might be null if subquery expression anywhere other than
// as expected in filter (where/having). We should throw an appropriate error
@@ -1779,8 +1784,8 @@ public class TypeCheckProcFactory {
Map<ASTNode, RelNode> subqueryToRelNode = ctx.getSubqueryToRelNode();
if(subqueryToRelNode == null) {
throw new CalciteSubquerySemanticException(ErrorMsg.UNSUPPORTED_SUBQUERY_EXPRESSION.getMsg(
- " Currently SubQuery expressions are only allowed as " +
- "Where and Having Clause predicates"));
+ " Currently SubQuery expressions are only allowed as " +
+ "Where and Having Clause predicates"));
}
RelNode subqueryRel = subqueryToRelNode.get(expr);
@@ -1789,29 +1794,27 @@ public class TypeCheckProcFactory {
// we will create subquery expression of boolean type
if(isEXISTS) {
return new ExprNodeSubQueryDesc(TypeInfoFactory.booleanTypeInfo, subqueryRel,
- ExprNodeSubQueryDesc.SubqueryType.EXISTS);
- }
- else if(isIN) {
+ ExprNodeSubQueryDesc.SubqueryType.EXISTS);
+ } else if(isIN) {
assert(nodeOutputs[2] != null);
ExprNodeDesc lhs = (ExprNodeDesc)nodeOutputs[2];
return new ExprNodeSubQueryDesc(TypeInfoFactory.booleanTypeInfo, subqueryRel,
- ExprNodeSubQueryDesc.SubqueryType.IN, lhs);
- }
- else if(isScalar){
+ ExprNodeSubQueryDesc.SubqueryType.IN, lhs);
+ } else if(isScalar){
// only single subquery expr is supported
if(subqueryRel.getRowType().getFieldCount() != 1) {
- throw new CalciteSubquerySemanticException(ErrorMsg.INVALID_SUBQUERY_EXPRESSION.getMsg(
- "More than one column expression in subquery"));
+ throw new CalciteSubquerySemanticException(ErrorMsg.INVALID_SUBQUERY_EXPRESSION.getMsg(
+ "More than one column expression in subquery"));
}
// figure out subquery expression column's type
TypeInfo subExprType = TypeConverter.convert(subqueryRel.getRowType().getFieldList().get(0).getType());
return new ExprNodeSubQueryDesc(subExprType, subqueryRel,
- ExprNodeSubQueryDesc.SubqueryType.SCALAR);
+ ExprNodeSubQueryDesc.SubqueryType.SCALAR);
} else if(isSOME) {
assert(nodeOutputs[2] != null);
ExprNodeDesc lhs = (ExprNodeDesc)nodeOutputs[2];
return new ExprNodeSubQueryDesc(TypeInfoFactory.booleanTypeInfo, subqueryRel,
- ExprNodeSubQueryDesc.SubqueryType.SOME, lhs, (ASTNode)subqueryOp.getChild(1) );
+ ExprNodeSubQueryDesc.SubqueryType.SOME, lhs, (ASTNode)subqueryOp.getChild(1));
} else if(isALL) {
assert(nodeOutputs[2] != null);
ExprNodeDesc lhs = (ExprNodeDesc)nodeOutputs[2];
@@ -1823,8 +1826,8 @@ public class TypeCheckProcFactory {
* Restriction.1.h :: SubQueries only supported in the SQL Where Clause.
*/
ctx.setError(ErrorMsg.UNSUPPORTED_SUBQUERY_EXPRESSION.getMsg(sqNode,
- "Currently only IN & EXISTS SubQuery expressions are allowed"),
- sqNode);
+ "Currently only IN & EXISTS SubQuery expressions are allowed"),
+ sqNode);
return null;
}
}