@Override public LogicalNode visitFilter(FilterPushDownContext context, LogicalPlan plan, LogicalPlan.QueryBlock block, SelectionNode selNode, Stack<LogicalNode> stack) throws TajoException { context.pushingDownFilters.addAll(new HashSet<>(Arrays.asList(AlgebraicUtil.toConjunctiveNormalFormArray(selNode.getQual())))); selNode.setQual(AlgebraicUtil.createSingletonExprFromCNF(matched.toArray(new EvalNode[matched.size()]))); context.pushingDownFilters.removeAll(matched);
/** * Check if an expression consists of one variable and one constant and * the expression is a comparison operator. * * @param evalNode The expression to be checked * @return true if an expression consists of one variable and one constant * and the expression is a comparison operator. Other, false. */ private boolean checkIfIndexablePredicate(EvalNode evalNode) { // TODO - LIKE with a trailing wild-card character and IN with an array can be indexable return AlgebraicUtil.containSingleVar(evalNode) && AlgebraicUtil.isIndexableOperator(evalNode); }
public List<Set<EvalNode>> findIndexablePredicateSet(@Nullable EvalNode qual, Column[] indexableColumns) throws IOException { List<Set<EvalNode>> indexablePredicateList = new ArrayList<>(); // if a query statement has a search condition, try to find indexable predicates if (indexableColumns != null && qual != null) { EvalNode[] disjunctiveForms = AlgebraicUtil.toDisjunctiveNormalFormArray(qual); // add qualifier to schema for qual for (Column column : indexableColumns) { for (EvalNode disjunctiveExpr : disjunctiveForms) { EvalNode[] conjunctiveForms = AlgebraicUtil.toConjunctiveNormalFormArray(disjunctiveExpr); Set<EvalNode> indexablePredicateSet = Sets.newHashSet(); for (EvalNode conjunctiveExpr : conjunctiveForms) { if (checkIfIndexablePredicateOnTargetColumn(conjunctiveExpr, column)) { indexablePredicateSet.add(conjunctiveExpr); } } if (!indexablePredicateSet.isEmpty()) { indexablePredicateList.add(indexablePredicateSet); } } } } return indexablePredicateList; }
new HashSet<>(Arrays.asList(AlgebraicUtil.toConjunctiveNormalFormArray(leftChild))) : new HashSet<>(Arrays.asList(AlgebraicUtil.toDisjunctiveNormalFormArray(leftChild))); Set<EvalNode> rightChildSplits = innerType == EvalType.AND ? new HashSet<>(Arrays.asList(AlgebraicUtil.toConjunctiveNormalFormArray(rightChild))) : new HashSet<>(Arrays.asList(AlgebraicUtil.toDisjunctiveNormalFormArray(rightChild))); leftChild = AlgebraicUtil.createSingletonExprFromCNF(leftChildSplits); rightChild = AlgebraicUtil.createSingletonExprFromCNF(rightChildSplits); commonQual = AlgebraicUtil.createSingletonExprFromCNF(commonQuals); } else { leftChild = AlgebraicUtil.createSingletonExprFromDNF(leftChildSplits); rightChild = AlgebraicUtil.createSingletonExprFromDNF(rightChildSplits); commonQual = AlgebraicUtil.createSingletonExprFromDNF(commonQuals);
private EvalNode sortQual(EvalNode qual) { EvalNode[] cnf = AlgebraicUtil.toConjunctiveNormalFormArray(qual); return sortQual(cnf); }
private EvalNode sortQual(EvalNode[] cnf) { Arrays.sort(cnf, evalNodeComparator); return AlgebraicUtil.createSingletonExprFromCNF(cnf); }
exprs = AlgebraicUtil.toConjunctiveNormalFormArray(algebra); visitor.setIsHiveCatalog(true); Expr[] filters = AlgebraicUtil.getRearrangedCNFExpressions(databaseName + "." + tableName, partitionColumns, exprs);
private static EvalNode _transpose(BinaryEval _expr, Column target) { EvalNode expr = eliminateConstantExprs(_expr); if (isSingleVar(binaryEval.getLeftExpr())) { return expr; PartialBinaryExpr tmpTerm = splitRightTerm((BinaryEval) left); tmpTerm.type = inverseOperator(tmpTerm.type); tmpTerm.setLeftExpr(((BinaryEval)expr).getRightExpr()); lTerm = ((BinaryEval)left).getLeftExpr(); } else { PartialBinaryExpr tmpTerm = splitLeftTerm((BinaryEval) left); tmpTerm.type = inverseOperator(tmpTerm.type); tmpTerm.setLeftExpr(((BinaryEval)expr).getRightExpr()); lTerm = ((BinaryEval)left).getRightExpr(); return _transpose(new BinaryEval(expr.getType(), lTerm, rTerm), target); } else { return _expr;
/** * Check if an expression consists of one variable and one constant and * the expression is a comparison operator. * * @param evalNode The expression to be checked * @return true if an expression consists of one variable and one constant * and the expression is a comparison operator. Other, false. */ private boolean checkIfIndexablePredicate(EvalNode evalNode) { return AlgebraicUtil.containSingleVar(evalNode) && isIndexableOperator(evalNode); }
@Test public final void testGetDNF() throws TajoException { // "select score from people where score > 1 and score < 3 or score > 7 and score < 10", // 7 EvalNode node = getRootSelection(QUERIES[7]); EvalNode [] cnf = AlgebraicUtil.toDisjunctiveNormalFormArray(node); assertEquals(2, cnf.length); assertEquals("(default.people.score (INT4) > 1 AND default.people.score (INT4) < 3)", cnf[0].toString()); assertEquals("(7 < default.people.score (INT4) AND default.people.score (INT4) < 10)", cnf[1].toString()); }
@Test public final void testSimplify() throws TajoException { List<Target> targets = getRawTargets(QUERIES[0]); EvalNode node = AlgebraicUtil.eliminateConstantExprs(targets.get(0).getEvalTree()); assertEquals(EvalType.CONST, node.getType()); assertEquals(7, node.bind(null, null).eval(null).asInt4()); node = AlgebraicUtil.eliminateConstantExprs(targets.get(1).getEvalTree()); assertEquals(EvalType.CONST, node.getType()); assertTrue(7.0d == node.bind(null, null).eval(null).asFloat8()); Expr expr = analyzer.parse(QUERIES[1]); LogicalPlan plan = planner.createPlan(defaultContext, expr, true); targets = plan.getRootBlock().getRawTargets(); Column col1 = new Column("default.people.score", TajoDataTypes.Type.INT4); Collection<EvalNode> exprs = EvalTreeUtil.getContainExpr(targets.get(0).getEvalTree(), col1); node = exprs.iterator().next(); }
TUtil.newHashSet(AlgebraicUtil.toConjunctiveNormalFormArray(leftChild)) : TUtil.newHashSet(AlgebraicUtil.toDisjunctiveNormalFormArray(leftChild)); Set<EvalNode> rightChildSplits = innerType == EvalType.AND ? TUtil.newHashSet(AlgebraicUtil.toConjunctiveNormalFormArray(rightChild)) : TUtil.newHashSet(AlgebraicUtil.toDisjunctiveNormalFormArray(rightChild)); leftChild = AlgebraicUtil.createSingletonExprFromCNF(leftChildSplits); rightChild = AlgebraicUtil.createSingletonExprFromCNF(rightChildSplits); commonQual = AlgebraicUtil.createSingletonExprFromCNF(commonQuals); } else { leftChild = AlgebraicUtil.createSingletonExprFromDNF(leftChildSplits); rightChild = AlgebraicUtil.createSingletonExprFromDNF(rightChildSplits); commonQual = AlgebraicUtil.createSingletonExprFromDNF(commonQuals);
private EvalNode sortQual(EvalNode qual) { EvalNode[] cnf = AlgebraicUtil.toConjunctiveNormalFormArray(qual); return sortQual(cnf); }
private EvalNode sortQual(EvalNode[] cnf) { Arrays.sort(cnf, evalNodeComparator); return AlgebraicUtil.createSingletonExprFromCNF(cnf); }
exprs = AlgebraicUtil.toConjunctiveNormalFormArray(algebra); visitor.setIsHiveCatalog(false); Expr[] filters = AlgebraicUtil.getRearrangedCNFExpressions(tableName, partitionColumns, exprs);
private static EvalNode _transpose(BinaryEval _expr, Column target) { EvalNode expr = eliminateConstantExprs(_expr); if (isSingleVar(binaryEval.getLeftExpr())) { return expr; PartialBinaryExpr tmpTerm = splitRightTerm((BinaryEval) left); tmpTerm.type = inverseOperator(tmpTerm.type); tmpTerm.setLeftExpr(((BinaryEval)expr).getRightExpr()); lTerm = ((BinaryEval)left).getLeftExpr(); } else { PartialBinaryExpr tmpTerm = splitLeftTerm((BinaryEval) left); tmpTerm.type = inverseOperator(tmpTerm.type); tmpTerm.setLeftExpr(((BinaryEval)expr).getRightExpr()); lTerm = ((BinaryEval)left).getRightExpr(); return _transpose(new BinaryEval(expr.getType(), lTerm, rTerm), target); } else { return _expr;
/** * Check if an expression consists of one variable and one constant and * the expression is a comparison operator. * * @param evalNode The expression to be checked * @return true if an expression consists of one variable and one constant * and the expression is a comparison operator. Other, false. */ private boolean checkIfIndexablePredicate(EvalNode evalNode) { return AlgebraicUtil.containSingleVar(evalNode) && isIndexableOperator(evalNode); }
List<EvalNode> leftFilters = Lists.newArrayList(); List<EvalNode> rightFilters = Lists.newArrayList(); for (EvalNode eachQual : AlgebraicUtil.toConjunctiveNormalFormArray(joinQual)) { if (!(eachQual instanceof BinaryEval)) { continue; // todo 'between', etc. joinQuals.isEmpty() ? null : AlgebraicUtil.createSingletonExprFromCNF(joinQuals), leftFilters.isEmpty() ? null : AlgebraicUtil.createSingletonExprFromCNF(leftFilters), rightFilters.isEmpty() ? null : AlgebraicUtil.createSingletonExprFromCNF(rightFilters) };
EvalNode[] originDnfs = AlgebraicUtil.toDisjunctiveNormalFormArray(node.getQual()); List<EvalNode> rewrittenDnfs = new ArrayList<>(); for (EvalNode eachDnf : originDnfs) { Set<EvalNode> cnfs = new HashSet<>(Arrays.asList(AlgebraicUtil.toConjunctiveNormalFormArray(eachDnf))); cnfs.removeAll(inSubqueries); if (!cnfs.isEmpty()) { rewrittenDnfs.add(AlgebraicUtil.createSingletonExprFromCNF(cnfs)); node.setQual(AlgebraicUtil.createSingletonExprFromDNF(rewrittenDnfs.toArray(new EvalNode[rewrittenDnfs.size()])));
public void setSingletonPredicate(EvalNode predicates) { this.setPredicates(Arrays.asList(AlgebraicUtil.toConjunctiveNormalFormArray(predicates))); }