public Statement buildStatement(final ParserRuleContext parseTree) {
    return build(Optional.of(getSources(parseTree)), parseTree);
  }
@Test
  public void shouldGetCorrectLocationsComplexCtas() {
    // Given:
    final String statementString =
    //   1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
        "CREATE TABLE customer_bookings\n" +                                                               // 1
        "  WITH (KAFKA_TOPIC = 'customer_bookings', KEY_FORMAT = 'JSON', VALUE_FORMAT = 'JSON') AS\n" +    // 2
        "  SELECT C.EMAIL,\n" +                                                                            // 3
        "         B.id,\n" +                                                                               // 4
        "         B.flight_id,\n" +                                                                        // 5
        "         COUNT(*)\n" +                                                                            // 6
        "  FROM bookings B\n" +                                                                            // 7
        "       INNER JOIN customers C ON B.customer_id = C.id\n" +                                        // 8
        "  WINDOW TUMBLING (SIZE 1 HOUR, GRACE PERIOD 2 HOURS)\n" +                                        // 9
        "  WHERE B.customer_id > 0 AND INSTR(C.EMAIL, '@') > 0\n" +                                        // 10
        "  GROUP BY C.EMAIL, B.ID, B.flight_id\n" +                                                        // 11
        "  HAVING COUNT(*) > 0;";                                                                          // 12
    //   1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
    final SingleStatementContext stmt = givenQuery(statementString);

    // When:
    final CreateTableAsSelect result = ((CreateTableAsSelect) builder.buildStatement(stmt));

    // Then:
    assertTrue(result.getLocation().isPresent());
    final NodeLocation createTableLocation = result.getLocation().get();
    assertThat(createTableLocation.getStartLineNumber(), is(1));
    assertThat(createTableLocation.getLength(), is(OptionalInt.of(statementString.length() - 1)));

    final Query query = result.getQuery();
    assertTrue(query.getLocation().isPresent());
    final NodeLocation queryLocation = query.getLocation().get();
    assertThat(queryLocation.getStartLineNumber(), is(3));
    assertThat(queryLocation.getStartColumnNumber(), is(3));
    assertThat(queryLocation.getLength(),
        is(OptionalInt.of((
            "SELECT C.EMAIL,\n" +
            "         B.id,\n" +
            "         B.flight_id,\n" +
            "         COUNT(*)\n" +
            "  FROM bookings B\n" +
            "       INNER JOIN customers C ON B.customer_id = C.id\n" +
            "  WINDOW TUMBLING (SIZE 1 HOUR, GRACE PERIOD 2 HOURS)\n" +
            "  WHERE B.customer_id > 0 AND INSTR(C.EMAIL, '@') > 0\n" +
            "  GROUP BY C.EMAIL, B.ID, B.flight_id\n" +
            "  HAVING COUNT(*) > 0").length())));

    final Select select = query.getSelect();
    assertTrue(select.getLocation().isPresent());
    final NodeLocation selectLocation = select.getLocation().get();
    assertThat(selectLocation.getStartLineNumber(), is(3));
    assertThat(selectLocation.getStartColumnNumber(), is(3));
    assertThat(selectLocation.getLength(),
        is(OptionalInt.of("SELECT".length())));

    final Join join = (Join) query.getFrom();
    assertTrue(join.getLocation().isPresent());
    final NodeLocation joinLocation = join.getLocation().get();
    assertThat(joinLocation.getStartLineNumber(), is(7));
    assertThat(joinLocation.getStartColumnNumber(), is(8));
    assertThat(joinLocation.getLength(),
        is(OptionalInt.of((
                   "bookings B\n" +
            "       INNER JOIN customers C ON B.customer_id = C.id").length())));

    assertTrue(query.getWindow().isPresent());
    final WindowExpression window = query.getWindow().get();
    assertTrue(window.getLocation().isPresent());
    final NodeLocation windowLocation = window.getLocation().get();
    assertThat(windowLocation.getStartLineNumber(), is(9));
    assertThat(windowLocation.getStartColumnNumber(), is(10));
    assertThat(windowLocation.getLength(),
        is(OptionalInt.of(("TUMBLING (SIZE 1 HOUR, GRACE PERIOD 2 HOURS)").length())));

    assertTrue(query.getWhere().isPresent());
    final LogicalBinaryExpression where = (LogicalBinaryExpression) query.getWhere().get();
    assertTrue(where.getLocation().isPresent());
    final NodeLocation whereLocation = where.getLocation().get();
    assertThat(whereLocation.getStartLineNumber(), is(10));
    assertThat(whereLocation.getStartColumnNumber(), is(27));
    assertThat(whereLocation.getLength(), is(OptionalInt.of(3)));

    assertTrue(query.getGroupBy().isPresent());
    final GroupBy groupBy = query.getGroupBy().get();
    assertTrue(groupBy.getLocation().isPresent());
    final NodeLocation groupByLocation = groupBy.getLocation().get();
    assertThat(groupByLocation.getStartLineNumber(), is(11));
    assertThat(groupByLocation.getStartColumnNumber(), is(12));
    assertThat(groupByLocation.getLength(),
        is(OptionalInt.of("C.EMAIL, B.ID, B.flight_id".length())));

    assertTrue(query.getHaving().isPresent());
    final ComparisonExpression having = (ComparisonExpression) query.getHaving().get();
    assertTrue(having.getLocation().isPresent());
    final NodeLocation havingLocation = having.getLocation().get();
    assertThat(havingLocation.getStartLineNumber(), is(12));
    assertThat(havingLocation.getStartColumnNumber(), is(19));
    assertThat(havingLocation.getLength(), is(OptionalInt.of(1)));
  }