diff --git a/src/interfaces/ecpg/preproc/ecpg.trailer b/src/interfaces/ecpg/preproc/ecpg.trailer index 6ccc8ab9165..14ad27c3597 100644 --- a/src/interfaces/ecpg/preproc/ecpg.trailer +++ b/src/interfaces/ecpg/preproc/ecpg.trailer @@ -1715,13 +1715,13 @@ cvariable: CVARIABLE ecpg_param: PARAM { $$ = make_name(); } ; -ecpg_bconst: BCONST { $$ = make_name(); } ; +ecpg_bconst: BCONST { $$ = $1; } ; ecpg_fconst: FCONST { $$ = make_name(); } ; ecpg_sconst: SCONST { $$ = $1; } ; -ecpg_xconst: XCONST { $$ = make_name(); } ; +ecpg_xconst: XCONST { $$ = $1; } ; ecpg_ident: IDENT { $$ = $1; } | CSTRING { $$ = make3_str(mm_strdup("\""), $1, mm_strdup("\"")); } diff --git a/src/interfaces/ecpg/preproc/ecpg.type b/src/interfaces/ecpg/preproc/ecpg.type index ffafa82af9c..eca298bdb80 100644 --- a/src/interfaces/ecpg/preproc/ecpg.type +++ b/src/interfaces/ecpg/preproc/ecpg.type @@ -122,7 +122,9 @@ %type CSTRING %type CPP_LINE %type CVARIABLE +%type BCONST %type SCONST +%type XCONST %type IDENT %type s_struct_union_symbol diff --git a/src/interfaces/ecpg/preproc/parse.pl b/src/interfaces/ecpg/preproc/parse.pl index 1a76b2d326b..52ba7dfa0cd 100644 --- a/src/interfaces/ecpg/preproc/parse.pl +++ b/src/interfaces/ecpg/preproc/parse.pl @@ -38,6 +38,7 @@ my %replace_token = ( 'BCONST' => 'ecpg_bconst', 'FCONST' => 'ecpg_fconst', 'Sconst' => 'ecpg_sconst', + 'XCONST' => 'ecpg_xconst', 'IDENT' => 'ecpg_ident', 'PARAM' => 'ecpg_param',); diff --git a/src/interfaces/ecpg/preproc/pgc.l b/src/interfaces/ecpg/preproc/pgc.l index 91d8b635787..1aebac89cd6 100644 --- a/src/interfaces/ecpg/preproc/pgc.l +++ b/src/interfaces/ecpg/preproc/pgc.l @@ -505,9 +505,9 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ { {xbstart} { token_start = yytext; + state_before_str_start = YYSTATE; BEGIN(xb); startlit(); - addlitchar('b'); } } /* */ @@ -519,9 +519,9 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ {xhstart} { token_start = yytext; + state_before_str_start = YYSTATE; BEGIN(xh); startlit(); - addlitchar('x'); } <> { mmfatal(PARSE_ERROR, "unterminated hexadecimal string literal"); } @@ -597,12 +597,14 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ switch (state_before_str_stop) { case xb: - if (literalbuf[strspn(literalbuf, "01") + 1] != '\0') + if (literalbuf[strspn(literalbuf, "01")] != '\0') mmerror(PARSE_ERROR, ET_ERROR, "invalid bit string literal"); - base_yylval.str = mm_strdup(literalbuf); + base_yylval.str = psprintf("b'%s'", literalbuf); return BCONST; case xh: - base_yylval.str = mm_strdup(literalbuf); + if (literalbuf[strspn(literalbuf, "0123456789abcdefABCDEF")] != '\0') + mmerror(PARSE_ERROR, ET_ERROR, "invalid hex string literal"); + base_yylval.str = psprintf("x'%s'", literalbuf); return XCONST; case xq: /* fallthrough */ diff --git a/src/interfaces/ecpg/test/expected/preproc-strings.c b/src/interfaces/ecpg/test/expected/preproc-strings.c index 1e50cd36c38..87662e01766 100644 --- a/src/interfaces/ecpg/test/expected/preproc-strings.c +++ b/src/interfaces/ecpg/test/expected/preproc-strings.c @@ -63,8 +63,18 @@ int main(void) printf("%s %s %s %s %s %s\n", s1, s2, s3, s4, s5, s6); + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select b'0010' , x'019ABcd'", ECPGt_EOIT, + ECPGt_char,&(s1),(long)0,(long)1,(1)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, + ECPGt_char,&(s2),(long)0,(long)1,(1)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);} +#line 26 "strings.pgc" + + + printf("%s %s\n", s1, s2); + { ECPGdisconnect(__LINE__, "CURRENT");} -#line 25 "strings.pgc" +#line 30 "strings.pgc" return 0; } diff --git a/src/interfaces/ecpg/test/expected/preproc-strings.stderr b/src/interfaces/ecpg/test/expected/preproc-strings.stderr index 4c3a8eee5aa..9f10ca0bf3a 100644 --- a/src/interfaces/ecpg/test/expected/preproc-strings.stderr +++ b/src/interfaces/ecpg/test/expected/preproc-strings.stderr @@ -38,5 +38,15 @@ [NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: ecpg_get_data on line 15: RESULT: abc$def offset: -1; array: no [NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 25: query: select b'0010' , x'019ABcd'; with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 25: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 25: correctly got 1 tuples with 2 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 25: RESULT: 0010 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 25: RESULT: 0000000110011010101111001101 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: ecpg_finish: connection ecpg1_regression closed [NO_PID]: sqlca: code: 0, state: 00000 diff --git a/src/interfaces/ecpg/test/expected/preproc-strings.stdout b/src/interfaces/ecpg/test/expected/preproc-strings.stdout index 1456b152d78..5abbe6928dc 100644 --- a/src/interfaces/ecpg/test/expected/preproc-strings.stdout +++ b/src/interfaces/ecpg/test/expected/preproc-strings.stdout @@ -1 +1,2 @@ abc'd\ef abc'd\ef abc'd\ef data data abc$def +0010 0000000110011010101111001101 diff --git a/src/interfaces/ecpg/test/preproc/strings.pgc b/src/interfaces/ecpg/test/preproc/strings.pgc index 25157f136c2..ab7eef6896a 100644 --- a/src/interfaces/ecpg/test/preproc/strings.pgc +++ b/src/interfaces/ecpg/test/preproc/strings.pgc @@ -22,6 +22,11 @@ int main(void) printf("%s %s %s %s %s %s\n", s1, s2, s3, s4, s5, s6); + exec sql select b'0010', X'019ABcd' + into :s1, :s2; + + printf("%s %s\n", s1, s2); + exec sql disconnect; return 0; }