OSDN Git Service

Fixed parsing of parameters. Added regression test for this.
authorMichael Meskes <meskes@postgresql.org>
Tue, 14 Oct 2008 09:31:05 +0000 (09:31 +0000)
committerMichael Meskes <meskes@postgresql.org>
Tue, 14 Oct 2008 09:31:05 +0000 (09:31 +0000)
src/interfaces/ecpg/ChangeLog
src/interfaces/ecpg/preproc/Makefile
src/interfaces/ecpg/preproc/preproc.y
src/interfaces/ecpg/test/expected/sql-fetch.c
src/interfaces/ecpg/test/expected/sql-fetch.stderr
src/interfaces/ecpg/test/expected/sql-fetch.stdout
src/interfaces/ecpg/test/sql/fetch.pgc

index 6f0bc35..928d412 100644 (file)
@@ -2382,6 +2382,10 @@ Tue, 07 Oct 2008 14:35:26 +0200
 Fri, 10 Oct 2008 14:03:05 +0200
 
        - Fixed "create role" parsing to accept optional "with" argument.
+
+Tue, 14 Oct 2008 11:25:51 +0200
+
+       - Fixed parameter parsing.
        - Set pgtypes library version to 3.1.
        - Set compat library version to 3.1.
        - Set ecpg library version to 6.2.
index 8deaace..3cfd52c 100644 (file)
@@ -4,7 +4,7 @@
 #
 # Copyright (c) 1998-2008, PostgreSQL Global Development Group
 #
-# $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/Makefile,v 1.136 2008/08/29 13:02:32 petere Exp $
+# $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/Makefile,v 1.137 2008/10/14 09:31:04 meskes Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -55,7 +55,6 @@ endif
 ecpg_keywords.o c_keywords.o keywords.o preproc.o parser.o: preproc.h
 
 # instead of maintaining our own list, take the one from the backend
-# we cannot just link it in, but must copy and make some minor changes
 keywords.c: % : $(top_srcdir)/src/backend/parser/%
        rm -f $@ && $(LN_S) $< .
 
index f519358..c4ad9d8 100644 (file)
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.375 2008/10/10 12:17:18 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.376 2008/10/14 09:31:04 meskes Exp $ */
 
 /* Copyright comment */
 %{
@@ -658,7 +658,7 @@ add_typedef(char *name, char * dimension, char * length, enum ECPGttype type_enu
 %type  <str>   AlterOwnerStmt OptTableSpaceOwner CreateTableSpaceStmt
 %type  <str>   DropTableSpaceStmt indirection indirection_el ECPGSetDescriptorHeader
 %type  <str>   AlterDatabaseStmt CreateRoleStmt OptRoleList AlterRoleStmt AlterRoleSetStmt
-%type  <str>   DropRoleStmt add_drop opt_validator common_func_opt_item
+%type  <str>   DropRoleStmt add_drop opt_validator common_func_opt_item Param
 %type  <str>   opt_grant_admin_option AlterFunctionStmt alterfunc_opt_list opt_restrict
 %type  <str>   AlterObjectSchemaStmt alterdb_opt_list for_locking_clause opt_for_locking_clause
 %type  <str>   locked_rels_list opt_granted_by RevokeRoleStmt alterdb_opt_item using_clause
@@ -3939,7 +3939,7 @@ where_clause:  WHERE a_expr               { $$ = cat2_str(make_str("where"), $2); }
 
 where_or_current_clause:  WHERE a_expr                 { $$ = cat2_str(make_str("where"), $2); }
                | WHERE CURRENT_P OF name               { $$ = cat2_str(make_str("where current of"), $4); }
-               | WHERE CURRENT_P OF PARAM              { $$ = make_str("where current of param"); }
+               | WHERE CURRENT_P OF Param              { $$ = cat2_str(make_str("where current of"), $4); }
                | /*EMPTY*/                             { $$ = EMPTY;  /* no qualifiers */ }
                ;
 
@@ -4397,8 +4397,8 @@ c_expr: columnref
                        { $$ = $1;      }
                | AexprConst
                        { $$ = $1;      }
-               | PARAM opt_indirection
-                       { $$ = cat2_str(make_str("param"), $2); }
+               | Param opt_indirection
+                       { $$ = cat2_str($1, $2); }
                | '(' a_expr ')' opt_indirection
                        { $$ = cat_str(4, make_str("("), $2, make_str(")"), $4); }
                | case_expr
@@ -4920,6 +4920,7 @@ AexprConst:  PosAllConst
                        { $$ = $1; }
                ;
 
+Param:   PARAM                         { $$ = make_name();};
 Iconst:  ICONST                                { $$ = make_name();};
 Fconst:  FCONST                                { $$ = make_name();};
 Bconst:  BCONST                                { $$ = make_name();};
index 52c3065..d8b2880 100644 (file)
@@ -162,34 +162,72 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
   printf("%d: %s\n", i, str);
 
-  { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close C", ECPGt_EOIT, ECPGt_EORT);
+  /* declare D  cursor  for select  *  from My_Table where Item1 = $1    */
 #line 42 "fetch.pgc"
 
+
+  { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare D  cursor  for select  *  from My_Table where Item1 = $1   ", 
+       ECPGt_const,"1",(long)1,(long)1,strlen("1"), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 44 "fetch.pgc"
+
 if (sqlca.sqlwarn[0] == 'W') sqlprint();
-#line 42 "fetch.pgc"
+#line 44 "fetch.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 42 "fetch.pgc"
+#line 44 "fetch.pgc"
+
+
+  /* exec sql whenever not found  break ; */
+#line 46 "fetch.pgc"
+
+  while (1) {
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch 1 in D", ECPGt_EOIT, 
+       ECPGt_int,&(i),(long)1,(long)1,sizeof(int), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
+       ECPGt_char,(str),(long)25,(long)1,(25)*sizeof(char), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+#line 48 "fetch.pgc"
+
+if (sqlca.sqlcode == ECPG_NOT_FOUND) break;
+#line 48 "fetch.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 48 "fetch.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 48 "fetch.pgc"
+
+       printf("%d: %s\n", i, str);
+  }
+  { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close D", ECPGt_EOIT, ECPGt_EORT);
+#line 51 "fetch.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 51 "fetch.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 51 "fetch.pgc"
 
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table My_Table ", ECPGt_EOIT, ECPGt_EORT);
-#line 44 "fetch.pgc"
+#line 53 "fetch.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') sqlprint();
-#line 44 "fetch.pgc"
+#line 53 "fetch.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 44 "fetch.pgc"
+#line 53 "fetch.pgc"
 
 
   { ECPGdisconnect(__LINE__, "ALL");
-#line 46 "fetch.pgc"
+#line 55 "fetch.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') sqlprint();
-#line 46 "fetch.pgc"
+#line 55 "fetch.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 46 "fetch.pgc"
+#line 55 "fetch.pgc"
 
 
   return 0;
index 937eaca..3e4d796 100644 (file)
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 39: RESULT: text4 offset: -1; array: yes
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 42: query: close C; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 44: query: declare D  cursor  for select  *  from My_Table where Item1 = $1   ; with 1 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 42: using PQexec
+[NO_PID]: ecpg_execute on line 44: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 42: OK: CLOSE CURSOR
+[NO_PID]: free_params on line 44: parameter 1 = 1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 44: query: drop table My_Table ; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 44: OK: DECLARE CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 44: using PQexec
+[NO_PID]: ecpg_execute on line 48: query: fetch 1 in D; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 44: OK: DROP TABLE
+[NO_PID]: ecpg_execute on line 48: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 48: correctly got 1 tuples with 2 fields
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 48: RESULT: 1 offset: -1; array: yes
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 48: RESULT: text1 offset: -1; array: yes
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 48: query: fetch 1 in D; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 48: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 48: correctly got 0 tuples with 2 fields
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: raising sqlcode 100 on line 48: no data found on line 48
+[NO_PID]: sqlca: code: 100, state: 02000
+[NO_PID]: ecpg_execute on line 51: query: close D; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 51: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 51: OK: CLOSE CURSOR
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 53: query: drop table My_Table ; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 53: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_check_PQresult on line 53: ERROR:  relation 16491 is still open
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: raising sqlstate XX000 (sqlcode -400) on line 53: relation 16491 is still open on line 53
+[NO_PID]: sqlca: code: -400, state: XX000
+sql error: relation 16491 is still open on line 53
 [NO_PID]: ecpg_finish: connection regress1 closed
 [NO_PID]: sqlca: code: 0, state: 00000
index 340b888..32ca8e4 100644 (file)
@@ -39,7 +39,16 @@ int main(int argc, char* argv[]) {
   EXEC SQL FETCH :count IN C INTO :i, :str;
   printf("%d: %s\n", i, str);
 
-  EXEC SQL CLOSE C;
+  EXEC SQL DECLARE D CURSOR FOR SELECT * FROM My_Table WHERE Item1 = $1;
+
+  EXEC SQL OPEN D using 1;
+
+  EXEC SQL WHENEVER NOT FOUND DO BREAK;
+  while (1) {
+       EXEC SQL FETCH 1 IN D INTO :i, :str;
+       printf("%d: %s\n", i, str);
+  }
+  EXEC SQL CLOSE D;
 
   EXEC SQL DROP TABLE My_Table;