use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.SqlKind in project flink by apache.
the class HiveParserBaseSemanticAnalyzer method getOrderKeys.
public static List<RexFieldCollation> getOrderKeys(OrderSpec orderSpec, HiveParserRexNodeConverter converter, HiveParserRowResolver inputRR, HiveParserTypeCheckCtx typeCheckCtx, HiveParserSemanticAnalyzer semanticAnalyzer) throws SemanticException {
List<RexFieldCollation> orderKeys = new ArrayList<>();
if (orderSpec != null) {
List<OrderExpression> oExprs = orderSpec.getExpressions();
for (OrderExpression oExpr : oExprs) {
typeCheckCtx.setAllowStatefulFunctions(true);
ExprNodeDesc exp = semanticAnalyzer.genExprNodeDesc(oExpr.getExpression(), inputRR, typeCheckCtx);
RexNode ordExp = converter.convert(exp);
Set<SqlKind> flags = new HashSet<>();
if (oExpr.getOrder() == Order.DESC) {
flags.add(SqlKind.DESCENDING);
}
if (oExpr.getNullOrder() == NullOrder.NULLS_FIRST) {
flags.add(SqlKind.NULLS_FIRST);
} else if (oExpr.getNullOrder() == NullOrder.NULLS_LAST) {
flags.add(SqlKind.NULLS_LAST);
} else {
throw new SemanticException("Unexpected null ordering option: " + oExpr.getNullOrder());
}
orderKeys.add(new RexFieldCollation(ordExp, flags));
}
}
return orderKeys;
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.SqlKind in project flink by apache.
the class RexSimplify method simplifyIs.
@Nonnull
private RexNode simplifyIs(RexCall call, RexUnknownAs unknownAs) {
final SqlKind kind = call.getKind();
final RexNode a = call.getOperands().get(0);
final RexNode simplified = simplifyIs1(kind, a, unknownAs);
return simplified == null ? call : simplified;
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.SqlKind in project flink by apache.
the class FlinkAggregateExpandDistinctAggregatesRule method onMatch.
// ~ Methods ----------------------------------------------------------------
public void onMatch(RelOptRuleCall call) {
final Aggregate aggregate = call.rel(0);
if (!AggregateUtil.containsAccurateDistinctCall(aggregate.getAggCallList())) {
return;
}
// accurate distinct call.
if (AggregateUtil.containsApproximateDistinctCall(aggregate.getAggCallList())) {
throw new TableException("There are both Distinct AggCall and Approximate Distinct AggCall in one sql statement, " + "it is not supported yet.\nPlease choose one of them.");
}
// by DecomposeGroupingSetsRule. Then this rule expands it's distinct aggregates.
if (aggregate.getGroupSets().size() > 1) {
return;
}
// Find all of the agg expressions. We use a LinkedHashSet to ensure determinism.
// Find all aggregate calls without distinct
int nonDistinctAggCallCount = 0;
// Find all aggregate calls without distinct but ignore MAX, MIN, BIT_AND, BIT_OR
int nonDistinctAggCallExcludingIgnoredCount = 0;
int filterCount = 0;
int unsupportedNonDistinctAggCallCount = 0;
final Set<Pair<List<Integer>, Integer>> argLists = new LinkedHashSet<>();
for (AggregateCall aggCall : aggregate.getAggCallList()) {
if (aggCall.filterArg >= 0) {
++filterCount;
}
if (!aggCall.isDistinct()) {
++nonDistinctAggCallCount;
final SqlKind aggCallKind = aggCall.getAggregation().getKind();
// We only support COUNT/SUM/MIN/MAX for the "single" count distinct optimization
switch(aggCallKind) {
case COUNT:
case SUM:
case SUM0:
case MIN:
case MAX:
break;
default:
++unsupportedNonDistinctAggCallCount;
}
if (aggCall.getAggregation().getDistinctOptionality() == Optionality.IGNORED) {
argLists.add(Pair.of(aggCall.getArgList(), aggCall.filterArg));
} else {
++nonDistinctAggCallExcludingIgnoredCount;
}
} else {
argLists.add(Pair.of(aggCall.getArgList(), aggCall.filterArg));
}
}
final int distinctAggCallCount = aggregate.getAggCallList().size() - nonDistinctAggCallCount;
Preconditions.checkState(argLists.size() > 0, "containsDistinctCall lied");
// we can still use this promotion.
if (nonDistinctAggCallExcludingIgnoredCount == 0 && argLists.size() == 1 && aggregate.getGroupType() == Group.SIMPLE) {
final Pair<List<Integer>, Integer> pair = com.google.common.collect.Iterables.getOnlyElement(argLists);
final RelBuilder relBuilder = call.builder();
convertMonopole(relBuilder, aggregate, pair.left, pair.right);
call.transformTo(relBuilder.build());
return;
}
if (useGroupingSets) {
rewriteUsingGroupingSets(call, aggregate);
return;
}
// we can generate multi-phase aggregates
if (// one distinct aggregate
distinctAggCallCount == 1 && // no filter
filterCount == 0 && unsupportedNonDistinctAggCallCount == // sum/min/max/count in non-distinct aggregate
0 && nonDistinctAggCallCount > 0) {
// one or more non-distinct aggregates
final RelBuilder relBuilder = call.builder();
convertSingletonDistinct(relBuilder, aggregate, argLists);
call.transformTo(relBuilder.build());
return;
}
// Create a list of the expressions which will yield the final result.
// Initially, the expressions point to the input field.
final List<RelDataTypeField> aggFields = aggregate.getRowType().getFieldList();
final List<RexInputRef> refs = new ArrayList<>();
final List<String> fieldNames = aggregate.getRowType().getFieldNames();
final ImmutableBitSet groupSet = aggregate.getGroupSet();
final int groupCount = aggregate.getGroupCount();
for (int i : Util.range(groupCount)) {
refs.add(RexInputRef.of(i, aggFields));
}
// Aggregate the original relation, including any non-distinct aggregates.
final List<AggregateCall> newAggCallList = new ArrayList<>();
int i = -1;
for (AggregateCall aggCall : aggregate.getAggCallList()) {
++i;
if (aggCall.isDistinct()) {
refs.add(null);
continue;
}
refs.add(new RexInputRef(groupCount + newAggCallList.size(), aggFields.get(groupCount + i).getType()));
newAggCallList.add(aggCall);
}
// In the case where there are no non-distinct aggregates (regardless of
// whether there are group bys), there's no need to generate the
// extra aggregate and join.
final RelBuilder relBuilder = call.builder();
relBuilder.push(aggregate.getInput());
int n = 0;
if (!newAggCallList.isEmpty()) {
final RelBuilder.GroupKey groupKey = relBuilder.groupKey(groupSet, aggregate.getGroupSets());
relBuilder.aggregate(groupKey, newAggCallList);
++n;
}
// set of operands.
for (Pair<List<Integer>, Integer> argList : argLists) {
doRewrite(relBuilder, aggregate, n++, argList.left, argList.right, refs);
}
relBuilder.project(refs, fieldNames);
call.transformTo(relBuilder.build());
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.SqlKind in project flink by apache.
the class FlinkAggregateRemoveRule method matches.
@Override
public boolean matches(RelOptRuleCall call) {
final Aggregate aggregate = call.rel(0);
final RelNode input = call.rel(1);
if (aggregate.getGroupCount() == 0 || aggregate.indicator || aggregate.getGroupType() != Aggregate.Group.SIMPLE) {
return false;
}
for (AggregateCall aggCall : aggregate.getAggCallList()) {
SqlKind aggCallKind = aggCall.getAggregation().getKind();
// TODO supports more AggregateCalls
boolean isAllowAggCall = aggCallKind == SqlKind.SUM || aggCallKind == SqlKind.MIN || aggCallKind == SqlKind.MAX || aggCall.getAggregation() instanceof SqlAuxiliaryGroupAggFunction;
if (!isAllowAggCall || aggCall.filterArg >= 0 || aggCall.getArgList().size() != 1) {
return false;
}
}
final RelMetadataQuery mq = call.getMetadataQuery();
return SqlFunctions.isTrue(mq.areColumnsUnique(input, aggregate.getGroupSet()));
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.SqlKind in project flink by apache.
the class SqlValidatorImpl method registerFrom.
/**
* Registers scopes and namespaces implied a relational expression in the FROM clause.
*
* <p>{@code parentScope} and {@code usingScope} are often the same. They differ when the
* namespace are not visible within the parent. (Example needed.)
*
* <p>Likewise, {@code enclosingNode} and {@code node} are often the same. {@code enclosingNode}
* is the topmost node within the FROM clause, from which any decorations like an alias (<code>
* AS alias</code>) or a table sample clause are stripped away to get {@code node}. Both are
* recorded in the namespace.
*
* @param parentScope Parent scope which this scope turns to in order to resolve objects
* @param usingScope Scope whose child list this scope should add itself to
* @param register Whether to register this scope as a child of {@code usingScope}
* @param node Node which namespace is based on
* @param enclosingNode Outermost node for namespace, including decorations such as alias and
* sample clause
* @param alias Alias
* @param extendList Definitions of extended columns
* @param forceNullable Whether to force the type of namespace to be nullable because it is in
* an outer join
* @param lateral Whether LATERAL is specified, so that items to the left of this in the JOIN
* tree are visible in the scope
* @return registered node, usually the same as {@code node}
*/
private SqlNode registerFrom(SqlValidatorScope parentScope, SqlValidatorScope usingScope, boolean register, final SqlNode node, SqlNode enclosingNode, String alias, SqlNodeList extendList, boolean forceNullable, final boolean lateral) {
final SqlKind kind = node.getKind();
SqlNode expr;
SqlNode newExpr;
// Add an alias if necessary.
SqlNode newNode = node;
if (alias == null) {
switch(kind) {
case IDENTIFIER:
case OVER:
alias = deriveAlias(node, -1);
if (alias == null) {
alias = deriveAlias(node, nextGeneratedId++);
}
if (config.identifierExpansion()) {
newNode = SqlValidatorUtil.addAlias(node, alias);
}
break;
case SELECT:
case UNION:
case INTERSECT:
case EXCEPT:
case VALUES:
case UNNEST:
case OTHER_FUNCTION:
case COLLECTION_TABLE:
case PIVOT:
case MATCH_RECOGNIZE:
// give this anonymous construct a name since later
// query processing stages rely on it
alias = deriveAlias(node, nextGeneratedId++);
if (config.identifierExpansion()) {
// Since we're expanding identifiers, we should make the
// aliases explicit too, otherwise the expanded query
// will not be consistent if we convert back to SQL, e.g.
// "select EXPR$1.EXPR$2 from values (1)".
newNode = SqlValidatorUtil.addAlias(node, alias);
}
break;
}
}
if (lateral) {
SqlValidatorScope s = usingScope;
while (s instanceof JoinScope) {
s = ((JoinScope) s).getUsingScope();
}
final SqlNode node2 = s != null ? s.getNode() : node;
final TableScope tableScope = new TableScope(parentScope, node2);
if (usingScope instanceof ListScope) {
for (ScopeChild child : ((ListScope) usingScope).children) {
tableScope.addChild(child.namespace, child.name, child.nullable);
}
}
parentScope = tableScope;
}
SqlCall call;
SqlNode operand;
SqlNode newOperand;
switch(kind) {
case AS:
call = (SqlCall) node;
if (alias == null) {
alias = call.operand(1).toString();
}
final boolean needAlias = call.operandCount() > 2;
expr = call.operand(0);
newExpr = registerFrom(parentScope, usingScope, !needAlias, expr, enclosingNode, alias, extendList, forceNullable, lateral);
if (newExpr != expr) {
call.setOperand(0, newExpr);
}
// column names. We skipped registering it just now.
if (needAlias) {
registerNamespace(usingScope, alias, new AliasNamespace(this, call, enclosingNode), forceNullable);
}
return node;
case MATCH_RECOGNIZE:
registerMatchRecognize(parentScope, usingScope, (SqlMatchRecognize) node, enclosingNode, alias, forceNullable);
return node;
case PIVOT:
registerPivot(parentScope, usingScope, (SqlPivot) node, enclosingNode, alias, forceNullable);
return node;
case TABLESAMPLE:
call = (SqlCall) node;
expr = call.operand(0);
newExpr = registerFrom(parentScope, usingScope, true, expr, enclosingNode, alias, extendList, forceNullable, lateral);
if (newExpr != expr) {
call.setOperand(0, newExpr);
}
return node;
case JOIN:
final SqlJoin join = (SqlJoin) node;
final JoinScope joinScope = new JoinScope(parentScope, usingScope, join);
scopes.put(join, joinScope);
final SqlNode left = join.getLeft();
final SqlNode right = join.getRight();
boolean forceLeftNullable = forceNullable;
boolean forceRightNullable = forceNullable;
switch(join.getJoinType()) {
case LEFT:
forceRightNullable = true;
break;
case RIGHT:
forceLeftNullable = true;
break;
case FULL:
forceLeftNullable = true;
forceRightNullable = true;
break;
}
final SqlNode newLeft = registerFrom(parentScope, joinScope, true, left, left, null, null, forceLeftNullable, lateral);
if (newLeft != left) {
join.setLeft(newLeft);
}
final SqlNode newRight = registerFrom(parentScope, joinScope, true, right, right, null, null, forceRightNullable, lateral);
if (newRight != right) {
join.setRight(newRight);
}
registerSubQueries(joinScope, join.getCondition());
final JoinNamespace joinNamespace = new JoinNamespace(this, join);
registerNamespace(null, null, joinNamespace, forceNullable);
return join;
case IDENTIFIER:
final SqlIdentifier id = (SqlIdentifier) node;
final IdentifierNamespace newNs = new IdentifierNamespace(this, id, extendList, enclosingNode, parentScope);
registerNamespace(register ? usingScope : null, alias, newNs, forceNullable);
if (tableScope == null) {
tableScope = new TableScope(parentScope, node);
}
tableScope.addChild(newNs, alias, forceNullable);
if (extendList != null && extendList.size() != 0) {
return enclosingNode;
}
return newNode;
case LATERAL:
return registerFrom(parentScope, usingScope, register, ((SqlCall) node).operand(0), enclosingNode, alias, extendList, forceNullable, true);
case COLLECTION_TABLE:
call = (SqlCall) node;
operand = call.operand(0);
newOperand = registerFrom(parentScope, usingScope, register, operand, enclosingNode, alias, extendList, forceNullable, lateral);
if (newOperand != operand) {
call.setOperand(0, newOperand);
}
// its first operand's (the table) scope.
if (operand instanceof SqlBasicCall) {
final SqlBasicCall call1 = (SqlBasicCall) operand;
final SqlOperator op = call1.getOperator();
if (op instanceof SqlWindowTableFunction && call1.operand(0).getKind() == SqlKind.SELECT) {
scopes.put(node, getSelectScope(call1.operand(0)));
return newNode;
}
}
// Put the usingScope which can be a JoinScope
// or a SelectScope, in order to see the left items
// of the JOIN tree.
scopes.put(node, usingScope);
return newNode;
case UNNEST:
if (!lateral) {
return registerFrom(parentScope, usingScope, register, node, enclosingNode, alias, extendList, forceNullable, true);
}
// fall through
case SELECT:
case UNION:
case INTERSECT:
case EXCEPT:
case VALUES:
case WITH:
case OTHER_FUNCTION:
if (alias == null) {
alias = deriveAlias(node, nextGeneratedId++);
}
registerQuery(parentScope, register ? usingScope : null, node, enclosingNode, alias, forceNullable);
return newNode;
case OVER:
if (!shouldAllowOverRelation()) {
throw Util.unexpected(kind);
}
call = (SqlCall) node;
final OverScope overScope = new OverScope(usingScope, call);
scopes.put(call, overScope);
operand = call.operand(0);
newOperand = registerFrom(parentScope, overScope, true, operand, enclosingNode, alias, extendList, forceNullable, lateral);
if (newOperand != operand) {
call.setOperand(0, newOperand);
}
for (ScopeChild child : overScope.children) {
registerNamespace(register ? usingScope : null, child.name, child.namespace, forceNullable);
}
return newNode;
case TABLE_REF:
call = (SqlCall) node;
registerFrom(parentScope, usingScope, register, call.operand(0), enclosingNode, alias, extendList, forceNullable, lateral);
if (extendList != null && extendList.size() != 0) {
return enclosingNode;
}
return newNode;
case EXTEND:
final SqlCall extend = (SqlCall) node;
return registerFrom(parentScope, usingScope, true, extend.getOperandList().get(0), extend, alias, (SqlNodeList) extend.getOperandList().get(1), forceNullable, lateral);
case SNAPSHOT:
call = (SqlCall) node;
operand = call.operand(0);
newOperand = registerFrom(parentScope, usingScope, register, operand, enclosingNode, alias, extendList, forceNullable, lateral);
if (newOperand != operand) {
call.setOperand(0, newOperand);
}
// Put the usingScope which can be a JoinScope
// or a SelectScope, in order to see the left items
// of the JOIN tree.
scopes.put(node, usingScope);
return newNode;
default:
throw Util.unexpected(kind);
}
}
Aggregations