use of org.apache.hadoop.hive.ql.optimizer.calcite.CalciteSubquerySemanticException in project hive by apache.
the class QBSubQuery method subqueryRestrictionsCheck.
/**
* @param parentQueryRR
* @param forHavingClause
* @param outerQueryAlias
* @return true if it is correlated scalar subquery with an aggregate
* @throws SemanticException
*/
boolean subqueryRestrictionsCheck(RowResolver parentQueryRR, boolean forHavingClause, String outerQueryAlias) throws SemanticException {
ASTNode insertClause = getChildFromSubqueryAST("Insert", HiveParser.TOK_INSERT);
ASTNode selectClause = (ASTNode) insertClause.getChild(1);
int selectExprStart = 0;
if (selectClause.getChild(0).getType() == HiveParser.QUERY_HINT) {
selectExprStart = 1;
}
/*
* Check.5.h :: For In and Not In the SubQuery must implicitly or
* explicitly only contain one select item.
*/
if (operator.getType() != SubQueryType.EXISTS && operator.getType() != SubQueryType.NOT_EXISTS && selectClause.getChildCount() - selectExprStart > 1) {
subQueryAST.setOrigin(originalSQASTOrigin);
throw new SemanticException(ErrorMsg.INVALID_SUBQUERY_EXPRESSION.getMsg(subQueryAST, "SubQuery can contain only 1 item in Select List."));
}
boolean hasAggreateExprs = false;
boolean hasWindowing = false;
// we need to know if aggregate is COUNT since IN corr subq with count aggregate
// is not special cased later in subquery remove rule
boolean hasCount = false;
for (int i = selectExprStart; i < selectClause.getChildCount(); i++) {
ASTNode selectItem = (ASTNode) selectClause.getChild(i);
int r = SubQueryUtils.checkAggOrWindowing(selectItem);
hasWindowing = hasWindowing | (r == 3);
hasAggreateExprs = hasAggreateExprs | (r == 1 | r == 2);
hasCount = hasCount | (r == 2);
}
ASTNode whereClause = SubQueryUtils.subQueryWhere(insertClause);
if (whereClause == null) {
return false;
}
ASTNode searchCond = (ASTNode) whereClause.getChild(0);
List<ASTNode> conjuncts = new ArrayList<ASTNode>();
SubQueryUtils.extractConjuncts(searchCond, conjuncts);
ConjunctAnalyzer conjunctAnalyzer = new ConjunctAnalyzer(parentQueryRR, forHavingClause, outerQueryAlias);
boolean hasCorrelation = false;
boolean hasNonEquiJoinPred = false;
for (ASTNode conjunctAST : conjuncts) {
Conjunct conjunct = conjunctAnalyzer.analyzeConjunct(conjunctAST);
if (conjunct.isCorrelated()) {
hasCorrelation = true;
}
if (conjunct.eitherSideRefersBoth() && conjunctAST.getType() != HiveParser.EQUAL) {
hasNonEquiJoinPred = true;
}
}
boolean noImplicityGby = true;
if (insertClause.getChild(1).getChildCount() > 3 && insertClause.getChild(1).getChild(3).getType() == HiveParser.TOK_GROUPBY) {
if ((ASTNode) insertClause.getChild(1).getChild(3) != null) {
noImplicityGby = false;
}
}
/*
* Restriction.14.h :: Correlated Sub Queries cannot contain Windowing clauses.
*/
if (hasWindowing && hasCorrelation) {
throw new CalciteSubquerySemanticException(ErrorMsg.UNSUPPORTED_SUBQUERY_EXPRESSION.getMsg(subQueryAST, "Correlated Sub Queries cannot contain Windowing clauses."));
}
// * NOT IN - always allow, but always return true because later subq remove rule will generate diff plan for this case
if (hasAggreateExprs && noImplicityGby) {
if (operator.getType() == SubQueryType.EXISTS || operator.getType() == SubQueryType.NOT_EXISTS) {
if (hasCorrelation) {
throw new CalciteSubquerySemanticException(ErrorMsg.INVALID_SUBQUERY_EXPRESSION.getMsg(subQueryAST, "A predicate on EXISTS/NOT EXISTS SubQuery with implicit Aggregation(no Group By clause) " + "cannot be rewritten."));
}
} else if (operator.getType() == SubQueryType.SCALAR) {
if (hasNonEquiJoinPred) {
throw new CalciteSubquerySemanticException(ErrorMsg.INVALID_SUBQUERY_EXPRESSION.getMsg(subQueryAST, "Scalar subqueries with aggregate cannot have non-equi join predicate"));
}
if (hasCorrelation) {
return true;
}
} else if (operator.getType() == SubQueryType.IN) {
if (hasCount && hasCorrelation) {
return true;
}
} else if (operator.getType() == SubQueryType.NOT_IN) {
if (hasCorrelation) {
return true;
}
}
}
return false;
}
use of org.apache.hadoop.hive.ql.optimizer.calcite.CalciteSubquerySemanticException in project hive by apache.
the class SubQueryUtils method checkForSubqueries.
static void checkForSubqueries(ASTNode node, boolean disallow) throws SemanticException {
// allow NOT but throw an error for rest
if (node.getType() == HiveParser.TOK_SUBQUERY_EXPR && disallow) {
throw new CalciteSubquerySemanticException(ErrorMsg.UNSUPPORTED_SUBQUERY_EXPRESSION.getMsg("Invalid subquery. Subquery in UDAF is not allowed."));
}
if (node.getType() == HiveParser.TOK_FUNCTION || node.getType() == HiveParser.TOK_FUNCTIONDI || node.getType() == HiveParser.TOK_FUNCTIONSTAR) {
if (node.getChild(0).getType() == HiveParser.Identifier) {
String functionName = SemanticAnalyzer.unescapeIdentifier(node.getChild(0).getText());
GenericUDAFResolver udafResolver = FunctionRegistry.getGenericUDAFResolver(functionName);
if (udafResolver != null) {
disallow = disallow || true;
}
}
}
for (int i = 0; i < node.getChildCount(); i++) {
checkForSubqueries((ASTNode) node.getChild(i), disallow);
}
}
use of org.apache.hadoop.hive.ql.optimizer.calcite.CalciteSubquerySemanticException in project hive by apache.
the class ExprNodeDescExprFactory method createSubqueryExpr.
/**
* {@inheritDoc}
*/
@Override
protected ExprNodeDesc createSubqueryExpr(TypeCheckCtx ctx, ASTNode expr, SubqueryType subqueryType, Object[] inputs) throws CalciteSubquerySemanticException {
// subqueryToRelNode might be null if subquery expression anywhere other than
// as expected in filter (where/having). We should throw an appropriate error
// message
Map<ASTNode, QBSubQueryParseInfo> 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"));
}
ASTNode subqueryOp = (ASTNode) expr.getChild(0);
RelNode subqueryRel = subqueryToRelNode.get(expr).getSubQueryRelNode();
// we will create subquery expression of boolean type
switch(subqueryType) {
case EXISTS:
{
if (subqueryToRelNode.get(expr).hasFullAggregate()) {
return createConstantExpr(TypeInfoFactory.booleanTypeInfo, true);
}
return new ExprNodeSubQueryDesc(TypeInfoFactory.booleanTypeInfo, subqueryRel, SubqueryType.EXISTS);
}
case IN:
{
assert (inputs[2] != null);
ExprNodeDesc lhs = (ExprNodeDesc) inputs[2];
return new ExprNodeSubQueryDesc(TypeInfoFactory.booleanTypeInfo, subqueryRel, SubqueryType.IN, lhs);
}
case SCALAR:
{
// 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"));
}
// figure out subquery expression column's type
TypeInfo subExprType = TypeConverter.convert(subqueryRel.getRowType().getFieldList().get(0).getType());
return new ExprNodeSubQueryDesc(subExprType, subqueryRel, SubqueryType.SCALAR);
}
case SOME:
{
assert (inputs[2] != null);
ExprNodeDesc lhs = (ExprNodeDesc) inputs[2];
return new ExprNodeSubQueryDesc(TypeInfoFactory.booleanTypeInfo, subqueryRel, SubqueryType.SOME, lhs, (ASTNode) subqueryOp.getChild(1));
}
case ALL:
{
assert (inputs[2] != null);
ExprNodeDesc lhs = (ExprNodeDesc) inputs[2];
return new ExprNodeSubQueryDesc(TypeInfoFactory.booleanTypeInfo, subqueryRel, SubqueryType.ALL, lhs, (ASTNode) subqueryOp.getChild(1));
}
default:
return null;
}
}
use of org.apache.hadoop.hive.ql.optimizer.calcite.CalciteSubquerySemanticException in project hive by apache.
the class RexNodeExprFactory method convertSubquerySomeAll.
public static RexNode convertSubquerySomeAll(final RelOptCluster cluster, final ASTNode comparisonOp, final SubqueryType subqueryType, final RelNode subqueryRel, final RexNode rexNodeLhs) throws SemanticException {
SqlQuantifyOperator quantifyOperator = null;
switch(comparisonOp.getType()) {
case HiveParser.EQUAL:
if (subqueryType == SubqueryType.ALL) {
throwInvalidSubqueryError(comparisonOp);
}
quantifyOperator = SqlStdOperatorTable.SOME_EQ;
break;
case HiveParser.LESSTHAN:
quantifyOperator = SqlStdOperatorTable.SOME_LT;
break;
case HiveParser.LESSTHANOREQUALTO:
quantifyOperator = SqlStdOperatorTable.SOME_LE;
break;
case HiveParser.GREATERTHAN:
quantifyOperator = SqlStdOperatorTable.SOME_GT;
break;
case HiveParser.GREATERTHANOREQUALTO:
quantifyOperator = SqlStdOperatorTable.SOME_GE;
break;
case HiveParser.NOTEQUAL:
if (subqueryType == SubqueryType.SOME) {
throwInvalidSubqueryError(comparisonOp);
}
quantifyOperator = SqlStdOperatorTable.SOME_NE;
break;
default:
throw new CalciteSubquerySemanticException(ErrorMsg.INVALID_SUBQUERY_EXPRESSION.getMsg("Invalid operator:" + comparisonOp.toString()));
}
if (subqueryType == SubqueryType.ALL) {
quantifyOperator = SqlStdOperatorTable.some(quantifyOperator.comparisonKind.negateNullSafe());
}
RexNode someQuery = getSomeSubquery(cluster, subqueryRel, rexNodeLhs, quantifyOperator);
if (subqueryType == SubqueryType.ALL) {
return cluster.getRexBuilder().makeCall(SqlStdOperatorTable.NOT, someQuery);
}
return someQuery;
}
use of org.apache.hadoop.hive.ql.optimizer.calcite.CalciteSubquerySemanticException in project hive by apache.
the class RexNodeConverter method convert.
private RexNode convert(final ExprNodeSubQueryDesc subQueryDesc) throws SemanticException {
if (subQueryDesc.getType() == ExprNodeSubQueryDesc.SubqueryType.IN) {
/*
* Check.5.h :: For In and Not In the SubQuery must implicitly or
* explicitly only contain one select item.
*/
if (subQueryDesc.getRexSubQuery().getRowType().getFieldCount() > 1) {
throw new CalciteSubquerySemanticException(ErrorMsg.INVALID_SUBQUERY_EXPRESSION.getMsg("SubQuery can contain only 1 item in Select List."));
}
// create RexNode for LHS
RexNode rexNodeLhs = convert(subQueryDesc.getSubQueryLhs());
// create RexSubQuery node
RexNode rexSubQuery = RexSubQuery.in(subQueryDesc.getRexSubQuery(), ImmutableList.<RexNode>of(rexNodeLhs));
return rexSubQuery;
} else if (subQueryDesc.getType() == ExprNodeSubQueryDesc.SubqueryType.EXISTS) {
RexNode subQueryNode = RexSubQuery.exists(subQueryDesc.getRexSubQuery());
return subQueryNode;
} else if (subQueryDesc.getType() == ExprNodeSubQueryDesc.SubqueryType.SCALAR) {
if (subQueryDesc.getRexSubQuery().getRowType().getFieldCount() > 1) {
throw new CalciteSubquerySemanticException(ErrorMsg.INVALID_SUBQUERY_EXPRESSION.getMsg("SubQuery can contain only 1 item in Select List."));
}
// create RexSubQuery node
RexNode rexSubQuery = RexSubQuery.scalar(subQueryDesc.getRexSubQuery());
return rexSubQuery;
} else {
throw new CalciteSubquerySemanticException(ErrorMsg.INVALID_SUBQUERY_EXPRESSION.getMsg("Invalid subquery: " + subQueryDesc.getType()));
}
}
Aggregations