]> granicus.if.org Git - postgresql/commitdiff
- Fixed indicator in SET DESCRIPTOR.
authorMichael Meskes <meskes@postgresql.org>
Mon, 5 Jul 2004 09:45:54 +0000 (09:45 +0000)
committerMichael Meskes <meskes@postgresql.org>
Mon, 5 Jul 2004 09:45:54 +0000 (09:45 +0000)
- Added special handling of descriptor header information.
- Some code cleanup.

src/interfaces/ecpg/ChangeLog
src/interfaces/ecpg/ecpglib/descriptor.c
src/interfaces/ecpg/ecpglib/execute.c
src/interfaces/ecpg/include/ecpglib.h
src/interfaces/ecpg/preproc/descriptor.c
src/interfaces/ecpg/preproc/preproc.y
src/interfaces/ecpg/test/test_desc.pgc

index 888dd73bc841bdba55ecfd3e0265b048d549bab9..e6d8a0098e0e286fe97bb96e7c992cde0de4a257 100644 (file)
@@ -1834,6 +1834,13 @@ Wed Jun 30 16:56:32 CEST 2004
 Sun Jul  4 16:53:53 CEST 2004
 
        - Made sure SET DESCRIPTOR accepts all data types including constants.
+       - Some code cleanup.
+       
+Mon,  5 Jul 2004 10:41:54 +0200
+
+       - Fixed indicator in SET DESCRIPTOR.
+       - Added special handling of descriptor header information.
+       - More code cleanup.
        - Set pgtypes library version to 1.2.
        - Set ecpg version to 3.2.0.
        - Set compat library version to 1.2.
index e653203f89b39dcd9546c17cff7a333923d3bd0e..bc56b0222bc47e730e00934d74a3efe7d9209a16 100644 (file)
@@ -1,6 +1,6 @@
 /* dynamic SQL support routines
  *
- * $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/descriptor.c,v 1.10 2004/07/04 15:02:22 meskes Exp $
+ * $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/descriptor.c,v 1.11 2004/07/05 09:45:53 meskes Exp $
  */
 
 #define POSTGRES_ECPG_INTERNAL
@@ -430,6 +430,27 @@ ECPGget_desc(int lineno, char *desc_name, int index,...)
        return (true);
 }
 
+bool
+ECPGset_desc_header(int lineno, char *desc_name, int count)
+{
+       struct descriptor *desc;
+       
+       for (desc = all_descriptors; desc; desc = desc->next)
+       {
+               if (strcmp(desc_name, desc->name)==0)
+                       break;
+       }
+
+       if (desc == NULL)
+       {
+               ECPGraise(lineno, ECPG_UNKNOWN_DESCRIPTOR, ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME, desc_name);
+               return false;
+       }
+
+       desc->count = count;
+       return true;
+}
+
 bool
 ECPGset_desc(int lineno, char *desc_name, int index,...)
 {
@@ -581,6 +602,7 @@ ECPGallocate_desc(int line, const char *name)
                ECPGfree(new);
                return false;
        }
+       new->count = -1;
        new->items = NULL;
        new->result = PQmakeEmptyPGresult(NULL, 0);
        if (!new->result)
index 6464ecb4b322a7270d7896daf1d26bd572f21059..a3a601aed52b1d936b806f292a10811ec40e2177 100644 (file)
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.36 2004/07/04 15:02:22 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.37 2004/07/05 09:45:53 meskes Exp $ */
 
 /*
  * The aim is to get a simpler inteface to the database routines.
@@ -1080,6 +1080,7 @@ ECPGexecute(struct statement * stmt)
                int        hostvarl = 0;
 
                tobeinserted = NULL;
+               
                /* A descriptor is a special case since it contains many variables but is listed only once. */
                if (var->type == ECPGt_descriptor)
                {
@@ -1100,28 +1101,43 @@ ECPGexecute(struct statement * stmt)
                        }
                        
                        desc_counter++;
