@@ -167,12 +167,12 @@ class ExpressionParserSuite extends PlanTest {
167167 }
168168
169169 test(" like expressions with ESCAPED_STRING_LITERALS = true" ) {
170- val parser = CatalystSqlParser
171- withSQLConf (SQLConf .ESCAPED_STRING_LITERALS .key -> " true" ) {
172- assertEqual( " a rlike '^ \\ x20[ \\ x20- \\ x23]+$' " , ' a rlike " ^ \\ x20[ \\ x20- \\ x23]+$ " , parser )
173- assertEqual(" a rlike 'pattern \\\\ '" , ' a rlike " pattern \\\\ " , parser)
174- assertEqual(" a rlike 'pattern\\ t \\ n '" , ' a rlike " pattern\\ t \\ n " , parser)
175- }
170+ val conf = new SQLConf ()
171+ conf.setConfString (SQLConf .ESCAPED_STRING_LITERALS .key, " true" )
172+ val parser = new CatalystSqlParser (conf )
173+ assertEqual(" a rlike '^ \\ x20[ \\ x20- \\ x23]+$ '" , ' a rlike " ^ \\ x20[ \\ x20- \\ x23]+$ " , parser)
174+ assertEqual(" a rlike 'pattern\\\\ '" , ' a rlike " pattern\\\\ " , parser)
175+ assertEqual( " a rlike 'pattern \\ t \\ n' " , ' a rlike " pattern \\ t \\ n " , parser)
176176 }
177177
178178 test(" is null expressions" ) {
@@ -435,85 +435,86 @@ class ExpressionParserSuite extends PlanTest {
435435 }
436436
437437 test(" strings" ) {
438- val parser = CatalystSqlParser
439438 Seq (true , false ).foreach { escape =>
440- withSQLConf(SQLConf .ESCAPED_STRING_LITERALS .key -> escape.toString) {
441- // tests that have same result whatever the conf is
442- // Single Strings.
443- assertEqual(" \" hello\" " , " hello" , parser)
444- assertEqual(" 'hello'" , " hello" , parser)
445-
446- // Multi-Strings.
447- assertEqual(" \" hello\" 'world'" , " helloworld" , parser)
448- assertEqual(" 'hello' \" \" 'world'" , " hello world" , parser)
449-
450- // 'LIKE' string literals. Notice that an escaped '%' is the same as an escaped '\' and a
451- // regular '%'; to get the correct result you need to add another escaped '\'.
452- // TODO figure out if we shouldn't change the ParseUtils.unescapeSQLString method?
453- assertEqual(" 'pattern%'" , " pattern%" , parser)
454- assertEqual(" 'no-pattern\\ %'" , " no-pattern\\ %" , parser)
455-
456- // tests that have different result regarding the conf
457- if (escape) {
458- // When SQLConf.ESCAPED_STRING_LITERALS is enabled, string literal parsing fallbacks to
459- // Spark 1.6 behavior.
460-
461- // 'LIKE' string literals.
462- assertEqual(" 'pattern\\\\ %'" , " pattern\\\\ %" , parser)
463- assertEqual(" 'pattern\\\\\\ %'" , " pattern\\\\\\ %" , parser)
464-
465- // Escaped characters.
466- // Unescape string literal "'\\0'" for ASCII NUL (X'00') doesn't work
467- // when ESCAPED_STRING_LITERALS is enabled.
468- // It is parsed literally.
469- assertEqual(" '\\ 0'" , " \\ 0" , parser)
470-
471- // Note: Single quote follows 1.6 parsing behavior when ESCAPED_STRING_LITERALS is
472- // enabled.
473- val e = intercept[ParseException ](parser.parseExpression(" '\' '" ))
474- assert(e.message.contains(" extraneous input '''" ))
475-
476- // The unescape special characters (e.g., "\\t") for 2.0+ don't work
477- // when ESCAPED_STRING_LITERALS is enabled. They are parsed literally.
478- assertEqual(" '\\\" '" , " \\\" " , parser) // Double quote
479- assertEqual(" '\\ b'" , " \\ b" , parser) // Backspace
480- assertEqual(" '\\ n'" , " \\ n" , parser) // Newline
481- assertEqual(" '\\ r'" , " \\ r" , parser) // Carriage return
482- assertEqual(" '\\ t'" , " \\ t" , parser) // Tab character
483-
484- // The unescape Octals for 2.0+ don't work when ESCAPED_STRING_LITERALS is enabled.
485- // They are parsed literally.
486- assertEqual(" '\\ 110\\ 145\\ 154\\ 154\\ 157\\ 041'" , " \\ 110\\ 145\\ 154\\ 154\\ 157\\ 041" , parser)
487- // The unescape Unicode for 2.0+ doesn't work when ESCAPED_STRING_LITERALS is enabled.
488- // They are parsed literally.
489- assertEqual(" '\\ u0057\\ u006F\\ u0072\\ u006C\\ u0064\\ u0020\\ u003A\\ u0029'" ,
490- " \\ u0057\\ u006F\\ u0072\\ u006C\\ u0064\\ u0020\\ u003A\\ u0029" , parser)
491- } else {
492- // Default behavior
493-
494- // 'LIKE' string literals.
495- assertEqual(" 'pattern\\\\ %'" , " pattern\\ %" , parser)
496- assertEqual(" 'pattern\\\\\\ %'" , " pattern\\\\ %" , parser)
497-
498- // Escaped characters.
499- // See: http://dev.mysql.com/doc/refman/5.7/en/string-literals.html
500- assertEqual(" '\\ 0'" , " \u0000 " , parser) // ASCII NUL (X'00')
501- assertEqual(" '\\ ''" , " \' " , parser) // Single quote
502- assertEqual(" '\\\" '" , " \" " , parser) // Double quote
503- assertEqual(" '\\ b'" , " \b " , parser) // Backspace
504- assertEqual(" '\\ n'" , " \n " , parser) // Newline
505- assertEqual(" '\\ r'" , " \r " , parser) // Carriage return
506- assertEqual(" '\\ t'" , " \t " , parser) // Tab character
507- assertEqual(" '\\ Z'" , " \u001A " , parser) // ASCII 26 - CTRL + Z (EOF on windows)
508-
509- // Octals
510- assertEqual(" '\\ 110\\ 145\\ 154\\ 154\\ 157\\ 041'" , " Hello!" , parser)
511-
512- // Unicode
513- assertEqual(" '\\ u0057\\ u006F\\ u0072\\ u006C\\ u0064\\ u0020\\ u003A\\ u0029'" , " World :)" ,
514- parser)
515- }
439+ val conf = new SQLConf ()
440+ conf.setConfString(SQLConf .ESCAPED_STRING_LITERALS .key, escape.toString)
441+ val parser = new CatalystSqlParser (conf)
442+
443+ // tests that have same result whatever the conf is
444+ // Single Strings.
445+ assertEqual(" \" hello\" " , " hello" , parser)
446+ assertEqual(" 'hello'" , " hello" , parser)
447+
448+ // Multi-Strings.
449+ assertEqual(" \" hello\" 'world'" , " helloworld" , parser)
450+ assertEqual(" 'hello' \" \" 'world'" , " hello world" , parser)
451+
452+ // 'LIKE' string literals. Notice that an escaped '%' is the same as an escaped '\' and a
453+ // regular '%'; to get the correct result you need to add another escaped '\'.
454+ // TODO figure out if we shouldn't change the ParseUtils.unescapeSQLString method?
455+ assertEqual(" 'pattern%'" , " pattern%" , parser)
456+ assertEqual(" 'no-pattern\\ %'" , " no-pattern\\ %" , parser)
457+
458+ // tests that have different result regarding the conf
459+ if (escape) {
460+ // When SQLConf.ESCAPED_STRING_LITERALS is enabled, string literal parsing fallbacks to
461+ // Spark 1.6 behavior.
462+
463+ // 'LIKE' string literals.
464+ assertEqual(" 'pattern\\\\ %'" , " pattern\\\\ %" , parser)
465+ assertEqual(" 'pattern\\\\\\ %'" , " pattern\\\\\\ %" , parser)
466+
467+ // Escaped characters.
468+ // Unescape string literal "'\\0'" for ASCII NUL (X'00') doesn't work
469+ // when ESCAPED_STRING_LITERALS is enabled.
470+ // It is parsed literally.
471+ assertEqual(" '\\ 0'" , " \\ 0" , parser)
472+
473+ // Note: Single quote follows 1.6 parsing behavior when ESCAPED_STRING_LITERALS is enabled.
474+ val e = intercept[ParseException ](parser.parseExpression(" '\' '" ))
475+ assert(e.message.contains(" extraneous input '''" ))
476+
477+ // The unescape special characters (e.g., "\\t") for 2.0+ don't work
478+ // when ESCAPED_STRING_LITERALS is enabled. They are parsed literally.
479+ assertEqual(" '\\\" '" , " \\\" " , parser) // Double quote
480+ assertEqual(" '\\ b'" , " \\ b" , parser) // Backspace
481+ assertEqual(" '\\ n'" , " \\ n" , parser) // Newline
482+ assertEqual(" '\\ r'" , " \\ r" , parser) // Carriage return
483+ assertEqual(" '\\ t'" , " \\ t" , parser) // Tab character
484+
485+ // The unescape Octals for 2.0+ don't work when ESCAPED_STRING_LITERALS is enabled.
486+ // They are parsed literally.
487+ assertEqual(" '\\ 110\\ 145\\ 154\\ 154\\ 157\\ 041'" , " \\ 110\\ 145\\ 154\\ 154\\ 157\\ 041" , parser)
488+ // The unescape Unicode for 2.0+ doesn't work when ESCAPED_STRING_LITERALS is enabled.
489+ // They are parsed literally.
490+ assertEqual(" '\\ u0057\\ u006F\\ u0072\\ u006C\\ u0064\\ u0020\\ u003A\\ u0029'" ,
491+ " \\ u0057\\ u006F\\ u0072\\ u006C\\ u0064\\ u0020\\ u003A\\ u0029" , parser)
492+ } else {
493+ // Default behavior
494+
495+ // 'LIKE' string literals.
496+ assertEqual(" 'pattern\\\\ %'" , " pattern\\ %" , parser)
497+ assertEqual(" 'pattern\\\\\\ %'" , " pattern\\\\ %" , parser)
498+
499+ // Escaped characters.
500+ // See: http://dev.mysql.com/doc/refman/5.7/en/string-literals.html
501+ assertEqual(" '\\ 0'" , " \u0000 " , parser) // ASCII NUL (X'00')
502+ assertEqual(" '\\ ''" , " \' " , parser) // Single quote
503+ assertEqual(" '\\\" '" , " \" " , parser) // Double quote
504+ assertEqual(" '\\ b'" , " \b " , parser) // Backspace
505+ assertEqual(" '\\ n'" , " \n " , parser) // Newline
506+ assertEqual(" '\\ r'" , " \r " , parser) // Carriage return
507+ assertEqual(" '\\ t'" , " \t " , parser) // Tab character
508+ assertEqual(" '\\ Z'" , " \u001A " , parser) // ASCII 26 - CTRL + Z (EOF on windows)
509+
510+ // Octals
511+ assertEqual(" '\\ 110\\ 145\\ 154\\ 154\\ 157\\ 041'" , " Hello!" , parser)
512+
513+ // Unicode
514+ assertEqual(" '\\ u0057\\ u006F\\ u0072\\ u006C\\ u0064\\ u0020\\ u003A\\ u0029'" , " World :)" ,
515+ parser)
516516 }
517+
517518 }
518519 }
519520
0 commit comments