@@ -166,7 +166,8 @@ static void escape_variable(bool as_ident);
166166 * <xe> extended quoted strings (support backslash escape sequences)
167167 * <xdolq> $foo$ quoted strings
168168 * <xui> quoted identifier with Unicode escapes
169- * <xus> quoted string with Unicode escapes
169+ * <xuiend> end of a quoted identifier with Unicode escapes, UESCAPE can follow * <xus> quoted string with Unicode escapes
170+ * <xusend> end of a quoted string with Unicode escapes, UESCAPE can follow
170171 *
171172 * Note: we intentionally don't mimic the backend's <xeu> state; we have
172173 * no need to distinguish it from <xe> state, and no good way to get out
@@ -182,7 +183,9 @@ static void escape_variable(bool as_ident);
182183%x xq
183184%x xdolq
184185%x xui
186+ %x xuiend
185187%x xus
188+ %x xusend
186189/* Additional exclusive states for psql only: lex backslash commands*/
187190%x xslashcmd
188191%x xslashargstart
@@ -307,17 +310,17 @@ xdinside[^"]+
307310/* Unicode escapes*/
308311uescape[uU][eE][sS ][cC][aA][pP][eE]{whitespace}*{quote}[^' ]{quote}
309312/* error rule to avoid backup */
310- uescapefail("-"| [uU][eE][sS][cC][aA][pP][eE]{whitespace}*"-"|[uU][eE][sS][cC][aA][pP][eE]{whitespace}*{quote}[^' ]|[uU][eE][sS ][cC][aA][pP][eE]{whitespace}*{quote}|[uU][eE][sS ][cC][aA][pP][eE]{whitespace}*|[uU][eE][sS ][cC][aA][pP]|[uU][eE][sS ][cC][aA]|[uU][eE][sS ][cC]|[uU][eE][sS ]|[uU][eE]|[uU])
313+ uescapefail[uU][eE][sS][cC][aA][pP][eE]{whitespace}*"-"|[uU][eE][sS][cC][aA][pP][eE]{whitespace}*{quote}[^' ]|[uU][eE][sS ][cC][aA][pP][eE]{whitespace}*{quote}|[uU][eE][sS ][cC][aA][pP][eE]{whitespace}*|[uU][eE][sS ][cC][aA][pP]|[uU][eE][sS ][cC][aA]|[uU][eE][sS ][cC]|[uU][eE][sS ]|[uU][eE]|[uU]
311314
312315/* Quoted identifier with Unicode escapes*/
313316xuistart[uU]&{dquote}
314- xuistop1{dquote}{whitespace}*{uescapefail}?
315- xuistop2{dquote}{whitespace}*{uescape}
316317
317318/* Quoted string with Unicode escapes*/
318319xusstart[uU]&{quote}
319- xusstop1{quote}{whitespace}*{uescapefail}?
320- xusstop2{quote}{whitespace}*{uescape}
320+
321+ /* Optional UESCAPE after a quoted string or identifier with Unicode escapes.*/
322+ xustop1{uescapefail}?
323+ xustop2{uescape}
321324
322325/* error rule to avoid backup*/
323326xufailed[uU]&
@@ -520,12 +523,22 @@ other.
520523BEGIN (INITIAL);
521524ECHO;
522525}
523- <xus>{xusstop1} {
526+ <xus>{quotestop} |
527+ <xus>{quotefail} {
524528yyless (1 );
529+ BEGIN (xusend);
530+ ECHO;
531+ }
532+ <xusend>{whitespace} {
533+ ECHO;
534+ }
535+ <xusend>{other} |
536+ <xusend>{xustop1} {
537+ yyless (0 );
525538BEGIN (INITIAL);
526539ECHO;
527540}
528- <xus>{xusstop2 } {
541+ <xusend>{xustop2 } {
529542BEGIN (INITIAL);
530543ECHO;
531544}
@@ -612,12 +625,21 @@ other.
612625BEGIN (INITIAL);
613626ECHO;
614627}
615- <xui>{xuistop1} {
628+ <xui>{dquote} {
616629yyless (1 );
630+ BEGIN (xuiend);
631+ ECHO;
632+ }
633+ <xuiend>{whitespace} {
634+ ECHO;
635+ }
636+ <xuiend>{other} |
637+ <xuiend>{xustop1} {
638+ yyless (0 );
617639BEGIN (INITIAL);
618640ECHO;
619641}
620- <xui>{xuistop2 }{
642+ <xuiend>{xustop2 }{
621643BEGIN (INITIAL);
622644ECHO;
623645}