Skip to content

feat(jdbc): Implement named parameter support in PreparedStatement#7

Open
rovshan-b wants to merge 3 commits intomainfrom
feature/arrow-support-named-bind-variables
Open

feat(jdbc): Implement named parameter support in PreparedStatement#7
rovshan-b wants to merge 3 commits intomainfrom
feature/arrow-support-named-bind-variables

Conversation

@rovshan-b
Copy link
Copy Markdown

@rovshan-b rovshan-b commented Apr 29, 2026

Add named bind parameter support (:name syntax)

The Arrow Flight JDBC driver previously only supported positional ? parameters. This PR adds
named parameter support entirely on the client side — no server changes required.

Usage

// Before — positional only
PreparedStatement ps = conn.prepareStatement(
    "SELECT * FROM orders WHERE id = ? AND status = ?");
ps.setInt(1, 42);
ps.setString(2, "active");

// After — named parameters (cast to NamedPreparedStatement to access named setters)
NamedPreparedStatement ps = (NamedPreparedStatement) conn.prepareStatement(
    "SELECT * FROM orders WHERE id = :id AND status = :status");
ps.setInt("id", 42);
ps.setString("status", "active");

// Duplicate name — both slots receive the same value automatically
NamedPreparedStatement ps = (NamedPreparedStatement) conn.prepareStatement(
    "SELECT * FROM events WHERE start_date = :date OR end_date = :date");
ps.setDate("date", someDate);

conn.prepareStatement() always returns a NamedPreparedStatement (which extends
PreparedStatement), so the cast is always safe — regardless of whether the SQL uses named
or positional parameters. This matches the pattern of Oracle's OraclePreparedStatement.
All existing setXxx(int index, …) positional calls continue to work unchanged on the same object.

What's in this PR

File Change
NamedPreparedStatement.java New — public interface extending PreparedStatement, declares all named-param setXxx(String, …) methods
NamedParamStatement.java New (package-private) — NamedPreparedStatement decorator; resolves each name to its 1-based positional index(es) and forwards to the delegate
utils/NamedSqlParser.java New — single-pass SQL scanner, translates :name?, builds name→index maps, rejects mixed ?/:name queries
ArrowFlightConnection.java Override all prepareStatement(String, …) variants to unconditionally wrap in NamedParamStatement
utils/NamedSqlParserTest.java 11 pure unit tests (string literals, comments, PG casts, mixed-param rejection, etc.)
NamedParamStatementTest.java 6 integration tests against the mock Flight SQL server

Notes

  • Translation from :name? is client-side only — the server receives a standard positional query unchanged.
  • PostgreSQL-style casts (col::int) are correctly left untouched.
  • :name tokens inside string literals ('…', "…") and comments (--, /* */) are ignored.
  • Mixing ? and :name in the same query throws SQLException.
  • Unknown parameter names throw SQLException("Unknown parameter name: '<name>'").
  • NamedParamStatement is package-private — callers always program against the NamedPreparedStatement interface.

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