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;
}
}
}