@Override protected Boolean visitFieldReference(FieldReference node, Void context) { if (orderByScope.isPresent()) { return true; } FieldId fieldId = requireNonNull(columnReferences.get(NodeRef.<Expression>of(node)), "No FieldId for FieldReference"); boolean inGroup = groupingFields.contains(fieldId); if (!inGroup) { Field field = sourceScope.getRelationType().getFieldByIndex(node.getFieldIndex()); String column; if (!field.getName().isPresent()) { column = Integer.toString(node.getFieldIndex() + 1); } else if (field.getRelationAlias().isPresent()) { column = String.format("'%s.%s'", field.getRelationAlias().get(), field.getName().get()); } else { column = "'" + field.getName().get() + "'"; } throw new SemanticException(MUST_BE_AGGREGATE_OR_GROUP_BY, node, "Column %s not in GROUP BY clause", column); } return inGroup; }
Field oldField = firstDescriptor.getFieldByIndex(i); outputDescriptorFields[i] = new Field( oldField.getRelationAlias(), oldField.getName(), outputFieldTypes[i],
oldField.getRelationAlias(), oldField.getName(), targetColumnTypes[i],
private void verifyAggregations( QuerySpecification node, List<FieldOrExpression> groupByExpressions, RelationType tupleDescriptor, FieldOrExpression fieldOrExpression, Set<Expression> columnReferences) { AggregationAnalyzer analyzer = new AggregationAnalyzer(groupByExpressions, metadata, tupleDescriptor, columnReferences); if (fieldOrExpression.isExpression()) { analyzer.analyze(fieldOrExpression.getExpression()); } else { int fieldIndex = fieldOrExpression.getFieldIndex(); if (!analyzer.analyze(fieldIndex)) { Field field = tupleDescriptor.getFieldByIndex(fieldIndex); if (field.getRelationAlias().isPresent()) { if (field.getName().isPresent()) { throw new SemanticException(MUST_BE_AGGREGATE_OR_GROUP_BY, node, "Column '%s.%s' not in GROUP BY clause", field.getRelationAlias().get(), field.getName().get()); } throw new SemanticException(MUST_BE_AGGREGATE_OR_GROUP_BY, node, "Columns from '%s' not in GROUP BY clause", field.getRelationAlias().get()); } if (field.getName().isPresent()) { throw new SemanticException(MUST_BE_AGGREGATE_OR_GROUP_BY, node, "Column '%s' not in GROUP BY clause", field.getName().get()); } throw new SemanticException(MUST_BE_AGGREGATE_OR_GROUP_BY, node, "Some columns from FROM clause not in GROUP BY clause"); } } }
for (int i = 0; i < outputFieldTypes.length; i++) { Field oldField = firstDescriptor.getFieldByIndex(i); outputDescriptorFields[i] = new Field(oldField.getRelationAlias(), oldField.getName(), outputFieldTypes[i], oldField.isHidden());
private RelationPlan addCoercions(RelationPlan plan, Type[] targetColumnTypes) { List<Symbol> oldSymbols = plan.getOutputSymbols(); RelationType oldDescriptor = plan.getDescriptor().withOnlyVisibleFields(); verify(targetColumnTypes.length == oldSymbols.size()); ImmutableList.Builder<Symbol> newSymbols = new ImmutableList.Builder<>(); Field[] newFields = new Field[targetColumnTypes.length]; ImmutableMap.Builder<Symbol, Expression> assignments = new ImmutableMap.Builder<>(); for (int i = 0; i < targetColumnTypes.length; i++) { Symbol inputSymbol = oldSymbols.get(i); Type inputType = symbolAllocator.getTypes().get(inputSymbol); Type outputType = targetColumnTypes[i]; if (outputType != inputType && !isTypeOnlyCoercion(inputType.getTypeSignature(), outputType.getTypeSignature())) { Expression cast = new Cast(new QualifiedNameReference(inputSymbol.toQualifiedName()), outputType.getTypeSignature().toString()); Symbol outputSymbol = symbolAllocator.newSymbol(cast, outputType); assignments.put(outputSymbol, cast); newSymbols.add(outputSymbol); } else { QualifiedNameReference qualifiedNameReference = new QualifiedNameReference(inputSymbol.toQualifiedName()); Symbol outputSymbol = symbolAllocator.newSymbol(qualifiedNameReference, outputType); assignments.put(outputSymbol, qualifiedNameReference); newSymbols.add(outputSymbol); } Field oldField = oldDescriptor.getFieldByIndex(i); newFields[i] = new Field(oldField.getRelationAlias(), oldField.getName(), targetColumnTypes[i], oldField.isHidden()); } ProjectNode projectNode = new ProjectNode(idAllocator.getNextId(), plan.getRoot(), assignments.build()); return new RelationPlan(projectNode, new RelationType(newFields), newSymbols.build(), plan.getSampleWeight()); }