mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	Applied patch by Boszormenyi Zoltan <zb@cybertec.at> to add out-of-scope cursor support to native mode.
This commit is contained in:
		@@ -1,4 +1,4 @@
 | 
			
		||||
/* $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
 | 
			
		||||
#include "postgres_fe.h"
 | 
			
		||||
@@ -1004,57 +1004,16 @@ rtypwidth(int sqltype, int sqllen)
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct var_list
 | 
			
		||||
{
 | 
			
		||||
	int			number;
 | 
			
		||||
	void	   *pointer;
 | 
			
		||||
	struct var_list *next;
 | 
			
		||||
}	*ivlist = NULL;
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ECPG_informix_set_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;
 | 
			
		||||
	}
 | 
			
		||||
	ECPGset_var(number, pointer, lineno);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void *
 | 
			
		||||
ECPG_informix_get_var(int number)
 | 
			
		||||
{
 | 
			
		||||
	struct var_list *ptr;
 | 
			
		||||
 | 
			
		||||
	for (ptr = ivlist; ptr != NULL && ptr->number != number; ptr = ptr->next);
 | 
			
		||||
	return (ptr) ? ptr->pointer : NULL;
 | 
			
		||||
	return ECPGget_var(number);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
# $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
 | 
			
		||||
ECPGallocate_desc                1
 | 
			
		||||
ECPGconnect                      2
 | 
			
		||||
@@ -26,4 +26,6 @@ ECPGstatus                       23
 | 
			
		||||
ECPGtrans                        24
 | 
			
		||||
sqlprint                         25
 | 
			
		||||
ECPGget_PGconn			 26
 | 
			
		||||
ECPGtransactionStatus      27
 | 
			
		||||
ECPGtransactionStatus		 27
 | 
			
		||||
ECPGset_var			 28
 | 
			
		||||
ECPGget_var			 29
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/* $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
 | 
			
		||||
#include "postgres_fe.h"
 | 
			
		||||
@@ -505,3 +505,55 @@ ecpg_gettext(const char *msgid)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#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;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
/*
 | 
			
		||||
 * this is a small part of c.h since we don't want to leak all postgres
 | 
			
		||||
 * 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
 | 
			
		||||
@@ -85,6 +85,9 @@ void		ECPGset_noind_null(enum ECPGttype, void *);
 | 
			
		||||
bool		ECPGis_noind_null(enum ECPGttype, void *);
 | 
			
		||||
bool		ECPGdescribe(int, int, bool, const char *, const char *, ...);
 | 
			
		||||
 | 
			
		||||
void		ECPGset_var(int, void *, int);
 | 
			
		||||
void	   *ECPGget_var(int number);
 | 
			
		||||
 | 
			
		||||
/* dynamic result allocation */
 | 
			
		||||
void		ECPGfree_auto_mem(void);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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
 | 
			
		||||
 * we need to check for a constant if we expect a constant
 | 
			
		||||
@@ -317,7 +317,7 @@ struct variable *
 | 
			
		||||
descriptor_variable(const char *name, int input)
 | 
			
		||||
{
 | 
			
		||||
	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] = {
 | 
			
		||||
		{descriptor_names[0], (struct ECPGtype *) & descriptor_type, 0, NULL},
 | 
			
		||||
		{descriptor_names[1], (struct ECPGtype *) & descriptor_type, 0, NULL}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/* $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
 | 
			
		||||
	{
 | 
			
		||||
		if (INFORMIX_MODE)
 | 
			
		||||
@@ -310,11 +310,14 @@ ECPG: DeclareCursorStmtDECLAREcursor_namecursor_optionsCURSORopt_holdFORSelectSt
 | 
			
		||||
 | 
			
		||||
		this->next = cur;
 | 
			
		||||
		this->name = $2;
 | 
			
		||||
		this->function = (current_function ? mm_strdup(current_function) : NULL);
 | 
			
		||||
		this->connection = connection;
 | 
			
		||||
		this->opened = false;
 | 
			
		||||
		this->command =  cat_str(7, make_str("declare"), cursor_marker, $3, make_str("cursor"), $5, make_str("for"), $7);
 | 
			
		||||
		this->argsinsert = argsinsert;
 | 
			
		||||
		this->argsinsert_oos = NULL;
 | 
			
		||||
		this->argsresult = argsresult;
 | 
			
		||||
		this->argsresult_oos = NULL;
 | 
			
		||||
		argsinsert = argsresult = NULL;
 | 
			
		||||
		cur = this;
 | 
			
		||||
 | 
			
		||||
@@ -327,17 +330,17 @@ ECPG: DeclareCursorStmtDECLAREcursor_namecursor_optionsCURSORopt_holdFORSelectSt
 | 
			
		||||
		}
 | 
			
		||||
		comment = cat_str(3, make_str("/*"), c1, make_str("*/"));
 | 
			
		||||
 | 
			
		||||
		if (INFORMIX_MODE)
 | 
			
		||||
		{
 | 
			
		||||
			if (braces_open > 0) /* we're in a function */
 | 
			
		||||
			{
 | 
			
		||||
				$$ = cat_str(4, adjust_informix(this->argsinsert), adjust_informix(this->argsresult), make_str("ECPG_informix_reset_sqlca();"), comment);
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
				$$ = cat_str(3, adjust_informix(this->argsinsert), adjust_informix(this->argsresult), comment);
 | 
			
		||||
		}
 | 
			
		||||
		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
 | 
			
		||||
			$$ = comment;
 | 
			
		||||
			$$ = cat_str(3,
 | 
			
		||||
				adjust_outofscope_cursor_vars(this, true),
 | 
			
		||||
				adjust_outofscope_cursor_vars(this, false),
 | 
			
		||||
				comment);
 | 
			
		||||
	}
 | 
			
		||||
ECPG: ClosePortalStmtCLOSEcursor_name block
 | 
			
		||||
	{
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/* $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. */
 | 
			
		||||
/* Copyright (c) 1996-2010, PostgreSQL Global Development Group */
 | 
			
		||||
@@ -419,8 +419,8 @@ main(int argc, char *const argv[])
 | 
			
		||||
				/* and structure member lists */
 | 
			
		||||
				memset(struct_member_list, 0, sizeof(struct_member_list));
 | 
			
		||||
 | 
			
		||||
				/* and our variable counter for Informix compatibility */
 | 
			
		||||
				ecpg_informix_var = 0;
 | 
			
		||||
				/* and our variable counter for out of scope cursors' variables */
 | 
			
		||||
				ecpg_internal_var = 0;
 | 
			
		||||
 | 
			
		||||
				/* finally the actual connection */
 | 
			
		||||
				connection = NULL;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg.header,v 1.10 2009/11/05 23:24:27 tgl Exp $ */
 | 
			
		||||
/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg.header,v 1.11 2010/01/26 09:07:31 meskes Exp $ */
 | 
			
		||||
 | 
			
		||||
/* Copyright comment */
 | 
			
		||||
%{
 | 
			
		||||
@@ -33,7 +33,8 @@
 | 
			
		||||
 */
 | 
			
		||||
int struct_level = 0;
 | 
			
		||||
int braces_open; /* brace level counter */
 | 
			
		||||
int ecpg_informix_var = 0;
 | 
			
		||||
char *current_function;
 | 
			
		||||
int ecpg_internal_var = 0;
 | 
			
		||||
char	*connection = NULL;
 | 
			
		||||
char	*input_filename = NULL;
 | 
			
		||||
 | 
			
		||||
@@ -53,10 +54,10 @@ static char *ECPGstruct_sizeof = NULL;
 | 
			
		||||
/* for forward declarations we have to store some data as well */
 | 
			
		||||
static char *forward_name = NULL;
 | 
			
		||||
 | 
			
		||||
struct ECPGtype ecpg_no_indicator = {ECPGt_NO_INDICATOR, NULL, NULL, {NULL}, 0};
 | 
			
		||||
struct ECPGtype ecpg_no_indicator = {ECPGt_NO_INDICATOR, NULL, NULL, NULL, {NULL}, 0};
 | 
			
		||||
struct variable no_indicator = {"no_indicator", &ecpg_no_indicator, 0, NULL};
 | 
			
		||||
 | 
			
		||||
struct ECPGtype ecpg_query = {ECPGt_char_variable, NULL, NULL, {NULL}, 0};
 | 
			
		||||
struct ECPGtype ecpg_query = {ECPGt_char_variable, NULL, NULL, NULL, {NULL}, 0};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Handle parsing errors and warnings
 | 
			
		||||
@@ -226,76 +227,153 @@ create_questionmarks(char *name, bool array)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *
 | 
			
		||||
adjust_informix(struct arguments *list)
 | 
			
		||||
adjust_outofscope_cursor_vars(struct cursor *cur, bool insert)
 | 
			
		||||
{
 | 
			
		||||
	/* Informix accepts DECLARE with variables that are out of scope when OPEN is called.
 | 
			
		||||
 	 * for instance you can declare variables in a function, and then subsequently use them
 | 
			
		||||
	 * {
 | 
			
		||||
	 *      declare_vars();
 | 
			
		||||
	 *      exec sql ... which uses vars declared in the above function
 | 
			
		||||
	 * For instance you can DECLARE a cursor in one function, and OPEN/FETCH/CLOSE
 | 
			
		||||
	 * it in other functions. This is very useful for e.g. event-driver programming,
 | 
			
		||||
	 * but may also lead to dangerous programming. The limitation when this is allowed
 | 
			
		||||
	 * and doesn's cause problems have to be documented, like the allocated variables
 | 
			
		||||
	 * must not be realloc()'ed.
 | 
			
		||||
	 *
 | 
			
		||||
	 * This breaks standard and leads to some very dangerous programming.
 | 
			
		||||
	 * Since they do, we have to work around and accept their syntax as well.
 | 
			
		||||
	 * But we will do so ONLY in Informix mode.
 | 
			
		||||
	 * We have to change the variables to our own struct and just store the pointer instead of the variable
 | 
			
		||||
	 * We have to change the variables to our own struct and just store the pointer
 | 
			
		||||
	 * instead of the variable. Do it only for local variables, not for globals.
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	 struct arguments *ptr;
 | 
			
		||||
	 char *result = make_str("");
 | 
			
		||||
	struct arguments *list;
 | 
			
		||||
	struct arguments *ptr;
 | 
			
		||||
	struct arguments *newlist = NULL;
 | 
			
		||||
	struct variable *newvar, *newind;
 | 
			
		||||
	char *result = make_str("");
 | 
			
		||||
 | 
			
		||||
	 for (ptr = list; ptr != NULL; ptr = ptr->next)
 | 
			
		||||
	 {
 | 
			
		||||
	 	char temp[20]; /* this should be sufficient unless you have 8 byte integers */
 | 
			
		||||
	list = (insert ? cur->argsinsert : cur->argsresult);
 | 
			
		||||
 | 
			
		||||
	for (ptr = list; ptr != NULL; ptr = ptr->next)
 | 
			
		||||
	{
 | 
			
		||||
		char temp[20]; /* this should be sufficient unless you have 8 byte integers */
 | 
			
		||||
		char *original_var;
 | 
			
		||||
		bool skip_set_var = false;
 | 
			
		||||
 | 
			
		||||
	 	/* change variable name to "ECPG_informix_get_var(<counter>)" */
 | 
			
		||||
		/* change variable name to "ECPGget_var(<counter>)" */
 | 
			
		||||
		original_var = ptr->variable->name;
 | 
			
		||||
		sprintf(temp, "%d))", ecpg_informix_var);
 | 
			
		||||
		sprintf(temp, "%d))", ecpg_internal_var);
 | 
			
		||||
 | 
			
		||||
		if ((ptr->variable->type->type != ECPGt_varchar && ptr->variable->type->type != ECPGt_char && ptr->variable->type->type != ECPGt_unsigned_char && ptr->variable->type->type != ECPGt_string) && atoi(ptr->variable->type->size) > 1)
 | 
			
		||||
		/* Don't emit ECPGset_var() calls for global variables */
 | 
			
		||||
		if (ptr->variable->brace_level == 0)
 | 
			
		||||
		{
 | 
			
		||||
			ptr->variable = new_variable(cat_str(4, make_str("("), mm_strdup(ecpg_type_name(ptr->variable->type->u.element->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_array_type(ECPGmake_simple_type(ptr->variable->type->u.element->type, make_str("1"), ptr->variable->type->u.element->lineno), ptr->variable->type->size), 0);
 | 
			
		||||
			sprintf(temp, "%d, (", ecpg_informix_var++);
 | 
			
		||||
			newvar = ptr->variable;
 | 
			
		||||
			skip_set_var = true;
 | 
			
		||||
		}
 | 
			
		||||
		else if ((ptr->variable->type->type == ECPGt_char_variable) && (!strncmp(ptr->variable->name, "ECPGprepared_statement", strlen("ECPGprepared_statement"))))
 | 
			
		||||
		{
 | 
			
		||||
			newvar = ptr->variable;
 | 
			
		||||
			skip_set_var = true;
 | 
			
		||||
		}
 | 
			
		||||
		else if ((ptr->variable->type->type != ECPGt_varchar && ptr->variable->type->type != ECPGt_char && ptr->variable->type->type != ECPGt_unsigned_char && ptr->variable->type->type != ECPGt_string) && atoi(ptr->variable->type->size) > 1)
 | 
			
		||||
		{
 | 
			
		||||
			newvar = new_variable(cat_str(4, make_str("("), mm_strdup(ecpg_type_name(ptr->variable->type->u.element->type)), make_str(" *)(ECPGget_var("), mm_strdup(temp)), ECPGmake_array_type(ECPGmake_simple_type(ptr->variable->type->u.element->type, make_str("1"), ptr->variable->type->u.element->lineno), ptr->variable->type->size), 0);
 | 
			
		||||
			sprintf(temp, "%d, (", ecpg_internal_var++);
 | 
			
		||||
		}
 | 
			
		||||
		else if ((ptr->variable->type->type == ECPGt_varchar || ptr->variable->type->type == ECPGt_char || ptr->variable->type->type == ECPGt_unsigned_char || ptr->variable->type->type == ECPGt_string) && atoi(ptr->variable->type->size) > 1)
 | 
			
		||||
		{
 | 
			
		||||
			ptr->variable = new_variable(cat_str(4, make_str("("), mm_strdup(ecpg_type_name(ptr->variable->type->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->variable->type->type, ptr->variable->type->size, ptr->variable->type->lineno), 0);
 | 
			
		||||
			sprintf(temp, "%d, (", ecpg_informix_var++);
 | 
			
		||||
			newvar = new_variable(cat_str(4, make_str("("), mm_strdup(ecpg_type_name(ptr->variable->type->type)), make_str(" *)(ECPGget_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->variable->type->type, ptr->variable->type->size, ptr->variable->type->lineno), 0);
 | 
			
		||||
			if (ptr->variable->type->type == ECPGt_varchar)
 | 
			
		||||
				sprintf(temp, "%d, &(", ecpg_internal_var++);
 | 
			
		||||
			else
 | 
			
		||||
				sprintf(temp, "%d, (", ecpg_internal_var++);
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		else if (ptr->variable->type->type == ECPGt_struct || ptr->variable->type->type == ECPGt_union)
 | 
			
		||||
		{
 | 
			
		||||
			ptr->variable = new_variable(cat_str(4, make_str("*("), mm_strdup(ecpg_type_name(ptr->variable->type->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->variable->type->type, ptr->variable->type->size, ptr->variable->type->lineno), 0);
 | 
			
		||||
			sprintf(temp, "%d, &(", ecpg_informix_var++);
 | 
			
		||||
			sprintf(temp, "%d)))", ecpg_internal_var);
 | 
			
		||||
			newvar = new_variable(cat_str(4, make_str("(*("), mm_strdup(ptr->variable->type->type_name), make_str(" *)(ECPGget_var("), mm_strdup(temp)), ECPGmake_struct_type(ptr->variable->type->u.members, ptr->variable->type->type, ptr->variable->type->type_name, ptr->variable->type->struct_sizeof), 0);
 | 
			
		||||
			sprintf(temp, "%d, &(", ecpg_internal_var++);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* create call to "ECPG_informix_set_var(<counter>, <pointer>. <linen number>)" */
 | 
			
		||||
		result = cat_str(5, result, make_str("ECPG_informix_set_var("), mm_strdup(temp), mm_strdup(original_var), make_str("), __LINE__);\n"));
 | 
			
		||||
 | 
			
		||||
		/* now the indicator if there is one */
 | 
			
		||||
		if (ptr->indicator->type->type != ECPGt_NO_INDICATOR)
 | 
			
		||||
		else if (ptr->variable->type->type == ECPGt_array)
 | 
			
		||||
		{
 | 
			
		||||
			/* change variable name to "ECPG_informix_get_var(<counter>)" */
 | 
			
		||||
			original_var = ptr->indicator->name;
 | 
			
		||||
			sprintf(temp, "%d))", ecpg_informix_var);
 | 
			
		||||
 | 
			
		||||
			/* create call to "ECPG_informix_set_var(<counter>, <pointer>. <linen number>)" */
 | 
			
		||||
			if (atoi(ptr->indicator->type->size) > 1)
 | 
			
		||||
			if (ptr->variable->type->u.element->type == ECPGt_struct || ptr->variable->type->u.element->type == ECPGt_union)
 | 
			
		||||
			{
 | 
			
		||||
				ptr->indicator = new_variable(cat_str(4, make_str("("), mm_strdup(ecpg_type_name(ptr->indicator->type->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->indicator->type->type, ptr->indicator->type->size, ptr->variable->type->lineno), 0);
 | 
			
		||||
				sprintf(temp, "%d, (", ecpg_informix_var++);
 | 
			
		||||
				sprintf(temp, "%d)))", ecpg_internal_var);
 | 
			
		||||
				newvar = new_variable(cat_str(4, make_str("(*("), mm_strdup(ptr->variable->type->u.element->type_name), make_str(" *)(ECPGget_var("), mm_strdup(temp)), ECPGmake_struct_type(ptr->variable->type->u.element->u.members, ptr->variable->type->u.element->type, ptr->variable->type->u.element->type_name, ptr->variable->type->u.element->struct_sizeof), 0);
 | 
			
		||||
				sprintf(temp, "%d, (", ecpg_internal_var++);
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				ptr->indicator = new_variable(cat_str(4, make_str("*("), mm_strdup(ecpg_type_name(ptr->indicator->type->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->indicator->type->type, ptr->indicator->type->size, ptr->variable->type->lineno), 0);
 | 
			
		||||
				sprintf(temp, "%d, &(", ecpg_informix_var++);
 | 
			
		||||
				newvar = new_variable(cat_str(4, make_str("("), mm_strdup(ecpg_type_name(ptr->variable->type->type)), make_str(" *)(ECPGget_var("), mm_strdup(temp)), ECPGmake_array_type(ECPGmake_simple_type(ptr->variable->type->u.element->type, ptr->variable->type->u.element->size, ptr->variable->type->u.element->lineno), ptr->variable->type->size), 0);
 | 
			
		||||
				sprintf(temp, "%d, &(", ecpg_internal_var++);
 | 
			
		||||
			}
 | 
			
		||||
			result = cat_str(5, result, make_str("ECPG_informix_set_var("), mm_strdup(temp), mm_strdup(original_var), make_str("), __LINE__);\n"));
 | 
			
		||||
		}
 | 
			
		||||
	 }
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			newvar = new_variable(cat_str(4, make_str("*("), mm_strdup(ecpg_type_name(ptr->variable->type->type)), make_str(" *)(ECPGget_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->variable->type->type, ptr->variable->type->size, ptr->variable->type->lineno), 0);
 | 
			
		||||
			sprintf(temp, "%d, &(", ecpg_internal_var++);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	 return result;
 | 
			
		||||
		/* create call to "ECPGset_var(<counter>, <pointer>. <linen number>)" */
 | 
			
		||||
		if (!skip_set_var)
 | 
			
		||||
			result = cat_str(5, result, make_str("ECPGset_var("), mm_strdup(temp), mm_strdup(original_var), make_str("), __LINE__);\n"));
 | 
			
		||||
 | 
			
		||||
		/* now the indicator if there is one and it's not a global variable */
 | 
			
		||||
		if ((ptr->indicator->type->type == ECPGt_NO_INDICATOR) || (ptr->indicator->brace_level == 0))
 | 
			
		||||
		{
 | 
			
		||||
			newind = ptr->indicator;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			/* change variable name to "ECPGget_var(<counter>)" */
 | 
			
		||||
			original_var = ptr->indicator->name;
 | 
			
		||||
			sprintf(temp, "%d))", ecpg_internal_var);
 | 
			
		||||
 | 
			
		||||
			if (ptr->indicator->type->type == ECPGt_struct || ptr->indicator->type->type == ECPGt_union)
 | 
			
		||||
			{
 | 
			
		||||
				sprintf(temp, "%d)))", ecpg_internal_var);
 | 
			
		||||
				newind = new_variable(cat_str(4, make_str("(*("), mm_strdup(ptr->indicator->type->type_name), make_str(" *)(ECPGget_var("), mm_strdup(temp)), ECPGmake_struct_type(ptr->indicator->type->u.members, ptr->indicator->type->type, ptr->indicator->type->type_name, ptr->indicator->type->struct_sizeof), 0);
 | 
			
		||||
				sprintf(temp, "%d, &(", ecpg_internal_var++);
 | 
			
		||||
			}
 | 
			
		||||
			else if (ptr->indicator->type->type == ECPGt_array)
 | 
			
		||||
			{
 | 
			
		||||
				if (ptr->indicator->type->u.element->type == ECPGt_struct || ptr->indicator->type->u.element->type == ECPGt_union)
 | 
			
		||||
				{
 | 
			
		||||
					sprintf(temp, "%d)))", ecpg_internal_var);
 | 
			
		||||
					newind = new_variable(cat_str(4, make_str("(*("), mm_strdup(ptr->indicator->type->u.element->type_name), make_str(" *)(ECPGget_var("), mm_strdup(temp)), ECPGmake_struct_type(ptr->indicator->type->u.element->u.members, ptr->indicator->type->u.element->type, ptr->indicator->type->u.element->type_name, ptr->indicator->type->u.element->struct_sizeof), 0);
 | 
			
		||||
					sprintf(temp, "%d, (", ecpg_internal_var++);
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					newind = new_variable(cat_str(4, make_str("("), mm_strdup(ecpg_type_name(ptr->indicator->type->u.element->type)), make_str(" *)(ECPGget_var("), mm_strdup(temp)), ECPGmake_array_type(ECPGmake_simple_type(ptr->indicator->type->u.element->type, ptr->indicator->type->u.element->size, ptr->indicator->type->u.element->lineno), ptr->indicator->type->size), 0);
 | 
			
		||||
					sprintf(temp, "%d, &(", ecpg_internal_var++);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else if (atoi(ptr->indicator->type->size) > 1)
 | 
			
		||||
			{
 | 
			
		||||
				newind = new_variable(cat_str(4, make_str("("), mm_strdup(ecpg_type_name(ptr->indicator->type->type)), make_str(" *)(ECPGget_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->indicator->type->type, ptr->indicator->type->size, ptr->variable->type->lineno), 0);
 | 
			
		||||
				sprintf(temp, "%d, (", ecpg_internal_var++);
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				newind = new_variable(cat_str(4, make_str("*("), mm_strdup(ecpg_type_name(ptr->indicator->type->type)), make_str(" *)(ECPGget_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->indicator->type->type, ptr->indicator->type->size, ptr->variable->type->lineno), 0);
 | 
			
		||||
				sprintf(temp, "%d, &(", ecpg_internal_var++);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			/* create call to "ECPGset_var(<counter>, <pointer>. <linen number>)" */
 | 
			
		||||
			result = cat_str(5, result, make_str("ECPGset_var("), mm_strdup(temp), mm_strdup(original_var), make_str("), __LINE__);\n"));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		add_variable_to_tail(&newlist, newvar, newind);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (insert)
 | 
			
		||||
		cur->argsinsert_oos = newlist;
 | 
			
		||||
	else
 | 
			
		||||
		cur->argsresult_oos = newlist;
 | 
			
		||||
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This tests whether the cursor was declared and opened in the same function. */
 | 
			
		||||
#define SAMEFUNC(cur)	\
 | 
			
		||||
	((cur->function == NULL) ||		\
 | 
			
		||||
	 (cur->function != NULL && !strcmp(cur->function, current_function)))
 | 
			
		||||
 | 
			
		||||
static struct cursor *
 | 
			
		||||
add_additional_variables(char *name, bool insert)
 | 
			
		||||
{
 | 
			
		||||
@@ -318,12 +396,12 @@ add_additional_variables(char *name, bool insert)
 | 
			
		||||
	{
 | 
			
		||||
		/* add all those input variables that were given earlier
 | 
			
		||||
		 * note that we have to append here but have to keep the existing order */
 | 
			
		||||
		for (p = ptr->argsinsert; p; p = p->next)
 | 
			
		||||
		for (p = (SAMEFUNC(ptr) ? ptr->argsinsert : ptr->argsinsert_oos); p; p = p->next)
 | 
			
		||||
			add_variable_to_tail(&argsinsert, p->variable, p->indicator);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* add all those output variables that were given earlier */
 | 
			
		||||
	for (p = ptr->argsresult; p; p = p->next)
 | 
			
		||||
	for (p = (SAMEFUNC(ptr) ? ptr->argsresult : ptr->argsresult_oos); p; p = p->next)
 | 
			
		||||
		add_variable_to_tail(&argsresult, p->variable, p->indicator);
 | 
			
		||||
 | 
			
		||||
	return ptr;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/* $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 statement
 | 
			
		||||
@@ -16,7 +16,17 @@ statement: ecpgstart at stmt ';'        { connection = NULL; }
 | 
			
		||||
                | c_thing               { fprintf(yyout, "%s", $1); free($1); }
 | 
			
		||||
                | CPP_LINE              { fprintf(yyout, "%s", $1); free($1); }
 | 
			
		||||
                | '{'                   { 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
 | 
			
		||||
@@ -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);
 | 
			
		||||
			struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
 | 
			
		||||
			const char *con = connection ? connection : "NULL";
 | 
			
		||||
			char *comment;
 | 
			
		||||
 | 
			
		||||
			for (ptr = cur; ptr != NULL; ptr = ptr->next)
 | 
			
		||||
			{
 | 
			
		||||
@@ -294,9 +305,11 @@ ECPGCursorStmt:  DECLARE cursor_name cursor_options CURSOR opt_hold FOR prepared
 | 
			
		||||
			/* initial definition */
 | 
			
		||||
			this->next = cur;
 | 
			
		||||
			this->name = $2;
 | 
			
		||||
			this->function = (current_function ? mm_strdup(current_function) : NULL);
 | 
			
		||||
			this->connection = connection;
 | 
			
		||||
			this->command =  cat_str(6, make_str("declare"), cursor_marker, $3, make_str("cursor"), $5, make_str("for $1"));
 | 
			
		||||
			this->argsresult = NULL;
 | 
			
		||||
			this->argsresult_oos = NULL;
 | 
			
		||||
 | 
			
		||||
			thisquery->type = &ecpg_query;
 | 
			
		||||
			thisquery->brace_level = 0;
 | 
			
		||||
@@ -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);
 | 
			
		||||
 | 
			
		||||
			this->argsinsert = NULL;
 | 
			
		||||
			this->argsinsert_oos = NULL;
 | 
			
		||||
			if ($2[0] == ':')
 | 
			
		||||
			{
 | 
			
		||||
				struct variable *var = find_variable($2 + 1);
 | 
			
		||||
@@ -315,10 +329,19 @@ ECPGCursorStmt:  DECLARE cursor_name cursor_options CURSOR opt_hold FOR prepared
 | 
			
		||||
 | 
			
		||||
			cur = this;
 | 
			
		||||
 | 
			
		||||
			if (INFORMIX_MODE && braces_open > 0) /* we're in a function */
 | 
			
		||||
				$$ = cat_str(4, make_str("ECPG_informix_reset_sqlca();"), make_str("/*"), mm_strdup(this->command), make_str("*/"));
 | 
			
		||||
			comment = cat_str(3, 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
 | 
			
		||||
				$$ = 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
 | 
			
		||||
		var_type
 | 
			
		||||
		{
 | 
			
		||||
			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_index = $2.type_index;
 | 
			
		||||
			actual_type[struct_level].type_sizeof = $2.type_sizeof;
 | 
			
		||||
@@ -415,6 +439,7 @@ var_declaration: storage_declaration
 | 
			
		||||
		| var_type
 | 
			
		||||
		{
 | 
			
		||||
			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_index = $1.type_index;
 | 
			
		||||
			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
 | 
			
		||||
				case ECPGt_struct:
 | 
			
		||||
				case ECPGt_union:
 | 
			
		||||
					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
 | 
			
		||||
						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);
 | 
			
		||||
					break;
 | 
			
		||||
@@ -1303,9 +1328,9 @@ ECPGVar: SQL_VAR
 | 
			
		||||
					case ECPGt_struct:
 | 
			
		||||
					case ECPGt_union:
 | 
			
		||||
						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
 | 
			
		||||
							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;
 | 
			
		||||
 | 
			
		||||
					case ECPGt_varchar:
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/* $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
 | 
			
		||||
#define _ECPG_PREPROC_EXTERN_H
 | 
			
		||||
@@ -26,9 +26,10 @@ extern int	braces_open,
 | 
			
		||||
			questionmarks,
 | 
			
		||||
			ret_value,
 | 
			
		||||
			struct_level,
 | 
			
		||||
			ecpg_informix_var,
 | 
			
		||||
			ecpg_internal_var,
 | 
			
		||||
			regression_mode,
 | 
			
		||||
			auto_prepare;
 | 
			
		||||
extern char *current_function;
 | 
			
		||||
extern char *descriptor_index;
 | 
			
		||||
extern char *descriptor_name;
 | 
			
		||||
extern char *connection;
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 * 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 */
 | 
			
		||||
static int		literallen;				/* actual current length */
 | 
			
		||||
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)
 | 
			
		||||
static void addlit(char *ytext, int yleng);
 | 
			
		||||
static void addlitchar (unsigned char);
 | 
			
		||||
@@ -789,6 +792,16 @@ cppline			{space}*#(.*\\{space})*.*{newline}
 | 
			
		||||
<C>{identifier} 	{
 | 
			
		||||
						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 */
 | 
			
		||||
						/* however, some defines have to be taken care of for compatibility */
 | 
			
		||||
						if ((!INFORMIX_MODE || !isinformixdefine()) && !isdefine())
 | 
			
		||||
@@ -811,8 +824,8 @@ cppline			{space}*#(.*\\{space})*.*{newline}
 | 
			
		||||
<C>"/"				{ return('/'); }
 | 
			
		||||
<C>"+"				{ return('+'); }
 | 
			
		||||
<C>"-"				{ return('-'); }
 | 
			
		||||
<C>"("				{ return('('); }
 | 
			
		||||
<C>")"				{ return(')'); }
 | 
			
		||||
<C>"("				{ parenths_open++; return('('); }
 | 
			
		||||
<C>")"				{ parenths_open--; return(')'); }
 | 
			
		||||
<C,xskip>{space}		{ ECHO; }
 | 
			
		||||
<C>\{				{ return('{'); }
 | 
			
		||||
<C>\}				{ return('}'); }
 | 
			
		||||
@@ -1178,6 +1191,8 @@ void
 | 
			
		||||
lex_init(void)
 | 
			
		||||
{
 | 
			
		||||
	braces_open = 0;
 | 
			
		||||
	parenths_open = 0;
 | 
			
		||||
	current_function = NULL;
 | 
			
		||||
 | 
			
		||||
	preproc_tos = 0;
 | 
			
		||||
	yylineno = 1;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/* $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"
 | 
			
		||||
 | 
			
		||||
@@ -46,7 +46,7 @@ ECPGstruct_member_dup(struct ECPGstruct_member * rm)
 | 
			
		||||
		{
 | 
			
		||||
			case ECPGt_struct:
 | 
			
		||||
			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;
 | 
			
		||||
			case ECPGt_array:
 | 
			
		||||
 | 
			
		||||
@@ -55,7 +55,7 @@ ECPGstruct_member_dup(struct ECPGstruct_member * rm)
 | 
			
		||||
				 * create the struct too
 | 
			
		||||
				 */
 | 
			
		||||
				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
 | 
			
		||||
					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;
 | 
			
		||||
@@ -98,6 +98,7 @@ ECPGmake_simple_type(enum ECPGttype type, char *size, int lineno)
 | 
			
		||||
	struct ECPGtype *ne = (struct ECPGtype *) mm_alloc(sizeof(struct ECPGtype));
 | 
			
		||||
 | 
			
		||||
	ne->type = type;
 | 
			
		||||
	ne->type_name = NULL;
 | 
			
		||||
	ne->size = size;
 | 
			
		||||
	ne->u.element = NULL;
 | 
			
		||||
	ne->struct_sizeof = NULL;
 | 
			
		||||
@@ -117,10 +118,11 @@ ECPGmake_array_type(struct ECPGtype * type, char *size)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
	ne->type_name = mm_strdup(type_name);
 | 
			
		||||
	ne->u.members = ECPGstruct_member_dup(rm);
 | 
			
		||||
	ne->struct_sizeof = struct_sizeof;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
/*
 | 
			
		||||
 * $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
 | 
			
		||||
#define _ECPG_PREPROC_TYPE_H
 | 
			
		||||
@@ -17,6 +17,7 @@ struct ECPGstruct_member
 | 
			
		||||
struct ECPGtype
 | 
			
		||||
{
 | 
			
		||||
	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
 | 
			
		||||
								 * varchar it is the maxsize of the area. */
 | 
			
		||||
	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
 | 
			
		||||
struct ECPGtype *ECPGmake_simple_type(enum ECPGttype, char *, int);
 | 
			
		||||
struct ECPGtype *ECPGmake_varchar_type(enum ECPGttype, long);
 | 
			
		||||
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 *);
 | 
			
		||||
 | 
			
		||||
/* Frees a type. */
 | 
			
		||||
@@ -123,11 +124,14 @@ struct _include_path
 | 
			
		||||
struct cursor
 | 
			
		||||
{
 | 
			
		||||
	char	   *name;
 | 
			
		||||
	char	   *function;
 | 
			
		||||
	char	   *command;
 | 
			
		||||
	char	   *connection;
 | 
			
		||||
	bool		opened;
 | 
			
		||||
	struct arguments *argsinsert;
 | 
			
		||||
	struct arguments *argsinsert_oos;
 | 
			
		||||
	struct arguments *argsresult;
 | 
			
		||||
	struct arguments *argsresult_oos;
 | 
			
		||||
	struct cursor *next;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/* $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"
 | 
			
		||||
 | 
			
		||||
@@ -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));
 | 
			
		||||
					case ECPGt_struct:
 | 
			
		||||
					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:
 | 
			
		||||
						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
 | 
			
		||||
								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_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:
 | 
			
		||||
								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)
 | 
			
		||||
						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_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:
 | 
			
		||||
						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
 | 
			
		||||
test: preproc/strings
 | 
			
		||||
test: preproc/type
 | 
			
		||||
test: preproc/variable
 | 
			
		||||
test: preproc/outofscope
 | 
			
		||||
test: preproc/whenever
 | 
			
		||||
test: sql/array
 | 
			
		||||
test: sql/binary
 | 
			
		||||
 
 | 
			
		||||
@@ -24,6 +24,7 @@ test: preproc/init
 | 
			
		||||
test: preproc/strings
 | 
			
		||||
test: preproc/type
 | 
			
		||||
test: preproc/variable
 | 
			
		||||
test: preproc/outofscope
 | 
			
		||||
test: preproc/whenever
 | 
			
		||||
test: sql/array
 | 
			
		||||
test: sql/binary
 | 
			
		||||
 
 | 
			
		||||
@@ -147,7 +147,7 @@ if (sqlca.sqlcode < 0) dosqlprint ( );}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	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  */
 | 
			
		||||
#line 49 "test_informix.pgc"
 | 
			
		||||
 | 
			
		||||
@@ -245,7 +245,7 @@ if (sqlca.sqlcode < 0) dosqlprint ( );}
 | 
			
		||||
static void openit(void)
 | 
			
		||||
{
 | 
			
		||||
	{ 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);
 | 
			
		||||
#line 95 "test_informix.pgc"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -153,7 +153,8 @@ if (sqlca.sqlcode < 0) exit (1);}
 | 
			
		||||
	/* Dynamic cursorname test with INTO list in FETCH stmts */
 | 
			
		||||
 | 
			
		||||
	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"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -286,7 +287,10 @@ if (sqlca.sqlcode < 0) exit (1);}
 | 
			
		||||
	/* Dynamic cursorname test with INTO list in DECLARE stmt */
 | 
			
		||||
 | 
			
		||||
	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"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -435,7 +439,8 @@ if (sqlca.sqlcode < 0) exit (1);}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	strcpy(msg, "declare");
 | 
			
		||||
	/* declare $0 cursor for $1 */
 | 
			
		||||
	ECPGset_var( 4, &( curname3 ), __LINE__);\
 | 
			
		||||
 /* declare $0 cursor for $1 */
 | 
			
		||||
#line 143 "cursor.pgc"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -590,7 +595,8 @@ if (sqlca.sqlcode < 0) exit (1);}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	strcpy(msg, "declare");
 | 
			
		||||
	/* declare $0 cursor for $1 */
 | 
			
		||||
	ECPGset_var( 5, &( curname4 ), __LINE__);\
 | 
			
		||||
 /* declare $0 cursor for $1 */
 | 
			
		||||
#line 193 "cursor.pgc"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -107,7 +107,8 @@ main (void)
 | 
			
		||||
      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"
 | 
			
		||||
 | 
			
		||||
  { 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)
 | 
			
		||||
  printf ("name=%s, accs=%d byte=%s\n", empl.name, empl.accs, empl.byte);
 | 
			
		||||
 | 
			
		||||
  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"
 | 
			
		||||
 | 
			
		||||
  { 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)
 | 
			
		||||
	printf("(%o)", (unsigned char)empl.byte[i]);
 | 
			
		||||
  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"
 | 
			
		||||
 | 
			
		||||
  { 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 \
 | 
			
		||||
	define define.c \
 | 
			
		||||
	init init.c \
 | 
			
		||||
	strings strings.c \
 | 
			
		||||
	outofscope outofscope.c \
 | 
			
		||||
	type type.c \
 | 
			
		||||
	variable variable.c \
 | 
			
		||||
	whenever whenever.c
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user