*** a/src/backend/parser/scan.l --- b/src/backend/parser/scan.l *************** *** 162,168 **** --- 162,170 ---- %x xq %x xdolq %x xui + %x xuiend %x xus + %x xusend %x xeu /* *************** *** 279,295 **** /* Unicode escapes */ uescape [uU][eE][sS][cC][aA][pP][eE]{whitespace}*{quote}[^']{quote} /* error rule to avoid backup */ ! 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]) /* Quoted identifier with Unicode escapes */ xuistart [uU]&{dquote} - xuistop1 {dquote}{whitespace}*{uescapefail}? - xuistop2 {dquote}{whitespace}*{uescape} /* Quoted string with Unicode escapes */ xusstart [uU]&{quote} ! xusstop1 {quote}{whitespace}*{uescapefail}? ! xusstop2 {quote}{whitespace}*{uescape} /* error rule to avoid backup */ xufailed [uU]& --- 281,297 ---- /* Unicode escapes */ uescape [uU][eE][sS][cC][aA][pP][eE]{whitespace}*{quote}[^']{quote} /* error rule to avoid backup */ ! 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] /* Quoted identifier with Unicode escapes */ xuistart [uU]&{dquote} /* Quoted string with Unicode escapes */ xusstart [uU]&{quote} ! ! xustop1 {uescapefail}? ! xustop2 {uescape} ! /* error rule to avoid backup */ xufailed [uU]& *************** *** 536,549 **** yylval->str = litbufdup(yyscanner); return SCONST; } ! {xusstop1} { ! /* throw back all but the quote */ yyless(1); BEGIN(INITIAL); yylval->str = litbuf_udeescape('\\', yyscanner); return SCONST; } ! {xusstop2} { BEGIN(INITIAL); yylval->str = litbuf_udeescape(yytext[yyleng-2], yyscanner); return SCONST; --- 538,558 ---- yylval->str = litbufdup(yyscanner); return SCONST; } ! {quotestop} | ! {quotefail} { yyless(1); + BEGIN(xusend); + } + {whitespace} + {other} | + {xustop1} { + /* throw back everything */ + yyless(0); BEGIN(INITIAL); yylval->str = litbuf_udeescape('\\', yyscanner); return SCONST; } ! {xustop2} { BEGIN(INITIAL); yylval->str = litbuf_udeescape(yytext[yyleng-2], yyscanner); return SCONST; *************** *** 702,708 **** yylval->str = ident; return IDENT; } ! {xuistop1} { char *ident; BEGIN(INITIAL); --- 711,723 ---- yylval->str = ident; return IDENT; } ! {dquote} { ! yyless(1); ! BEGIN(xuiend); ! } ! {whitespace} { } ! {other} | ! {xustop1} { char *ident; BEGIN(INITIAL); *************** *** 712,722 **** if (yyextra->literallen >= NAMEDATALEN) truncate_identifier(ident, yyextra->literallen, true); yylval->str = ident; ! /* throw back all but the quote */ ! yyless(1); return IDENT; } ! {xuistop2} { char *ident; BEGIN(INITIAL); --- 727,736 ---- if (yyextra->literallen >= NAMEDATALEN) truncate_identifier(ident, yyextra->literallen, true); yylval->str = ident; ! /* throw back everything that follows the end quote */ return IDENT; } ! {xustop2} { char *ident; BEGIN(INITIAL);