- Applied error reporting patch by Matthew Vanecek
- Started with an Informix compatibility option.
This commit is contained in:
parent
e529e9fa44
commit
1a9b0613c1
@ -1324,3 +1324,13 @@ Tue Jan 21 20:50:58 CET 2003
|
||||
|
||||
- Set ecpg version to 2.11.0.
|
||||
- Synced preproc.y with gram.y.
|
||||
|
||||
Thu Feb 13 14:06:28 CET 2003
|
||||
|
||||
- Applied patch by Matthew Vanecek <mevanecek@yahoo.com> for better
|
||||
error reporting.
|
||||
- Started working on an Informix compatibility mode. With option "-C
|
||||
INFORMIX" set, ecpg now accepts "$" as alias for "exec sql" and to
|
||||
denote variables inside SQL statements.
|
||||
- Set ecpg version to 2.12.0.
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
#
|
||||
# Copyright (c) 1994, Regents of the University of California
|
||||
#
|
||||
# $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/Makefile,v 1.18 2002/12/11 04:07:39 momjian Exp $
|
||||
# $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/Makefile,v 1.19 2003/02/13 13:11:52 meskes Exp $
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
@ -16,7 +16,7 @@ NAME= ecpg
|
||||
SO_MAJOR_VERSION= 3
|
||||
SO_MINOR_VERSION= 4.2
|
||||
|
||||
override CPPFLAGS := -I$(top_srcdir)/src/interfaces/ecpg/include -I$(libpq_srcdir) $(CPPFLAGS)
|
||||
override CPPFLAGS := -g -I$(top_srcdir)/src/interfaces/ecpg/include -I$(libpq_srcdir) $(CPPFLAGS)
|
||||
|
||||
|
||||
OBJS= execute.o typename.o descriptor.o data.o error.o prepare.o memory.o \
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/connect.c,v 1.19 2002/09/04 20:31:46 momjian Exp $ */
|
||||
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/connect.c,v 1.20 2003/02/13 13:11:52 meskes Exp $ */
|
||||
|
||||
#include "postgres_fe.h"
|
||||
|
||||
@ -419,15 +419,20 @@ ECPGconnect(int lineno, const char *name, const char *user, const char *passwd,
|
||||
|
||||
if (PQstatus(this->connection) == CONNECTION_BAD)
|
||||
{
|
||||
const char *errmsg = PQerrorMessage(this->connection);
|
||||
char *db = realname ? realname : "<DEFAULT>";
|
||||
|
||||
set_backend_err(errmsg, lineno);
|
||||
ecpg_finish(this);
|
||||
ECPGlog("connect: could not open database %s on %s port %s %s%s%s%s in line %d\n",
|
||||
realname ? realname : "<DEFAULT>",
|
||||
ECPGlog("connect: could not open database %s on %s port %s %s%s%s%s in line %d\n\t%s\n",
|
||||
db,
|
||||
host ? host : "<DEFAULT>",
|
||||
port ? port : "<DEFAULT>",
|
||||
options ? "with options " : "", options ? options : "",
|
||||
user ? "for user " : "", user ? user : "",
|
||||
lineno);
|
||||
ECPGraise(lineno, ECPG_CONNECT, realname ? realname : "<DEFAULT>");
|
||||
lineno, errmsg);
|
||||
|
||||
ECPGraise(lineno, ECPG_CONNECT, db);
|
||||
if (host)
|
||||
ECPGfree(host);
|
||||
if (port)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/error.c,v 1.16 2002/09/04 20:31:46 momjian Exp $ */
|
||||
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/error.c,v 1.17 2003/02/13 13:11:52 meskes Exp $ */
|
||||
|
||||
#include "postgres_fe.h"
|
||||
|
||||
@ -10,6 +10,10 @@
|
||||
#include "extern.h"
|
||||
#include "sqlca.h"
|
||||
|
||||
/* This should hold the back-end error message from
|
||||
* the last back-end operation. */
|
||||
char *ECPGerr;
|
||||
|
||||
void
|
||||
ECPGraise(int line, int code, const char *str)
|
||||
{
|
||||
@ -162,6 +166,29 @@ ECPGraise(int line, int code, const char *str)
|
||||
ECPGfree_auto_mem();
|
||||
}
|
||||
|
||||
/* Set the error message string from the backend */
|
||||
void
|
||||
set_backend_err(const char *err, int lineno)
|
||||
{
|
||||
if (ECPGerr)
|
||||
ECPGfree(ECPGerr);
|
||||
|
||||
if (!err)
|
||||
{
|
||||
ECPGerr = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
ECPGerr = ECPGstrdup(err, lineno);
|
||||
}
|
||||
|
||||
/* Retrieve the error message from the backend. */
|
||||
char *
|
||||
ECPGerrmsg(void)
|
||||
{
|
||||
return ECPGerr;
|
||||
}
|
||||
|
||||
/* print out an error message */
|
||||
void
|
||||
sqlprint(void)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/execute.c,v 1.40 2002/10/21 13:09:31 meskes Exp $ */
|
||||
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/execute.c,v 1.41 2003/02/13 13:11:52 meskes Exp $ */
|
||||
|
||||
/*
|
||||
* The aim is to get a simpler inteface to the database routines.
|
||||
@ -850,6 +850,7 @@ ECPGexecute(struct statement * stmt)
|
||||
{
|
||||
bool status = false;
|
||||
char *copiedquery;
|
||||
char *errmsg, *cmdstat;
|
||||
PGresult *results;
|
||||
PGnotify *notify;
|
||||
struct variable *var;
|
||||
@ -949,9 +950,10 @@ ECPGexecute(struct statement * stmt)
|
||||
|
||||
if (results == NULL)
|
||||
{
|
||||
ECPGlog("ECPGexecute line %d: error: %s", stmt->lineno,
|
||||
PQerrorMessage(stmt->connection->connection));
|
||||
ECPGraise(stmt->lineno, ECPG_PGSQL, PQerrorMessage(stmt->connection->connection));
|
||||
errmsg = PQerrorMessage(stmt->connection->connection);
|
||||
ECPGlog("ECPGexecute line %d: error: %s", stmt->lineno, errmsg);
|
||||
ECPGraise(stmt->lineno, ECPG_PGSQL, errmsg);
|
||||
set_backend_err(errmsg, stmt->lineno);
|
||||
}
|
||||
else
|
||||
|
||||
@ -961,7 +963,9 @@ ECPGexecute(struct statement * stmt)
|
||||
*/
|
||||
{
|
||||
bool clear_result = TRUE;
|
||||
|
||||
errmsg = PQresultErrorMessage(results);
|
||||
set_backend_err(errmsg, stmt->lineno);
|
||||
|
||||
var = stmt->outlist;
|
||||
switch (PQresultStatus(results))
|
||||
{
|
||||
@ -1027,20 +1031,20 @@ ECPGexecute(struct statement * stmt)
|
||||
break;
|
||||
case PGRES_COMMAND_OK:
|
||||
status = true;
|
||||
cmdstat = PQcmdStatus(results);
|
||||
sqlca.sqlerrd[1] = PQoidValue(results);
|
||||
sqlca.sqlerrd[2] = atol(PQcmdTuples(results));
|
||||
ECPGlog("ECPGexecute line %d Ok: %s\n", stmt->lineno, PQcmdStatus(results));
|
||||
if (!sqlca.sqlerrd[2] && (!strncmp(PQcmdStatus(results), "UPDATE", 6)
|
||||
|| !strncmp(PQcmdStatus(results), "INSERT", 6)
|
||||
|| !strncmp(PQcmdStatus(results), "DELETE", 6)))
|
||||
ECPGlog("ECPGexecute line %d Ok: %s\n", stmt->lineno, cmdstat);
|
||||
if (!sqlca.sqlerrd[2] && ( !strncmp(cmdstat, "UPDATE", 6)
|
||||
|| !strncmp(cmdstat, "INSERT", 6)
|
||||
|| !strncmp(cmdstat, "DELETE", 6)))
|
||||
ECPGraise(stmt->lineno, ECPG_NOT_FOUND, NULL);
|
||||
break;
|
||||
case PGRES_NONFATAL_ERROR:
|
||||
case PGRES_FATAL_ERROR:
|
||||
case PGRES_BAD_RESPONSE:
|
||||
ECPGlog("ECPGexecute line %d: Error: %s",
|
||||
stmt->lineno, PQerrorMessage(stmt->connection->connection));
|
||||
ECPGraise(stmt->lineno, ECPG_PGSQL, PQerrorMessage(stmt->connection->connection));
|
||||
ECPGlog("ECPGexecute line %d: Error: %s", stmt->lineno, errmsg);
|
||||
ECPGraise(stmt->lineno, ECPG_PGSQL, errmsg);
|
||||
status = false;
|
||||
break;
|
||||
case PGRES_COPY_OUT:
|
||||
@ -1054,7 +1058,7 @@ ECPGexecute(struct statement * stmt)
|
||||
default:
|
||||
ECPGlog("ECPGexecute line %d: Got something else, postgres error.\n",
|
||||
stmt->lineno);
|
||||
ECPGraise(stmt->lineno, ECPG_PGSQL, PQerrorMessage(stmt->connection->connection));
|
||||
ECPGraise(stmt->lineno, ECPG_PGSQL, errmsg);
|
||||
status = false;
|
||||
break;
|
||||
}
|
||||
|
@ -5,6 +5,10 @@
|
||||
#include "libpq-fe.h"
|
||||
|
||||
/* Here are some methods used by the lib. */
|
||||
|
||||
/* Stores the backend error message for client access */
|
||||
void set_backend_err(const char *err, int lineon);
|
||||
|
||||
/* Returns a pointer to a string containing a simple type name. */
|
||||
void ECPGadd_mem(void *ptr, int lineno);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/ecpg.c,v 1.58 2002/10/18 22:05:36 petere Exp $ */
|
||||
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/ecpg.c,v 1.59 2003/02/13 13:11:52 meskes Exp $ */
|
||||
|
||||
/* New main for ecpg, the PostgreSQL embedded SQL precompiler. */
|
||||
/* (C) Michael Meskes <meskes@postgresql.org> Feb 5th, 1998 */
|
||||
@ -19,6 +19,9 @@ extern char *optarg;
|
||||
int ret_value = 0,
|
||||
autocommit = false,
|
||||
auto_create_c = false;
|
||||
|
||||
enum COMPAT_MODE compat = ECPG_COMPAT_PGSQL;
|
||||
|
||||
struct _include_path *include_paths = NULL;
|
||||
struct cursor *cur = NULL;
|
||||
struct typedefs *types = NULL;
|
||||
@ -38,6 +41,8 @@ help(const char *progname)
|
||||
#ifdef YYDEBUG
|
||||
printf(" -d generate parser debug output\n");
|
||||
#endif
|
||||
printf(" -C <mode> set compatibility mode\n"
|
||||
" mode may be INFORMIX only at the moment\n");
|
||||
printf(" -D SYMBOL define SYMBOL\n");
|
||||
printf(" -I DIRECTORY search DIRECTORY for include files\n");
|
||||
printf(" -o OUTFILE write result to OUTFILE\n");
|
||||
@ -107,7 +112,7 @@ main(int argc, char *const argv[])
|
||||
add_include_path("/usr/local/include");
|
||||
add_include_path(".");
|
||||
|
||||
while ((c = getopt(argc, argv, "vco:I:tD:d")) != -1)
|
||||
while ((c = getopt(argc, argv, "vco:I:tD:dC:")) != -1)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
@ -130,6 +135,15 @@ main(int argc, char *const argv[])
|
||||
case 'c':
|
||||
auto_create_c = true;
|
||||
break;
|
||||
case 'C':
|
||||
if (strcmp(optarg, "INFORMIX") == 0)
|
||||
compat = ECPG_COMPAT_INFORMIX;
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Try '%s --help' for more information.\n", argv[0]);
|
||||
return ILLEGAL_OPTION;
|
||||
}
|
||||
break;
|
||||
case 'D':
|
||||
add_preprocessor_define(optarg);
|
||||
break;
|
||||
|
@ -93,4 +93,7 @@ extern ScanKeyword *ScanKeywordLookup(char *text);
|
||||
#define INDICATOR_NOT_STRUCT 6
|
||||
#define INDICATOR_NOT_SIMPLE 7
|
||||
|
||||
enum COMPAT_MODE { ECPG_COMPAT_PGSQL = 0, ECPG_COMPAT_INFORMIX};
|
||||
extern enum COMPAT_MODE compat;
|
||||
|
||||
#endif /* _ECPG_PREPROC_EXTERN_H */
|
||||
|
@ -12,7 +12,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.101 2002/11/07 06:06:17 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.102 2003/02/13 13:11:52 meskes Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -70,7 +70,6 @@ static struct _if_value
|
||||
|
||||
%option 8bit
|
||||
%option never-interactive
|
||||
%option nounput
|
||||
%option noyywrap
|
||||
|
||||
%option yylineno
|
||||
@ -247,6 +246,10 @@ whitespace ({space}+|{comment})
|
||||
horiz_whitespace ({horiz_space}|{comment})
|
||||
whitespace_with_newline ({horiz_whitespace}*{newline}{whitespace}*)
|
||||
|
||||
/* special characters for other dbms */
|
||||
/* we have to react differently in compat mode */
|
||||
informix_special [\$]
|
||||
|
||||
other .
|
||||
|
||||
/* some stuff needed for ecpg */
|
||||
@ -416,6 +419,16 @@ cppline {space}*#(.*\\{space})*.*
|
||||
}
|
||||
<xdc>{xdcinside} { addlit(yytext, yyleng); }
|
||||
<SQL>{typecast} { return TYPECAST; }
|
||||
<SQL>{informix_special} {
|
||||
/* are we simulating Informix? */
|
||||
if (compat == ECPG_COMPAT_INFORMIX)
|
||||
{
|
||||
printf ("unput $\n");
|
||||
unput(':');
|
||||
}
|
||||
else
|
||||
return yytext[0];
|
||||
}
|
||||
<SQL>{self} { /*
|
||||
* We may find a ';' inside a structure
|
||||
* definition in a TYPE or VAR statement.
|
||||
@ -584,7 +597,17 @@ cppline {space}*#(.*\\{space})*.*
|
||||
}
|
||||
<SQL>{other} { return yytext[0]; }
|
||||
<C>{exec_sql} { BEGIN SQL; return SQL_START; }
|
||||
<C>{ccomment} { /* ignore */ }
|
||||
<C>{informix_special} {
|
||||
/* are we simulating Informix? */
|
||||
if (compat == ECPG_COMPAT_INFORMIX)
|
||||
{
|
||||
BEGIN SQL;
|
||||
return SQL_START;
|
||||
}
|
||||
else
|
||||
return S_ANYTHING;
|
||||
}
|
||||
<C>{ccomment} { /* ignore */ }
|
||||
<C>{xch} {
|
||||
char* endptr;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user