@Override protected RelationPlan visitValues(Values node, Void context) { TupleDescriptor descriptor = analysis.getOutputDescriptor(node); ImmutableList.Builder<Symbol> outputSymbolsBuilder = ImmutableList.builder(); for (Field field : descriptor.getVisibleFields()) { Symbol symbol = symbolAllocator.newSymbol(field); outputSymbolsBuilder.add(symbol); } ImmutableList.Builder<List<Expression>> rows = ImmutableList.builder(); for (Expression row : node.getRows()) { ImmutableList.Builder<Expression> values = ImmutableList.builder(); if (row instanceof Row) { List<Expression> items = ((Row) row).getItems(); for (int i = 0; i < items.size(); i++) { Expression expression = items.get(i); Object constantValue = evaluateConstantExpression(expression, analysis.getCoercions(), metadata, session); values.add( LiteralInterpreter.toExpression( constantValue, descriptor.getFieldByIndex(i).getType())); } } else { Object constantValue = evaluateConstantExpression(row, analysis.getCoercions(), metadata, session); values.add( LiteralInterpreter.toExpression( constantValue, descriptor.getFieldByIndex(0).getType())); } rows.add(values.build()); } ValuesNode valuesNode = new ValuesNode(idAllocator.getNextId(), outputSymbolsBuilder.build(), rows.build()); return new RelationPlan(valuesNode, descriptor, outputSymbolsBuilder.build(), Optional.empty()); }
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()); }