use of io.trino.sql.analyzer.ResolvedField in project trino by trinodb.
the class ScopeAware method scopeAwareHash.
private OptionalInt scopeAwareHash(Node node) {
if (node instanceof Expression) {
Expression expression = (Expression) node;
if (analysis.isColumnReference(expression)) {
ResolvedField field = analysis.getResolvedField(expression);
Scope resolvedScope = field.getScope();
if (resolvedScope.hasOuterParent(queryScope)) {
return OptionalInt.of(treeHash(expression, CanonicalizationAware::canonicalizationAwareHash));
}
return OptionalInt.of(field.getFieldId().hashCode());
} else if (expression instanceof Identifier) {
return OptionalInt.of(treeHash(expression, CanonicalizationAware::canonicalizationAwareHash));
} else if (node.getChildren().isEmpty()) {
// Calculate shallow hash since node doesn't have any children
return OptionalInt.of(expression.hashCode());
}
}
return OptionalInt.empty();
}
use of io.trino.sql.analyzer.ResolvedField in project trino by trinodb.
the class ScopeAware method scopeAwareComparison.
private Boolean scopeAwareComparison(Node left, Node right) {
if (left instanceof Expression && right instanceof Expression) {
Expression leftExpression = (Expression) left;
Expression rightExpression = (Expression) right;
if (analysis.isColumnReference(leftExpression) && analysis.isColumnReference(rightExpression)) {
ResolvedField leftField = analysis.getResolvedField(leftExpression);
ResolvedField rightField = analysis.getResolvedField(rightExpression);
Scope leftScope = leftField.getScope();
Scope rightScope = rightField.getScope();
// For subqueries of the query associated with the current expression, compare by syntax
// Note: it'd appear that hash() and equal() are inconsistent with each other in the case that:
// * left.hasOuterParent(...) == true and right.hasOuterParent(...) == false
// * leftField.getFieldId().equals(rightField.getFieldId()) == true
// Both fields would seem to have different hashes but be equal to each other.
// However, this cannot happen because we *require* that both expressions being compared by
// rooted in the same "query scope" (i.e., sub-scopes that are local to each other) -- see ScopeAwareKey.equals().
// If both fields have the same field id, by definition they will produce the same result for hasOuterParent().
checkState(leftScope.hasOuterParent(queryScope) == rightScope.hasOuterParent(queryScope));
if (leftScope.hasOuterParent(queryScope) && rightScope.hasOuterParent(queryScope)) {
return treeEqual(leftExpression, rightExpression, CanonicalizationAware::canonicalizationAwareComparison);
}
// expression, compare by resolved field
return leftField.getFieldId().equals(rightField.getFieldId());
} else if (leftExpression instanceof Identifier && rightExpression instanceof Identifier) {
return treeEqual(leftExpression, rightExpression, CanonicalizationAware::canonicalizationAwareComparison);
}
}
if (!left.shallowEquals(right)) {
return false;
}
return null;
}
use of io.trino.sql.analyzer.ResolvedField in project trino by trinodb.
the class GroupingOperationRewriter method rewriteGroupingOperation.
public static Expression rewriteGroupingOperation(GroupingOperation expression, List<Set<Integer>> groupingSets, Map<NodeRef<Expression>, ResolvedField> columnReferenceFields, Optional<Symbol> groupIdSymbol) {
requireNonNull(groupIdSymbol, "groupIdSymbol is null");
// See SQL:2011:4.16.2 and SQL:2011:6.9.10.
if (groupingSets.size() == 1) {
return new LongLiteral("0");
} else {
checkState(groupIdSymbol.isPresent(), "groupId symbol is missing");
RelationId relationId = columnReferenceFields.get(NodeRef.of(expression.getGroupingColumns().get(0))).getFieldId().getRelationId();
List<Integer> columns = expression.getGroupingColumns().stream().map(NodeRef::of).peek(groupingColumn -> checkState(columnReferenceFields.containsKey(groupingColumn), "the grouping column is not in the columnReferencesField map")).map(columnReferenceFields::get).map(ResolvedField::getFieldId).map(fieldId -> translateFieldToInteger(fieldId, relationId)).collect(toImmutableList());
List<Expression> groupingResults = groupingSets.stream().map(groupingSet -> String.valueOf(calculateGrouping(groupingSet, columns))).map(LongLiteral::new).collect(toImmutableList());
// It is necessary to add a 1 to the groupId because the underlying array is indexed starting at 1
return new SubscriptExpression(new ArrayConstructor(groupingResults), new ArithmeticBinaryExpression(ADD, groupIdSymbol.get().toSymbolReference(), new GenericLiteral("BIGINT", "1")));
}
}
Aggregations