Add support for escaping single quote strings

This commit is contained in:
Justin Haug 2019-04-22 13:32:05 -04:00
parent 5b464e6b1a
commit 80dccf6885
3 changed files with 39 additions and 2 deletions

View file

@ -35,7 +35,7 @@ impl ToString for Value {
Value::Long(v) => v.to_string(),
Value::Double(v) => v.to_string(),
Value::Uuid(v) => v.to_string(),
Value::SingleQuotedString(v) => format!("'{}'", v),
Value::SingleQuotedString(v) => format!("'{}'", escape_single_quote_string(v)),
Value::NationalStringLiteral(v) => format!("N'{}'", v),
Value::Boolean(v) => v.to_string(),
Value::Date(v) => v.to_string(),
@ -46,3 +46,15 @@ impl ToString for Value {
}
}
}
fn escape_single_quote_string(s: &str) -> String {
let mut escaped = String::new();
for c in s.chars() {
if c == '\'' {
escaped.push_str("\'\'");
} else {
escaped.push(c);
}
}
escaped
}

View file

@ -462,7 +462,15 @@ impl<'a> Tokenizer<'a> {
match ch {
'\'' => {
chars.next(); // consume
break;
let escaped_quote = chars.peek()
.map(|c| *c == '\'')
.unwrap_or(false);
if escaped_quote {
s.push('\'');
chars.next();
} else {
break;
}
}
_ => {
chars.next(); // consume

View file

@ -148,6 +148,23 @@ fn parse_projection_nested_type() {
//TODO: add assertions
}
#[test]
fn parse_escaped_single_quote_string_predicate() {
use self::ASTNode::*;
use self::SQLOperator::*;
let sql = "SELECT id, fname, lname FROM customer \
WHERE salary != 'Jim''s salary'";
let ast = verified_only_select(sql);
assert_eq!(
Some(SQLBinaryExpr {
left: Box::new(SQLIdentifier("salary".to_string())),
op: NotEq,
right: Box::new(SQLValue(Value::SingleQuotedString("Jim's salary".to_string())))
}),
ast.selection,
);
}
#[test]
fn parse_compound_expr_1() {
use self::ASTNode::*;