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

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

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Minor
    • Resolution: Fixed
    • None
    • 1.12.0
    • core
    • 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

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

              Dates

                Created:
                Updated:
                Resolved: