use of io.trino.sql.tree.GenericLiteral in project trino by trinodb.
the class ImplementExceptDistinctAsUnion method apply.
@Override
public Result apply(ExceptNode node, Captures captures, Context context) {
SetOperationNodeTranslator translator = new SetOperationNodeTranslator(context.getSession(), metadata, context.getSymbolAllocator(), context.getIdAllocator());
SetOperationNodeTranslator.TranslationResult result = translator.makeSetContainmentPlanForDistinct(node);
// except predicate: the row must be present in the first source and absent in all the other sources
ImmutableList.Builder<Expression> predicatesBuilder = ImmutableList.builder();
predicatesBuilder.add(new ComparisonExpression(GREATER_THAN_OR_EQUAL, result.getCountSymbols().get(0).toSymbolReference(), new GenericLiteral("BIGINT", "1")));
for (int i = 1; i < node.getSources().size(); i++) {
predicatesBuilder.add(new ComparisonExpression(EQUAL, result.getCountSymbols().get(i).toSymbolReference(), new GenericLiteral("BIGINT", "0")));
}
return Result.ofPlanNode(new ProjectNode(context.getIdAllocator().getNextId(), new FilterNode(context.getIdAllocator().getNextId(), result.getPlanNode(), and(predicatesBuilder.build())), Assignments.identity(node.getOutputSymbols())));
}
use of io.trino.sql.tree.GenericLiteral in project trino by trinodb.
the class ImplementLimitWithTies method rewriteLimitWithTiesWithPartitioning.
/**
* Rewrite LimitNode with ties to WindowNode and FilterNode, with partitioning defined by partitionBy.
* <p>
* This method does not prune outputs of the rewritten plan. After the rewrite, the output consists of
* source's output symbols and the newly created rankSymbol.
* Passing all input symbols is intentional, because this method is used for de-correlation in the scenario
* where the original LimitNode is in the correlated subquery, and the rewrite result is placed on top of
* de-correlated join.
* It is the responsibility of the caller to prune redundant outputs.
*/
public static PlanNode rewriteLimitWithTiesWithPartitioning(LimitNode limitNode, PlanNode source, Session session, Metadata metadata, PlanNodeIdAllocator idAllocator, SymbolAllocator symbolAllocator, List<Symbol> partitionBy) {
checkArgument(limitNode.isWithTies(), "Expected LimitNode with ties");
Symbol rankSymbol = symbolAllocator.newSymbol("rank_num", BIGINT);
WindowNode.Function rankFunction = new WindowNode.Function(metadata.resolveFunction(session, QualifiedName.of("rank"), ImmutableList.of()), ImmutableList.of(), DEFAULT_FRAME, false);
WindowNode windowNode = new WindowNode(idAllocator.getNextId(), source, new WindowNode.Specification(partitionBy, limitNode.getTiesResolvingScheme()), ImmutableMap.of(rankSymbol, rankFunction), Optional.empty(), ImmutableSet.of(), 0);
return new FilterNode(idAllocator.getNextId(), windowNode, new ComparisonExpression(ComparisonExpression.Operator.LESS_THAN_OR_EQUAL, rankSymbol.toSymbolReference(), new GenericLiteral("BIGINT", Long.toString(limitNode.getCount()))));
}
use of io.trino.sql.tree.GenericLiteral in project trino by trinodb.
the class HashGenerationOptimizer method getHashExpression.
public static Optional<Expression> getHashExpression(Session session, Metadata metadata, SymbolAllocator symbolAllocator, List<Symbol> symbols) {
if (symbols.isEmpty()) {
return Optional.empty();
}
Expression result = new GenericLiteral(StandardTypes.BIGINT, String.valueOf(INITIAL_HASH_VALUE));
for (Symbol symbol : symbols) {
Expression hashField = FunctionCallBuilder.resolve(session, metadata).setName(QualifiedName.of(HASH_CODE)).addArgument(symbolAllocator.getTypes().get(symbol), new SymbolReference(symbol.getName())).build();
hashField = new CoalesceExpression(hashField, new LongLiteral(String.valueOf(NULL_HASH_CODE)));
result = FunctionCallBuilder.resolve(session, metadata).setName(QualifiedName.of("combine_hash")).addArgument(BIGINT, result).addArgument(BIGINT, hashField).build();
}
return Optional.of(result);
}
use of io.trino.sql.tree.GenericLiteral in project trino by trinodb.
the class TestDereferencePushDown method testDereferencePushdownJoin.
@Test
public void testDereferencePushdownJoin() {
// dereference pushdown + constant folding
assertPlan("WITH t(msg) AS (VALUES ROW(CAST(ROW(1, 2.0) AS ROW(x BIGINT, y DOUBLE))))" + "SELECT b.msg.x " + "FROM t a, t b " + "WHERE a.msg.y = b.msg.y", output(project(ImmutableMap.of("b_x", expression("b_x")), filter("a_y = b_y", values(ImmutableList.of("b_x", "b_y", "a_y"), ImmutableList.of(ImmutableList.of(new GenericLiteral("BIGINT", "1"), new DoubleLiteral("2e0"), new DoubleLiteral("2e0"))))))));
assertPlan("WITH t(msg) AS (VALUES ROW(CAST(ROW(1, 2.0) AS ROW(x BIGINT, y DOUBLE))))" + "SELECT a.msg.y " + "FROM t a JOIN t b ON a.msg.y = b.msg.y " + "WHERE a.msg.x > BIGINT '5'", output(ImmutableList.of("a_y"), join(INNER, ImmutableList.of(), values("a_y"), values())));
assertPlan("WITH t(msg) AS (VALUES ROW(CAST(ROW(1, 2.0) AS ROW(x BIGINT, y DOUBLE))))" + "SELECT b.msg.x " + "FROM t a JOIN t b ON a.msg.y = b.msg.y " + "WHERE a.msg.x + b.msg.x < BIGINT '10'", output(ImmutableList.of("b_x"), join(INNER, ImmutableList.of(), project(filter("a_y = 2e0", values(ImmutableList.of("a_y"), ImmutableList.of(ImmutableList.of(new DoubleLiteral("2e0")))))), project(filter("b_y = 2e0", values(ImmutableList.of("b_x", "b_y"), ImmutableList.of(ImmutableList.of(new GenericLiteral("BIGINT", "1"), new DoubleLiteral("2e0")))))))));
}
use of io.trino.sql.tree.GenericLiteral in project trino by trinodb.
the class QueryPlanner method planFrameOffset.
private FrameOffsetPlanAndSymbol planFrameOffset(PlanBuilder subPlan, Optional<Symbol> frameOffset) {
if (frameOffset.isEmpty()) {
return new FrameOffsetPlanAndSymbol(subPlan, Optional.empty());
}
Symbol offsetSymbol = frameOffset.get();
Type offsetType = symbolAllocator.getTypes().get(offsetSymbol);
// Append filter to validate offset values. They mustn't be negative or null.
Expression zeroOffset = zeroOfType(offsetType);
ResolvedFunction fail = plannerContext.getMetadata().resolveFunction(session, QualifiedName.of("fail"), fromTypes(VARCHAR));
Expression predicate = new IfExpression(new ComparisonExpression(GREATER_THAN_OR_EQUAL, offsetSymbol.toSymbolReference(), zeroOffset), TRUE_LITERAL, new Cast(new FunctionCall(fail.toQualifiedName(), ImmutableList.of(new Cast(new StringLiteral("Window frame offset value must not be negative or null"), toSqlType(VARCHAR)))), toSqlType(BOOLEAN)));
subPlan = subPlan.withNewRoot(new FilterNode(idAllocator.getNextId(), subPlan.getRoot(), predicate));
if (offsetType.equals(BIGINT)) {
return new FrameOffsetPlanAndSymbol(subPlan, Optional.of(offsetSymbol));
}
Expression offsetToBigint;
if (offsetType instanceof DecimalType && !((DecimalType) offsetType).isShort()) {
String maxBigint = Long.toString(Long.MAX_VALUE);
int maxBigintPrecision = maxBigint.length();
int actualPrecision = ((DecimalType) offsetType).getPrecision();
if (actualPrecision < maxBigintPrecision) {
offsetToBigint = new Cast(offsetSymbol.toSymbolReference(), toSqlType(BIGINT));
} else if (actualPrecision > maxBigintPrecision) {
// If the offset value exceeds max bigint, it implies that the frame bound falls beyond the partition bound.
// In such case, the frame bound is set to the partition bound. Passing max bigint as the offset value has
// the same effect. The offset value can be truncated to max bigint for the purpose of cast.
offsetToBigint = new GenericLiteral("BIGINT", maxBigint);
} else {
offsetToBigint = new IfExpression(new ComparisonExpression(LESS_THAN_OR_EQUAL, offsetSymbol.toSymbolReference(), new DecimalLiteral(maxBigint)), new Cast(offsetSymbol.toSymbolReference(), toSqlType(BIGINT)), new GenericLiteral("BIGINT", maxBigint));
}
} else {
offsetToBigint = new Cast(offsetSymbol.toSymbolReference(), toSqlType(BIGINT), false, typeCoercion.isTypeOnlyCoercion(offsetType, BIGINT));
}
Symbol coercedOffsetSymbol = symbolAllocator.newSymbol(offsetToBigint, BIGINT);
subPlan = subPlan.withNewRoot(new ProjectNode(idAllocator.getNextId(), subPlan.getRoot(), Assignments.builder().putIdentities(subPlan.getRoot().getOutputSymbols()).put(coercedOffsetSymbol, offsetToBigint).build()));
return new FrameOffsetPlanAndSymbol(subPlan, Optional.of(coercedOffsetSymbol));
}
Aggregations