-                       for (desc_item = desc->items; desc_item; desc_item = desc_item->next)
+                       if (desc->count < 0 || desc->count >= desc_counter)
                        {
-                               if (desc_item->num == desc_counter)
+                               for (desc_item = desc->items; desc_item; desc_item = desc_item->next)
                                {
-                                       desc_inlist.type = ECPGt_char;
-                                       desc_inlist.value = desc_item->data;
-                                       desc_inlist.pointer = &(desc_item->data);
-                                       desc_inlist.varcharsize = strlen(desc_item->data);
-                                       desc_inlist.arrsize = 1;
-                                       desc_inlist.offset = 0;
-                                       desc_inlist.ind_type = ECPGt_NO_INDICATOR;
-                                       desc_inlist.ind_value = desc_inlist.ind_pointer = NULL;
-                                       desc_inlist.ind_varcharsize = desc_inlist.ind_arrsize = desc_inlist.ind_offset = 0;
-
-                                       if (!ECPGstore_input(stmt->lineno, stmt->force_indicator, &desc_inlist, &tobeinserted, &malloced))
-                                               return false;
-                                       
-                                       break;
+                                       if (desc_item->num == desc_counter)
+                                       {
+                                               desc_inlist.type = ECPGt_char;
+                                               desc_inlist.value = desc_item->data;
+                                               desc_inlist.pointer = &(desc_item->data);
+                                               desc_inlist.varcharsize = strlen(desc_item->data);
+                                               desc_inlist.arrsize = 1;
+                                               desc_inlist.offset = 0;
+                                               if (!desc_item->indicator)
+                                               {
+                                                       desc_inlist.ind_type = ECPGt_NO_INDICATOR;
+                                                       desc_inlist.ind_value = desc_inlist.ind_pointer = NULL;
+                                                       desc_inlist.ind_varcharsize = desc_inlist.ind_arrsize = desc_inlist.ind_offset = 0;
+                                               }
+                                               else
+                                               {
+                                                       desc_inlist.ind_type = ECPGt_int;
+                                                       desc_inlist.ind_value = &(desc_item->indicator);
+                                                       desc_inlist.ind_pointer = &(desc_inlist.ind_value);
+                                                       desc_inlist.ind_varcharsize = desc_inlist.ind_arrsize = 1;
+                                                       desc_inlist.ind_offset = 0;
+                                               }
+                                               if (!ECPGstore_input(stmt->lineno, stmt->force_indicator, &desc_inlist, &tobeinserted, &malloced))
+                                                       return false;
+                                               
+                                               break;
+                                       }
                                }
-                       }
 
-                       if (!desc_item) /* no more entries found in descriptor */
+                               if (!desc_item) /* no more entries found in descriptor */
+                                       desc_counter = 0;
+                       }
+                       else
                                desc_counter = 0;
                }
                else
@@ -1129,6 +1145,7 @@ ECPGexecute(struct statement * stmt)
                        if (!ECPGstore_input(stmt->lineno, stmt->force_indicator, var, &tobeinserted, &malloced))
                                return false;
                }
