mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-09 08:10:09 +08:00
- Fixed indicator in SET DESCRIPTOR.
- Added special handling of descriptor header information. - Some code cleanup.
This commit is contained in:
parent
da09dea3e3
commit
073f7312a4
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
{
|
||||
/*
|
||||
|
@ -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 *);
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user