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

RelToSqlConverter doesn't handle cartesian join (no join cond)

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Minor
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 1.12.0
    • Component/s: core
    • Labels:
      None

      Description

      this test fails (added in RelToSqlConverterTest):

        @Test public void testCartesianProduct() {
          String query = "select * from \"department\" , \"employee\"";
          String expected = "SELECT *\n" +
                            "FROM \"foodmart\".\"department\"\n" +
                            "INNER JOIN \"foodmart\".\"employee\"";
          sql(query).ok(expected);
        }
      

      RelToSqlConverter is checking that the join condition is a RexCall. In this case (and RelBuilder.join() with no join cond), the join cond is a RexLiteral with a value of true.

      Suggested fix is to handle the case with this specific join condition before convertConditionToSqlNode():

       --- a/core/src/main/java/org/apache/calcite/rel/rel2sql/RelToSqlConverter.java
       +++ b/core/src/main/java/org/apache/calcite/rel/rel2sql/RelToSqlConverter.java
       @@ -104,17 +104,23 @@ public Result visit(Join e) {
            final Context leftContext = leftResult.qualifiedContext();
            final Context rightContext =
                rightResult.qualifiedContext();
       -    SqlNode sqlCondition = convertConditionToSqlNode(e.getCondition(),
       -        leftContext,
       -        rightContext,
       -        e.getLeft().getRowType().getFieldCount());
       +    SqlNode sqlCondition = null;
       +    SqlLiteral condType = JoinConditionType.ON.symbol(POS);
       +    if (e.getCondition().isAlwaysTrue()) {
       +      condType = JoinConditionType.NONE.symbol(POS);
       +    } else {
       +      sqlCondition = convertConditionToSqlNode(e.getCondition(),
       +          leftContext,
       +          rightContext,
       +          e.getLeft().getRowType().getFieldCount());
       +    }
            SqlNode join =
                new SqlJoin(POS,
                    leftResult.asFrom(),
                    SqlLiteral.createBoolean(false, POS),
                    joinType(e.getJoinType()).symbol(POS),
                    rightResult.asFrom(),
       -            JoinConditionType.ON.symbol(POS),
       +            condType,
                    sqlCondition);
            return result(join, leftResult, rightResult);
          }
      

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                julianhyde Julian Hyde
                Reporter:
                jbalint@gmail.com Jess Balint
              • Votes:
                0 Vote for this issue
                Watchers:
                2 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: