Commit aa6ac352 authored by Michael Meskes's avatar Michael Meskes

Applied patch by Boszormenyi Zoltan <zb@cybertec.at> to add out-of-scope...

Applied patch by Boszormenyi Zoltan <zb@cybertec.at> to add out-of-scope cursor support to native mode.
parent 525d2cbb
/* $PostgreSQL: pgsql/src/interfaces/ecpg/compatlib/informix.c,v 1.62 2009/10/01 18:03:54 meskes Exp $ */ /* $PostgreSQL: pgsql/src/interfaces/ecpg/compatlib/informix.c,v 1.63 2010/01/26 09:07:31 meskes Exp $ */
#define POSTGRES_ECPG_INTERNAL #define POSTGRES_ECPG_INTERNAL
#include "postgres_fe.h" #include "postgres_fe.h"
...@@ -1004,57 +1004,16 @@ rtypwidth(int sqltype, int sqllen) ...@@ -1004,57 +1004,16 @@ rtypwidth(int sqltype, int sqllen)
return 0; return 0;
} }
static struct var_list
{
int number;
void *pointer;
struct var_list *next;
} *ivlist = NULL;
void void
ECPG_informix_set_var(int number, void *pointer, int lineno) ECPG_informix_set_var(int number, void *pointer, int lineno)
{ {
struct var_list *ptr; ECPGset_var(number, pointer, lineno);
for (ptr = ivlist; ptr != NULL; ptr = ptr->next)
{
if (ptr->number == number)
{
/* already known => just change pointer value */
ptr->pointer = pointer;
return;
}
}
/* a new one has to be added */
ptr = (struct var_list *) calloc(1L, sizeof(struct var_list));
if (!ptr)
{
struct sqlca_t *sqlca = ECPGget_sqlca();
sqlca->sqlcode = ECPG_OUT_OF_MEMORY;
strncpy(sqlca->sqlstate, "YE001", sizeof("YE001"));
snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), "out of memory on line %d", lineno);
sqlca->sqlerrm.sqlerrml = strlen(sqlca->sqlerrm.sqlerrmc);
/* free all memory we have allocated for the user */
ECPGfree_auto_mem();
}
else
{
ptr->number = number;
ptr->pointer = pointer;
ptr->next = ivlist;
ivlist = ptr;
}
} }
void * void *
ECPG_informix_get_var(int number) ECPG_informix_get_var(int number)
{ {
struct var_list *ptr; return ECPGget_var(number);
for (ptr = ivlist; ptr != NULL && ptr->number != number; ptr = ptr->next);
return (ptr) ? ptr->pointer : NULL;
} }
void void
......
# $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/exports.txt,v 1.6 2009/09/18 13:13:32 meskes Exp $ # $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/exports.txt,v 1.7 2010/01/26 09:07:31 meskes Exp $
# Functions to be exported by ecpglib DLL # Functions to be exported by ecpglib DLL
ECPGallocate_desc 1 ECPGallocate_desc 1
ECPGconnect 2 ECPGconnect 2
...@@ -26,4 +26,6 @@ ECPGstatus 23 ...@@ -26,4 +26,6 @@ ECPGstatus 23
ECPGtrans 24 ECPGtrans 24
sqlprint 25 sqlprint 25
ECPGget_PGconn 26 ECPGget_PGconn 26
ECPGtransactionStatus 27 ECPGtransactionStatus 27
ECPGset_var 28
ECPGget_var 29
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/misc.c,v 1.53 2009/11/24 16:30:31 meskes Exp $ */ /* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/misc.c,v 1.54 2010/01/26 09:07:31 meskes Exp $ */
#define POSTGRES_ECPG_INTERNAL #define POSTGRES_ECPG_INTERNAL
#include "postgres_fe.h" #include "postgres_fe.h"
...@@ -505,3 +505,55 @@ ecpg_gettext(const char *msgid) ...@@ -505,3 +505,55 @@ ecpg_gettext(const char *msgid)
} }
#endif /* ENABLE_NLS */ #endif /* ENABLE_NLS */
static struct var_list
{
int number;
void *pointer;
struct var_list *next;
} *ivlist = NULL;
void
ECPGset_var(int number, void *pointer, int lineno)
{
struct var_list *ptr;
for (ptr = ivlist; ptr != NULL; ptr = ptr->next)
{
if (ptr->number == number)
{
/* already known => just change pointer value */
ptr->pointer = pointer;
return;
}
}
/* a new one has to be added */
ptr = (struct var_list *) calloc(1L, sizeof(struct var_list));
if (!ptr)
{
struct sqlca_t *sqlca = ECPGget_sqlca();
sqlca->sqlcode = ECPG_OUT_OF_MEMORY;
strncpy(sqlca->sqlstate, "YE001", sizeof("YE001"));
snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), "out of memory on line %d", lineno);
sqlca->sqlerrm.sqlerrml = strlen(sqlca->sqlerrm.sqlerrmc);
/* free all memory we have allocated for the user */
ECPGfree_auto_mem();
}
else
{
ptr->number = number;
ptr->pointer = pointer;
ptr->next = ivlist;
ivlist = ptr;
}
}
void *
ECPGget_var(int number)
{
struct var_list *ptr;
for (ptr = ivlist; ptr != NULL && ptr->number != number; ptr = ptr->next);
return (ptr) ? ptr->pointer : NULL;
}
/* /*
* this is a small part of c.h since we don't want to leak all postgres * this is a small part of c.h since we don't want to leak all postgres
* definitions into ecpg programs * definitions into ecpg programs
* $PostgreSQL: pgsql/src/interfaces/ecpg/include/ecpglib.h,v 1.81 2010/01/15 10:44:36 meskes Exp $ * $PostgreSQL: pgsql/src/interfaces/ecpg/include/ecpglib.h,v 1.82 2010/01/26 09:07:31 meskes Exp $
*/ */
#ifndef _ECPGLIB_H #ifndef _ECPGLIB_H
...@@ -85,6 +85,9 @@ void ECPGset_noind_null(enum ECPGttype, void *); ...@@ -85,6 +85,9 @@ void ECPGset_noind_null(enum ECPGttype, void *);
bool ECPGis_noind_null(enum ECPGttype, void *); bool ECPGis_noind_null(enum ECPGttype, void *);
bool ECPGdescribe(int, int, bool, const char *, const char *, ...); bool ECPGdescribe(int, int, bool, const char *, const char *, ...);
void ECPGset_var(int, void *, int);
void *ECPGget_var(int number);
/* dynamic result allocation */ /* dynamic result allocation */
void ECPGfree_auto_mem(void); void ECPGfree_auto_mem(void);
......
/* /*
* functions needed for descriptor handling * functions needed for descriptor handling
* *
* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/descriptor.c,v 1.29 2010/01/05 16:38:23 meskes Exp $ * $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/descriptor.c,v 1.30 2010/01/26 09:07:31 meskes Exp $
* *
* since descriptor might be either a string constant or a string var * since descriptor might be either a string constant or a string var
* we need to check for a constant if we expect a constant * we need to check for a constant if we expect a constant
...@@ -317,7 +317,7 @@ struct variable * ...@@ -317,7 +317,7 @@ struct variable *
descriptor_variable(const char *name, int input) descriptor_variable(const char *name, int input)
{ {
static char descriptor_names[2][MAX_DESCRIPTOR_NAMELEN]; static char descriptor_names[2][MAX_DESCRIPTOR_NAMELEN];
static const struct ECPGtype descriptor_type = {ECPGt_descriptor, NULL, NULL, {NULL}, 0}; static const struct ECPGtype descriptor_type = {ECPGt_descriptor, NULL, NULL, NULL, {NULL}, 0};
static const struct variable varspace[2] = { static const struct variable varspace[2] = {
{descriptor_names[0], (struct ECPGtype *) & descriptor_type, 0, NULL}, {descriptor_names[0], (struct ECPGtype *) & descriptor_type, 0, NULL},
{descriptor_names[1], (struct ECPGtype *) & descriptor_type, 0, NULL} {descriptor_names[1], (struct ECPGtype *) & descriptor_type, 0, NULL}
......
/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg.addons,v 1.14 2010/01/15 10:44:37 meskes Exp $ */ /* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg.addons,v 1.15 2010/01/26 09:07:31 meskes Exp $ */
ECPG: stmtClosePortalStmt block ECPG: stmtClosePortalStmt block
{ {
if (INFORMIX_MODE) if (INFORMIX_MODE)
...@@ -310,11 +310,14 @@ ECPG: DeclareCursorStmtDECLAREcursor_namecursor_optionsCURSORopt_holdFORSelectSt ...@@ -310,11 +310,14 @@ ECPG: DeclareCursorStmtDECLAREcursor_namecursor_optionsCURSORopt_holdFORSelectSt
this->next = cur; this->next = cur;
this->name = $2; this->name = $2;
this->function = (current_function ? mm_strdup(current_function) : NULL);
this->connection = connection; this->connection = connection;
this->opened = false; this->opened = false;
this->command = cat_str(7, make_str("declare"), cursor_marker, $3, make_str("cursor"), $5, make_str("for"), $7); this->command = cat_str(7, make_str("declare"), cursor_marker, $3, make_str("cursor"), $5, make_str("for"), $7);
this->argsinsert = argsinsert; this->argsinsert = argsinsert;
this->argsinsert_oos = NULL;
this->argsresult = argsresult; this->argsresult = argsresult;
this->argsresult_oos = NULL;
argsinsert = argsresult = NULL; argsinsert = argsresult = NULL;
cur = this; cur = this;
...@@ -327,17 +330,17 @@ ECPG: DeclareCursorStmtDECLAREcursor_namecursor_optionsCURSORopt_holdFORSelectSt ...@@ -327,17 +330,17 @@ ECPG: DeclareCursorStmtDECLAREcursor_namecursor_optionsCURSORopt_holdFORSelectSt
} }
comment = cat_str(3, make_str("/*"), c1, make_str("*/")); comment = cat_str(3, make_str("/*"), c1, make_str("*/"));
if (INFORMIX_MODE) if ((braces_open > 0) && INFORMIX_MODE) /* we're in a function */
{ $$ = cat_str(4,
if (braces_open > 0) /* we're in a function */ adjust_outofscope_cursor_vars(this, true),
{ adjust_outofscope_cursor_vars(this, false),
$$ = cat_str(4, adjust_informix(this->argsinsert), adjust_informix(this->argsresult), make_str("ECPG_informix_reset_sqlca();"), comment); make_str("ECPG_informix_reset_sqlca();"),
} comment);
else
$$ = cat_str(3, adjust_informix(this->argsinsert), adjust_informix(this->argsresult), comment);
}
else else
$$ = comment; $$ = cat_str(3,
adjust_outofscope_cursor_vars(this, true),
adjust_outofscope_cursor_vars(this, false),
comment);
} }
ECPG: ClosePortalStmtCLOSEcursor_name block ECPG: ClosePortalStmtCLOSEcursor_name block
{ {
......
/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg.c,v 1.112 2010/01/02 16:58:11 momjian Exp $ */ /* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg.c,v 1.113 2010/01/26 09:07:31 meskes Exp $ */
/* Main for ecpg, the PostgreSQL embedded SQL precompiler. */ /* Main for ecpg, the PostgreSQL embedded SQL precompiler. */
/* Copyright (c) 1996-2010, PostgreSQL Global Development Group */ /* Copyright (c) 1996-2010, PostgreSQL Global Development Group */
...@@ -419,8 +419,8 @@ main(int argc, char *const argv[]) ...@@ -419,8 +419,8 @@ main(int argc, char *const argv[])
/* and structure member lists */ /* and structure member lists */
memset(struct_member_list, 0, sizeof(struct_member_list)); memset(struct_member_list, 0, sizeof(struct_member_list));
/* and our variable counter for Informix compatibility */ /* and our variable counter for out of scope cursors' variables */
ecpg_informix_var = 0; ecpg_internal_var = 0;
/* finally the actual connection */ /* finally the actual connection */
connection = NULL; connection = NULL;
......
This diff is collapsed.
/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg.trailer,v 1.18 2010/01/15 10:44:37 meskes Exp $ */ /* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg.trailer,v 1.19 2010/01/26 09:07:31 meskes Exp $ */
statements: /*EMPTY*/ statements: /*EMPTY*/
| statements statement | statements statement
...@@ -16,7 +16,17 @@ statement: ecpgstart at stmt ';' { connection = NULL; } ...@@ -16,7 +16,17 @@ statement: ecpgstart at stmt ';' { connection = NULL; }
| c_thing { fprintf(yyout, "%s", $1); free($1); } | c_thing { fprintf(yyout, "%s", $1); free($1); }
| CPP_LINE { fprintf(yyout, "%s", $1); free($1); } | CPP_LINE { fprintf(yyout, "%s", $1); free($1); }
| '{' { braces_open++; fputs("{", yyout); } | '{' { braces_open++; fputs("{", yyout); }
| '}' { remove_typedefs(braces_open); remove_variables(braces_open--); fputs("}", yyout); } | '}'
{
remove_typedefs(braces_open);
remove_variables(braces_open--);
if (braces_open == 0)
{
free(current_function);
current_function = NULL;
}
fputs("}", yyout);
}
; ;
CreateAsStmt: CREATE OptTemp TABLE create_as_target AS {FoundInto = 0;} SelectStmt opt_with_data CreateAsStmt: CREATE OptTemp TABLE create_as_target AS {FoundInto = 0;} SelectStmt opt_with_data
...@@ -281,6 +291,7 @@ ECPGCursorStmt: DECLARE cursor_name cursor_options CURSOR opt_hold FOR prepared ...@@ -281,6 +291,7 @@ ECPGCursorStmt: DECLARE cursor_name cursor_options CURSOR opt_hold FOR prepared
char *cursor_marker = $2[0] == ':' ? make_str("$0") : mm_strdup($2); char *cursor_marker = $2[0] == ':' ? make_str("$0") : mm_strdup($2);
struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable)); struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
const char *con = connection ? connection : "NULL"; const char *con = connection ? connection : "NULL";
char *comment;
for (ptr = cur; ptr != NULL; ptr = ptr->next) for (ptr = cur; ptr != NULL; ptr = ptr->next)
{ {
...@@ -294,9 +305,11 @@ ECPGCursorStmt: DECLARE cursor_name cursor_options CURSOR opt_hold FOR prepared ...@@ -294,9 +305,11 @@ ECPGCursorStmt: DECLARE cursor_name cursor_options CURSOR opt_hold FOR prepared
/* initial definition */ /* initial definition */
this->next = cur; this->next = cur;
this->name = $2; this->name = $2;
this->function = (current_function ? mm_strdup(current_function) : NULL);
this->connection = connection; this->connection = connection;
this->command = cat_str(6, make_str("declare"), cursor_marker, $3, make_str("cursor"), $5, make_str("for $1")); this->command = cat_str(6, make_str("declare"), cursor_marker, $3, make_str("cursor"), $5, make_str("for $1"));
this->argsresult = NULL; this->argsresult = NULL;
this->argsresult_oos = NULL;
thisquery->type = &ecpg_query; thisquery->type = &ecpg_query;
thisquery->brace_level = 0; thisquery->brace_level = 0;
...@@ -305,6 +318,7 @@ ECPGCursorStmt: DECLARE cursor_name cursor_options CURSOR opt_hold FOR prepared ...@@ -305,6 +318,7 @@ ECPGCursorStmt: DECLARE cursor_name cursor_options CURSOR opt_hold FOR prepared
sprintf(thisquery->name, "ECPGprepared_statement(%s, %s, __LINE__)", con, $7); sprintf(thisquery->name, "ECPGprepared_statement(%s, %s, __LINE__)", con, $7);
this->argsinsert = NULL; this->argsinsert = NULL;
this->argsinsert_oos = NULL;
if ($2[0] == ':') if ($2[0] == ':')
{ {
struct variable *var = find_variable($2 + 1); struct variable *var = find_variable($2 + 1);
...@@ -315,10 +329,19 @@ ECPGCursorStmt: DECLARE cursor_name cursor_options CURSOR opt_hold FOR prepared ...@@ -315,10 +329,19 @@ ECPGCursorStmt: DECLARE cursor_name cursor_options CURSOR opt_hold FOR prepared
cur = this; cur = this;
if (INFORMIX_MODE && braces_open > 0) /* we're in a function */ comment = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/"));
$$ = cat_str(4, make_str("ECPG_informix_reset_sqlca();"), make_str("/*"), mm_strdup(this->command), make_str("*/"));
if ((braces_open > 0) && INFORMIX_MODE) /* we're in a function */
$$ = cat_str(4,
adjust_outofscope_cursor_vars(this, true),
adjust_outofscope_cursor_vars(this, false),
make_str("ECPG_informix_reset_sqlca();"),
comment);
else else
$$ = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/")); $$ = cat_str(3,
adjust_outofscope_cursor_vars(this, true),
adjust_outofscope_cursor_vars(this, false),
comment);
} }
; ;
...@@ -402,6 +425,7 @@ var_declaration: storage_declaration ...@@ -402,6 +425,7 @@ var_declaration: storage_declaration
var_type var_type
{ {
actual_type[struct_level].type_enum = $2.type_enum; actual_type[struct_level].type_enum = $2.type_enum;
actual_type[struct_level].type_str = $2.type_str;
actual_type[struct_level].type_dimension = $2.type_dimension; actual_type[struct_level].type_dimension = $2.type_dimension;
actual_type[struct_level].type_index = $2.type_index; actual_type[struct_level].type_index = $2.type_index;
actual_type[struct_level].type_sizeof = $2.type_sizeof; actual_type[struct_level].type_sizeof = $2.type_sizeof;
...@@ -415,6 +439,7 @@ var_declaration: storage_declaration ...@@ -415,6 +439,7 @@ var_declaration: storage_declaration
| var_type | var_type
{ {
actual_type[struct_level].type_enum = $1.type_enum; actual_type[struct_level].type_enum = $1.type_enum;
actual_type[struct_level].type_str = $1.type_str;
actual_type[struct_level].type_dimension = $1.type_dimension; actual_type[struct_level].type_dimension = $1.type_dimension;
actual_type[struct_level].type_index = $1.type_index; actual_type[struct_level].type_index = $1.type_index;
actual_type[struct_level].type_sizeof = $1.type_sizeof; actual_type[struct_level].type_sizeof = $1.type_sizeof;
...@@ -826,9 +851,9 @@ variable: opt_pointer ECPGColLabel opt_array_bounds opt_bit_field opt_initialize ...@@ -826,9 +851,9 @@ variable: opt_pointer ECPGColLabel opt_array_bounds opt_bit_field opt_initialize
case ECPGt_struct: case ECPGt_struct:
case ECPGt_union: case ECPGt_union:
if (atoi(dimension) < 0) if (atoi(dimension) < 0)
type = ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum, actual_type[struct_level].type_sizeof); type = ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum, actual_type[struct_level].type_str, actual_type[struct_level].type_sizeof);
else else
type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum, actual_type[struct_level].type_sizeof), dimension); type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum, actual_type[struct_level].type_str, actual_type[struct_level].type_sizeof), dimension);
$$ = cat_str(5, $1, mm_strdup($2), $3.str, $4, $5); $$ = cat_str(5, $1, mm_strdup($2), $3.str, $4, $5);
break; break;
...@@ -1303,9 +1328,9 @@ ECPGVar: SQL_VAR ...@@ -1303,9 +1328,9 @@ ECPGVar: SQL_VAR
case ECPGt_struct: case ECPGt_struct:
case ECPGt_union: case ECPGt_union:
if (atoi(dimension) < 0) if (atoi(dimension) < 0)
type = ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum, $5.type_sizeof); type = ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum, $5.type_str, $5.type_sizeof);
else else
type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum,$5.type_sizeof), dimension); type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum, $5.type_str, $5.type_sizeof), dimension);
break; break;
case ECPGt_varchar: case ECPGt_varchar:
......
/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/extern.h,v 1.77 2010/01/05 16:38:23 meskes Exp $ */ /* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/extern.h,v 1.78 2010/01/26 09:07:31 meskes Exp $ */
#ifndef _ECPG_PREPROC_EXTERN_H #ifndef _ECPG_PREPROC_EXTERN_H
#define _ECPG_PREPROC_EXTERN_H #define _ECPG_PREPROC_EXTERN_H
...@@ -26,9 +26,10 @@ extern int braces_open, ...@@ -26,9 +26,10 @@ extern int braces_open,
questionmarks, questionmarks,
ret_value, ret_value,
struct_level, struct_level,
ecpg_informix_var, ecpg_internal_var,
regression_mode, regression_mode,
auto_prepare; auto_prepare;
extern char *current_function;
extern char *descriptor_index; extern char *descriptor_index;
extern char *descriptor_name; extern char *descriptor_name;
extern char *connection; extern char *connection;
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.171 2010/01/02 16:58:11 momjian Exp $ * $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.172 2010/01/26 09:07:31 meskes Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -41,6 +41,9 @@ static char *literalbuf = NULL; /* expandable buffer */ ...@@ -41,6 +41,9 @@ static char *literalbuf = NULL; /* expandable buffer */
static int literallen; /* actual current length */ static int literallen; /* actual current length */
static int literalalloc; /* current allocated buffer size */ static int literalalloc; /* current allocated buffer size */
/* Used for detecting global state together with braces_open */
static int parenths_open;
#define startlit() (literalbuf[0] = '\0', literallen = 0) #define startlit() (literalbuf[0] = '\0', literallen = 0)
static void addlit(char *ytext, int yleng); static void addlit(char *ytext, int yleng);
static void addlitchar (unsigned char); static void addlitchar (unsigned char);
...@@ -788,7 +791,17 @@ cppline {space}*#(.*\\{space})*.*{newline} ...@@ -788,7 +791,17 @@ cppline {space}*#(.*\\{space})*.*{newline}
} }
<C>{identifier} { <C>{identifier} {
const ScanKeyword *keyword; const ScanKeyword *keyword;
/*
* Try to detect a function name:
* look for identifiers at the global scope
* keep the last identifier before the first '(' and '{' */
if (braces_open == 0 && parenths_open == 0)
{
if (current_function)
free(current_function);
current_function = mm_strdup(yytext);
}
/* Informix uses SQL defines only in SQL space */ /* Informix uses SQL defines only in SQL space */
/* however, some defines have to be taken care of for compatibility */ /* however, some defines have to be taken care of for compatibility */
if ((!INFORMIX_MODE || !isinformixdefine()) && !isdefine()) if ((!INFORMIX_MODE || !isinformixdefine()) && !isdefine())
...@@ -811,8 +824,8 @@ cppline {space}*#(.*\\{space})*.*{newline} ...@@ -811,8 +824,8 @@ cppline {space}*#(.*\\{space})*.*{newline}
<C>"/" { return('/'); } <C>"/" { return('/'); }
<C>"+" { return('+'); } <C>"+" { return('+'); }
<C>"-" { return('-'); } <C>"-" { return('-'); }
<C>"(" { return('('); } <C>"(" { parenths_open++; return('('); }
<C>")" { return(')'); } <C>")" { parenths_open--; return(')'); }
<C,xskip>{space} { ECHO; } <C,xskip>{space} { ECHO; }
<C>\{ { return('{'); } <C>\{ { return('{'); }
<C>\} { return('}'); } <C>\} { return('}'); }
...@@ -1178,6 +1191,8 @@ void ...@@ -1178,6 +1191,8 @@ void
lex_init(void) lex_init(void)
{ {
braces_open = 0; braces_open = 0;
parenths_open = 0;
current_function = NULL;
preproc_tos = 0; preproc_tos = 0;
yylineno = 1; yylineno = 1;
......
/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/type.c,v 1.86 2010/01/05 16:38:23 meskes Exp $ */ /* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/type.c,v 1.87 2010/01/26 09:07:31 meskes Exp $ */
#include "postgres_fe.h" #include "postgres_fe.h"
...@@ -46,7 +46,7 @@ ECPGstruct_member_dup(struct ECPGstruct_member * rm) ...@@ -46,7 +46,7 @@ ECPGstruct_member_dup(struct ECPGstruct_member * rm)
{ {
case ECPGt_struct: case ECPGt_struct:
case ECPGt_union: case ECPGt_union:
type = ECPGmake_struct_type(rm->type->u.members, rm->type->type, rm->type->struct_sizeof); type = ECPGmake_struct_type(rm->type->u.members, rm->type->type, rm->type->type_name, rm->type->struct_sizeof);
break; break;
case ECPGt_array: case ECPGt_array:
...@@ -55,7 +55,7 @@ ECPGstruct_member_dup(struct ECPGstruct_member * rm) ...@@ -55,7 +55,7 @@ ECPGstruct_member_dup(struct ECPGstruct_member * rm)
* create the struct too * create the struct too
*/ */
if (rm->type->u.element->type == ECPGt_struct) if (rm->type->u.element->type == ECPGt_struct)
type = ECPGmake_struct_type(rm->type->u.element->u.members, rm->type->u.element->type, rm->type->u.element->struct_sizeof); type = ECPGmake_struct_type(rm->type->u.element->u.members, rm->type->u.element->type, rm->type->u.element->type_name, rm->type->u.element->struct_sizeof);
else else
type = ECPGmake_array_type(ECPGmake_simple_type(rm->type->u.element->type, rm->type->u.element->size, rm->type->u.element->lineno), rm->type->size); type = ECPGmake_array_type(ECPGmake_simple_type(rm->type->u.element->type, rm->type->u.element->size, rm->type->u.element->lineno), rm->type->size);
break; break;
...@@ -98,6 +98,7 @@ ECPGmake_simple_type(enum ECPGttype type, char *size, int lineno) ...@@ -98,6 +98,7 @@ ECPGmake_simple_type(enum ECPGttype type, char *size, int lineno)
struct ECPGtype *ne = (struct ECPGtype *) mm_alloc(sizeof(struct ECPGtype)); struct ECPGtype *ne = (struct ECPGtype *) mm_alloc(sizeof(struct ECPGtype));
ne->type = type; ne->type = type;
ne->type_name = NULL;
ne->size = size; ne->size = size;
ne->u.element = NULL; ne->u.element = NULL;
ne->struct_sizeof = NULL; ne->struct_sizeof = NULL;
...@@ -117,10 +118,11 @@ ECPGmake_array_type(struct ECPGtype * type, char *size) ...@@ -117,10 +118,11 @@ ECPGmake_array_type(struct ECPGtype * type, char *size)
} }
struct ECPGtype * struct ECPGtype *
ECPGmake_struct_type(struct ECPGstruct_member * rm, enum ECPGttype type, char *struct_sizeof) ECPGmake_struct_type(struct ECPGstruct_member * rm, enum ECPGttype type, char *type_name, char *struct_sizeof)
{ {
struct ECPGtype *ne = ECPGmake_simple_type(type, make_str("1"), 0); struct ECPGtype *ne = ECPGmake_simple_type(type, make_str("1"), 0);
ne->type_name = mm_strdup(type_name);
ne->u.members = ECPGstruct_member_dup(rm); ne->u.members = ECPGstruct_member_dup(rm);
ne->struct_sizeof = struct_sizeof; ne->struct_sizeof = struct_sizeof;
......
/* /*
* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/type.h,v 1.51 2009/06/11 14:49:13 momjian Exp $ * $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/type.h,v 1.52 2010/01/26 09:07:31 meskes Exp $
*/ */
#ifndef _ECPG_PREPROC_TYPE_H #ifndef _ECPG_PREPROC_TYPE_H
#define _ECPG_PREPROC_TYPE_H #define _ECPG_PREPROC_TYPE_H
...@@ -17,6 +17,7 @@ struct ECPGstruct_member ...@@ -17,6 +17,7 @@ struct ECPGstruct_member
struct ECPGtype struct ECPGtype
{ {
enum ECPGttype type; enum ECPGttype type;
char *type_name; /* For struct and union types it is the struct name */
char *size; /* For array it is the number of elements. For char *size; /* For array it is the number of elements. For
* varchar it is the maxsize of the area. */ * varchar it is the maxsize of the area. */
char *struct_sizeof; /* For a struct this is the sizeof() type as char *struct_sizeof; /* For a struct this is the sizeof() type as
...@@ -36,7 +37,7 @@ void ECPGmake_struct_member(char *, struct ECPGtype *, struct ECPGstruct_member ...@@ -36,7 +37,7 @@ void ECPGmake_struct_member(char *, struct ECPGtype *, struct ECPGstruct_member
struct ECPGtype *ECPGmake_simple_type(enum ECPGttype, char *, int); struct ECPGtype *ECPGmake_simple_type(enum ECPGttype, char *, int);
struct ECPGtype *ECPGmake_varchar_type(enum ECPGttype, long); struct ECPGtype *ECPGmake_varchar_type(enum ECPGttype, long);
struct ECPGtype *ECPGmake_array_type(struct ECPGtype *, char *); struct ECPGtype *ECPGmake_array_type(struct ECPGtype *, char *);
struct ECPGtype *ECPGmake_struct_type(struct ECPGstruct_member *, enum ECPGttype, char *); struct ECPGtype *ECPGmake_struct_type(struct ECPGstruct_member *, enum ECPGttype, char *, char *);
struct ECPGstruct_member *ECPGstruct_member_dup(struct ECPGstruct_member *); struct ECPGstruct_member *ECPGstruct_member_dup(struct ECPGstruct_member *);
/* Frees a type. */ /* Frees a type. */
...@@ -123,11 +124,14 @@ struct _include_path ...@@ -123,11 +124,14 @@ struct _include_path
struct cursor struct cursor
{ {
char *name; char *name;
char *function;
char *command; char *command;
char *connection; char *connection;
bool opened; bool opened;
struct arguments *argsinsert; struct arguments *argsinsert;
struct arguments *argsinsert_oos;
struct arguments *argsresult; struct arguments *argsresult;
struct arguments *argsresult_oos;
struct cursor *next; struct cursor *next;
}; };
......
/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/variable.c,v 1.51 2009/11/26 15:06:47 meskes Exp $ */ /* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/variable.c,v 1.52 2010/01/26 09:07:31 meskes Exp $ */
#include "postgres_fe.h" #include "postgres_fe.h"
...@@ -47,7 +47,7 @@ find_struct_member(char *name, char *str, struct ECPGstruct_member * members, in ...@@ -47,7 +47,7 @@ find_struct_member(char *name, char *str, struct ECPGstruct_member * members, in
return (new_variable(name, ECPGmake_array_type(ECPGmake_simple_type(members->type->u.element->type, members->type->u.element->size, members->type->u.element->lineno), members->type->size), brace_level)); return (new_variable(name, ECPGmake_array_type(ECPGmake_simple_type(members->type->u.element->type, members->type->u.element->size, members->type->u.element->lineno), members->type->size), brace_level));
case ECPGt_struct: case ECPGt_struct:
case ECPGt_union: case ECPGt_union:
return (new_variable(name, ECPGmake_struct_type(members->type->u.members, members->type->type, members->type->struct_sizeof), brace_level)); return (new_variable(name, ECPGmake_struct_type(members->type->u.members, members->type->type, members->type->type_name, members->type->struct_sizeof), brace_level));
default: default:
return (new_variable(name, ECPGmake_simple_type(members->type->type, members->type->size, members->type->lineno), brace_level)); return (new_variable(name, ECPGmake_simple_type(members->type->type, members->type->size, members->type->lineno), brace_level));
} }
...@@ -94,7 +94,7 @@ find_struct_member(char *name, char *str, struct ECPGstruct_member * members, in ...@@ -94,7 +94,7 @@ find_struct_member(char *name, char *str, struct ECPGstruct_member * members, in
return (new_variable(name, ECPGmake_array_type(ECPGmake_simple_type(members->type->u.element->u.element->type, members->type->u.element->u.element->size, members->type->u.element->u.element->lineno), members->type->u.element->size), brace_level)); return (new_variable(name, ECPGmake_array_type(ECPGmake_simple_type(members->type->u.element->u.element->type, members->type->u.element->u.element->size, members->type->u.element->u.element->lineno), members->type->u.element->size), brace_level));
case ECPGt_struct: case ECPGt_struct:
case ECPGt_union: case ECPGt_union:
return (new_variable(name, ECPGmake_struct_type(members->type->u.element->u.members, members->type->u.element->type, members->type->u.element->struct_sizeof), brace_level)); return (new_variable(name, ECPGmake_struct_type(members->type->u.element->u.members, members->type->u.element->type, members->type->u.element->type_name, members->type->u.element->struct_sizeof), brace_level));
default: default:
return (new_variable(name, ECPGmake_simple_type(members->type->u.element->type, members->type->u.element->size, members->type->u.element->lineno), brace_level)); return (new_variable(name, ECPGmake_simple_type(members->type->u.element->type, members->type->u.element->size, members->type->u.element->lineno), brace_level));
} }
...@@ -235,7 +235,7 @@ find_variable(char *name) ...@@ -235,7 +235,7 @@ find_variable(char *name)
return (new_variable(name, ECPGmake_array_type(ECPGmake_simple_type(p->type->u.element->u.element->type, p->type->u.element->u.element->size, p->type->u.element->u.element->lineno), p->type->u.element->size), p->brace_level)); return (new_variable(name, ECPGmake_array_type(ECPGmake_simple_type(p->type->u.element->u.element->type, p->type->u.element->u.element->size, p->type->u.element->u.element->lineno), p->type->u.element->size), p->brace_level));
case ECPGt_struct: case ECPGt_struct:
case ECPGt_union: case ECPGt_union:
return (new_variable(name, ECPGmake_struct_type(p->type->u.element->u.members, p->type->u.element->type, p->type->u.element->struct_sizeof), p->brace_level)); return (new_variable(name, ECPGmake_struct_type(p->type->u.element->u.members, p->type->u.element->type, p->type->u.element->type_name, p->type->u.element->struct_sizeof), p->brace_level));
default: default:
return (new_variable(name, ECPGmake_simple_type(p->type->u.element->type, p->type->u.element->size, p->type->u.element->lineno), p->brace_level)); return (new_variable(name, ECPGmake_simple_type(p->type->u.element->type, p->type->u.element->size, p->type->u.element->lineno), p->brace_level));
} }
......
...@@ -24,6 +24,7 @@ test: preproc/init ...@@ -24,6 +24,7 @@ test: preproc/init
test: preproc/strings test: preproc/strings
test: preproc/type test: preproc/type
test: preproc/variable test: preproc/variable
test: preproc/outofscope
test: preproc/whenever test: preproc/whenever
test: sql/array test: sql/array
test: sql/binary test: sql/binary
......
...@@ -24,6 +24,7 @@ test: preproc/init ...@@ -24,6 +24,7 @@ test: preproc/init
test: preproc/strings test: preproc/strings
test: preproc/type test: preproc/type
test: preproc/variable test: preproc/variable
test: preproc/outofscope
test: preproc/whenever test: preproc/whenever
test: sql/array test: sql/array
test: sql/binary test: sql/binary
......
...@@ -147,7 +147,7 @@ if (sqlca.sqlcode < 0) dosqlprint ( );} ...@@ -147,7 +147,7 @@ if (sqlca.sqlcode < 0) dosqlprint ( );}
sqlca.sqlcode = 100; sqlca.sqlcode = 100;
ECPG_informix_set_var( 0, &( i ), __LINE__);\ ECPGset_var( 0, &( i ), __LINE__);\
ECPG_informix_reset_sqlca(); /* declare c cursor for select * from test where i <= $1 */ ECPG_informix_reset_sqlca(); /* declare c cursor for select * from test where i <= $1 */
#line 49 "test_informix.pgc" #line 49 "test_informix.pgc"
...@@ -245,7 +245,7 @@ if (sqlca.sqlcode < 0) dosqlprint ( );} ...@@ -245,7 +245,7 @@ if (sqlca.sqlcode < 0) dosqlprint ( );}
static void openit(void) static void openit(void)
{ {
{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "declare c cursor for select * from test where i <= $1 ", { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "declare c cursor for select * from test where i <= $1 ",
ECPGt_int,&(*( int *)(ECPG_informix_get_var( 0))),(long)1,(long)1,sizeof(int), ECPGt_int,&(*( int *)(ECPGget_var( 0))),(long)1,(long)1,sizeof(int),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
#line 95 "test_informix.pgc" #line 95 "test_informix.pgc"
......
...@@ -153,7 +153,8 @@ if (sqlca.sqlcode < 0) exit (1);} ...@@ -153,7 +153,8 @@ if (sqlca.sqlcode < 0) exit (1);}
/* Dynamic cursorname test with INTO list in FETCH stmts */ /* Dynamic cursorname test with INTO list in FETCH stmts */
strcpy(msg, "declare"); strcpy(msg, "declare");
/* declare $0 cursor for select id , t from t1 */ ECPGset_var( 0, &( curname1 ), __LINE__);\
/* declare $0 cursor for select id , t from t1 */
#line 59 "cursor.pgc" #line 59 "cursor.pgc"
...@@ -286,7 +287,10 @@ if (sqlca.sqlcode < 0) exit (1);} ...@@ -286,7 +287,10 @@ if (sqlca.sqlcode < 0) exit (1);}
/* Dynamic cursorname test with INTO list in DECLARE stmt */ /* Dynamic cursorname test with INTO list in DECLARE stmt */
strcpy(msg, "declare"); strcpy(msg, "declare");
/* declare $0 cursor for select id , t from t1 */ ECPGset_var( 3, &( curname2 ), __LINE__);\
ECPGset_var( 1, ( t ), __LINE__);\
ECPGset_var( 2, &( id ), __LINE__);\
/* declare $0 cursor for select id , t from t1 */
#line 100 "cursor.pgc" #line 100 "cursor.pgc"
...@@ -435,7 +439,8 @@ if (sqlca.sqlcode < 0) exit (1);} ...@@ -435,7 +439,8 @@ if (sqlca.sqlcode < 0) exit (1);}
strcpy(msg, "declare"); strcpy(msg, "declare");
/* declare $0 cursor for $1 */ ECPGset_var( 4, &( curname3 ), __LINE__);\
/* declare $0 cursor for $1 */
#line 143 "cursor.pgc" #line 143 "cursor.pgc"
...@@ -590,7 +595,8 @@ if (sqlca.sqlcode < 0) exit (1);} ...@@ -590,7 +595,8 @@ if (sqlca.sqlcode < 0) exit (1);}
strcpy(msg, "declare"); strcpy(msg, "declare");
/* declare $0 cursor for $1 */ ECPGset_var( 5, &( curname4 ), __LINE__);\
/* declare $0 cursor for $1 */
#line 193 "cursor.pgc" #line 193 "cursor.pgc"
......
...@@ -107,7 +107,8 @@ main (void) ...@@ -107,7 +107,8 @@ main (void)
exit (sqlca.sqlcode); exit (sqlca.sqlcode);
} }
/* declare C cursor for select name , accs , byte from empl where idnum = $1 */ ECPGset_var( 0, &( empl.idnum ), __LINE__);\
/* declare C cursor for select name , accs , byte from empl where idnum = $1 */
#line 58 "binary.pgc" #line 58 "binary.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare C cursor for select name , accs , byte from empl where idnum = $1 ", { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare C cursor for select name , accs , byte from empl where idnum = $1 ",
...@@ -133,7 +134,8 @@ main (void) ...@@ -133,7 +134,8 @@ main (void)
printf ("name=%s, accs=%d byte=%s\n", empl.name, empl.accs, empl.byte); printf ("name=%s, accs=%d byte=%s\n", empl.name, empl.accs, empl.byte);
memset(empl.name, 0, 21L); memset(empl.name, 0, 21L);
/* declare B binary cursor for select name , accs , byte from empl where idnum = $1 */ ECPGset_var( 1, &( empl.idnum ), __LINE__);\
/* declare B binary cursor for select name , accs , byte from empl where idnum = $1 */
#line 70 "binary.pgc" #line 70 "binary.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare B binary cursor for select name , accs , byte from empl where idnum = $1 ", { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare B binary cursor for select name , accs , byte from empl where idnum = $1 ",
...@@ -166,7 +168,8 @@ main (void) ...@@ -166,7 +168,8 @@ main (void)
printf("(%o)", (unsigned char)empl.byte[i]); printf("(%o)", (unsigned char)empl.byte[i]);
printf("\n"); printf("\n");
/* declare A binary cursor for select byte from empl where idnum = $1 */ ECPGset_var( 2, &( empl.idnum ), __LINE__);\
/* declare A binary cursor for select byte from empl where idnum = $1 */
#line 87 "binary.pgc" #line 87 "binary.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare A binary cursor for select byte from empl where idnum = $1 ", { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare A binary cursor for select byte from empl where idnum = $1 ",
......
...@@ -11,6 +11,7 @@ TESTS = array_of_struct array_of_struct.c \ ...@@ -11,6 +11,7 @@ TESTS = array_of_struct array_of_struct.c \
define define.c \ define define.c \
init init.c \ init init.c \
strings strings.c \ strings strings.c \
outofscope outofscope.c \
type type.c \ type type.c \
variable variable.c \ variable variable.c \
whenever whenever.c whenever whenever.c
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment