tnakama created CALCITE-7921:
--------------------------------

             Summary: BigQuery string literals should decode backslash escape 
sequences
                 Key: CALCITE-7921
                 URL: https://issues.apache.org/jira/browse/CALCITE-7921
             Project: Calcite
          Issue Type: Bug
          Components: core
    Affects Versions: 1.42.0, 1.40.0
            Reporter: tnakama


When SqlParser is configured with {{Lex.BIG_QUERY}}, backslash escapes other 
than the enclosing quotation mark are not decoded in ordinary string literals.

This is reproducible with the released {{calcite-core:1.42.0}} artifact, 
independently of any custom parser. It also occurs in 1.40.0. The current main 
{{Parser.jj}} still calls {{SqlParserUtil.stripQuotes}} for 
{{BIG_QUERY_QUOTED_STRING}}, {{BIG_QUERY_DOUBLE_QUOTED_STRING}}, and 
{{SimpleStringLiteral}}.

h3. Minimal Java reproduction
{code:java}
import org.apache.calcite.config.Lex;
import org.apache.calcite.sql.SqlCharStringLiteral;
import org.apache.calcite.sql.SqlSelect;
import org.apache.calcite.sql.parser.SqlParser;
import org.apache.calcite.sql.validate.SqlConformanceEnum;

var config = SqlParser.config()
    .withLex(Lex.BIG_QUERY)
    .withConformance(SqlConformanceEnum.BIG_QUERY);
var select = (SqlSelect) SqlParser.create("SELECT 'a\\nb'", 
config).parseQuery();
var literal = (SqlCharStringLiteral) select.getSelectList().get(0);
String value = literal.getValueAs(String.class);
System.out.println(value.length()); // actual: 4; expected: 3
value.codePoints().forEach(cp -> System.out.printf("U+%04X ", cp));
// actual:   U+0061 U+005C U+006E U+0062
// expected: U+0061 U+000A U+0062
{code}

h3. SQL examples
The following examples show SQL source text, not Java string literals.
{noformat}
SELECT 'a\nb'
  Expected: a + newline + b (3 characters)
  Actual:   a + backslash + n + b (4 characters)

SELECT 'a\\b'
  Expected: a + one backslash + b (3 characters)
  Actual:   a + two backslashes + b (4 characters)

SELECT 'a\qb'
  Expected under GoogleSQL rules: invalid escape sequence error
  Actual: the backslash and q are preserved
{noformat}

The same issue affects double-quoted string literals. {{SimpleStringLiteral}} 
should also apply the same decoding when used for typed literals such as DATE.

GoogleSQL treats backslash as an escape introducer in ordinary string literals, 
including backslashes, newlines, tabs, and numerical/Unicode escapes. Quotation 
removal alone does not produce the specified value.

{{SqlParserUtil.replaceEscapedChars}} can already decode several common 
sequences, but follows PostgreSQL-style rules and differs from GoogleSQL for 
some sequences and malformed input. Reusing it could address common cases; 
exact GoogleSQL compatibility would require checking those differences. Raw 
string support is a separate feature and is not required to reproduce this bug.

h3. Related issues
* CALCITE-4247 and CALCITE-4847 added BigQuery quotation handling, but do not 
cover the remaining escape decoding.
* PR #5094 and CALCITE-7781 address SQL generation/unparsing, rather than 
parsing input SQL.

h3. References
* 
https://docs.cloud.google.com/bigquery/docs/reference/standard-sql/lexical#escape_sequences_for_string_and_bytes_literals
* 
https://github.com/apache/calcite/blob/main/core/src/main/codegen/templates/Parser.jj
* https://github.com/apache/calcite/pull/5094




--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to