checkState(sourceTypeParameters.size() == resultTypeParameters.size()); for (int i = 0; i < sourceTypeParameters.size(); i++) { if (!isTypeOnlyCoercion(sourceTypeParameters.get(i), resultTypeParameters.get(i))) { return false;
@Test public void testIsTypeOnlyCoercion() { assertTrue(TypeRegistry.isTypeOnlyCoercion(BIGINT.getTypeSignature(), BIGINT.getTypeSignature())); assertTrue(TypeRegistry.isTypeOnlyCoercion(parseTypeSignature("varchar(42)"), parseTypeSignature("varchar(44)"))); assertFalse(TypeRegistry.isTypeOnlyCoercion(parseTypeSignature("varchar(44)"), parseTypeSignature("varchar(42)"))); assertTrue(TypeRegistry.isTypeOnlyCoercion(parseTypeSignature("array(varchar(42))"), parseTypeSignature("array(varchar(44))"))); assertFalse(TypeRegistry.isTypeOnlyCoercion(parseTypeSignature("array(varchar(44))"), parseTypeSignature("array(varchar(42))"))); }
private static boolean typesMatchForInsert(Iterable<Type> tableTypes, Iterable<Type> queryTypes) { if (Iterables.size(tableTypes) != Iterables.size(queryTypes)) { return false; } Iterator<Type> tableTypesIterator = tableTypes.iterator(); Iterator<Type> queryTypesIterator = queryTypes.iterator(); while (tableTypesIterator.hasNext()) { Type tableType = tableTypesIterator.next(); Type queryType = queryTypesIterator.next(); if (isStructuralType(tableType)) { if (!tableType.getTypeSignature().getBase().equals(queryType.getTypeSignature().getBase())) { return false; } if (!typesMatchForInsert(tableType.getTypeParameters(), queryType.getTypeParameters())) { return false; } } else { if (!Objects.equals(tableType, queryType) && !isTypeOnlyCoercion(queryType.getTypeSignature(), tableType.getTypeSignature())) { return false; } } } return true; }
private Map<Symbol, Expression> coerce(Iterable<? extends Expression> expressions, PlanBuilder subPlan, TranslationMap translations) { ImmutableMap.Builder<Symbol, Expression> projections = ImmutableMap.builder(); for (Expression expression : expressions) { Type type = analysis.getType(expression); Type coercion = analysis.getCoercion(expression); Symbol symbol = symbolAllocator.newSymbol(expression, firstNonNull(coercion, type)); Expression rewritten = subPlan.rewrite(expression); if (coercion != null) { rewritten = new Cast( rewritten, coercion.getTypeSignature().toString(), false, isTypeOnlyCoercion(type.getTypeSignature(), coercion.getTypeSignature())); } projections.put(symbol, rewritten); translations.put(expression, symbol); } return projections.build(); }
if (!isTypeOnlyCoercion(actualParameterSignature.get(), expectedParameterSignature.get())) { return false;
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()); }
@Override public Expression rewriteExpression(Expression node, Void context, ExpressionTreeRewriter<Void> treeRewriter) { Expression rewrittenExpression = treeRewriter.defaultRewrite(node, context); // cast expression if coercion is registered Type coercion = analysis.getCoercion(node); if (coercion != null) { Type type = analysis.getType(node); rewrittenExpression = new Cast( rewrittenExpression, coercion.getTypeSignature().toString(), false, isTypeOnlyCoercion(type.getTypeSignature(), coercion.getTypeSignature())); } return rewrittenExpression; }
@Override public Expression rewriteDereferenceExpression(DereferenceExpression node, Void context, ExpressionTreeRewriter<Void> treeRewriter) { if (analysis.getFieldIndex(node).isPresent()) { return rewriteExpressionWithResolvedName(node); } // Rewrite all row field reference to function call. QualifiedName mangledName = QualifiedName.of(mangleFieldReference(node.getFieldName())); FunctionCall functionCall = new FunctionCall(mangledName, ImmutableList.of(node.getBase())); // hackish - add type for created node to analysis object so further rewriting does not fail IdentityHashMap<Expression, Type> functionType = new IdentityHashMap<>(); functionType.put(functionCall, analysis.getType(node)); analysis.addTypes(functionType); Expression rewrittenExpression = rewriteFunctionCall(functionCall, context, treeRewriter); // cast expression if coercion is registered Type type = analysis.getType(node); Type coercion = analysis.getCoercion(node); if (coercion != null) { rewrittenExpression = new Cast( rewrittenExpression, coercion.getTypeSignature().toString(), false, isTypeOnlyCoercion(type.getTypeSignature(), coercion.getTypeSignature())); } return rewrittenExpression; } }, expression);
@Override public Expression rewriteExpression(Expression node, Void context, ExpressionTreeRewriter<Void> treeRewriter) { Expression rewrittenExpression = treeRewriter.defaultRewrite(node, context); // cast expression if coercion is registered Type type = analysis.getType(node); Type coercion = analysis.getCoercion(node); if (coercion != null) { rewrittenExpression = new Cast( rewrittenExpression, coercion.getTypeSignature().toString(), false, isTypeOnlyCoercion(type.getTypeSignature(), coercion.getTypeSignature())); } return rewrittenExpression; }