aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Meskes <meskes@postgresql.org>2004-07-05 09:45:54 +0000
committerMichael Meskes <meskes@postgresql.org>2004-07-05 09:45:54 +0000
commit073f7312a4c0aff9030ccc52010095a260c6a7a6 (patch)
treebc64a74145ae3c68e0b6466b25610447d1db95f8 /src
parentda09dea3e32fcc430102f6377caee24a2afe2101 (diff)
downloadpostgresql-073f7312a4c0aff9030ccc52010095a260c6a7a6.tar.gz
postgresql-073f7312a4c0aff9030ccc52010095a260c6a7a6.zip
- Fixed indicator in SET DESCRIPTOR.
- Added special handling of descriptor header information. - Some code cleanup.
Diffstat (limited to 'src')
-rw-r--r--src/interfaces/ecpg/ChangeLog7
-rw-r--r--src/interfaces/ecpg/ecpglib/descriptor.c24
-rw-r--r--src/interfaces/ecpg/ecpglib/execute.c55
-rw-r--r--src/interfaces/ecpg/include/ecpglib.h2
-rw-r--r--src/interfaces/ecpg/preproc/descriptor.c3
-rw-r--r--src/interfaces/ecpg/preproc/preproc.y47
-rw-r--r--src/interfaces/ecpg/test/test_desc.pgc27
7 files changed, 132 insertions, 33 deletions
diff --git a/src/interfaces/ecpg/ChangeLog b/src/interfaces/ecpg/ChangeLog
index 888dd73bc84..e6d8a0098e0 100644
--- a/src/interfaces/ecpg/ChangeLog
+++ b/src/interfaces/ecpg/ChangeLog
@@ -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.
diff --git a/src/interfaces/ecpg/ecpglib/descriptor.c b/src/interfaces/ecpg/ecpglib/descriptor.c
index e653203f89b..bc56b0222bc 100644
--- a/src/interfaces/ecpg/ecpglib/descriptor.c
+++ b/src/interfaces/ecpg/ecpglib/descriptor.c
@@ -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
@@ -431,6 +431,27 @@ ECPGget_desc(int lineno, char *desc_name, int index,...)
}
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,...)
{
va_list args;
@@ -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)
diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index 6464ecb4b32..a3a601aed52 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -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)
{
/*
diff --git a/src/interfaces/ecpg/include/ecpglib.h b/src/interfaces/ecpg/include/ecpglib.h
index 778104a27b2..6145e79cb4d 100644
--- a/src/interfaces/ecpg/include/ecpglib.h
+++ b/src/interfaces/ecpg/include/ecpglib.h
@@ -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 *);
diff --git a/src/interfaces/ecpg/preproc/descriptor.c b/src/interfaces/ecpg/preproc/descriptor.c
index 6861a91dc7f..43193364b47 100644
--- a/src/interfaces/ecpg/preproc/descriptor.c
+++ b/src/interfaces/ecpg/preproc/descriptor.c
@@ -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)
diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y
index e1dab2b72e8..3c10072f686 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.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);
}
diff --git a/src/interfaces/ecpg/test/test_desc.pgc b/src/interfaces/ecpg/test/test_desc.pgc
index aee30bc59f3..7d4854cfdf2 100644
--- a/src/interfaces/ecpg/test/test_desc.pgc
+++ b/src/interfaces/ecpg/test/test_desc.pgc
@@ -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;