-
Notifications
You must be signed in to change notification settings - Fork 100
fix: sql fn params #366
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
fix: sql fn params #366
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR fixes SQL function parameter substitution by replacing function parameters with type‐based default values while refactoring SQL function signature extraction and integrating these changes into the typecheck flow.
- Added utility methods to StatementId.
- Refactored SQL function parsing to utilize SQLFunctionSignature and SQLFunctionArgs.
- Updated document parsing, typecheck, and identifier application with improved default value resolution.
Reviewed Changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 3 comments.
Show a summary per file
File | Description |
---|---|
crates/pgt_workspace/src/workspace/server/statement_identifier.rs | Added helper methods (is_root, is_child, parent) for statement hierarchy. |
crates/pgt_workspace/src/workspace/server/sql_function.rs | Introduced SQLFunctionSignature and revamped function parameter extraction. |
crates/pgt_workspace/src/workspace/server/parsed_document.rs | Removed legacy SQLFunctionBodyStore and integrated new SQL function extraction. |
crates/pgt_workspace/src/workspace/server/document.rs | Added statement_content method to get statement SQL content. |
crates/pgt_workspace/src/workspace/server.rs | Updated typecheck integration with new schema cache and identifier handling. |
crates/pgt_typecheck/src/typed_identifier.rs | Enhanced apply_identifiers with default value formatting and support for type-based defaults. |
crates/pgt_treesitter_queries | Updated parameter extraction queries and tests for ParameterMatch. |
Other files | Minor adjustments to tests, diagnostics, and schema cache types to support the changes. |
Comments suppressed due to low confidence (1)
crates/pgt_workspace/src/workspace/server.rs:376
- [nitpick] The async block here could be refactored for improved readability and maintainability. A clearer structure may help future developers understand the schema cache and identifier propagation logic.
// sorry for the ugly code :(
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just details, the concept looks great!
if parts.len() == 1 && parts[0].starts_with('$') { | ||
let idx = parts[0][1..].parse::<usize>().ok()?; | ||
let identifier = identifiers.get(idx - 1)?; | ||
return Some((identifier, idx)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sehr nice
assert_eq!( | ||
sql_out, | ||
"select 0 + 0 + 0 + 0 + 0 + NULL " | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assert_eq!( | |
sql_out, | |
"select 0 + 0 + 0 + 0 + 0 + NULL " | |
); | |
// the numeric parameters are filled with 0; the enum does not have a default, so it's filled with `null` | |
assert_eq!( | |
sql_out, | |
"select 0 + 0 + 0 + 0 + 0 + NULL " | |
); |
db: DashMap<StatementId, Option<Arc<SQLFunctionBody>>>, | ||
#[derive(Debug, Clone)] | ||
pub struct SQLFunctionSignature { | ||
pub name: (Option<String>, String), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: i think it would be more readable if it had a name
and a schema
property
pub struct SQLFunctionBody { | ||
pub range: TextRange, | ||
pub body: String, | ||
pub struct SQLFunctionArgs { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is a single Arg
right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes!
// If not cached, try to extract it from the AST | ||
let fn_body = get_sql_fn(ast, content).map(Arc::new); | ||
// Extract language from function options | ||
let language = find_option_value(create_fn, "language")?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i really like that api
// If the default value is longer than "NULL", use "NULL" instead | ||
"NULL".to_string() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why are we doing this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
because we need to throw away positions when the replacement is longer than its original, and NULL
will be shorter than a few default values (e.g. timestamps or custom enums)
|
||
let mut result = sql.to_string(); | ||
|
||
let mut valid_positions = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what position
is in this context.
I understand it this way: We'll need to adjust the statements ranges if a parameter's default value is longer than the substituted text.
If that's correct, how about we rename this to something like should_adjust_ranges
(default false) ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sometimes (almost never), we get a position back for the type error. in that case, we show the diagnostics on that position instead of the entire statement. since we are replacing the vars in the text, the position we get back does not match the position in the original statement anymore if the replacements are not the same length. hence, if valid_positions
is false
, we throw away the position from the type error and always show the error on the entire length of the statement.
the idea is to replace the fn params with a default value based on their type:
will become
Todo
apply_identifiers
fixes #353
fixes #352