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

ASF GitHub Bot updated SPARK-60672:
-----------------------------------
    Labels: pull-request-available  (was: )

> Fix error offsets to use proepr codepoints
> ------------------------------------------
>
>                 Key: SPARK-60672
>                 URL: https://issues.apache.org/jira/browse/SPARK-60672
>             Project: Spark
>          Issue Type: Bug
>          Components: SQL
>    Affects Versions: 5.0.0
>            Reporter: Serge Rielau
>            Priority: Major
>              Labels: pull-request-available
>
> Things get strictly better wherever supplementary characters (emoji and other 
> characters above U+FFFF) are involved, and nothing changes for text without 
> them. Named-parameter substitution and procedure parameters can't regress in 
> their results, because the proposed changes only touch error rendering. The 
> real risk is narrower: it lies in doing the change incompletely.
> What is broken today. I ran a throwaway probe on the current branch, which 
> renders errors the same way as master; I didn't commit it. Every error after 
> a supplementary character is already wrong on the regular SQL path:
> ||Case||Fragment reported today||Correct||
> |{{SELECT '😀' AS a, DATE 'bad'}}|{{DATE 'bad}}|{{DATE 'bad'}}|
> |Same with ASCII {{'x'}}|{{DATE 'bad'}}|ok|
> |{{{}SELECT :p AS a, DATE 'bad'{}}}, {{p = '😀'}}|{{DATE 'bad}} (start 
> 15)|start 16|
> |Same with {{p = 'x'}}|{{DATE 'bad'}} (start 16)|ok|
> |Positional {{?}} with {{'😀'}}|{{DATE 'bad}}|wrong|
> |Unresolved column after a named {{'😀'}} value|{{no_such_co}}|wrong|
> |{{EXECUTE IMMEDIATE}} with an emoji|{{DATE 'bad}}|wrong|
> |Unresolved column after an emoji literal|{{no_such_co}}|wrong|
> The {{PRETTY}} caret is one column left in each wrong case. The parameter 
> rows matter most: the SQL text is pure ASCII, yet the position is still 
> wrong. That is because {{PositionMapper}} takes substitution bounds from 
> ANTLR (code points) but measures the replacement with {{String.length}} 
> (UTF-16 units).
> Why substitution and procedure parameters are safe.
>  * The text substitution itself, {{{}applySubstitutions{}}}, already converts 
> with {{{}offsetByCodePoints{}}}, and the existing emoji tests in 
> {{ParameterSubstitutionSuite}} cover it. The proposal doesn't touch it.
>  * {{PositionMapper}} is only used in {{{}Origin.context{}}}, which builds 
> error contexts. It plays no part in binding, so fixing it can only change 
> error text.
>  * Positional markers get their identity from ANTLR 
> ({{{}PosParameter(getStartIndex){}}}). Those indexes stay the same.
>  * Procedure, SQL-function and script parameter resolution never reads 
> {{Origin}} indexes.
> Where it is strictly no-change. If the text has no surrogate pairs, every 
> code-point index equals its UTF-16 index. So the fragment, caret and validity 
> check are the same for all ASCII, Latin-1 and other BMP text, which is nearly 
> every workload. Spark has no golden or test with a supplementary character in 
> an error context, so no expected outputs change.
> Real risks:
>  # The renderer and its producers must change together.
>  ** Three places set {{stopIndex}} from a UTF-16 length: parameterized 
> queries ({{{}SparkSqlParser{}}}), {{{}EXECUTE IMMEDIATE{}}}, and scripting 
> simple-CASE conditions. {{parse_sql}} is already in code points.
>  ** If the renderer switches but one producer doesn't, that producer's 
> whole-text context fails the stricter validity check and is dropped for text 
> with emoji. You would get no context, not a wrong one. Tests for each 
> producer catch this.
>  # Four places the reviewer didn't mention. These slice SQL text with 
> {{{}substring(startIndex, stopIndex + 1){}}}, outside the renderer:
>  ** {{SingleStatement.getText}}
>  ** {{SingleStatementExec.getText}}
>  ** {{ResolveExecuteImmediate.extractOriginalText}}
>  ** the pipelines file registration, which also reads {{origin.startIndex}}
> The first three only feed error messages, and they are already wrong after an 
> emoji because parser indexes are code points. If the CASE-condition producer 
> switches to code points, {{SingleStatementExec.getText}} would cut those 
> conditions short, but in practice that path can't be reached ({{{}x = v{}}} 
> is always a single-row BOOLEAN). They should move to code-point slicing in 
> the same change; that also fixes them.
>  # External clients that slice text themselves. Parser-origin indexes don't 
> change. For the three whole-text contexts, {{stopIndex}} drops by the number 
> of supplementary characters. A Java or JavaScript consumer that slices by 
> UTF-16 would then see that context short by that many characters, but that 
> consumer is already wrong for every parser-origin context. Python slices by 
> code points, so it gets more correct. I can't verify how Databricks editor 
> highlighting reads these indexes; it's worth checking separately.
>  # Edge and cost. A context whose code-point stop lies past the text's 
> code-point length is now dropped instead of rendered as garbage. Nothing else 
> costs more: the extra code-point walk only runs when an error context is 
> rendered.



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

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to