Skip to content
This repository has been archived by the owner on Oct 18, 2023. It is now read-only.

query_analysis: allow CREATE FUNCTION statement #365

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 32 additions & 13 deletions sqld/src/query_analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,25 +200,44 @@ impl Statement {
is_insert,
})
}

// Workaround for CREATE FUNCTION.
// FIXME: this should be handled by the parser (or *at least* trimmed + case insensitive)
let is_create_function = s.starts_with("CREATE FUNCTION");
Copy link
Collaborator

Choose a reason for hiding this comment

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

yeah this needs to be handled by the parser 100%, trimming and case insensitive won't be enough, there can be an arbitrary number of whitespace between create and function

let mut maybe_create_function_stmt = is_create_function.then(|| {
Ok(Statement {
stmt: s.to_string(),
kind: StmtKind::Other,
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is definitely a write

is_iud: false,
is_insert: false,
})
});

// The parser needs to be boxed because it's large, and you don't want it on the stack.
// There's upstream work to make it smaller, but in the meantime the parser should remain
// on the heap:
// - https://github.com/gwenn/lemon-rs/issues/8
// - https://github.com/gwenn/lemon-rs/pull/19
let mut parser = Box::new(Parser::new(s.as_bytes()));
std::iter::from_fn(move || match parser.next() {
Ok(Some(cmd)) => Some(parse_inner(s, cmd)),
Ok(None) => None,
Err(sqlite3_parser::lexer::sql::Error::ParserError(
ParserError::SyntaxError {
token_type: _,
found: Some(found),
},
Some((line, col)),
)) => Some(Err(anyhow::anyhow!(
"syntax error around L{line}:{col}: `{found}`"
))),
Err(e) => Some(Err(e.into())),
std::iter::from_fn(move || {
if is_create_function {
return maybe_create_function_stmt.take();
}
Comment on lines +223 to +225
Copy link
Collaborator

Choose a reason for hiding this comment

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

this is not correct, the string can contain multiple statements


match parser.next() {
Ok(Some(cmd)) => Some(parse_inner(s, cmd)),
Ok(None) => None,
Err(sqlite3_parser::lexer::sql::Error::ParserError(
ParserError::SyntaxError {
token_type: _,
found: Some(found),
},
Some((line, col)),
)) => Some(Err(anyhow::anyhow!(
"syntax error around L{line}:{col}: `{found}`"
))),
Err(e) => Some(Err(e.into())),
}
})
}

Expand Down