@@ -167,12 +167,12 @@ class ExpressionParserSuite extends PlanTest {
167167 }
168168
169169 test(" like expressions with ESCAPED_STRING_LITERALS = true" ) {
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)
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+ }
176176 }
177177
178178 test(" is null expressions" ) {
@@ -435,86 +435,85 @@ class ExpressionParserSuite extends PlanTest {
435435 }
436436
437437 test(" strings" ) {
438+ val parser = CatalystSqlParser
438439 Seq (true , false ).foreach { escape =>
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)
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+ }
516516 }
517-
518517 }
519518 }
520519
0 commit comments