public boolean eval(StructLike data) {
    return new EvalVisitor().eval(data);
  }
@Test
  public void testAnd() {
    Evaluator evaluator = new Evaluator(STRUCT, and(equal("x", 7), notNull("z")));
    assertThat(evaluator.eval(TestHelpers.Row.of(7, 0, 3))).as("7, 3 => true").isTrue();
    assertThat(evaluator.eval(TestHelpers.Row.of(8, 0, 3))).as("8, 3 => false").isFalse();
    assertThat(evaluator.eval(TestHelpers.Row.of(7, 0, null))).as("7, null => false").isFalse();
    assertThat(evaluator.eval(TestHelpers.Row.of(8, 0, null))).as("8, null => false").isFalse();

    Evaluator structEvaluator =
        new Evaluator(STRUCT, and(equal("s1.s2.s3.s4.i", 7), notNull("s1.s2.s3.s4.i")));

    assertThat(
            structEvaluator.eval(
                TestHelpers.Row.of(
                    7,
                    0,
                    3,
                    TestHelpers.Row.of(
                        TestHelpers.Row.of(TestHelpers.Row.of(TestHelpers.Row.of(7)))))))
        .as("7, 7 => true")
        .isTrue();
    assertThat(
            structEvaluator.eval(
                TestHelpers.Row.of(
                    8,
                    0,
                    3,
                    TestHelpers.Row.of(
                        TestHelpers.Row.of(TestHelpers.Row.of(TestHelpers.Row.of(8)))))))
        .as("8, 8 => false")
        .isFalse();

    assertThat(structEvaluator.eval(TestHelpers.Row.of(7, 0, null, null)))
        .as("7, null => false")
        .isFalse();

    assertThat(
            structEvaluator.eval(
                TestHelpers.Row.of(
                    8,
                    0,
                    null,
                    TestHelpers.Row.of(
                        TestHelpers.Row.of(TestHelpers.Row.of(TestHelpers.Row.of(8)))))))
        .as("8, notnull => false")
        .isFalse();
  }