use of io.prestosql.spi.relation.RowExpression in project hetu-core by openlookeng.
the class SortExpressionExtractor method extractSortExpression.
public static Optional<SortExpressionContext> extractSortExpression(Metadata metadata, Set<Symbol> buildSymbols, RowExpression filter) {
List<RowExpression> filterConjuncts = extractConjuncts(filter);
SortExpressionVisitor visitor = new SortExpressionVisitor(buildSymbols, metadata.getFunctionAndTypeManager());
RowExpressionDeterminismEvaluator determinismEvaluator = new RowExpressionDeterminismEvaluator(metadata);
List<SortExpressionContext> sortExpressionCandidates = filterConjuncts.stream().filter(determinismEvaluator::isDeterministic).map(conjunct -> conjunct.accept(visitor, null)).filter(Optional::isPresent).map(Optional::get).collect(toMap(SortExpressionContext::getSortExpression, identity(), SortExpressionExtractor::merge)).values().stream().collect(toImmutableList());
// TODO: make it cost based decision based on symbol statistics
return sortExpressionCandidates.stream().sorted(comparing(context -> -1 * context.getSearchExpressions().size())).findFirst();
}
use of io.prestosql.spi.relation.RowExpression in project hetu-core by openlookeng.
the class RowExpressionEqualityInference method generateEqualitiesPartitionedBy.
/**
* Dumps the inference equalities as equality expressions that are partitioned by the variableScope.
* All stored equalities are returned in a compact set and will be classified into three groups as determined by the symbol scope:
* <ol>
* <li>equalities that fit entirely within the symbol scope</li>
* <li>equalities that fit entirely outside of the symbol scope</li>
* <li>equalities that straddle the symbol scope</li>
* </ol>
* <pre>
* Example:
* Stored Equalities:
* a = b = c
* d = e = f = g
*
* Symbol Scope:
* a, b, d, e
*
* Output EqualityPartition:
* Scope Equalities:
* a = b
* d = e
* Complement Scope Equalities
* f = g
* Scope Straddling Equalities
* a = c
* d = f
* </pre>
*/
public EqualityPartition generateEqualitiesPartitionedBy(Predicate<VariableReferenceExpression> variableScope) {
ImmutableSet.Builder<RowExpression> scopeEqualities = ImmutableSet.builder();
ImmutableSet.Builder<RowExpression> scopeComplementEqualities = ImmutableSet.builder();
ImmutableSet.Builder<RowExpression> scopeStraddlingEqualities = ImmutableSet.builder();
for (Collection<RowExpression> equalitySet : equalitySets.asMap().values()) {
Set<RowExpression> scopeExpressions = new LinkedHashSet<>();
Set<RowExpression> scopeComplementExpressions = new LinkedHashSet<>();
Set<RowExpression> scopeStraddlingExpressions = new LinkedHashSet<>();
// Try to push each non-derived expression into one side of the scope
for (RowExpression expression : filter(equalitySet, not(derivedExpressions::contains))) {
RowExpression scopeRewritten = rewriteExpression(expression, variableScope, false);
if (scopeRewritten != null) {
scopeExpressions.add(scopeRewritten);
}
RowExpression scopeComplementRewritten = rewriteExpression(expression, not(variableScope), false);
if (scopeComplementRewritten != null) {
scopeComplementExpressions.add(scopeComplementRewritten);
}
if (scopeRewritten == null && scopeComplementRewritten == null) {
scopeStraddlingExpressions.add(expression);
}
}
// Compile the equality expressions on each side of the scope
RowExpression matchingCanonical = getCanonical(scopeExpressions);
if (scopeExpressions.size() >= 2) {
for (RowExpression expression : filter(scopeExpressions, not(equalTo(matchingCanonical)))) {
scopeEqualities.add(buildEqualsExpression(functionAndTypeManager, matchingCanonical, expression));
}
}
RowExpression complementCanonical = getCanonical(scopeComplementExpressions);
if (scopeComplementExpressions.size() >= 2) {
for (RowExpression expression : filter(scopeComplementExpressions, not(equalTo(complementCanonical)))) {
scopeComplementEqualities.add(buildEqualsExpression(functionAndTypeManager, complementCanonical, expression));
}
}
// Compile the scope straddling equality expressions
List<RowExpression> connectingExpressions = new ArrayList<>();
connectingExpressions.add(matchingCanonical);
connectingExpressions.add(complementCanonical);
connectingExpressions.addAll(scopeStraddlingExpressions);
connectingExpressions = ImmutableList.copyOf(filter(connectingExpressions, Predicates.notNull()));
RowExpression connectingCanonical = getCanonical(connectingExpressions);
if (connectingCanonical != null) {
for (RowExpression expression : filter(connectingExpressions, not(equalTo(connectingCanonical)))) {
scopeStraddlingEqualities.add(buildEqualsExpression(functionAndTypeManager, connectingCanonical, expression));
}
}
}
return new EqualityPartition(scopeEqualities.build(), scopeComplementEqualities.build(), scopeStraddlingEqualities.build());
}
use of io.prestosql.spi.relation.RowExpression in project hetu-core by openlookeng.
the class RowExpressionVariableInliner method rewriteLambda.
@Override
public RowExpression rewriteLambda(LambdaDefinitionExpression node, Void context, RowExpressionTreeRewriter<Void> treeRewriter) {
checkArgument(!node.getArguments().stream().anyMatch(excludedNames::contains), "Lambda argument already contained in excluded names.");
excludedNames.addAll(node.getArguments());
RowExpression result = treeRewriter.defaultRewrite(node, context);
excludedNames.removeAll(node.getArguments());
return result;
}
use of io.prestosql.spi.relation.RowExpression in project hetu-core by openlookeng.
the class BenchmarkEqualsOperator method setup.
@Setup
public void setup() {
Metadata metadata = createTestMetadataManager();
ExpressionCompiler expressionCompiler = new ExpressionCompiler(metadata, new PageFunctionCompiler(metadata, 0));
RowExpression projection = generateComplexComparisonProjection(FIELDS_COUNT, COMPARISONS_COUNT);
compiledProcessor = expressionCompiler.compilePageProcessor(Optional.empty(), ImmutableList.of(projection)).get();
}
use of io.prestosql.spi.relation.RowExpression in project hetu-core by openlookeng.
the class FunctionAssertions method assertCachedInstanceHasBoundedRetainedSize.
public void assertCachedInstanceHasBoundedRetainedSize(String projection) {
requireNonNull(projection, "projection is null");
Expression projectionExpression = createExpression(session, projection, metadata, TypeProvider.copyOf(INPUT_TYPES));
RowExpression projectionRowExpression = toRowExpression(session, projectionExpression);
PageProcessor processor = compiler.compilePageProcessor(Optional.empty(), ImmutableList.of(projectionRowExpression)).get();
// This is a heuristic to detect whether the retained size of cachedInstance is bounded.
// * The test runs at least 1000 iterations.
// * The test passes if max retained size doesn't refresh after
// 4x the number of iterations when max was last updated.
// * The test fails if retained size reaches 1MB.
// Note that 1MB is arbitrarily chosen and may be increased if a function implementation
// legitimately needs more.
long maxRetainedSize = 0;
int maxIterationCount = 0;
for (int iterationCount = 0; iterationCount < Math.max(1000, maxIterationCount * 4); iterationCount++) {
Iterator<Optional<Page>> output = processor.process(session.toConnectorSession(), new DriverYieldSignal(), newSimpleAggregatedMemoryContext().newLocalMemoryContext(PageProcessor.class.getSimpleName()), SOURCE_PAGE);
// consume the iterator
Iterators.getOnlyElement(output);
long retainedSize = processor.getProjections().stream().mapToLong(this::getRetainedSizeOfCachedInstance).sum();
if (retainedSize > maxRetainedSize) {
maxRetainedSize = retainedSize;
maxIterationCount = iterationCount;
}
if (maxRetainedSize >= 1048576) {
fail(format("The retained size of cached instance of function invocation is likely unbounded: %s", projection));
}
}
}
Aggregations