[ 
https://issues.apache.org/jira/browse/CALCITE-5311?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17613852#comment-17613852
 ] 

Julian Hyde commented on CALCITE-5311:
--------------------------------------

I agree that the position of the IN should span from the "a" to the ")" 
(inclusive). Arguably the sub-select should span from "(" to ")", if it makes 
the IN case easier.

I have a feeling that these problems are not that unusual, because of how we 
test: we only check the position of a {{SqlNode}} when it occurs in an error 
message. The solution to the general problem is to make it easier to write more 
tests, then write more tests.

So, what test infrastructure do we need? The trick in the tests where we use 
caret (^) symbols to denote a region of the SQL is one we should continue. It 
is superior to manually entering column positions, or even taking substrings, 
as you did, because it handles multi-line strings, and only requires you to 
type the SQL once.

The test infrastructure should make it possible to write your test as
{code:java}
sql("SELECT ^a IN (SELECT a FROM c WHERE d)^ FROM t")
    .checkPosition(rootNode -> ((SqlSelect) 
rootNode).getSelectList().get(0));{code}
 

> SqlNode.parserPosition missing closing ')' for expression subquery
> ------------------------------------------------------------------
>
>                 Key: CALCITE-5311
>                 URL: https://issues.apache.org/jira/browse/CALCITE-5311
>             Project: Calcite
>          Issue Type: Bug
>            Reporter: Steven Talbot
>            Priority: Major
>
> Here's an obscure one!
> Background: I'm trying to use the values of parserPos to recover the original 
> slices of SQL corresponding to various SQL entities. 
> When we parse a statement like 
>  
> {code:java}
> SELECT a IN (SELECT a FROM c WHERE d) FROM t{code}
> The parsed SqlNode corresponding to "a IN (SELECT a FROM c WHERE d)" stops at 
> the index of "d", not the ")".
>  
> I am almost sure this is due to this very original special case code in the 
> parser: 
> [https://github.com/apache/calcite/blame/a505b25eacc473c6ec0ef8abd40c1ccae86297b6/core/src/main/codegen/templates/Parser.jj#L3602]
> The parser drops the "list" of the single parenthesized query in favor of 
> just the query, which completely makes sense, but in doing so it discards the 
> parserPos of the list, which includes the index of ")", for the parserPos of 
> the query, which does not. Then, when the parserPositions of the arguments to 
> the IN are added together, the final parserPosition does not include the ')'.
> Test is perhaps easier to see:
>  
> {code:java}
> @Test
> void testSubqueryParserPosParse() throws SqlParseException {
>   String sql = "SELECT a IN (SELECT a FROM c WHERE d) FROM t";
>   SqlNode parsed = SqlParser.create(sql).parseQuery();
>   SqlCall inCall = (SqlCall) ((SqlSelect) parsed).getSelectList().get(0);
>   assertEquals("a IN (SELECT a FROM c WHERE d)",
>       sql.substring(
>           inCall.getParserPosition().getColumnNum() - 1, // pos is 1-indexed
>           inCall.getParserPosition().getEndColumnNum()   // but inclusive
>       ));
> } {code}
> {noformat}
> org.opentest4j.AssertionFailedError:
> Expected :a IN (SELECT a FROM c WHERE d)
> Actual   :a IN (SELECT a FROM c WHERE d
> {noformat}
>  
>  



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to