hi team,

I met a NullPointerException when I used calcite 1.24.0 to convert a relNode to sqlNode.

The trace:

java.lang.NullPointerException
    at java.base/java.util.Objects.requireNonNull(Objects.java:221)
    at org.apache.calcite.rel.rel2sql.RelToSqlConverter.result(RelToSqlConverter.java:152)     at org.apache.calcite.rel.rel2sql.SqlImplementor.result(SqlImplementor.java:454)     at org.apache.calcite.rel.rel2sql.SqlImplementor$Builder.result(SqlImplementor.java:1822)     at org.apache.calcite.rel.rel2sql.RelToSqlConverter.visit(RelToSqlConverter.java:392)
    at server.TestRelToSqlConverter.test(TestRelToSqlConverter.java:84)


Attched file is a junit5 test case,you can repeat the issue with this code.

Maven configuration:

        <dependency>
            <groupId>org.apache.calcite</groupId>
            <artifactId>calcite-core</artifactId>
            <version>1.24.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-dbcp2</artifactId>
            <version>2.7.0</version>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>42.2.12</version>
        </dependency>


import com.glodon.gdc.parser.TestSqlTranslateService;
import com.google.common.collect.ImmutableList;
import org.apache.calcite.sql.*;
import org.apache.calcite.sql.parser.SqlParseException;
import org.apache.calcite.sql.parser.SqlParser;
import org.apache.calcite.sql.util.SqlBasicVisitor;
import org.junit.Test;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;

import static org.apache.calcite.sql.parser.SqlParser.create;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;

public class TestSimpleSql {

  TestSqlTranslateService service = new TestSqlTranslateService();

  @Test
  public void performance() throws InterruptedException, ExecutionException, SqlParseException {
    test(0);
    test(0);
    test(0);
    long start = System.currentTimeMillis();
    for(int i = 0; i < 10000; i++) {
      this.test(i);
    }
    long end = System.currentTimeMillis();
    System.out.println("total" + (end - start));
  }

  private void test(int count) throws SqlParseException, ExecutionException, InterruptedException {
    String sql = "select a, b from project where c = '1'";
    @SuppressWarnings("unused")
	SqlNode sqlNode = Utils.parse(sql);
    String s = service.translateSql(sql).get();
    System.out.println(count + ": " + s);
  }

  @Test
  public void testStarSelect() {

  }

  @Test
  public void testSimpleSelect() throws SqlParseException, ExecutionException, InterruptedException {
    String sql = "select a, b from project where c = '1'";
    SqlNode sqlNode = Utils.parse(sql);
    assertThat(sqlNode.getKind(), equalTo(SqlKind.SELECT));
    SqlSelect sqlSelect = (SqlSelect) sqlNode;
    List<SqlIdentifier> selectNodes = getSqlList(sqlSelect, SqlIdentifier.class);

    List<String> fields = selectNodes.stream().map(node -> node.getSimple()).collect(Collectors.toList());
    assertEquals(fields, Arrays.asList("A", "B"));

    assertEquals("PROJECT", ((SqlIdentifier) sqlSelect.getFrom()).getSimple());

    System.out.println(service.translateSql(sql).get());
  }

  @SuppressWarnings("unchecked")
private <T extends SqlNode> List<T> getSqlList(SqlSelect sqlSelect, Class<T> clz) {
    return (List<T>) sqlSelect.getSelectList().getList();
  }

  @Test
  public void testComplexFieldsSelect() throws SqlParseException {
    SqlNode sqlNode = Utils.parse("select t.a, t.b from pim.project");
    SqlSelect sqlSelect = (SqlSelect) sqlNode;
    List<SqlIdentifier> selectNodes = getSqlList(sqlSelect, SqlIdentifier.class);
    List<ImmutableList<String>> collect = selectNodes.stream().map(node -> node.names).collect(Collectors.toList());
    assertEquals(collect, Arrays.asList(ImmutableList.of("T", "A"), ImmutableList.of("T", "B")));
    assertEquals(ImmutableList.of("PIM", "PROJECT"), ((SqlIdentifier) sqlSelect.getFrom()).names);
  }

  @Test
  public void testSelectAs() throws SqlParseException {
    SqlNode sqlNode = Utils.parse("select t.a as m, t.b as n from project");
    SqlSelect sqlSelect = (SqlSelect) sqlNode;
    List<SqlCall> sqlCalls = getSqlList(sqlSelect, SqlCall.class);
    sqlCalls.forEach(call -> {
      assertEquals(call.getOperator().getKind(), SqlKind.AS);
//      assertEquals(call.getOperandList(), 1);
    });
  }


  @Test
  public void testSimpleParser() throws SqlParseException {
    SqlParser parser = create("select * from pim.project group by a");
    SqlNode sqlNode = parser.parseQuery();
    sqlNode.accept(new Visitor());
    assertThat(sqlNode.getKind(), equalTo(SqlKind.SELECT));
    System.out.println(sqlNode.toString());
  }

  class Visitor extends SqlBasicVisitor<Void> {
    @Override
    public Void visit(SqlIdentifier id) {
//      id.setNames(Arrays.asList("a"), Arrays.asList(new SqlParserPos(1, 8)));
      System.out.println(id.toString());
      return null;
    }
  }
}

Reply via email to