Uploaded image for project: 'Calcite'
  1. Calcite
  2. CALCITE-5032

The unexpected behavior on method RelOptUtil#splitJoinCondition

    XMLWordPrintableJSON

Details

    Description

      When I call the method

      RexNode splitJoinCondition(
            List<RelDataTypeField> sysFieldList,
            List<RelNode> inputs,
            RexNode condition,
            List<List<RexNode>> joinKeys,
            @Nullable List<Integer> filterNulls,
            @Nullable List<SqlOperator> rangeOp)
      

      , and the passed `joinKeys` is list with size 2, `condition` is like "1 = 1", then I found the `joinKeys` passed dosen't change as expected.

      For the `joinKeys`, the first list will contain two RexNodes, and the second list contains no RexNode. I think the expected behavior should be the first list contain one RexNode, and the second contain one RexNode too.

      After I dive into the code, I found such code will be invoked:

      if ((rangeOp == null)
                && ((leftKey == null) || (rightKey == null))) {
              // no equality join keys found yet:
              // try transforming the condition to
              // equality "join" conditions, e.g.
              //     f(LHS) > 0 ===> ( f(LHS) > 0 ) = TRUE,
              // and make the RHS produce TRUE, but only if we're strictly
              // looking for equi-joins
              final ImmutableBitSet projRefs = InputFinder.bits(condition);
              leftKey = null;
              rightKey = null;
      
              boolean foundInput = false;
              for (int i = 0; i < inputs.size() && !foundInput; i++) {
                if (inputsRange[i].contains(projRefs)) {
                  leftInput = i;
                  leftFields = inputs.get(leftInput).getRowType().getFieldList();
      
                  leftKey = condition.accept(
                      new RelOptUtil.RexInputConverter(
                          rexBuilder,
                          leftFields,
                          leftFields,
                          adjustments));
      
                  rightKey = rexBuilder.makeLiteral(true);
      
                  // effectively performing an equality comparison
                  kind = SqlKind.EQUALS;
      
                  foundInput = true;
                }
              }
            }
      

      It'll set `leftKey` and `righeKey`, but it won't set `rightInput`. So `rightInput` will be 0.
      Then it'll try to add `leftKey` and `righeKey` to `joinKeys`,

      addJoinKey(
                  joinKeys.get(leftInput),
                  leftKey,
                  (rangeOp != null) && !rangeOp.isEmpty());
      addJoinKey(
                  joinKeys.get(rightInput),
                  rightKey,
      (rangeOp != null) && !rangeOp.isEmpty());
      

      But the `rightInput` is 0, so the first list of `joinKeys` will be also add `righeKey`.

      Could anyone please help me? Is it a bug or I misunderstand something? Thanks very much.

      Attachments

        Issue Links

          Activity

            People

              libenchao Benchao Li
              luoyuxia luoyuxia
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Time Tracking

                  Estimated:
                  Original Estimate - Not Specified
                  Not Specified
                  Remaining:
                  Remaining Estimate - 0h
                  0h
                  Logged:
                  Time Spent - 1h 20m
                  1h 20m