Skip to content

[SPARK-59672][SQL] Bind SQL parameters when a custom parser is injected - #58932

Open
franciscoabsampaio wants to merge 1 commit into
apache:masterfrom
franciscoabsampaio:SPARK-parameterized-sql-injected-parser
Open

franciscoabsampaio wants to merge 1 commit into
apache:masterfrom
franciscoabsampaio:SPARK-parameterized-sql-injected-parser

Conversation

@franciscoabsampaio

Copy link
Copy Markdown

What changes were proposed in this pull request?

ParserInterface.parsePlanWithParameters had a default implementation that discarded the ParameterContext and called parsePlan(sqlText). Only SparkSqlParser overrides it, so any parser injected through SparkSessionExtensions.injectParser silently dropped the parameter values.

The default now marks the parsed plan for parameter binding during analysis, using the same ParameterizedQuery nodes the analyzer already applies in legacy mode, so implementations that only override parsePlan keep working with parameterized SQL.

Why are the changes needed?

Since SPARK-53573 moved parameter handling into a parser pre-processor, spark.sql(query, args) fails with UNBOUND_SQL_PARAMETER on any session that sets spark.sql.extensions, for both positional and named parameters, in classic Spark and through Spark Connect. Delta Lake and Apache Iceberg both inject a parser, so parameterized SQL - the recommended defence against SQL injection - is unusable for their users on 4.1.x.

Does this PR introduce any user-facing change?

Yes. Parameterized SQL works again on sessions with an injected parser. Parameter markers are bound wherever the parser produces a parameter expression; parsers that want markers in every position a literal is allowed should override parsePlanWithParameters, as SparkSqlParser does.

How was this patch tested?

New test in SparkSessionExtensionSuite covering positional and named parameters through an injected parser, unbound markers still being rejected, and legacy mode. It fails without the change with UNBOUND_SQL_PARAMETER. Also ran ParametersSuite, LegacyParameterSubstitutionSuite, SparkSessionExtensionSuite, SparkConnectWithSessionExtensionSuite and SparkConnectPlannerSuite, plus scalastyle.

Was this patch authored or co-authored using generative AI tooling?

Generated-by: Claude Opus 5

### What changes were proposed in this pull request?

`ParserInterface.parsePlanWithParameters` had a default implementation that
discarded the `ParameterContext` and called `parsePlan(sqlText)`. Only
`SparkSqlParser` overrides it, so any parser injected through
`SparkSessionExtensions.injectParser` silently dropped the parameter values.

The default now marks the parsed plan for parameter binding during analysis,
using the same `ParameterizedQuery` nodes the analyzer already applies in
legacy mode, so implementations that only override `parsePlan` keep working
with parameterized SQL.

### Why are the changes needed?

Since SPARK-53573 moved parameter handling into a parser pre-processor,
`spark.sql(query, args)` fails with `UNBOUND_SQL_PARAMETER` on any session
that sets `spark.sql.extensions`, for both positional and named parameters,
in classic Spark and through Spark Connect. Delta Lake and Apache Iceberg both
inject a parser, so parameterized SQL - the recommended defence against SQL
injection - is unusable for their users on 4.1.x.

### Does this PR introduce any user-facing change?

Yes. Parameterized SQL works again on sessions with an injected parser.
Parameter markers are bound wherever the parser produces a parameter
expression; parsers that want markers in every position a literal is allowed
should override `parsePlanWithParameters`, as `SparkSqlParser` does.

### How was this patch tested?

New test in `SparkSessionExtensionSuite` covering positional and named
parameters through an injected parser, unbound markers still being rejected,
and legacy mode. It fails without the change with `UNBOUND_SQL_PARAMETER`.
Also ran `ParametersSuite`, `LegacyParameterSubstitutionSuite`,
`SparkSessionExtensionSuite`, `SparkConnectWithSessionExtensionSuite` and
`SparkConnectPlannerSuite`, plus scalastyle.

### Was this patch authored or co-authored using generative AI tooling?

Generated-by: Claude Opus 5

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@franciscoabsampaio
franciscoabsampaio force-pushed the SPARK-parameterized-sql-injected-parser branch from 642c22c to 96939fc Compare September 20, 2026 09:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant