From e91600d1c2e79914e6c8ac445c340e704c710b66 Mon Sep 17 00:00:00 2001 From: Michael Meskes Date: Fri, 18 Aug 2006 15:59:35 +0000 Subject: [PATCH] Changed lexer to no longer use the default rule. Synced parser and keyword list. Fixed parsing of CONNECT statement so it accepts a C string again. --- src/interfaces/ecpg/ChangeLog | 6 +++ src/interfaces/ecpg/preproc/keywords.c | 3 +- src/interfaces/ecpg/preproc/pgc.l | 46 +++++++++---------- src/interfaces/ecpg/preproc/preproc.y | 42 +++++++++-------- src/interfaces/ecpg/test/connect/test3.pgc | 2 +- .../ecpg/test/expected/connect-test3.c | 2 +- 6 files changed, 55 insertions(+), 46 deletions(-) diff --git a/src/interfaces/ecpg/ChangeLog b/src/interfaces/ecpg/ChangeLog index bf1e305a8a..af7420b3b2 100644 --- a/src/interfaces/ecpg/ChangeLog +++ b/src/interfaces/ecpg/ChangeLog @@ -2095,5 +2095,11 @@ Mo Aug 14 10:39:59 CEST 2006 - Fixed broken newline on Windows. - Fixed a nasty buffer underrun that only occured when using Informix no_indicator NULL setting on timestamps and intervals. + +Fr 18. Aug 17:32:54 CEST 2006 + + - Changed lexer to no longer use the default rule. + - Synced parser and keyword list. + - Fixed parsing of CONNECT statement so it accepts a C string again. - Set ecpg library version to 5.2. - Set ecpg version to 4.2.1. diff --git a/src/interfaces/ecpg/preproc/keywords.c b/src/interfaces/ecpg/preproc/keywords.c index a1879c9973..3fd8d6d236 100644 --- a/src/interfaces/ecpg/preproc/keywords.c +++ b/src/interfaces/ecpg/preproc/keywords.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/keywords.c,v 1.74 2006/08/02 13:43:23 meskes Exp $ + * $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/keywords.c,v 1.75 2006/08/18 15:59:35 meskes Exp $ * *------------------------------------------------------------------------- */ @@ -277,6 +277,7 @@ static ScanKeyword ScanKeywords[] = { {"reset", RESET}, {"restart", RESTART}, {"restrict", RESTRICT}, + {"returning", RETURNING}, {"returns", RETURNS}, {"revoke", REVOKE}, {"right", RIGHT}, diff --git a/src/interfaces/ecpg/preproc/pgc.l b/src/interfaces/ecpg/preproc/pgc.l index 5dff416f6b..e9f87fe183 100644 --- a/src/interfaces/ecpg/preproc/pgc.l +++ b/src/interfaces/ecpg/preproc/pgc.l @@ -12,7 +12,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.148 2006/08/02 13:43:23 meskes Exp $ + * $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.149 2006/08/18 15:59:35 meskes Exp $ * *------------------------------------------------------------------------- */ @@ -79,7 +79,7 @@ static struct _if_value %option yylineno -%s C SQL incl def def_ident undef +%x C SQL incl def def_ident undef /* * OK, here is a short description of lex/flex rules behavior. @@ -109,7 +109,6 @@ static struct _if_value %x xe %x xq %x xdolq -%x xpre %x xcond %x xskip @@ -327,7 +326,7 @@ cppline {space}*#(.*\\{space})*.*{newline} {whitespace} { /* ignore */ } -{xcstart} { +{xcstart} { token_start = yytext; state_before = YYSTATE; xcdepth = 0; @@ -545,7 +544,7 @@ cppline {space}*#(.*\\{space})*.*{newline} * This is not an EOL marker. */ if (yytext[0] == ';' && struct_level == 0) - BEGIN C; + BEGIN(C); return yytext[0]; } {operator} { @@ -720,12 +719,12 @@ cppline {space}*#(.*\\{space})*.*{newline} } } {other} { return yytext[0]; } -{exec_sql} { BEGIN SQL; return SQL_START; } +{exec_sql} { BEGIN(SQL); return SQL_START; } {informix_special} { /* are we simulating Informix? */ if (INFORMIX_MODE) { - BEGIN SQL; + BEGIN(SQL); return SQL_START; } else @@ -896,7 +895,7 @@ cppline {space}*#(.*\\{space})*.*{newline} BEGIN(C); } -{other} { +{other}|\n { mmerror(PARSE_ERROR, ET_FATAL, "Missing identifier in 'EXEC SQL UNDEF' command"); yyterminate(); } @@ -1077,24 +1076,24 @@ cppline {space}*#(.*\\{space})*.*{newline} } if (stacked_if_value[preproc_tos].condition) - BEGIN C; + BEGIN(C); else BEGIN(xskip); } -{other} { - mmerror(PARSE_ERROR, ET_FATAL, "Missing identifier in 'EXEC SQL IFDEF' command"); - yyterminate(); - } +{other}|\n { + mmerror(PARSE_ERROR, ET_FATAL, "Missing identifier in 'EXEC SQL IFDEF' command"); + yyterminate(); + } {identifier} { old = mm_strdup(yytext); BEGIN(def); startlit(); } -{other} { - mmerror(PARSE_ERROR, ET_FATAL, "Missing identifier in 'EXEC SQL DEFINE' command"); - yyterminate(); - } +{other}|\n { + mmerror(PARSE_ERROR, ET_FATAL, "Missing identifier in 'EXEC SQL DEFINE' command"); + yyterminate(); + } {space}*";" { struct _defines *ptr, *this; @@ -1124,10 +1123,10 @@ cppline {space}*#(.*\\{space})*.*{newline} \<[^\>]+\>{space}*";"? { parse_include(); } {dquote}{xdinside}{dquote}{space}*";"? { parse_include(); } [^;\<\>\"]+";" { parse_include(); } -{other} { - mmerror(PARSE_ERROR, ET_FATAL, "Incorrect 'EXEC SQL INCLUDE' command"); - yyterminate(); - } +{other}|\n { + mmerror(PARSE_ERROR, ET_FATAL, "Incorrect 'EXEC SQL INCLUDE' command"); + yyterminate(); + } <> { if (yy_buffer == NULL) @@ -1174,6 +1173,7 @@ cppline {space}*#(.*\\{space})*.*{newline} } } +{other}|\n { mmerror(PARSE_ERROR, ET_FATAL, "Internal error: unreachable state, please inform pgsql-bugs@postgresql.org"); } %% void lex_init(void) @@ -1194,7 +1194,7 @@ lex_init(void) } startlit(); - BEGIN C; + BEGIN(C); } static void @@ -1318,7 +1318,7 @@ parse_include(void) yylineno = 1; output_line_number(); - BEGIN C; + BEGIN(C); } static void diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y index ae14e1973a..8824de58d2 100644 --- a/src/interfaces/ecpg/preproc/preproc.y +++ b/src/interfaces/ecpg/preproc/preproc.y @@ -1,4 +1,4 @@ -/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.328 2006/08/08 11:51:24 meskes Exp $ */ +/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.329 2006/08/18 15:59:35 meskes Exp $ */ /* Copyright comment */ %{ @@ -407,7 +407,7 @@ add_additional_variables(char *name, bool insert) QUOTE READ REAL REASSIGN RECHECK REFERENCES REINDEX RELATIVE_P RELEASE RENAME - REPEATABLE REPLACE RESET RESTART RESTRICT RETURNS REVOKE RIGHT + REPEATABLE REPLACE RESET RESTART RESTRICT RETURNING RETURNS REVOKE RIGHT ROLE ROLLBACK ROW ROWS RULE SAVEPOINT SCHEMA SCROLL SECOND_P SECURITY SELECT SEQUENCE @@ -497,7 +497,7 @@ add_additional_variables(char *name, bool insert) %type columnList DeleteStmt UpdateStmt DeclareCursorStmt %type NotifyStmt columnElem UnlistenStmt TableElement %type copy_delimiter ListenStmt CopyStmt copy_file_name opt_binary -%type FetchStmt from_in CreateOpClassStmt +%type FetchStmt from_in CreateOpClassStmt returning_clause %type ClosePortalStmt DropStmt VacuumStmt AnalyzeStmt opt_verbose %type opt_full func_arg OptWith opt_freeze alter_table_cmd %type analyze_keyword opt_name_list ExplainStmt index_params @@ -3090,8 +3090,8 @@ DeallocateStmt: DEALLOCATE name { $$ = cat2_str(make_str("deallocate"), $2); } * *****************************************************************************/ -InsertStmt: INSERT INTO qualified_name insert_rest - { $$ = cat_str(3, make_str("insert into"), $3, $4); } +InsertStmt: INSERT INTO qualified_name insert_rest returning_clause + { $$ = cat_str(4, make_str("insert into"), $3, $4, $5); } ; insert_rest: @@ -3113,6 +3113,9 @@ insert_column_item: ColId opt_indirection { $$ = cat2_str($1, $2); } ; +returning_clause: RETURNING target_list { $$ = cat2_str(make_str("returning"), $2); } + | /* EMPTY */ { $$ = EMPTY; } + ; /***************************************************************************** * @@ -3121,8 +3124,8 @@ insert_column_item: ColId opt_indirection * *****************************************************************************/ -DeleteStmt: DELETE_P FROM relation_expr_opt_alias using_clause where_clause - { $$ = cat_str(4, make_str("delete from"), $3, $4, $5); } +DeleteStmt: DELETE_P FROM relation_expr_opt_alias using_clause where_clause returning_clause + { $$ = cat_str(5, make_str("delete from"), $3, $4, $5, $6); } ; using_clause: USING from_list { cat2_str(make_str("using"), $2); } @@ -3164,7 +3167,8 @@ UpdateStmt: UPDATE relation_expr_opt_alias SET update_target_list from_clause where_clause - {$$ = cat_str(6, make_str("update"), $2, make_str("set"), $4, $5, $6); } + returning_clause + {$$ = cat_str(7, make_str("update"), $2, make_str("set"), $4, $5, $6, $7); } ; @@ -4615,8 +4619,12 @@ connection_target: database_name opt_server opt_port /* old style: dbname[@server][:port] */ if (strlen($2) > 0 && *($2) != '@') mmerror(PARSE_ERROR, ET_ERROR, "Expected '@', found '%s'", $2); - - $$ = make3_str(make_str("\""), make3_str($1, $2, $3), make_str("\"")); + + /* C strings need to be handled differently */ + if ($1[0] == '\"') + $$ = $1; + else + $$ = make3_str(make_str("\""), make3_str($1, $2, $3), make_str("\"")); } | db_prefix ':' server opt_port '/' database_name opt_options { @@ -4634,13 +4642,6 @@ connection_target: database_name opt_server opt_port $$ = make3_str(make3_str(make_str("\""), $1, make_str(":")), $3, make3_str(make3_str($4, make_str("/"), $6), $7, make_str("\""))); } - | Sconst - { - if ($1[0] == '\"') - $$ = $1; - else - $$ = make3_str(make_str("\""), $1, make_str("\"")); - } | char_variable { $$ = $1; @@ -6509,9 +6510,10 @@ reserved_keyword: | OR { $$ = make_str("or"); } | ORDER { $$ = make_str("order"); } | PRIMARY { $$ = make_str("primary"); } - | REFERENCES { $$ = make_str("references"); } + | REFERENCES { $$ = make_str("references"); } + | RETURNING { $$ = make_str("returning"); } | SELECT { $$ = make_str("select"); } - | SESSION_USER { $$ = make_str("session_user"); } + | SESSION_USER { $$ = make_str("session_user"); } | SOME { $$ = make_str("some"); } | SYMMETRIC { $$ = make_str("symmetric"); } | TABLE { $$ = make_str("table"); } @@ -6604,7 +6606,7 @@ cvariable: CVARIABLE } ; ident: IDENT { $$ = $1; } - | CSTRING { $$ = make3_str(make_str("\""), $1, make_str("\"")); } + | CSTRING { $$ = make3_str(make_str("\""), $1, make_str("\"")); } ; quoted_ident_stringvar: name diff --git a/src/interfaces/ecpg/test/connect/test3.pgc b/src/interfaces/ecpg/test/connect/test3.pgc index 9910cb1b0c..40c866f1fb 100644 --- a/src/interfaces/ecpg/test/connect/test3.pgc +++ b/src/interfaces/ecpg/test/connect/test3.pgc @@ -34,7 +34,7 @@ exec sql end declare section; /* will close "second" */ exec sql disconnect DEFAULT; - exec sql connect to REGRESSDB1 as second; + exec sql connect to "connectdb" as second; exec sql disconnect ALL; exec sql disconnect CURRENT; diff --git a/src/interfaces/ecpg/test/expected/connect-test3.c b/src/interfaces/ecpg/test/expected/connect-test3.c index 62a3cd6809..32d24bedf4 100644 --- a/src/interfaces/ecpg/test/expected/connect-test3.c +++ b/src/interfaces/ecpg/test/expected/connect-test3.c @@ -78,7 +78,7 @@ main(void) #line 35 "test3.pgc" - { ECPGconnect(__LINE__, 0, "regress1" , NULL,NULL , "second", 0); } + { ECPGconnect(__LINE__, 0, "connectdb" , NULL,NULL , "second", 0); } #line 37 "test3.pgc" { ECPGdisconnect(__LINE__, "ALL");} -- 2.40.0