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);
}
}
}
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;
}
}
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);
}
}
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;
}
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);
}
}
Aggregations