Skip to content

Support with_parameter and with_parameters in query engine#125

Open
leiyuou wants to merge 3 commits intolance-format:mainfrom
leiyuou:yuolei/para
Open

Support with_parameter and with_parameters in query engine#125
leiyuou wants to merge 3 commits intolance-format:mainfrom
leiyuou:yuolei/para

Conversation

@leiyuou
Copy link
Contributor

@leiyuou leiyuou commented Feb 4, 2026

Support $param, @param, :param, and {param} placeholder in query engine.

Key Changes:

  1. Storage user parameter in a HashMap
  2. Propagate parameters down to the expression planning layer through PlanningContext
  3. Replace parameter placeholders with their corresponding user-provided values during query planning.
  4. Added end-to-end tests in both Rust and Python to verify correct parsing and execution of parameterized queries.

Closes #103.

@leiyuou leiyuou changed the title Support with_parameter and with_parameters in query engine Support with_parameter and with_parameters in query engine (WIP) Feb 4, 2026
@codecov-commenter
Copy link

Codecov Report

❌ Patch coverage is 89.86784% with 23 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...s/lance-graph/src/datafusion_planner/expression.rs 88.78% 12 Missing ⚠️
crates/lance-graph/src/parser.rs 82.81% 11 Missing ⚠️

📢 Thoughts on this report? Let us know!

@leiyuou leiyuou changed the title Support with_parameter and with_parameters in query engine (WIP) Support with_parameter and with_parameters in query engine Feb 4, 2026
Copy link
Collaborator

@ChunxuTang ChunxuTang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@leiyuou Thanks for the contribution! This is a very nice work.

I carefully re-evaluated the three design options for the parameter support, and I think it's better to go with option 1 (replacing the parameters during the semantic analysis pass). Could you update the PR?

Comment on lines +975 to +986
alt((
// $param
map(preceded(char('$'), identifier), |s| s.to_string()),
// @param
map(preceded(char('@'), identifier), |s| s.to_string()),
// :param
map(preceded(char(':'), identifier), |s| s.to_string()),
// {param}
map(delimited(char('{'), identifier, char('}')), |s| {
s.to_string()
}),
))(input)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Formal Cypher syntax only supports using $ for parameters. Could you remove other special symbols?

assert "company" in engine_config.node_labels()


def test_cypher_parameter_syntax(graph_env):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new test is unrelated to the CypherEngine API: maybe put it into the test_graph.py?

Comment on lines -327 to -330
// 1. Resolve parameters during semantic analysis (substitute before planning)
// 2. Pass parameter map to to_df_value_expr and resolve here
// 3. Use DataFusion's parameter binding mechanism
col(format!("${}", name))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@leiyuou I've carefully considered the design options here, and I think it's better to go with option 1 for now. Here are the rationales:

  1. If using option 2/3, we can only support parameters in the DataFusion planner, but we also have the simple executor and later Lance native planner. We'll have to re-implement similar mechanisms in all these planners.

  2. Very recently, we added a case-insensitivity enforcement feat: implement case-insensitive support #119), which lowers all table/column/alias names. But the parameters here are case-sensitive, which will cause execution failures. It's better to replace them during the semantic analysis step.

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.

feat: Properly support parameter placeholders in Python/Rust

3 participants