+               
                if (tobeinserted)
                {
                        /*
index 778104a27b22e39ab905cda1199b5d021d48dbac..6145e79cb4df05910ed0cd711a3335ff85e5d83f 100644 (file)
@@ -77,7 +77,7 @@ void          ECPGraise(int line, int code, const char *sqlstate, const char *str);
 void           ECPGraise_backend(int line, PGresult *result, PGconn *conn, int compat);
 bool           ECPGget_desc_header(int, char *, int *);
 bool           ECPGget_desc(int, char *, int,...);
-bool           ECPGset_desc_header(int, char *, int *);
+bool           ECPGset_desc_header(int, char *, int);
 bool           ECPGset_desc(int, char *, int,...);
 
 void           ECPGset_noind_null(enum ECPGttype, void *);
index 6861a91dc7fb8fc0443c65983b8503172f74c582..43193364b474250d70d025d514c9740cdfc207aa 100644 (file)
@@ -55,6 +55,7 @@ ECPGnumeric_lvalue(FILE *f, char *name)
                case ECPGt_unsigned_int:
                case ECPGt_unsigned_long:
                case ECPGt_unsigned_long_long:
+               case ECPGt_const:
                        fputs(name, yyout);
                        break;
                default:
@@ -198,7 +199,7 @@ output_set_descr_header(char *desc_name)
 {
        struct assignment *results;
 
-       fprintf(yyout, "{ ECPGset_desc_header(__LINE__, %s, &(", desc_name);
+       fprintf(yyout, "{ ECPGset_desc_header(__LINE__, %s, (int)(", desc_name);
        for (results = assignments; results != NULL; results = results->next)
        {
                if (results->value == ECPGd_count)
index e1dab2b72e8a0b8e3e069ee74afba20a5c723af0..3c10072f6860fd790b4a0b54f937927068e6c036 100644 (file)
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.291 2004/07/04 15:02:23 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.292 2004/07/05 09:45:53 meskes Exp $ */
 
 /* Copyright comment */
 %{
@@ -522,7 +522,7 @@ add_additional_variables(char *name, bool insert)
 %type  <str>   select_limit opt_for_update_clause CheckPointStmt
 %type  <str>   OptSchemaName OptSchemaEltList schema_stmt opt_drop_behavior
 %type  <str>   handler_name any_name_list any_name opt_as insert_column_list
-%type  <str>   columnref function_name insert_target_el
+%type  <str>   columnref function_name insert_target_el AllConstVar
 %type  <str>   insert_target_list insert_column_item DropRuleStmt
 %type  <str>   createfunc_opt_item set_rest var_list_or_default
 %type  <str>   CreateFunctionStmt createfunc_opt_list func_table
@@ -4207,7 +4207,7 @@ IntConst: PosIntConst             { $$ = $1; }
 IntConstVar:   Iconst  
                {
                        char *length = mm_alloc(32);
-                       
+
                        sprintf(length, "%d", (int) strlen($1));
                        new_variable($1, ECPGmake_simple_type(ECPGt_const, length), 0);
                        $$ = $1;
@@ -4215,6 +4215,45 @@ IntConstVar:     Iconst
                | cvariable     { $$ = $1; }
                ;
 
+AllConstVar:   Fconst
+               {
+                       char *length = mm_alloc(32);
+                       
+                       sprintf(length, "%d", (int) strlen($1));
+                       new_variable($1, ECPGmake_simple_type(ECPGt_const, length), 0);
+                       $$ = $1;
+               }
+               | IntConstVar           { $$ = $1; }
+               | '-' Fconst
+               {
+                       char *length = mm_alloc(32);
+                       char *var = cat2_str(make_str("-"), $2);
+                       
+                       sprintf(length, "%d", (int) strlen(var));
+                       new_variable(var, ECPGmake_simple_type(ECPGt_const, length), 0);
+                       $$ = var;
+               }
+               | '-' Iconst
+               {
+                       char *length = mm_alloc(32);
+                       char *var = cat2_str(make_str("-"), $2);
+                       
+                       sprintf(length, "%d", (int) strlen(var));
+                       new_variable(var, ECPGmake_simple_type(ECPGt_const, length), 0);
+                       $$ = var;
+               }
+               | Sconst                
+               {
+                       char *length = mm_alloc(32);
+                       char *var = $1 + 1;
+                       
+                       var[strlen(var) - 1] = '\0';
+                       sprintf(length, "%d", (int) strlen(var));
+                       new_variable(var, ECPGmake_simple_type(ECPGt_const, length), 0);
+                       $$ = var;
+               }
+               ;
+
 StringConst:   Sconst          { $$ = $1; }
                | civar         { $$ = $1; }
                ;
@@ -5375,7 +5414,7 @@ ECPGSetDescItems: ECPGSetDescItem
                | ECPGSetDescItems ',' ECPGSetDescItem
                ;
 
-ECPGSetDescItem: descriptor_item '=' IntConstVar
+ECPGSetDescItem: descriptor_item '=' AllConstVar
                {
                        push_assignment($3, $1);
                }
index aee30bc59f344cf1b717104176d9240cb2d22faa..7d4854cfdf2ad04e60fa05d397851b8e9559c9f6 100644 (file)
@@ -6,11 +6,12 @@ main()
        EXEC SQL BEGIN DECLARE SECTION;
        char *stmt1 = "INSERT INTO test1 VALUES (?, ?)";
        char *stmt2 = "SELECT * from test1 where a = ? and b = ?";
+       char *stmt3 = "SELECT * from test1 where a = ?";
 
        int val1 = 1;
        char val2[] = "one", val2output[] = "AAA";
        int val1output = 2, val2i = 0;
-       int val2null = 1;
+       int val2null = -1;
        EXEC SQL END DECLARE SECTION;
        FILE *dbgs;
 
@@ -28,6 +29,7 @@ main()
        EXEC SQL CREATE TABLE test1 (a int, b text);
        EXEC SQL PREPARE foo1 FROM :stmt1;
        EXEC SQL PREPARE foo2 FROM :stmt2;
+       EXEC SQL PREPARE foo3 FROM :stmt3;
 
        EXEC SQL EXECUTE foo1 USING DESCRIPTOR indesc;
 
@@ -44,16 +46,27 @@ main()
        EXEC SQL GET DESCRIPTOR outdesc VALUE 1 :val2output = DATA;
        printf("output = %s\n", val2output);
        
-       EXEC SQL DECLARE c CURSOR FOR foo2;
-       EXEC SQL OPEN c USING DESCRIPTOR indesc;
+       EXEC SQL DECLARE c1 CURSOR FOR foo2;
+       EXEC SQL OPEN c1 USING DESCRIPTOR indesc;
 
-       EXEC SQL FETCH next FROM c INTO :val1output, :val2output;
+       EXEC SQL FETCH next FROM c1 INTO :val1output, :val2output;
        printf("val1=%d val2=%s\n", val1output, val2output);
 
-       EXEC SQL CLOSE c;
+       EXEC SQL CLOSE c1;
+
+       EXEC SQL SET DESCRIPTOR indesc COUNT = 1;
+       EXEC SQL SET DESCRIPTOR indesc VALUE 1 DATA = 2;
        
-       EXEC SQL SELECT * INTO :val1output, :val2output FROM test1 where a = 2;
-       printf("val1=%d val2=%s\n", val1output, val2output);
+       EXEC SQL DECLARE c2 CURSOR FOR foo3;
+       EXEC SQL OPEN c2 USING DESCRIPTOR indesc;
+
+       EXEC SQL FETCH next FROM c2 INTO :val1output, :val2output :val2i;
+       printf("val1=%d val2=%s\n", val1output, val2i ? "null" : val2output);
+
+       EXEC SQL CLOSE c2;
+       
+       EXEC SQL SELECT * INTO :val1output, :val2output :val2i FROM test1 where a = 2;
+       printf("val1=%d val2=%s\n", val1output, val2i ? "null" : val2output);
        
        EXEC SQL DROP TABLE test1;
        EXEC SQL DISCONNECT;