- Synced preproc.y with gram.y.

- Synced pgc.l with scan.l.
- Synced keyword.c.
- Include the remaining patches by Christof Petig <christof.petig@wtal.de>.
This commit is contained in:
Michael Meskes 2001-09-19 14:09:32 +00:00
parent 3baf7400d9
commit f0212ced68
24 changed files with 223 additions and 356 deletions

View File

@ -1084,10 +1084,17 @@ Wed Jun 13 14:39:12 CEST 2001
- Synced preproc.y with gram.y.
- Applied bug fix by John Summerfield.
- Set ecpg version to 2.9.0.
- Set library version to 3.3.0.
Son Aug 19 11:04:39 CEST 2001
- Synced preproc.y with gram.y.
- Include some patches by Christof Petig <christof.petig@wtal.de>.
Wed Sep 19 15:57:49 CEST 2001
- Synced preproc.y with gram.y.
- Synced pgc.l with scan.l.
- Synced keyword.c.
- Include the remaining patches by Christof Petig <christof.petig@wtal.de>.
- Set ecpg version to 2.9.0.
- Set library version to 3.3.0.

View File

@ -46,7 +46,8 @@ extern "C"
ECPGt_EOIT, /* End of insert types. */
ECPGt_EORT, /* End of result types. */
ECPGt_NO_INDICATOR, /* no indicator */
ECPGt_long_long, ECPGt_unsigned_long_long
ECPGt_long_long, ECPGt_unsigned_long_long,
ECPGt_descriptor /* sql descriptor, no C variable */
};
/* descriptor items */
@ -71,7 +72,7 @@ extern "C"
ECPGd_EODT /* End of descriptor types. */
};
#define IS_SIMPLE_TYPE(type) (((type) >= ECPGt_char && (type) <= ECPGt_varchar2) || (type)>=ECPGt_long_long)
#define IS_SIMPLE_TYPE(type) (((type) >= ECPGt_char && (type) <= ECPGt_varchar2) || ((type)>=ECPGt_long_long && (type) <= ECPGt_unsigned_long_long))
#ifdef __cplusplus
}

View File

@ -2,7 +2,7 @@
*
* Copyright (c) 2000, Christof Petig <christof.petig@wtal.de>
*
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/include/sql3types.h,v 1.4 2000/04/12 17:17:01 momjian Exp $
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/include/sql3types.h,v 1.5 2001/09/19 14:09:32 meskes Exp $
*/
/* chapter 13.1 table 2: Codes used for SQL data types in Dynamic SQL */

View File

@ -4,7 +4,7 @@
#
# Copyright (c) 1994, Regents of the University of California
#
# $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/Makefile,v 1.12 2001/05/11 01:46:33 momjian Exp $
# $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/Makefile,v 1.13 2001/09/19 14:09:32 meskes Exp $
#
#-------------------------------------------------------------------------

View File

@ -1,4 +1,4 @@
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/connect.c,v 1.11 2001/08/24 14:07:49 petere Exp $ */
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/connect.c,v 1.12 2001/09/19 14:09:32 meskes Exp $ */
#include "postgres_fe.h"

View File

@ -1,4 +1,4 @@
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/data.c,v 1.14 2001/08/24 14:07:49 petere Exp $ */
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/data.c,v 1.15 2001/09/19 14:09:32 meskes Exp $ */
#include "postgres_fe.h"

View File

@ -1,4 +1,7 @@
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/descriptor.c,v 1.15 2001/08/24 14:07:49 petere Exp $ */
/* dynamic SQL support routines
*
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/descriptor.c,v 1.16 2001/09/19 14:09:32 meskes Exp $
*/
#include "postgres_fe.h"
@ -8,27 +11,15 @@
#include "extern.h"
#include "sql3types.h"
struct descriptor
{
char *name;
PGresult *result;
struct descriptor *next;
} *all_descriptors = NULL;
struct descriptor *all_descriptors = NULL;
/* old internal convenience function that might go away later */
static PGresult
*
ECPGresultByDescriptor(int line, const char *name)
{
struct descriptor *i;
for (i = all_descriptors; i != NULL; i = i->next)
{
if (!strcmp(name, i->name))
return i->result;
}
ECPGraise(line, ECPG_UNKNOWN_DESCRIPTOR, name);
PGresult **resultpp = ECPGdescriptor_lvalue ( line, name );
if (resultpp) return *resultpp;
return NULL;
}
@ -373,3 +364,18 @@ ECPGallocate_desc(int line, const char *name)
all_descriptors = new;
return true;
}
PGresult **
ECPGdescriptor_lvalue(int line, const char *descriptor)
{
struct descriptor *i;
for (i = all_descriptors; i != NULL; i = i->next)
{
if (!strcmp(descriptor, i->name))
return &i->result;
}
ECPGraise(line, ECPG_UNKNOWN_DESCRIPTOR, (char *) descriptor);
return NULL;
}

View File

@ -1,4 +1,4 @@
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/error.c,v 1.9 2001/08/24 14:07:49 petere Exp $ */
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/error.c,v 1.10 2001/09/19 14:09:32 meskes Exp $ */
#include "postgres_fe.h"

