use of io.trino.metadata.ResolvedFunction in project trino by trinodb.
the class AbstractTestAggregationFunction method testSlidingWindow.
@Test
public void testSlidingWindow() {
// Builds trailing windows of length 0, 1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 0
int totalPositions = 12;
int[] windowWidths = new int[totalPositions];
Object[] expectedValues = new Object[totalPositions];
for (int i = 0; i < totalPositions; ++i) {
int windowWidth = Integer.min(i, totalPositions - 1 - i);
windowWidths[i] = windowWidth;
expectedValues[i] = getExpectedValue(i, windowWidth);
}
Page inputPage = new Page(totalPositions, getSequenceBlocks(0, totalPositions));
PagesIndex pagesIndex = new PagesIndex.TestingFactory(false).newPagesIndex(getFunctionParameterTypes(), totalPositions);
pagesIndex.addPage(inputPage);
WindowIndex windowIndex = new PagesWindowIndex(pagesIndex, 0, totalPositions - 1);
ResolvedFunction resolvedFunction = functionResolution.resolveFunction(QualifiedName.of(getFunctionName()), fromTypes(getFunctionParameterTypes()));
AggregationMetadata aggregationMetadata = functionResolution.getPlannerContext().getFunctionManager().getAggregateFunctionImplementation(resolvedFunction);
WindowAccumulator aggregation = createWindowAccumulator(resolvedFunction, aggregationMetadata);
int oldStart = 0;
int oldWidth = 0;
for (int start = 0; start < totalPositions; ++start) {
int width = windowWidths[start];
// Note that add/removeInput's interval is inclusive on both ends
if (aggregationMetadata.getRemoveInputFunction().isPresent()) {
for (int oldi = oldStart; oldi < oldStart + oldWidth; ++oldi) {
if (oldi < start || oldi >= start + width) {
aggregation.removeInput(windowIndex, oldi, oldi);
}
}
for (int newi = start; newi < start + width; ++newi) {
if (newi < oldStart || newi >= oldStart + oldWidth) {
aggregation.addInput(windowIndex, newi, newi);
}
}
} else {
aggregation = createWindowAccumulator(resolvedFunction, aggregationMetadata);
aggregation.addInput(windowIndex, start, start + width - 1);
}
oldStart = start;
oldWidth = width;
Type outputType = resolvedFunction.getSignature().getReturnType();
BlockBuilder blockBuilder = outputType.createBlockBuilder(null, 1000);
aggregation.evaluateFinal(blockBuilder);
Block block = blockBuilder.build();
assertThat(makeValidityAssertion(expectedValues[start]).apply(BlockAssertions.getOnlyValue(outputType, block), expectedValues[start])).isTrue();
}
}
use of io.trino.metadata.ResolvedFunction in project trino by trinodb.
the class ExpressionTestUtils method resolveFunctionCalls.
public static Expression resolveFunctionCalls(PlannerContext plannerContext, Session session, TypeProvider typeProvider, Expression expression, Scope scope) {
ExpressionAnalyzer analyzer = ExpressionAnalyzer.createWithoutSubqueries(plannerContext, new AllowAllAccessControl(), session, typeProvider, ImmutableMap.of(), node -> semanticException(EXPRESSION_NOT_CONSTANT, node, "Constant expression cannot contain a subquery"), WarningCollector.NOOP, false);
analyzer.analyze(expression, scope);
return ExpressionTreeRewriter.rewriteWith(new ExpressionRewriter<>() {
@Override
public Expression rewriteFunctionCall(FunctionCall node, Void context, ExpressionTreeRewriter<Void> treeRewriter) {
ResolvedFunction resolvedFunction = analyzer.getResolvedFunctions().get(NodeRef.of(node));
checkArgument(resolvedFunction != null, "Function has not been analyzed: %s", node);
FunctionCall rewritten = treeRewriter.defaultRewrite(node, context);
FunctionCall newFunctionCall = new FunctionCall(rewritten.getLocation(), resolvedFunction.toQualifiedName(), rewritten.getWindow(), rewritten.getFilter(), rewritten.getOrderBy(), rewritten.isDistinct(), rewritten.getNullTreatment(), rewritten.getProcessingMode(), rewritten.getArguments());
return coerceIfNecessary(node, newFunctionCall);
}
@Override
protected Expression rewriteExpression(Expression node, Void context, ExpressionTreeRewriter<Void> treeRewriter) {
Expression rewrittenExpression = treeRewriter.defaultRewrite(node, context);
rewrittenExpression = coerceIfNecessary(node, rewrittenExpression);
return rewrittenExpression;
}
private Expression coerceIfNecessary(Expression originalExpression, Expression rewrittenExpression) {
// cast expression if coercion is registered
Type coercion = analyzer.getExpressionCoercions().get(NodeRef.of(originalExpression));
if (coercion != null) {
rewrittenExpression = new Cast(rewrittenExpression, toSqlType(coercion), false, analyzer.getTypeOnlyCoercions().contains(NodeRef.of(originalExpression)));
}
return rewrittenExpression;
}
}, expression);
}
use of io.trino.metadata.ResolvedFunction in project trino by trinodb.
the class TestExpressionOptimizer method testCastWithJsonParseOptimization.
private void testCastWithJsonParseOptimization(ResolvedFunction jsonParseFunction, Type targetType, String jsonStringToRowName) {
ResolvedFunction jsonCastFunction = functionResolution.getCoercion(JSON, targetType);
RowExpression jsonCastExpression = new CallExpression(jsonCastFunction, ImmutableList.of(call(jsonParseFunction, field(1, VARCHAR))));
RowExpression resultExpression = optimizer.optimize(jsonCastExpression);
assertEquals(resultExpression, call(functionResolution.getCoercion(QualifiedName.of(jsonStringToRowName), VARCHAR, targetType), field(1, VARCHAR)));
}
use of io.trino.metadata.ResolvedFunction in project trino by trinodb.
the class TestPrunePattenRecognitionColumns method testPruneUnreferencedWindowFunctionAndSources.
@Test
public void testPruneUnreferencedWindowFunctionAndSources() {
ResolvedFunction lag = createTestMetadataManager().resolveFunction(tester().getSession(), QualifiedName.of("lag"), fromTypes(BIGINT));
// remove window function "lag" and input symbol "b" used only by that function
tester().assertThat(new PrunePattenRecognitionColumns()).on(p -> p.project(Assignments.identity(p.symbol("measure")), p.patternRecognition(builder -> builder.addWindowFunction(p.symbol("lag"), new WindowNode.Function(lag, ImmutableList.of(p.symbol("b").toSymbolReference()), DEFAULT_FRAME, false)).addMeasure(p.symbol("measure"), "LAST(X.a)", BIGINT).rowsPerMatch(WINDOW).frame(new WindowNode.Frame(ROWS, CURRENT_ROW, Optional.empty(), Optional.empty(), UNBOUNDED_FOLLOWING, Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty())).skipTo(NEXT).pattern(new IrLabel("X")).addVariableDefinition(new IrLabel("X"), "true").source(p.values(p.symbol("a"), p.symbol("b")))))).matches(strictProject(ImmutableMap.of("measure", expression("measure")), patternRecognition(builder -> builder.addMeasure("measure", "LAST(X.a)", BIGINT).rowsPerMatch(WINDOW).frame(windowFrame(ROWS, CURRENT_ROW, Optional.empty(), UNBOUNDED_FOLLOWING, Optional.empty(), Optional.empty())).skipTo(NEXT).pattern(new IrLabel("X")).addVariableDefinition(new IrLabel("X"), "true"), strictProject(ImmutableMap.of("a", expression("a")), values("a", "b")))));
}
use of io.trino.metadata.ResolvedFunction in project trino by trinodb.
the class TestPrunePattenRecognitionColumns method testPruneUnreferencedMeasureAndSources.
@Test
public void testPruneUnreferencedMeasureAndSources() {
ResolvedFunction lag = createTestMetadataManager().resolveFunction(tester().getSession(), QualifiedName.of("lag"), fromTypes(BIGINT));
// remove row pattern measure "measure" and input symbol "a" used only by that measure
tester().assertThat(new PrunePattenRecognitionColumns()).on(p -> p.project(Assignments.identity(p.symbol("lag")), p.patternRecognition(builder -> builder.addWindowFunction(p.symbol("lag"), new WindowNode.Function(lag, ImmutableList.of(p.symbol("b").toSymbolReference()), DEFAULT_FRAME, false)).addMeasure(p.symbol("measure"), "LAST(X.a)", BIGINT).rowsPerMatch(WINDOW).frame(new WindowNode.Frame(ROWS, CURRENT_ROW, Optional.empty(), Optional.empty(), UNBOUNDED_FOLLOWING, Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty())).skipTo(NEXT).pattern(new IrLabel("X")).addVariableDefinition(new IrLabel("X"), "true").source(p.values(p.symbol("a"), p.symbol("b")))))).matches(strictProject(ImmutableMap.of("lag", expression("lag")), patternRecognition(builder -> builder.addFunction("lag", functionCall("lag", ImmutableList.of("b"))).rowsPerMatch(WINDOW).frame(windowFrame(ROWS, CURRENT_ROW, Optional.empty(), UNBOUNDED_FOLLOWING, Optional.empty(), Optional.empty())).skipTo(NEXT).pattern(new IrLabel("X")).addVariableDefinition(new IrLabel("X"), "true"), strictProject(ImmutableMap.of("b", expression("b")), values("a", "b")))));
}
Aggregations