lowka commented on code in PR #3505:
URL: https://github.com/apache/ignite-3/pull/3505#discussion_r1544214768
##########
modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/RexUtils.java:
##########
@@ -176,6 +182,104 @@ public static boolean isIdentity(List<? extends RexNode>
projects, RelDataType i
return true;
}
+ /** Calcite based dnf wrapper with OR nodes limitation. */
+ public static class DnfHelper {
+ final RexBuilder rexBuilder;
+ final int maxOrNodes;
+
+ /** Constructor.
+ *
+ * @param rexBuilder Rex builder.
+ * @param maxOrNodes Limit for OR nodes, if limit is reached further
processing will be stopped.
+ */
+ public DnfHelper(RexBuilder rexBuilder, int maxOrNodes) {
+ this.rexBuilder = rexBuilder;
+ this.maxOrNodes = maxOrNodes;
+ }
+
+ /** Return dnf representation or {@code null} if limit is reached. */
+ public @Nullable RexNode tryToDnf(RexNode rex) {
+ try {
+ return toDnf(rex);
+ } catch (FoundOne e) {
+ return null;
+ }
+ }
+
+ private RexNode toDnf(RexNode rex) {
+ List<RexNode> operands;
+ switch (rex.getKind()) {
+ case AND:
+ operands = flattenAnd(((RexCall) rex).getOperands());
+ RexNode head = operands.get(0);
+ RexNode headDnf = toDnf(head);
+ List<RexNode> headDnfs = RelOptUtil.disjunctions(headDnf);
+ RexNode tail = and(Util.skip(operands));
+ RexNode tailDnf = toDnf(tail);
+ List<RexNode> tailDnfs = RelOptUtil.disjunctions(tailDnf);
+ List<RexNode> list = new ArrayList<>(headDnfs.size() *
tailDnfs.size());
+ for (RexNode h : headDnfs) {
+ for (RexNode t : tailDnfs) {
+ list.add(and(ImmutableList.of(h, t)));
+ }
+ }
+ return or(list);
+ case OR:
+ operands = flattenOr(((RexCall) rex).getOperands());
+ List<RexNode> processed = toDnfs(operands);
+ return or(processed);
+ case NOT:
+ RexNode arg = ((RexCall) rex).getOperands().get(0);
+ switch (arg.getKind()) {
+ case NOT:
+ return toDnf(((RexCall) arg).getOperands().get(0));
+ case OR:
+ operands = ((RexCall) arg).getOperands();
+ return toDnf(
+ and(Util.transform(flattenOr(operands),
RexUtil::not)));
+ case AND:
+ operands = ((RexCall) arg).getOperands();
+ return toDnf(
+ or(Util.transform(flattenAnd(operands),
RexUtil::not)));
+ default:
+ return rex;
+ }
+ default:
+ return rex;
+ }
+ }
+
+ private List<RexNode> toDnfs(List<RexNode> nodes) {
+ List<RexNode> list = new ArrayList<>();
+ for (RexNode node : nodes) {
+ RexNode dnf = toDnf(node);
+ switch (dnf.getKind()) {
+ case OR:
+ list.addAll(((RexCall) dnf).getOperands());
+ break;
+ default:
+ list.add(dnf);
+ }
+ }
+ return list;
+ }
+
+ private RexNode and(Iterable<? extends RexNode> nodes) {
+ return composeConjunction(rexBuilder, nodes);
+ }
+
+ private RexNode or(Iterable<? extends RexNode> nodes) {
+ RexNode res = composeDisjunction(rexBuilder, nodes);
+ if (res instanceof RexCall) {
+ RexCall res0 = (RexCall) res;
+ if (res0.getOperands().size() > maxOrNodes) {
Review Comment:
Is this condition the only difference between this code and
RexUtils::DnfHelper?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]