Repository: apache/arrow
File: cpp/src/arrow/acero/hash_join_node_test.cc (C++)

Code before:

      {
        // Right anti join.
        JoinType join_type = JoinType::RIGHT_ANTI;
        auto expected = ExecBatchFromJSON({utf8(), int32(), utf8()}, R"([
                            [null, null, "r_payload"],
                            [null, 0, "r_payload"],
                            [null, 42, "r_payload"],
                            ["both1", null, "r_payload"],
                            ["both2", null, "r_payload"],
                            ["right_only", null, "r_payload"],
                            ["right_only", 0, "r_payload"],
                            ["right_only", 42, "r_payload"]])");
        for (const auto& projector : projectors) {
          runner.Run(join_type, left_keys, right_keys, projector.LeftOutput(join_type),
                     projector.RightOutput(join_type), filter,
                     {projector.Project(join_type, expected)});
        }
      }
    }
  }

  {
    // Literal false, null, and scalar false, null.
    for (Expression filter :
         {literal(false), literal(NullScalar()), equal(literal(0), literal(1)),
          equal(literal(1), literal(NullScalar()))}) {
      std::vector<FieldRef> left_keys{"l_key", "l_filter"},
          right_keys{"r_key", "r_filter"};
      {
        // Inner join.
        JoinType join_type = JoinType::INNER;
        auto expected = ExecBatchFromJSON(
            {utf8(), int32(), utf8(), utf8(), int32(), utf8()}, R"([])");
        for (const auto& projector : projectors) {
          runner.Run(join_type, left_keys, right_keys, projector.LeftOutput(join_type),
                     projector.RightOutput(join_type), filter,
                     {projector.Project(join_type, expected)});
        }
      }

      {
        // Left outer join.
        JoinType join_type = JoinType::LEFT_OUTER;
        auto expected =
            ExecBatchFromJSON({utf8(), int32(), utf8(), utf8(), int32(), utf8()}, R"([
                [null, null, "l_payload", null, null, null],
                [null, 0, "l_payload", null, null, null],
                [null, 42, "l_payload", null, null, null],
                ["left_only", null, "l_payload", null, null, null],
                ["left_only", 0, "l_payload", null, null, null],

Review comment (suggestion):
The null type null (`literal(NullScalar())`) is invalid. Replacing it with a boolean type `null`.

Code after:
      }

      {
        // Left anti join.
        JoinType join_type = JoinType::LEFT_ANTI;
        auto expected = ExecBatchFromJSON({utf8(), int32(), utf8()}, R"([
                            [null, null, "l_payload"],
                            [null, 0, "l_payload"],
                            [null, 42, "l_payload"],
                            ["left_only", null, "l_payload"],
                            ["left_only", 0, "l_payload"],
                            ["left_only", 42, "l_payload"],
                            ["both1", null, "l_payload"],
                            ["both2", null, "l_payload"]])");
        for (const auto& projector : projectors) {
          runner.Run(join_type, left_keys, right_keys, projector.LeftOutput(join_type),
                     projector.RightOutput(join_type), filter,
                     {projector.Project(join_type, expected)});
        }
      }

      {
        // Right semi join.
        JoinType join_type = JoinType::RIGHT_SEMI;
        auto expected = ExecBatchFromJSON({utf8(), int32(), utf8()}, R"([
                            ["both1", 0, "r_payload"],
                            ["both1", 42, "r_payload"],
                            ["both2", 0, "r_payload"],
                            ["both2", 42, "r_payload"]])");
        for (const auto& projector : projectors) {
          runner.Run(join_type, left_keys, right_keys, projector.LeftOutput(join_type),
                     projector.RightOutput(join_type), filter,
                     {projector.Project(join_type, expected)});
        }
      }

      {
        // Right anti join.
        JoinType join_type = JoinType::RIGHT_ANTI;
        auto expected = ExecBatchFromJSON({utf8(), int32(), utf8()}, R"([
                            [null, null, "r_payload"],
                            [null, 0, "r_payload"],
                            [null, 42, "r_payload"],
                            ["both1", null, "r_payload"],
                            ["both2", null, "r_payload"],
                            ["right_only", null, "r_payload"],
                            ["right_only", 0, "r_payload"],
                            ["right_only", 42, "r_payload"]])");
        for (const auto& projector : projectors) {
          runner.Run(join_type, left_keys, right_keys, projector.LeftOutput(join_type),
                     projector.RightOutput(join_type), filter,