private RelationPlan addConstantSampleWeight(RelationPlan subPlan) { ImmutableMap.Builder<Symbol, Expression> projections = ImmutableMap.builder(); for (Symbol symbol : subPlan.getOutputSymbols()) { Expression expression = new QualifiedNameReference(symbol.toQualifiedName()); projections.put(symbol, expression); } Expression one = new LongLiteral("1"); Symbol sampleWeightSymbol = symbolAllocator.newSymbol("$sampleWeight", BIGINT); projections.put(sampleWeightSymbol, one); ProjectNode projectNode = new ProjectNode(idAllocator.getNextId(), subPlan.getRoot(), projections.build()); return new RelationPlan( projectNode, subPlan.getDescriptor(), projectNode.getOutputSymbols(), Optional.of(sampleWeightSymbol)); }
private RelationPlan processAndCoerceIfNecessary(Relation node, Void context) { Type[] coerceToTypes = analysis.getRelationCoercion(node); RelationPlan plan = node.accept(this, context); if (coerceToTypes == null) { return plan; } List<Symbol> oldSymbols = plan.getOutputSymbols(); TupleDescriptor oldDescriptor = plan.getDescriptor().withOnlyVisibleFields(); verify(coerceToTypes.length == oldSymbols.size()); ImmutableList.Builder<Symbol> newSymbols = new ImmutableList.Builder<>(); Field[] newFields = new Field[coerceToTypes.length]; ImmutableMap.Builder<Symbol, Expression> assignments = new ImmutableMap.Builder<>(); for (int i = 0; i < coerceToTypes.length; i++) { Symbol inputSymbol = oldSymbols.get(i); Type inputType = symbolAllocator.getTypes().get(inputSymbol); Type outputType = coerceToTypes[i]; if (outputType != inputType) { Cast cast = new Cast( new QualifiedNameReference(inputSymbol.toQualifiedName()), outputType.getTypeSignature().toString()); Symbol outputSymbol = symbolAllocator.newSymbol(cast, outputType); assignments.put(outputSymbol, cast); newSymbols.add(outputSymbol); } else { assignments.put(inputSymbol, new QualifiedNameReference(inputSymbol.toQualifiedName())); newSymbols.add(inputSymbol); } Field oldField = oldDescriptor.getFieldByIndex(i); newFields[i] = new Field( oldField.getRelationAlias(), oldField.getName(), coerceToTypes[i], oldField.isHidden()); } ProjectNode projectNode = new ProjectNode(idAllocator.getNextId(), plan.getRoot(), assignments.build()); return new RelationPlan( projectNode, new TupleDescriptor(newFields), newSymbols.build(), plan.getSampleWeight()); }
@Override protected RelationPlan visitUnion(Union node, Void context) { checkArgument(!node.getRelations().isEmpty(), "No relations specified for UNION"); List<Symbol> unionOutputSymbols = null; ImmutableList.Builder<PlanNode> sources = ImmutableList.builder(); ImmutableListMultimap.Builder<Symbol, Symbol> symbolMapping = ImmutableListMultimap.builder(); List<RelationPlan> subPlans = node.getRelations() .stream() .map(relation -> processAndCoerceIfNecessary(relation, context)) .collect(toImmutableList()); boolean hasSampleWeight = false; for (RelationPlan subPlan : subPlans) { if (subPlan.getSampleWeight().isPresent()) { hasSampleWeight = true; break; } } Optional<Symbol> outputSampleWeight = Optional.empty(); for (RelationPlan relationPlan : subPlans) { if (hasSampleWeight && !relationPlan.getSampleWeight().isPresent()) { relationPlan = addConstantSampleWeight(relationPlan); } List<Symbol> childOutputSymbols = relationPlan.getOutputSymbols(); if (unionOutputSymbols == null) { // Use the first Relation to derive output symbol names TupleDescriptor descriptor = relationPlan.getDescriptor(); ImmutableList.Builder<Symbol> outputSymbolBuilder = ImmutableList.builder(); for (Field field : descriptor.getVisibleFields()) { int fieldIndex = descriptor.indexOf(field); Symbol symbol = childOutputSymbols.get(fieldIndex); outputSymbolBuilder.add( symbolAllocator.newSymbol(symbol.getName(), symbolAllocator.getTypes().get(symbol))); } unionOutputSymbols = outputSymbolBuilder.build(); outputSampleWeight = relationPlan.getSampleWeight(); } TupleDescriptor descriptor = relationPlan.getDescriptor(); checkArgument( descriptor.getVisibleFieldCount() == unionOutputSymbols.size(), "Expected relation to have %s symbols but has %s symbols", descriptor.getVisibleFieldCount(), unionOutputSymbols.size()); int unionFieldId = 0; for (Field field : descriptor.getVisibleFields()) { int fieldIndex = descriptor.indexOf(field); symbolMapping.put(unionOutputSymbols.get(unionFieldId), childOutputSymbols.get(fieldIndex)); unionFieldId++; } sources.add(relationPlan.getRoot()); } PlanNode planNode = new UnionNode(idAllocator.getNextId(), sources.build(), symbolMapping.build()); if (node.isDistinct()) { planNode = distinct(planNode); } return new RelationPlan( planNode, analysis.getOutputDescriptor(node), planNode.getOutputSymbols(), outputSampleWeight); }