Search in sources :

Example 1 with FilterQueryTree

use of com.linkedin.pinot.common.utils.request.FilterQueryTree in project pinot by linkedin.

the class RangeMergeOptimizerTest method compareTrees.

/**
   * Helper method to compare two filter query trees
   * @param actualTree Actual tree
   * @param expectedTree Expected tree
   */
private void compareTrees(FilterQueryTree actualTree, FilterQueryTree expectedTree) {
    Assert.assertNotNull(actualTree);
    Assert.assertNotNull(expectedTree);
    Assert.assertEquals(actualTree.getOperator(), expectedTree.getOperator());
    Assert.assertEquals(actualTree.getColumn(), expectedTree.getColumn());
    Assert.assertEquals(actualTree.getValue(), expectedTree.getValue());
    List<FilterQueryTree> actualChildren = actualTree.getChildren();
    List<FilterQueryTree> expectedChildren = expectedTree.getChildren();
    if (expectedChildren != null) {
        Assert.assertNotNull(actualChildren);
        Assert.assertEquals(actualChildren.size(), expectedChildren.size());
        Map<String, FilterQueryTree> expectedSet = new HashMap<>(expectedChildren.size());
        for (FilterQueryTree expectedChild : expectedChildren) {
            expectedSet.put(expectedChild.getColumn(), expectedChild);
        }
        for (FilterQueryTree actualChild : actualChildren) {
            FilterQueryTree expectedChild = expectedSet.get(actualChild.getColumn());
            compareTrees(actualChild, expectedChild);
        }
    }
}
Also used : FilterQueryTree(com.linkedin.pinot.common.utils.request.FilterQueryTree) HashMap(java.util.HashMap)

Example 2 with FilterQueryTree

use of com.linkedin.pinot.common.utils.request.FilterQueryTree in project pinot by linkedin.

the class RangeMergeOptimizerTest method buildFilterQueryTree.

/**
   * Helper method to build the filter query tree for the given query
   * @param query Query for which to build the filter query tree
   * @param optimize If true, then range optimization is performed
   * @return Filter query tree for the query
   */
private FilterQueryTree buildFilterQueryTree(String query, boolean optimize) {
    BrokerRequest brokerRequest = _compiler.compileToBrokerRequest(query);
    FilterQueryTree filterQueryTree = RequestUtils.generateFilterQueryTree(brokerRequest);
    if (optimize) {
        FilterQueryOptimizerRequest request = _builder.setFilterQueryTree(filterQueryTree).setTimeColumn(TIME_COLUMN).build();
        return _optimizer.optimize(request);
    } else {
        return filterQueryTree;
    }
}
Also used : FilterQueryTree(com.linkedin.pinot.common.utils.request.FilterQueryTree) BrokerRequest(com.linkedin.pinot.common.request.BrokerRequest)

Example 3 with FilterQueryTree

use of com.linkedin.pinot.common.utils.request.FilterQueryTree in project pinot by linkedin.

the class MultipleOrEqualitiesToInClauseFilterQueryTreeOptimizer method applyOptimizationToChildNodes.

private void applyOptimizationToChildNodes(FilterQueryTree filterQueryTree) {
    Iterator<FilterQueryTree> childTreeIterator = filterQueryTree.getChildren().iterator();
    List<FilterQueryTree> childrenToAdd = null;
    while (childTreeIterator.hasNext()) {
        FilterQueryTree childQueryTree = childTreeIterator.next();
        FilterQueryTree optimizedChildQueryTree = optimize(childQueryTree, filterQueryTree);
        if (childQueryTree != optimizedChildQueryTree) {
            childTreeIterator.remove();
            if (childrenToAdd == null) {
                childrenToAdd = new ArrayList<>();
            }
            childrenToAdd.add(optimizedChildQueryTree);
        }
    }
    if (childrenToAdd != null) {
        filterQueryTree.getChildren().addAll(childrenToAdd);
    }
}
Also used : FilterQueryTree(com.linkedin.pinot.common.utils.request.FilterQueryTree)

Example 4 with FilterQueryTree

use of com.linkedin.pinot.common.utils.request.FilterQueryTree in project pinot by linkedin.

the class MultipleOrEqualitiesToInClauseFilterQueryTreeOptimizer method collectChildOperators.

