mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-21 16:02:28 +00:00
143 lines
4.7 KiB
Rust
143 lines
4.7 KiB
Rust
// input should contain a single statement. remove all comments before and after it
|
|
pub fn remove_comments(stmt: &str) -> &str {
|
|
let mut in_stmt = false;
|
|
let mut in_line_comment = false;
|
|
let mut in_block_comment = false;
|
|
let mut in_string = false;
|
|
let mut string_delimiter = '\0';
|
|
let mut start_byte = None;
|
|
let mut end_byte = stmt.len();
|
|
|
|
let mut prev_char = '\0';
|
|
let mut char_indices = stmt.char_indices().peekable();
|
|
|
|
while let Some((byte_pos, c)) = char_indices.next() {
|
|
let next_char = char_indices.peek().map(|(_, ch)| *ch).unwrap_or('\0');
|
|
|
|
// Handle string literals (single or double quotes)
|
|
if !in_line_comment && !in_block_comment {
|
|
if (c == '\'' || c == '"') && prev_char != '\\' {
|
|
if in_string && c == string_delimiter {
|
|
// Exiting string
|
|
in_string = false;
|
|
string_delimiter = '\0';
|
|
} else if !in_string {
|
|
// Entering string
|
|
in_string = true;
|
|
string_delimiter = c;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Handle comments only when not inside a string
|
|
if !in_string {
|
|
// Check for start of line comment
|
|
if !in_block_comment && c == '-' && next_char == '-' {
|
|
in_line_comment = true;
|
|
}
|
|
// Check for end of line comment
|
|
else if in_line_comment && c == '\n' {
|
|
in_line_comment = false;
|
|
}
|
|
// Check for start of block comment
|
|
else if !in_line_comment && c == '/' && next_char == '*' {
|
|
in_block_comment = true;
|
|
}
|
|
// Check for end of block comment
|
|
else if in_block_comment && c == '*' && next_char == '/' {
|
|
in_block_comment = false;
|
|
// Skip the closing '/' by advancing the iterator
|
|
char_indices.next();
|
|
prev_char = '/';
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// Track statement boundaries
|
|
if !in_line_comment && !in_block_comment && !in_string {
|
|
// Mark start of statement
|
|
if !in_stmt && !c.is_whitespace() {
|
|
start_byte = Some(byte_pos);
|
|
in_stmt = true;
|
|
}
|
|
// Mark end of statement at semicolon
|
|
if in_stmt && c == ';' {
|
|
end_byte = byte_pos + c.len_utf8();
|
|
break;
|
|
}
|
|
}
|
|
|
|
prev_char = c;
|
|
}
|
|
|
|
&stmt[start_byte.unwrap_or(0)..end_byte]
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
// Tests for remove_comments function
|
|
#[test]
|
|
fn test_remove_comments_single_line() {
|
|
let sql = "-- This is a comment\nSELECT * FROM table;";
|
|
assert_eq!(remove_comments(sql), "SELECT * FROM table;");
|
|
}
|
|
#[test]
|
|
fn test_remove_comments_multi_line() {
|
|
let sql = "-- This is a comment\nSELECT * FROM table;\n-- Another comment";
|
|
assert_eq!(remove_comments(sql), "SELECT * FROM table;");
|
|
}
|
|
#[test]
|
|
fn test_remove_comments_inline_comment() {
|
|
let sql = " SELECT * FROM table; -- This is an inline comment ";
|
|
assert_eq!(remove_comments(sql), "SELECT * FROM table;");
|
|
}
|
|
#[test]
|
|
fn test_remove_comments_no_comments() {
|
|
let sql = "SELECT * FROM table;";
|
|
assert_eq!(remove_comments(sql), "SELECT * FROM table;");
|
|
}
|
|
#[test]
|
|
fn test_remove_comments_empty_string() {
|
|
let sql = "";
|
|
assert_eq!(remove_comments(sql), "");
|
|
}
|
|
#[test]
|
|
fn test_remove_comments_with_whitespace() {
|
|
let sql = " -- Comment\n -- Comment2\n -- Comment3\n SELECT\n\n * FROM\n table\n;\n\n -- end comment ";
|
|
assert_eq!(remove_comments(sql), "SELECT\n\n * FROM\n table\n;");
|
|
}
|
|
#[test]
|
|
fn test_remove_comments_comment_in_string() {
|
|
let sql = "SELECT '-- not a comment' FROM table;";
|
|
let result = remove_comments(sql);
|
|
assert_eq!(result, "SELECT '-- not a comment' FROM table;");
|
|
}
|
|
#[test]
|
|
fn test_remove_comments_multiple_dashes() {
|
|
let sql = "SELECT 5 - - 3;";
|
|
let result = remove_comments(sql);
|
|
// This correctly handles the subtraction of negative number
|
|
assert_eq!(result, sql);
|
|
}
|
|
|
|
#[test]
|
|
fn test_remove_comments_invalid_truncate() {
|
|
let sql = r#"-- Mise à jour de la table café
|
|
UPDATE xyz.abcd t
|
|
SET
|
|
uio = s.uio
|
|
FROM table1 s
|
|
WHERE t.attrib = s.attrib;
|
|
"#;
|
|
let expected = r#"UPDATE xyz.abcd t
|
|
SET
|
|
uio = s.uio
|
|
FROM table1 s
|
|
WHERE t.attrib = s.attrib;"#;
|
|
let result = remove_comments(sql);
|
|
assert_eq!(result.trim(), expected);
|
|
}
|
|
}
|