View File

@ -1,4 +1,4 @@
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/execute.c,v 1.22 2001/08/24 14:07:49 petere Exp $ */
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/execute.c,v 1.23 2001/09/19 14:09:32 meskes Exp $ */
/*
* The aim is to get a simpler inteface to the database routines.
@ -817,6 +817,7 @@ ECPGexecute(struct statement * stmt)
* it should go into a separate function
*/
{
bool clear_result = TRUE;
var = stmt->outlist;
switch (PQresultStatus(results))
{
@ -840,7 +841,19 @@ ECPGexecute(struct statement * stmt)
break;
}
for (act_field = 0; act_field < nfields && status; act_field++)
if (var != NULL && var->type==ECPGt_descriptor)
{ PGresult **resultpp = ECPGdescriptor_lvalue(stmt->lineno, (const char*)var->pointer);
if (resultpp == NULL) status = false;
else
{ if (*resultpp)
PQclear(*resultpp);
*resultpp=results;
clear_result = FALSE;
ECPGlog("ECPGexecute putting result into descriptor '%s'\n", (const char*)var->pointer);
}
var = var->next;
}
else for (act_field = 0; act_field < nfields && status; act_field++)
{
if (var == NULL)
{
@ -972,7 +985,7 @@ ECPGexecute(struct statement * stmt)
status = false;
break;
}
PQclear(results);
if (clear_result) PQclear(results);
}
/* check for asynchronous returns */
@ -1032,186 +1045,12 @@ ECPGdo(int lineno, const char *connection_name, char *query,...)
return (status);
}
/* dynamic SQL support routines
*
* Copyright (c) 2000, Christof Petig <christof.petig@wtal.de>
*
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/execute.c,v 1.22 2001/08/24 14:07:49 petere Exp $
*/
PGconn *ECPG_internal_get_connection(char *name);
extern struct descriptor
{
char *name;
PGresult *result;
struct descriptor *next;
} *all_descriptors;
/* like ECPGexecute */
static bool
execute_descriptor(int lineno, const char *query
,struct connection * con, PGresult **resultptr)
{
bool status = false;
PGresult *results;
PGnotify *notify;
/* Now the request is built. */
if (con->committed && !con->autocommit)
{
if ((results = PQexec(con->connection, "begin transaction")) == NULL)
{
ECPGraise(lineno, ECPG_TRANS, NULL);
return false;
}
PQclear(results);
con->committed = false;
}
ECPGlog("execute_descriptor line %d: QUERY: %s on connection %s\n", lineno, query, con->name);
results = PQexec(con->connection, query);
if (results == NULL)
{
ECPGlog("ECPGexecute line %d: error: %s", lineno,
PQerrorMessage(con->connection));
ECPGraise(lineno, ECPG_PGSQL, PQerrorMessage(con->connection));
}
else
{
*resultptr = results;
switch (PQresultStatus(results))
{
int ntuples;
case PGRES_TUPLES_OK:
status = true;
sqlca.sqlerrd[2] = ntuples = PQntuples(results);
if (ntuples < 1)
{
ECPGlog("execute_descriptor line %d: Incorrect number of matches: %d\n",
lineno, ntuples);
ECPGraise(lineno, ECPG_NOT_FOUND, NULL);
status = false;
break;
}
break;
#if 1 /* strictly these are not needed (yet) */
case PGRES_EMPTY_QUERY:
/* do nothing */
ECPGraise(lineno, ECPG_EMPTY, NULL);
break;
case PGRES_COMMAND_OK:
status = true;
sqlca.sqlerrd[1] = PQoidValue(results);
sqlca.sqlerrd[2] = atol(PQcmdTuples(results));
ECPGlog("ECPGexecute line %d Ok: %s\n", lineno, PQcmdStatus(results));
break;
case PGRES_COPY_OUT:
ECPGlog("ECPGexecute line %d: Got PGRES_COPY_OUT ... tossing.\n", lineno);
PQendcopy(con->connection);
break;
case PGRES_COPY_IN:
ECPGlog("ECPGexecute line %d: Got PGRES_COPY_IN ... tossing.\n", lineno);
PQendcopy(con->connection);
break;
#else
case PGRES_EMPTY_QUERY:
case PGRES_COMMAND_OK:
case PGRES_COPY_OUT:
case PGRES_COPY_IN:
break;
#endif
case PGRES_NONFATAL_ERROR:
case PGRES_FATAL_ERROR:
case PGRES_BAD_RESPONSE:
ECPGlog("ECPGexecute line %d: Error: %s",
lineno, PQerrorMessage(con->connection));
ECPGraise(lineno, ECPG_PGSQL, PQerrorMessage(con->connection));
status = false;
break;
default:
ECPGlog("ECPGexecute line %d: Got something else, postgres error.\n",
lineno);
ECPGraise(lineno, ECPG_PGSQL, PQerrorMessage(con->connection));
status = false;
break;
}
}
/* check for asynchronous returns */
notify = PQnotifies(con->connection);
if (notify)
{
ECPGlog("ECPGexecute line %d: ASYNC NOTIFY of '%s' from backend pid '%d' received\n",
lineno, notify->relname, notify->be_pid);
free(notify);
}
return status;
}
/* like ECPGdo */
static bool
do_descriptor2(int lineno, const char *connection_name,
PGresult **resultptr, const char *query)
{
struct connection *con = get_connection(connection_name);
bool status = true;
char *locale = setlocale(LC_NUMERIC, NULL);
/* Make sure we do NOT honor the locale for numeric input/output */
/* since the database wants teh standard decimal point */
setlocale(LC_NUMERIC, "C");
if (!ecpg_init(con, connection_name, lineno))
{
setlocale(LC_NUMERIC, locale);
return (false);
}
/* are we connected? */
if (con == NULL || con->connection == NULL)
{
ECPGlog("do_descriptor2: not connected to %s\n", con->name);
ECPGraise(lineno, ECPG_NOT_CONN, NULL);
setlocale(LC_NUMERIC, locale);
return false;
}
status = execute_descriptor(lineno, query, con, resultptr);
/* and reset locale value so our application is not affected */
setlocale(LC_NUMERIC, locale);
return (status);
}
/* old descriptor interface */
bool
ECPGdo_descriptor(int line, const char *connection,
const char *descriptor, const char *query)
{
struct descriptor *i;
for (i = all_descriptors; i != NULL; i = i->next)
{
if (!strcmp(descriptor, i->name))
{
bool status;
/* free previous result */
if (i->result)
PQclear(i->result);
i->result = NULL;
status = do_descriptor2(line, connection, &i->result, query);
if (!i->result)
PQmakeEmptyPGresult(NULL, 0);
return (status);
}
}
ECPGraise(line, ECPG_UNKNOWN_DESCRIPTOR, (char *) descriptor);
return false;
return ECPGdo(line, connection, (char *)query, ECPGt_EOIT,
ECPGt_descriptor, descriptor, 0L, 0L, 0L,
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
}

View File

@ -52,3 +52,14 @@ struct connection
struct ECPGtype_information_cache *cache_head;
struct connection *next;
};
/* structure to store descriptors */
struct descriptor
{
char *name;
PGresult *result;
struct descriptor *next;
};
PGresult **
ECPGdescriptor_lvalue(int line, const char *descriptor);

