use of com.facebook.presto.metadata.Metadata in project presto by prestodb.
the class CreateFunctionTask method createSqlInvokedFunction.
private SqlInvokedFunction createSqlInvokedFunction(CreateFunction statement, Metadata metadata, Analysis analysis) {
QualifiedObjectName functionName = statement.isTemporary() ? QualifiedObjectName.valueOf(SESSION_NAMESPACE, statement.getFunctionName().getSuffix()) : qualifyObjectName(statement.getFunctionName());
List<Parameter> parameters = statement.getParameters().stream().map(parameter -> new Parameter(parameter.getName().toString(), parseTypeSignature(parameter.getType()))).collect(toImmutableList());
TypeSignature returnType = parseTypeSignature(statement.getReturnType());
String description = statement.getComment().orElse("");
RoutineCharacteristics routineCharacteristics = RoutineCharacteristics.builder().setLanguage(new RoutineCharacteristics.Language(statement.getCharacteristics().getLanguage().getLanguage())).setDeterminism(RoutineCharacteristics.Determinism.valueOf(statement.getCharacteristics().getDeterminism().name())).setNullCallClause(RoutineCharacteristics.NullCallClause.valueOf(statement.getCharacteristics().getNullCallClause().name())).build();
RoutineBody body = statement.getBody();
if (statement.getBody() instanceof Return) {
Expression bodyExpression = ((Return) statement.getBody()).getExpression();
Type bodyType = analysis.getType(bodyExpression);
// Coerce expressions in body if necessary
bodyExpression = ExpressionTreeRewriter.rewriteWith(new ExpressionRewriter<Void>() {
@Override
public Expression rewriteExpression(Expression expression, Void context, ExpressionTreeRewriter<Void> treeRewriter) {
Expression rewritten = treeRewriter.defaultRewrite(expression, null);
Type coercion = analysis.getCoercion(expression);
if (coercion != null) {
return new Cast(rewritten, coercion.getTypeSignature().toString(), false, analysis.isTypeOnlyCoercion(expression));
}
return rewritten;
}
}, bodyExpression, null);
if (!bodyType.equals(metadata.getType(returnType))) {
// Casting is safe here, since we have verified at analysis time that the actual type of the body is coercible to declared return type.
bodyExpression = new Cast(bodyExpression, statement.getReturnType());
}
body = new Return(bodyExpression);
}
return new SqlInvokedFunction(functionName, parameters, returnType, description, routineCharacteristics, formatSql(body, Optional.empty()), notVersioned());
}
use of com.facebook.presto.metadata.Metadata in project presto by prestodb.
the class TestRowBasedSerialization method setUp.
@BeforeClass
public void setUp() {
Metadata metadata = MetadataManager.createTestMetadataManager();
this.functionAndTypeManager = metadata.getFunctionAndTypeManager();
}
use of com.facebook.presto.metadata.Metadata in project presto by prestodb.
the class PropertyDerivations method deriveProperties.
public static ActualProperties deriveProperties(PlanNode node, List<ActualProperties> inputProperties, Metadata metadata, Session session, TypeProvider types, SqlParser parser) {
ActualProperties output = node.accept(new Visitor(metadata, session, types, parser), inputProperties);
output.getNodePartitioning().ifPresent(partitioning -> verify(node.getOutputVariables().containsAll(partitioning.getVariableReferences()), "Node-level partitioning properties contain columns not present in node's output"));
verify(node.getOutputVariables().containsAll(output.getConstants().keySet()), "Node-level constant properties contain columns not present in node's output");
Set<VariableReferenceExpression> localPropertyColumns = output.getLocalProperties().stream().flatMap(property -> property.getColumns().stream()).collect(Collectors.toSet());
verify(node.getOutputVariables().containsAll(localPropertyColumns), "Node-level local properties contain columns not present in node's output");
return output;
}
use of com.facebook.presto.metadata.Metadata in project presto by prestodb.
the class TranslateExpressions method createRewriter.
private static PlanRowExpressionRewriter createRewriter(Metadata metadata, SqlParser sqlParser) {
return new PlanRowExpressionRewriter() {
@Override
public RowExpression rewrite(RowExpression expression, Rule.Context context) {
// special treatment of the CallExpression in Aggregation
if (expression instanceof CallExpression && ((CallExpression) expression).getArguments().stream().anyMatch(OriginalExpressionUtils::isExpression)) {
return removeOriginalExpressionArguments((CallExpression) expression, context.getSession(), context.getVariableAllocator());
}
return removeOriginalExpression(expression, context);
}
private RowExpression removeOriginalExpressionArguments(CallExpression callExpression, Session session, PlanVariableAllocator variableAllocator) {
Map<NodeRef<Expression>, Type> types = analyzeCallExpressionTypes(callExpression, session, variableAllocator.getTypes());
return new CallExpression(callExpression.getSourceLocation(), callExpression.getDisplayName(), callExpression.getFunctionHandle(), callExpression.getType(), callExpression.getArguments().stream().map(expression -> removeOriginalExpression(expression, session, types)).collect(toImmutableList()));
}
private Map<NodeRef<Expression>, Type> analyzeCallExpressionTypes(CallExpression callExpression, Session session, TypeProvider typeProvider) {
List<LambdaExpression> lambdaExpressions = callExpression.getArguments().stream().filter(OriginalExpressionUtils::isExpression).map(OriginalExpressionUtils::castToExpression).filter(LambdaExpression.class::isInstance).map(LambdaExpression.class::cast).collect(toImmutableList());
ImmutableMap.Builder<NodeRef<Expression>, Type> builder = ImmutableMap.<NodeRef<Expression>, Type>builder();
if (!lambdaExpressions.isEmpty()) {
List<FunctionType> functionTypes = metadata.getFunctionAndTypeManager().getFunctionMetadata(callExpression.getFunctionHandle()).getArgumentTypes().stream().filter(typeSignature -> typeSignature.getBase().equals(FunctionType.NAME)).map(typeSignature -> (FunctionType) (metadata.getFunctionAndTypeManager().getType(typeSignature))).collect(toImmutableList());
InternalAggregationFunction internalAggregationFunction = metadata.getFunctionAndTypeManager().getAggregateFunctionImplementation(callExpression.getFunctionHandle());
List<Class> lambdaInterfaces = internalAggregationFunction.getLambdaInterfaces();
verify(lambdaExpressions.size() == functionTypes.size());
verify(lambdaExpressions.size() == lambdaInterfaces.size());
for (int i = 0; i < lambdaExpressions.size(); i++) {
LambdaExpression lambdaExpression = lambdaExpressions.get(i);
FunctionType functionType = functionTypes.get(i);
// To compile lambda, LambdaDefinitionExpression needs to be generated from LambdaExpression,
// which requires the types of all sub-expressions.
//
// In project and filter expression compilation, ExpressionAnalyzer.getExpressionTypesFromInput
// is used to generate the types of all sub-expressions. (see visitScanFilterAndProject and visitFilter)
//
// This does not work here since the function call representation in final aggregation node
// is currently a hack: it takes intermediate type as input, and may not be a valid
// function call in Presto.
//
// TODO: Once the final aggregation function call representation is fixed,
// the same mechanism in project and filter expression should be used here.
verify(lambdaExpression.getArguments().size() == functionType.getArgumentTypes().size());
Map<NodeRef<Expression>, Type> lambdaArgumentExpressionTypes = new HashMap<>();
Map<String, Type> lambdaArgumentSymbolTypes = new HashMap<>();
for (int j = 0; j < lambdaExpression.getArguments().size(); j++) {
LambdaArgumentDeclaration argument = lambdaExpression.getArguments().get(j);
Type type = functionType.getArgumentTypes().get(j);
lambdaArgumentExpressionTypes.put(NodeRef.of(argument), type);
lambdaArgumentSymbolTypes.put(argument.getName().getValue(), type);
}
// the lambda expression itself
builder.put(NodeRef.of(lambdaExpression), functionType).putAll(lambdaArgumentExpressionTypes).putAll(getExpressionTypes(session, metadata, sqlParser, TypeProvider.copyOf(lambdaArgumentSymbolTypes), lambdaExpression.getBody(), emptyList(), NOOP));
}
}
for (RowExpression argument : callExpression.getArguments()) {
if (!isExpression(argument) || castToExpression(argument) instanceof LambdaExpression) {
continue;
}
builder.putAll(analyze(castToExpression(argument), session, typeProvider));
}
return builder.build();
}
private Map<NodeRef<Expression>, Type> analyze(Expression expression, Session session, TypeProvider typeProvider) {
return getExpressionTypes(session, metadata, sqlParser, typeProvider, expression, emptyList(), NOOP);
}
private RowExpression toRowExpression(Expression expression, Session session, Map<NodeRef<Expression>, Type> types) {
return SqlToRowExpressionTranslator.translate(expression, types, ImmutableMap.of(), metadata.getFunctionAndTypeManager(), session);
}
private RowExpression removeOriginalExpression(RowExpression expression, Rule.Context context) {
if (isExpression(expression)) {
return toRowExpression(castToExpression(expression), context.getSession(), analyze(castToExpression(expression), context.getSession(), context.getVariableAllocator().getTypes()));
}
return expression;
}
private RowExpression removeOriginalExpression(RowExpression rowExpression, Session session, Map<NodeRef<Expression>, Type> types) {
if (isExpression(rowExpression)) {
Expression expression = castToExpression(rowExpression);
return toRowExpression(expression, session, types);
}
return rowExpression;
}
};
}
use of com.facebook.presto.metadata.Metadata in project presto by prestodb.
the class AbstractAnalyzerTest method createTestingCatalog.
private Catalog createTestingCatalog(String catalogName, ConnectorId connectorId) {
ConnectorId systemId = createSystemTablesConnectorId(connectorId);
Connector connector = AbstractAnalyzerTest.createTestingConnector();
InternalNodeManager nodeManager = new InMemoryNodeManager();
return new Catalog(catalogName, connectorId, connector, createInformationSchemaConnectorId(connectorId), new InformationSchemaConnector(catalogName, nodeManager, metadata, accessControl, ImmutableList.of()), systemId, new SystemConnector(systemId, nodeManager, connector.getSystemTables(), transactionId -> transactionManager.getConnectorTransaction(transactionId, connectorId)));
}
Aggregations