private boolean collectChildOperators(FilterQueryTree filterQueryTree, Map<String, Set<String>> columnToValues, List<FilterQueryTree> nonEqualityOperators) {
    boolean containsDuplicates = false;
    for (FilterQueryTree childQueryTree : filterQueryTree.getChildren()) {
        if (childQueryTree.getOperator() == FilterOperator.EQUALITY || childQueryTree.getOperator() == FilterOperator.IN) {
            List<String> childValues = valueDoubleTabListToElements(childQueryTree.getValue());
            if (!columnToValues.containsKey(childQueryTree.getColumn())) {
                TreeSet<String> value = new TreeSet<>(childValues);
                columnToValues.put(childQueryTree.getColumn(), value);
                if (!containsDuplicates && value.size() != childValues.size()) {
                    containsDuplicates = true;
                }
            } else {
                Set<String> currentValues = columnToValues.get(childQueryTree.getColumn());
                for (String childValue : childValues) {
                    if (!containsDuplicates && currentValues.contains(childValue)) {
                        containsDuplicates = true;
                    } else {
                        currentValues.add(childValue);
                    }
                }
            }
        } else {
            nonEqualityOperators.add(childQueryTree);
        }
    }
    return containsDuplicates;
}
Also used : FilterQueryTree(com.linkedin.pinot.common.utils.request.FilterQueryTree) TreeSet(java.util.TreeSet)

Example 5 with FilterQueryTree

use of com.linkedin.pinot.common.utils.request.FilterQueryTree in project pinot by linkedin.

the class RangeMergeOptimizer method optimizeRanges.

/**
   * Recursive method that performs the actual optimization of merging range predicates.
   *
   * @param current Current node being visited in the DFS of the filter query tree.
   * @param timeColumn Name of time column
   * @return Returns the optimized filter query tree
   */
@Nonnull
private static FilterQueryTree optimizeRanges(@Nonnull FilterQueryTree current, @Nullable String timeColumn) {
    if (timeColumn == null) {
        return current;
    }
    List<FilterQueryTree> children = current.getChildren();
    if (children == null || children.isEmpty()) {
        return current;
    }
    // For OR, we optimize all its children, but do not propagate up.
    FilterOperator operator = current.getOperator();
    if (operator == FilterOperator.OR) {
        int length = children.size();
        for (int i = 0; i < length; i++) {
            children.set(i, optimizeRanges(children.get(i), timeColumn));
        }
        return current;
    }
    // After this point, since the node has children, it can only be an 'AND' node (only OR/AND supported).
    assert operator == FilterOperator.AND;
    List<FilterQueryTree> newChildren = new ArrayList<>();
    List<String> intersect = null;
    for (FilterQueryTree child : children) {
        FilterQueryTree newChild = optimizeRanges(child, timeColumn);
        if (newChild.getOperator() == FilterOperator.RANGE && newChild.getColumn().equals(timeColumn)) {
            List<String> value = newChild.getValue();
            intersect = (intersect == null) ? value : intersectRanges(intersect, value);
        } else {
            newChildren.add(newChild);
        }
    }
    if (newChildren.isEmpty()) {
        return new FilterQueryTree(timeColumn, intersect, FilterOperator.RANGE, null);
    } else {
        if (intersect != null) {
            newChildren.add(new FilterQueryTree(timeColumn, intersect, FilterOperator.RANGE, null));
        }
        return new FilterQueryTree(null, null, FilterOperator.AND, newChildren);
    }
}
Also used : FilterOperator(com.linkedin.pinot.common.request.FilterOperator) FilterQueryTree(com.linkedin.pinot.common.utils.request.FilterQueryTree) ArrayList(java.util.ArrayList) Nonnull(javax.annotation.Nonnull)

Aggregations

FilterQueryTree (com.linkedin.pinot.common.utils.request.FilterQueryTree)24 BrokerRequest (com.linkedin.pinot.common.request.BrokerRequest)7 FilterOperator (com.linkedin.pinot.common.request.FilterOperator)6 ArrayList (java.util.ArrayList)5 Pql2Compiler (com.linkedin.pinot.pql.parsers.Pql2Compiler)4 BaseFilterOperator (com.linkedin.pinot.core.operator.filter.BaseFilterOperator)3 Test (org.testng.annotations.Test)3 GroupBy (com.linkedin.pinot.common.request.GroupBy)2 SegmentMetadata (com.linkedin.pinot.common.segment.SegmentMetadata)2 BitmapBasedFilterOperator (com.linkedin.pinot.core.operator.filter.BitmapBasedFilterOperator)2 EmptyFilterOperator (com.linkedin.pinot.core.operator.filter.EmptyFilterOperator)2 MatchEntireSegmentOperator (com.linkedin.pinot.core.operator.filter.MatchEntireSegmentOperator)2 ScanBasedFilterOperator (com.linkedin.pinot.core.operator.filter.ScanBasedFilterOperator)2 SortedInvertedIndexBasedFilterOperator (com.linkedin.pinot.core.operator.filter.SortedInvertedIndexBasedFilterOperator)2 ColumnMetadata (com.linkedin.pinot.core.segment.index.ColumnMetadata)2 Pql2CompilationException (com.linkedin.pinot.pql.parsers.Pql2CompilationException)2 HashMap (java.util.HashMap)2 TreeSet (java.util.TreeSet)2 VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 FieldSpec (com.linkedin.pinot.common.data.FieldSpec)1