View File

@ -1,4 +1,4 @@
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/memory.c,v 1.4 2001/08/24 14:07:49 petere Exp $ */
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/memory.c,v 1.5 2001/09/19 14:09:32 meskes Exp $ */
#include "postgres_fe.h"

View File

@ -1,4 +1,4 @@
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/misc.c,v 1.4 2001/08/24 14:07:49 petere Exp $ */
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/misc.c,v 1.5 2001/09/19 14:09:32 meskes Exp $ */
#include "postgres_fe.h"

View File

@ -1,4 +1,4 @@
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/prepare.c,v 1.6 2001/08/24 14:07:49 petere Exp $ */
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/prepare.c,v 1.7 2001/09/19 14:09:32 meskes Exp $ */
#include "postgres_fe.h"

View File

@ -1,4 +1,4 @@
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/typename.c,v 1.18 2001/08/24 14:07:49 petere Exp $ */
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/typename.c,v 1.19 2001/09/19 14:09:32 meskes Exp $ */
#include "postgres_fe.h"

View File

@ -1,4 +1,4 @@
# $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/Makefile,v 1.76 2001/05/12 19:49:48 petere Exp $
# $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/Makefile,v 1.77 2001/09/19 14:09:32 meskes Exp $
subdir = src/interfaces/ecpg/preproc
top_builddir = ../../../..

View File

@ -196,3 +196,24 @@ output_get_descr(char *desc_name, char *index)
whenever_action(2 | 1);
}
/* I consider dynamic allocation overkill since at most two descriptor
variables are possible per statement. (input and output descriptor)
And descriptors are no normal variables, so they don't belong into
the variable list.
*/
#define MAX_DESCRIPTOR_NAMELEN 128
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, 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 }
};
strncpy(descriptor_names[input],name,MAX_DESCRIPTOR_NAMELEN);
descriptor_names[input][MAX_DESCRIPTOR_NAMELEN-1]=0;
return (struct variable*)&varspace[input];
}

View File

@ -1,4 +1,4 @@
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/ecpg.c,v 1.48 2001/08/28 02:47:18 tgl Exp $ */
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/ecpg.c,v 1.49 2001/09/19 14:09:32 meskes Exp $ */
/* New main for ecpg, the PostgreSQL embedded SQL precompiler. */
/* (C) Michael Meskes <meskes@postgresql.org> Feb 5th, 1998 */

View File

@ -4,7 +4,7 @@
* lexical token lookup for reserved words in postgres embedded SQL
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/ecpg_keywords.c,v 1.24 2001/08/19 09:21:44 meskes Exp $
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/ecpg_keywords.c,v 1.25 2001/09/19 14:09:32 meskes Exp $
*
*-------------------------------------------------------------------------
*/

View File

