Skip to content

core: the three physical join classes accept eight of the twelve join types their protos define #1295

Description

@alexandrefimov

Join.JoinType maps every join type JoinRel.JoinType defines. The three physical join classes map eight of the twelve theirs define. physical/HashJoin.java:79, physical/MergeJoin.java:79 and physical/NestedLoopJoin.java:33 each declare INNER, OUTER, LEFT, RIGHT, LEFT_SEMI, RIGHT_SEMI, LEFT_ANTI, RIGHT_ANTI beside the UNKNOWN sentinel and stop, while HashJoinRel.JoinType, MergeJoinRel.JoinType and NestedLoopJoinRel.JoinType in algebra.proto each carry the same twelve JoinRel.JoinType does. The four with no mapping are LEFT_SINGLE, RIGHT_SINGLE, LEFT_MARK and RIGHT_MARK.

A plan using any of the four is rejected while it is being read. ProtoRelConverter calls fromProto at lines 1133, 1172 and 1253, and the enum throws: IllegalArgumentException: Unknown type: JOIN_TYPE_LEFT_MARK, at physical/HashJoin.java:118, physical/MergeJoin.java:118 and physical/NestedLoopJoin.java:82.

Observed

One plan per cell, each a two-column read joined to a two-column read with nothing varied but the message and the join type. LEFT_SEMI is the control.

join type HashJoinRel MergeJoinRel NestedLoopJoinRel
LEFT_SEMI (control) [i64, i64?] [i64, i64?] [i64, i64?]
LEFT_SINGLE Unknown type Unknown type Unknown type
RIGHT_SINGLE Unknown type Unknown type Unknown type
LEFT_MARK Unknown type Unknown type Unknown type
RIGHT_MARK Unknown type Unknown type Unknown type

The same four types on JoinRel are read without complaint and derive a schema, so this is the physical classes rather than the join types.

Reproduced at fff639064df794840db36fffcd881c09100e23df (v0.103.0), and main at ee9f3d20a declares the same eight in all three.

#1067 fixed MergeJoin.getLeftTypes() in these same classes; the table in it lists those eight types and the four here were outside it.

Reproducer

Convert this plan through ProtoPlanConverter. The other eleven cells change only hashJoin to mergeJoin or nestedLoopJoin and the value of type; the nested-loop form carries expression instead of keys.

{
  "version": {
    "minorNumber": 102
  },
  "relations": [
    {
      "root": {
        "names": [
          "a",
          "b",
          "c"
        ],
        "input": {
          "hashJoin": {
            "common": {
              "direct": {}
            },
            "left": {
              "read": {
                "common": {
                  "direct": {}
                },
                "baseSchema": {
                  "names": [
                    "c0",
                    "c1"
                  ],
                  "struct": {
                    "types": [
                      {
                        "i64": {
                          "nullability": "NULLABILITY_REQUIRED"
                        }
                      },
                      {
                        "i64": {
                          "nullability": "NULLABILITY_NULLABLE"
                        }
                      }
                    ],
                    "nullability": "NULLABILITY_REQUIRED"
                  }
                },
                "namedTable": {
                  "names": [
                    "l"
                  ]
                }
              }
            },
            "right": {
              "read": {
                "common": {
                  "direct": {}
                },
                "baseSchema": {
                  "names": [
                    "c0",
                    "c1"
                  ],
                  "struct": {
                    "types": [
                      {
                        "i64": {
                          "nullability": "NULLABILITY_NULLABLE"
                        }
                      },
                      {
                        "i64": {
                          "nullability": "NULLABILITY_REQUIRED"
                        }
                      }
                    ],
                    "nullability": "NULLABILITY_REQUIRED"
                  }
                },
                "namedTable": {
                  "names": [
                    "r"
                  ]
                }
              }
            },
            "keys": [
              {
                "left": {
                  "directReference": {
                    "structField": {}
                  },
                  "rootReference": {}
                },
                "right": {
                  "directReference": {
                    "structField": {}
                  },
                  "rootReference": {}
                },
                "comparison": {
                  "simple": "SIMPLE_COMPARISON_TYPE_EQ"
                }
              }
            ],
            "type": "JOIN_TYPE_LEFT_MARK"
          }
        }
      }
    }
  ]
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions