You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@calcite.apache.org by "Abhishek Dasgupta (Jira)" <ji...@apache.org> on 2022/03/29 16:39:00 UTC

[jira] [Updated] (CALCITE-4401) Add auxiliary SqlSelect wrap over SqlJoin to resolve RuntimeException in SqlJoin#toString

     [ https://issues.apache.org/jira/browse/CALCITE-4401?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Abhishek Dasgupta updated CALCITE-4401:
---------------------------------------
    Summary: Add auxiliary SqlSelect wrap over SqlJoin to resolve RuntimeException in SqlJoin#toString  (was: Add auxillary SqlSelect wrap over SqlJoin to resolve RuntimeException in SqlJoin#toString)

> Add auxiliary SqlSelect wrap over SqlJoin to resolve RuntimeException in SqlJoin#toString
> -----------------------------------------------------------------------------------------
>
>                 Key: CALCITE-4401
>                 URL: https://issues.apache.org/jira/browse/CALCITE-4401
>             Project: Calcite
>          Issue Type: Bug
>          Components: core
>    Affects Versions: 1.25.0, 1.26.0
>            Reporter: Dominik Labuda
>            Assignee: Abhishek Dasgupta
>            Priority: Minor
>             Fix For: 1.31.0
>
>
> Hi,
> In our project we use Kotlin along with [Strikt assertion library|https://strikt.io/] in tests. The thing is that Strikt calls `.toString()` method on failing asserted objects to provide users with a nicely formatted output.
> Lets say the test looks like this: 
> {code:java}
>     @Test
>     fun `test correct type of JOIN in the root of generated SQL without neighboring JOINs`() {
>         // Generates SqlSelect that fails one of the conditions below
>         val rootSelect: SqlSelect = generateRootSql()
>         
>         expectThat(rootSelect.from) {
>             // Passes - from is a SqlJoin
>             val join = isA<SqlJoin>()
>             // Passes - joinType is FULL
>             join.get { joinType }.isEqualTo(JoinType.FULL)
>             // Fails - left is a SqlJoin, calls .toString() on rootSelect.from to provide output info
>             join.get { left }.isNotA<SqlJoin>()
>             join.get { right }.isNotA<SqlJoin>()
>         }
>     }
> {code}
> This can be inherently reduced to this example:
> {code:java}
> fun main() {
>     val frameworkConfig = initSchema()
>     val relBuilder: RelBuilder = RelBuilder.create(frameworkConfig)
>     val rootRelationalNode = relBuilder
>         .scan("tpch", "out_tpch_vw__customer")
>         .project(
>             relBuilder.field("c_custkey"),
>             relBuilder.field("region_name")
>         )
>         .scan("tpch", "out_tpch_vw__orders")
>         .project(
>             relBuilder.field("o_custkey"),
>             relBuilder.field("o_totalprice")
>         )
>         .join(
>             JoinRelType.INNER,
>             relBuilder.call(
>                 SqlStdOperatorTable.EQUALS,
>                 relBuilder.field(2, 0, "c_custkey"),
>                 relBuilder.field(2, 1, "o_custkey")
>             )
>         )
>         .build()
>     val sqlNode = RelToSqlConverter(PostgresqlSqlDialect.DEFAULT)
>         .visitRoot(rootRelationalNode)
>         .asStatement()
>     println("SQL:")
>     println(sqlNode)
>     println()
>     println("sqlNode root is SqlSelect: ${sqlNode is SqlSelect}")
>     // Treat sqlNode as SqlSelect
>     sqlNode as SqlSelect
>     println("sqlNode.from field is a SqlJoin: ${sqlNode.from is SqlJoin}")
>     println("Printing out the SqlJoin: ${sqlNode.from}")
> }
> {code}
> Which results in:
> {code:java}
> SQL:
> SELECT *
> FROM (SELECT `c_custkey`, `region_name`
> FROM `tpch`.`out_tpch_vw__customer`) AS `t`
> INNER JOIN (SELECT `o_custkey`, `o_totalprice`
> FROM `tpch`.`out_tpch_vw__orders`) AS `t0` ON `t`.`c_custkey` = `t0`.`o_custkey`
> sqlNode root is SqlSelect: true
> sqlNode.from field is a SqlJoin: true
> Exception in thread "main" java.lang.RuntimeException: No list started
>   at org.apache.calcite.sql.pretty.SqlPrettyWriter.sep(SqlPrettyWriter.java:1079)
>   at org.apache.calcite.sql.pretty.SqlPrettyWriter.sep(SqlPrettyWriter.java:1074)
>   at org.apache.calcite.sql.SqlJoin$SqlJoinOperator.unparse(SqlJoin.java:214)
>   at org.apache.calcite.sql.SqlDialect.unparseCall(SqlDialect.java:453)
>   at org.apache.calcite.sql.SqlCall.unparse(SqlCall.java:104)
>   at org.apache.calcite.sql.SqlNode.toSqlString(SqlNode.java:154)
>   at org.apache.calcite.sql.SqlNode.toString(SqlNode.java:129)
>   at java.base/java.lang.String.valueOf(String.java:2951)
>   at java.base/java.lang.StringBuilder.append(StringBuilder.java:168)
>   ...{code}
>  



--
This message was sent by Atlassian Jira
(v8.20.1#820001)