@ -48,7 +48,7 @@ extern const char *get_dtype(enum ECPGdtype);
extern void lex_init(void);
extern char *make_str(const char *);
extern void output_line_number(void);
extern void output_statement(char *, int, char *, char *);
extern void output_statement(char *, int, char *);
extern void output_simple_statement(char *);
extern char *hashline_number(void);
extern int yyparse(void);
@ -67,6 +67,7 @@ extern void whenever_action(int);
extern void add_descriptor(char *, char *);
extern void drop_descriptor(char *, char *);
extern struct descriptor *lookup_descriptor(char *, char *);
extern struct variable *descriptor_variable(const char *name,int input);
extern void add_variable(struct arguments **, struct variable *, struct variable *);
extern void append_variable(struct arguments **, struct variable *, struct variable *);
extern void dump_variables(struct arguments *, int);

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/keywords.c,v 1.43 2001/08/16 20:38:55 tgl Exp $
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/keywords.c,v 1.44 2001/09/19 14:09:32 meskes Exp $
*
*-------------------------------------------------------------------------
*/
@ -102,6 +102,7 @@ static ScanKeyword ScanKeywords[] = {
{"each", EACH},
{"else", ELSE},
{"encoding", ENCODING},
{"encrypted", ENCRYPTED},
{"end", END_TRANS},
{"escape", ESCAPE},
{"except", EXCEPT},
@ -261,6 +262,7 @@ static ScanKeyword ScanKeywords[] = {
{"truncate", TRUNCATE},
{"trusted", TRUSTED},
{"type", TYPE_P},
{"unencrypted", UNENCRYPTED},
{"union", UNION},
{"unique", UNIQUE},
{"unknown", UNKNOWN},

View File

@ -103,16 +103,12 @@ hashline_number(void)
}
void
output_statement(char *stmt, int mode, char *descriptor, char *con)
output_statement(char *stmt, int mode, char *con)
{
int i,
j = strlen(stmt);
if (descriptor == NULL)
fprintf(yyout, "{ ECPGdo(__LINE__, %s, \"", con ? con : "NULL");
else
fprintf(yyout, "{ ECPGdo_descriptor(__LINE__, %s, %s, \"",
con ? con : "NULL", descriptor);
fprintf(yyout, "{ ECPGdo(__LINE__, %s, \"", con ? con : "NULL");
/* do this char by char as we have to filter '\"' */
for (i = 0; i < j; i++)
@ -123,25 +119,18 @@ output_statement(char *stmt, int mode, char *descriptor, char *con)
fputs("\\\"", yyout);
}
if (descriptor == NULL)
{
fputs("\", ", yyout);
fputs("\", ", yyout);
/* dump variables to C file */
dump_variables(argsinsert, 1);
fputs("ECPGt_EOIT, ", yyout);
dump_variables(argsresult, 1);
fputs("ECPGt_EORT);", yyout);
reset_variables();
}
else
fputs("\");", yyout);
/* dump variables to C file */
dump_variables(argsinsert, 1);
fputs("ECPGt_EOIT, ", yyout);
dump_variables(argsresult, 1);
fputs("ECPGt_EORT);", yyout);
reset_variables();
mode |= 2;
whenever_action(mode);
free(stmt);
if (descriptor != NULL)
free(descriptor);
if (connection != NULL)
free(connection);
}

View File

@ -12,7 +12,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.80 2001/09/07 23:17:14 tgl Exp $
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.81 2001/09/19 14:09:32 meskes Exp $
*
*-------------------------------------------------------------------------
*/

View File

@ -217,8 +217,8 @@ make_name(void)
%token ABORT_TRANS, ACCESS, AFTER, AGGREGATE, ANALYSE, ANALYZE,
BACKWARD, BEFORE, BINARY, BIT, CACHE, CHECKPOINT, CLUSTER,
COMMENT, COPY, CREATEDB, CREATEUSER, CYCLE, DATABASE,
DELIMITERS, DO, EACH, ENCODING, EXCLUSIVE, EXPLAIN, EXTEND,
FORCE, FORWARD, FUNCTION, HANDLER, INCREMENT,
DELIMITERS, DO, EACH, ENCODING, EXCLUSIVE, EXPLAIN,
FORCE, FORWARD, FREEZE, FUNCTION, HANDLER, INCREMENT,
INDEX, INHERITS, INSTEAD, ISNULL, LANCOMPILER, LIMIT,
LISTEN, UNLISTEN, LOAD, LOCATION, LOCK_P, MAXVALUE,
MINVALUE, MODE, MOVE, NEW, NOCREATEDB, NOCREATEUSER,
@ -303,7 +303,7 @@ make_name(void)
%type <str> copy_delimiter ListenStmt CopyStmt copy_file_name opt_binary
%type <str> opt_with_copy FetchStmt direction fetch_how_many from_in
%type <str> ClosePortalStmt DropStmt VacuumStmt AnalyzeStmt opt_verbose
%type <str> opt_full func_arg OptWithOids
%type <str> opt_full func_arg OptWithOids opt_freeze opt_ecpg_into
%type <str> analyze_keyword opt_name_list ExplainStmt index_params
%type <str> index_list func_index index_elem opt_class access_method_clause
%type <str> index_opt_unique IndexStmt func_return ConstInterval
@ -342,7 +342,7 @@ make_name(void)
%type <str> select_limit opt_for_update_clause CheckPointStmt
%type <str> ECPGWhenever ECPGConnect connection_target ECPGOpen
%type <str> indicator ECPGExecute ECPGPrepare ecpg_using
%type <str> indicator ECPGExecute ECPGPrepare ecpg_using ecpg_into
%type <str> storage_clause opt_initializer c_anything blockstart
%type <str> blockend variable_list variable c_thing c_term
%type <str> opt_pointer ECPGDisconnect dis_name storage_modifier
@ -360,7 +360,7 @@ make_name(void)
%type <str> ECPGGetDescriptorHeader ECPGColLabel ECPGTypeName
%type <str> ECPGLabelTypeName ECPGColId variablelist cvariable
%type <descriptor> ECPGFetchDescStmt ECPGGetDescriptor
%type <descriptor> ECPGGetDescriptor
%type <type_enum> simple_type signed_type unsigned_type varchar_type
@ -392,68 +392,68 @@ statement: ecpgstart opt_at stmt ';' { connection = NULL; }
opt_at: AT connection_target { connection = $2; };
stmt: AlterSchemaStmt { output_statement($1, 0, NULL, connection); }
| AlterTableStmt { output_statement($1, 0, NULL, connection); }
| AlterGroupStmt { output_statement($1, 0, NULL, connection); }
| AlterUserStmt { output_statement($1, 0, NULL, connection); }
| ClosePortalStmt { output_statement($1, 0, NULL, connection); }
| CommentStmt { output_statement($1, 0, NULL, connection); }
| CopyStmt { output_statement($1, 0, NULL, connection); }
| CreateStmt { output_statement($1, 0, NULL, connection); }
| CreateAsStmt { output_statement($1, 0, NULL, connection); }
| CreateSchemaStmt { output_statement($1, 0, NULL, connection); }
| CreateGroupStmt { output_statement($1, 0, NULL, connection); }
| CreateSeqStmt { output_statement($1, 0, NULL, connection); }
| CreatePLangStmt { output_statement($1, 0, NULL, connection); }
| CreateTrigStmt { output_statement($1, 0, NULL, connection); }
| CreateUserStmt { output_statement($1, 0, NULL, connection); }
| ClusterStmt { output_statement($1, 0, NULL, connection); }
| DefineStmt { output_statement($1, 0, NULL, connection); }
| DropStmt { output_statement($1, 0, NULL, connection); }
| DropSchemaStmt { output_statement($1, 0, NULL, connection); }
| TruncateStmt { output_statement($1, 0, NULL, connection); }
| DropGroupStmt { output_statement($1, 0, NULL, connection); }
| DropPLangStmt { output_statement($1, 0, NULL, connection); }
| DropTrigStmt { output_statement($1, 0, NULL, connection); }
| DropUserStmt { output_statement($1, 0, NULL, connection); }
| ExplainStmt { output_statement($1, 0, NULL, connection); }
| FetchStmt { output_statement($1, 1, NULL, connection); }
| GrantStmt { output_statement($1, 0, NULL, connection); }
| IndexStmt { output_statement($1, 0, NULL, connection); }
| ListenStmt { output_statement($1, 0, NULL, connection); }
| UnlistenStmt { output_statement($1, 0, NULL, connection); }
| LockStmt { output_statement($1, 0, NULL, connection); }
| NotifyStmt { output_statement($1, 0, NULL, connection); }
| ProcedureStmt { output_statement($1, 0, NULL, connection); }
| ReindexStmt { output_statement($1, 0, NULL, connection); }
| RemoveAggrStmt { output_statement($1, 0, NULL, connection); }
| RemoveOperStmt { output_statement($1, 0, NULL, connection); }
| RemoveFuncStmt { output_statement($1, 0, NULL, connection); }
| RenameStmt { output_statement($1, 0, NULL, connection); }
| RevokeStmt { output_statement($1, 0, NULL, connection); }
stmt: AlterSchemaStmt { output_statement($1, 0, connection); }
| AlterTableStmt { output_statement($1, 0, connection); }
| AlterGroupStmt { output_statement($1, 0, connection); }
| AlterUserStmt { output_statement($1, 0, connection); }
| ClosePortalStmt { output_statement($1, 0, connection); }
| CommentStmt { output_statement($1, 0, connection); }
| CopyStmt { output_statement($1, 0, connection); }
| CreateStmt { output_statement($1, 0, connection); }
| CreateAsStmt { output_statement($1, 0, connection); }
| CreateSchemaStmt { output_statement($1, 0, connection); }
| CreateGroupStmt { output_statement($1, 0, connection); }
| CreateSeqStmt { output_statement($1, 0, connection); }
| CreatePLangStmt { output_statement($1, 0, connection); }
| CreateTrigStmt { output_statement($1, 0, connection); }
| CreateUserStmt { output_statement($1, 0, connection); }
| ClusterStmt { output_statement($1, 0, connection); }
| DefineStmt { output_statement($1, 0, connection); }
| DropStmt { output_statement($1, 0, connection); }
| DropSchemaStmt { output_statement($1, 0, connection); }
| TruncateStmt { output_statement($1, 0, connection); }
| DropGroupStmt { output_statement($1, 0, connection); }
| DropPLangStmt { output_statement($1, 0, connection); }
| DropTrigStmt { output_statement($1, 0, connection); }
| DropUserStmt { output_statement($1, 0, connection); }
| ExplainStmt { output_statement($1, 0, connection); }
| FetchStmt { output_statement($1, 1, connection); }
| GrantStmt { output_statement($1, 0, connection); }
| IndexStmt { output_statement($1, 0, connection); }
| ListenStmt { output_statement($1, 0, connection); }
| UnlistenStmt { output_statement($1, 0, connection); }
| LockStmt { output_statement($1, 0, connection); }
| NotifyStmt { output_statement($1, 0, connection); }
| ProcedureStmt { output_statement($1, 0, connection); }
| ReindexStmt { output_statement($1, 0, connection); }
| RemoveAggrStmt { output_statement($1, 0, connection); }
| RemoveOperStmt { output_statement($1, 0, connection); }
| RemoveFuncStmt { output_statement($1, 0, connection); }
| RenameStmt { output_statement($1, 0, connection); }
| RevokeStmt { output_statement($1, 0, connection); }
| OptimizableStmt {
if (strncmp($1, "/* " , sizeof("/* ")-1) == 0)
output_simple_statement($1);
else
output_statement($1, 1, NULL, connection);
output_statement($1, 1, connection);
}
| RuleStmt { output_statement($1, 0, NULL, connection); }
| RuleStmt { output_statement($1, 0, connection); }
| TransactionStmt {
fprintf(yyout, "{ ECPGtrans(__LINE__, %s, \"%s\");", connection ? connection : "NULL", $1);
whenever_action(2);
free($1);
}
| ViewStmt { output_statement($1, 0, NULL, connection); }
| LoadStmt { output_statement($1, 0, NULL, connection); }
| CreatedbStmt { output_statement($1, 0, NULL, connection); }
| DropdbStmt { output_statement($1, 0, NULL, connection); }
| VacuumStmt { output_statement($1, 0, NULL, connection); }
| AnalyzeStmt { output_statement($1, 0, NULL, connection); }
| VariableSetStmt { output_statement($1, 0, NULL, connection); }
| VariableShowStmt { output_statement($1, 0, NULL, connection); }
| VariableResetStmt { output_statement($1, 0, NULL, connection); }
| ConstraintsSetStmt { output_statement($1, 0, NULL, connection); }
| CheckPointStmt { output_statement($1, 0, NULL, connection); }
| ViewStmt { output_statement($1, 0, connection); }
| LoadStmt { output_statement($1, 0, connection); }
| CreatedbStmt { output_statement($1, 0, connection); }
| DropdbStmt { output_statement($1, 0, connection); }
| VacuumStmt { output_statement($1, 0, connection); }
| AnalyzeStmt { output_statement($1, 0, connection); }
| VariableSetStmt { output_statement($1, 0, connection); }
| VariableShowStmt { output_statement($1, 0, connection); }
| VariableResetStmt { output_statement($1, 0, connection); }
| ConstraintsSetStmt { output_statement($1, 0, connection); }
| CheckPointStmt { output_statement($1, 0, connection); }
| ECPGAllocateDescr { fprintf(yyout,"ECPGallocate_desc(__LINE__, %s);",$1);
whenever_action(0);
free($1);
@ -496,8 +496,7 @@ stmt: AlterSchemaStmt { output_statement($1, 0, NULL, connection); }
whenever_action(2);
free($1);
}
| ECPGExecute { output_statement($1, 0, NULL, connection); }
| ECPGFetchDescStmt { output_statement($1.str, 1, $1.name, connection); }
| ECPGExecute { output_statement($1, 0, connection); }
| ECPGFree {
fprintf(yyout, "{ ECPGdeallocate(__LINE__, \"%s\");", $1);
@ -538,7 +537,7 @@ stmt: AlterSchemaStmt { output_statement($1, 0, NULL, connection); }
for (p = ptr->argsresult; p; p = p->next)
add_variable(&argsresult, p->variable, p->indicator);
output_statement(mm_strdup(ptr->command), 0, NULL, ptr->connection ? mm_strdup(ptr->connection) : NULL);
output_statement(mm_strdup(ptr->command), 0, ptr->connection ? mm_strdup(ptr->connection) : NULL);
}
| ECPGPrepare {
if (connection)
@ -1566,26 +1565,26 @@ TruncateStmt: TRUNCATE opt_table relation_name
*
*****************************************************************************/
FetchStmt: FETCH direction fetch_how_many from_in name INTO into_list
FetchStmt: FETCH direction fetch_how_many from_in name ecpg_into
{
if (strcmp($2, "relative") == 0 && atol($3) == 0L)
mmerror(ET_ERROR, "FETCH/RELATIVE at current position is not supported");
$$ = cat_str(5, make_str("fetch"), $2, $3, $4, $5);
}
| FETCH fetch_how_many from_in name INTO into_list
| FETCH fetch_how_many from_in name ecpg_into
{
$$ = cat_str(4, make_str("fetch"), $2, $3, $4);
}
| FETCH direction from_in name INTO into_list
| FETCH direction from_in name ecpg_into
{
$$ = cat_str(4, make_str("fetch"), $2, $3, $4);
}
| FETCH from_in name INTO into_list
| FETCH from_in name ecpg_into
{
$$ = cat_str(3, make_str("fetch"), $2, $3);
}
| FETCH name INTO into_list
| FETCH name ecpg_into
{
$$ = cat2_str(make_str("fetch"), $2);
}
@ -1804,15 +1803,14 @@ RevokeStmt: REVOKE privileges ON opt_table relation_name_list FROM grantee_list
* QUERY:
* create index <indexname> on <relname>
* [ using <access> ] "(" (<col> with <op>)+ ")"
* [ with <parameters> ]
* [ where <predicate> ]
*
*****************************************************************************/
IndexStmt: CREATE index_opt_unique INDEX index_name ON relation_name
access_method_clause '(' index_params ')' opt_with where_clause
access_method_clause '(' index_params ')' where_clause
{
$$ = cat_str(12, make_str("create"), $2, make_str("index"), $4, make_str("on"), $6, $7, make_str("("), $9, make_str(")"), $11, $12);
$$ = cat_str(11, make_str("create"), $2, make_str("index"), $4, make_str("on"), $6, $7, make_str("("), $9, make_str(")"), $11);
}
;
@ -2279,17 +2277,17 @@ ClusterStmt: CLUSTER index_name ON relation_name
*
*****************************************************************************/
VacuumStmt: VACUUM opt_full opt_verbose
{
$$ = cat_str(3, make_str("vacuum"), $2, $3);
}
| VACUUM opt_full opt_verbose relation_name
VacuumStmt: VACUUM opt_full opt_freeze opt_verbose
{
$$ = cat_str(4, make_str("vacuum"), $2, $3, $4);
}
| VACUUM opt_full opt_verbose AnalyzeStmt
| VACUUM opt_full opt_freeze opt_verbose relation_name
{
$$ = cat_str(4, make_str("vacuum"), $2, $3, $4);
$$ = cat_str(5, make_str("vacuum"), $2, $3, $4, $5);
}
| VACUUM opt_full opt_freeze opt_verbose AnalyzeStmt
{
$$ = cat_str(5, make_str("vacuum"), $2, $3, $4, $5);
}
;
@ -2315,6 +2313,10 @@ opt_full: FULL { $$ = make_str("full"); }
| /*EMPTY*/ { $$ = EMPTY; }
;
opt_freeze: FREEZE { $$ = make_str("freeze"); }
| /*EMPTY*/ { $$ = EMPTY; }
;
opt_name_list: '(' name_list ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
| /*EMPTY*/ { $$ = EMPTY; }
;
@ -2580,8 +2582,8 @@ into_clause: INTO OptTempTableName {
FoundInto = 1;
$$= cat2_str(make_str("into"), $2);
}
| INTO into_list { $$ = EMPTY; }
| /*EMPTY*/ { $$ = EMPTY; }
| ecpg_into { $$ = EMPTY; }
| /*EMPTY*/ { $$ = EMPTY; }
;
/*
@ -4494,7 +4496,7 @@ ECPGExecute : EXECUTE IMMEDIATE execstring
sprintf(thisquery->name, "ECPGprepared_statement(\"%s\")", $2);
add_variable(&argsinsert, thisquery, &no_indicator);
} ecpg_using
} ecpg_using opt_ecpg_into
{
$$ = make_str("?");
}
@ -4522,6 +4524,22 @@ ecpg_using: /* empty */ { $$ = EMPTY; }
}
;
opt_sql: /* empty */ | SQL_SQL;
ecpg_into: INTO into_list {
$$ = EMPTY;
}
| INTO opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
{
add_variable(&argsresult, descriptor_variable($4,0), &no_indicator);
$$ = EMPTY;
}
;
opt_ecpg_into: /* empty */ { $$ = EMPTY; }
| ecpg_into { $$ = $1; }
;
variable: civarind | civar
variablelist: variable | variable ',' variablelist;
@ -4601,45 +4619,6 @@ ECPGGetDescriptor: SQL_GET SQL_DESCRIPTOR quoted_ident_stringvar SQL_VALUE cvari
{ $$.str = $5; $$.name = $3; }
;
/*****************************************************************************
*
* QUERY:
* fetch [forward | backward] [ # | all ] [ in <portalname> ]
* fetch [ forward | backward | absolute | relative ]
* [ # | all | next | prior ] [ [ in | from ] <portalname> ]
*
* Have to seperate the descriptor version since we have to
* call a different output function
*
*****************************************************************************/
ECPGFetchDescStmt: FETCH direction fetch_how_many from_in name INTO SQL_SQL SQL_DESCRIPTOR quoted_ident_stringvar
{
$$.str = cat_str(5, make_str("fetch"), $2, $3, $4, $5);
$$.name=$9;
}
| FETCH fetch_how_many from_in name INTO SQL_SQL SQL_DESCRIPTOR quoted_ident_stringvar
{
$$.str = cat_str(4, make_str("fetch"), $2, $3, $4);
$$.name=$8;
}
| FETCH direction from_in name INTO SQL_SQL SQL_DESCRIPTOR quoted_ident_stringvar
{
$$.str = cat_str(4, make_str("fetch"), $2, $3, $4);
$$.name=$8;
}
| FETCH from_in name INTO SQL_SQL SQL_DESCRIPTOR quoted_ident_stringvar
{
$$.str = cat_str(3, make_str("fetch"), $2, $3);
$$.name=$7;
}
| FETCH name INTO SQL_SQL SQL_DESCRIPTOR quoted_ident_stringvar
{
$$.str = cat2_str(make_str("fetch"), $2);
$$.name=$6;
}
;
/*
* for compatibility with ORACLE we will also allow the keyword RELEASE
* after a transaction statement to disconnect from the database.
@ -5010,6 +4989,7 @@ TokenId: ABSOLUTE { $$ = make_str("absolute"); }
| DROP { $$ = make_str("drop"); }
| EACH { $$ = make_str("each"); }
| ENCODING { $$ = make_str("encoding"); }
| ENCRYPTED { $$ = make_str("encrypted"); }
| ESCAPE { $$ = make_str("escape"); }
| EXCLUSIVE { $$ = make_str("exclusive"); }
| EXECUTE { $$ = make_str("execute"); }
@ -5087,6 +5067,7 @@ TokenId: ABSOLUTE { $$ = make_str("absolute"); }
| TRIGGER { $$ = make_str("trigger"); }
| TRUNCATE { $$ = make_str("truncate"); }
| TRUSTED { $$ = make_str("trusted"); }
| UNENCRYPTED { $$ = make_str("unencrypted"); }
| UNLISTEN { $$ = make_str("unlisten"); }
| UNTIL { $$ = make_str("until"); }
| UPDATE { $$ = make_str("update"); }
@ -5148,7 +5129,6 @@ ECPGColLabel: ECPGColId { $$ = $1; }
| DISTINCT { $$ = make_str("distinct"); }
| DO { $$ = make_str("do"); }
| ELSE { $$ = make_str("else"); }
| ENCRYPTED { $$ = make_str("encrypted"); }
| END_TRANS { $$ = make_str("end"); }
| EXCEPT { $$ = make_str("except"); }
| EXISTS { $$ = make_str("exists"); }
@ -5157,6 +5137,7 @@ ECPGColLabel: ECPGColId { $$ = $1; }
| FALSE_P { $$ = make_str("false"); }
| FOR { $$ = make_str("for"); }
| FOREIGN { $$ = make_str("foreign"); }
| FREEZE { $$ = make_str("freeze"); }
| FROM { $$ = make_str("from"); }
| FULL { $$ = make_str("full"); }
| IN { $$ = make_str("in"); }
@ -5216,7 +5197,6 @@ ECPGColLabel: ECPGColId { $$ = $1; }
| TRANSACTION { $$ = make_str("transaction"); }
| TRIM { $$ = make_str("trim"); }
| TRUE_P { $$ = make_str("true"); }
| UNENCRYPTED { $$ = make_str("unencrypted"); }
| UNIQUE { $$ = make_str("unique"); }
| UNKNOWN { $$ = make_str("unknown"); }
| USER { $$ = make_str("user"); }

View File

@ -169,6 +169,9 @@ get_type(enum ECPGttype typ)
* quoted */
return ("ECPGt_char_variable");
break;
case ECPGt_descriptor:
return ("ECPGt_descriptor");
break;
default:
sprintf(errortext, "illegal variable type %d\n", typ);
yyerror(errortext);
@ -252,6 +255,10 @@ ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype * typ, const char *in
ECPGdump_a_simple(o, name, typ->typ, 1, 1, NULL, prefix);
ECPGdump_a_simple(o, ind_name, ind_typ->typ, ind_typ->size, -1, NULL, ind_prefix);
break;
case ECPGt_descriptor:
ECPGdump_a_simple(o, name, typ->typ, 0, -1, NULL, prefix);
ECPGdump_a_simple(o, ind_name, ind_typ->typ, ind_typ->size, -1, NULL, ind_prefix);
break;
default:
ECPGdump_a_simple(o, name, typ->typ, typ->size, -1, NULL, prefix);
if (ind_typ != NULL)
@ -273,6 +280,9 @@ ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype typ,
{
if (typ == ECPGt_NO_INDICATOR)
fprintf(o, "\n\tECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ");
else if (typ == ECPGt_descriptor)
/* remember that name here already contains quotes (if needed) */
fprintf(o, "\n\tECPGt_descriptor, %s, 0L, 0L, 0L, ", name);
else
{
char *variable = (char *) mm_alloc(strlen(name) + ((prefix == NULL) ? 0 : strlen(prefix)) + 4);