@@ -39,6 +39,8 @@ pub enum Token {
3939 /// A character that could not be tokenized
4040 Char ( char ) ,
4141 /// Single quoted string: i.e: 'string'
42+ /// This should retains the escaped character sequences so that
43+ /// .to_string() of the value will give the value that was in the input
4244 SingleQuotedString ( String ) ,
4345 /// "National" string literal: i.e: N'string'
4446 NationalStringLiteral ( String ) ,
@@ -550,22 +552,28 @@ impl<'a> Tokenizer<'a> {
550552 ) -> Result < String , TokenizerError > {
551553 let mut s = String :: new ( ) ;
552554 chars. next ( ) ; // consume the opening quote
553- while let Some ( & ch) = chars. peek ( ) {
555+ while let Some ( ch) = chars. next ( ) {
556+ let next_char_is_quote = chars. peek ( ) . map ( |c| * c == '\'' ) . unwrap_or ( false ) ;
554557 match ch {
555- '\'' => {
556- chars. next ( ) ; // consume
557- let escaped_quote = chars. peek ( ) . map ( |c| * c == '\'' ) . unwrap_or ( false ) ;
558- if escaped_quote {
559- s. push ( '\'' ) ;
560- chars. next ( ) ;
561- } else {
562- return Ok ( s) ;
558+ // allow backslash to escape the next character, whatever it is
559+ '\\' => {
560+ s. push ( '\\' ) ;
561+ if let Some ( next_ch) = chars. next ( ) {
562+ s. push ( next_ch) ;
563563 }
564564 }
565- _ => {
566- chars. next ( ) ; // consume
567- s. push ( ch) ;
565+ // bq allows escaping only with backslash; other warehouses
566+ // allow escaping the quote character by repeating it
567+ _ if !dialect_of ! ( self is BigQueryDialect )
568+ && ch == '\''
569+ && next_char_is_quote =>
570+ {
571+ s. push ( '\'' ) ;
572+ s. push ( '\'' ) ;
573+ chars. next ( ) ; // consume '
568574 }
575+ '\'' => return Ok ( s) ,
576+ _ => s. push ( ch) ,
569577 }
570578 }
571579 self . tokenizer_error ( "Unterminated string literal" )
0 commit comments