Skip to content

Commit 4f7df90

Browse files
committed
Make ecpg SQLSTATE-aware. Map existing SQLCODE assignments to SQLSTATEs,
rather than parsing the message. Add some documentation about embedded SQL.
1 parent 1ffc5b0 commit 4f7df90

File tree

15 files changed

+1129
-435
lines changed

15 files changed

+1129
-435
lines changed

doc/src/sgml/ecpg.sgml

Lines changed: 953 additions & 198 deletions
Large diffs are not rendered by default.

src/backend/commands/portalcmds.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
*
1515
*
1616
* IDENTIFICATION
17-
* $Header: /cvsroot/pgsql/src/backend/commands/portalcmds.c,v 1.18 2003/07/28 00:09:14 tgl Exp $
17+
* $Header: /cvsroot/pgsql/src/backend/commands/portalcmds.c,v 1.19 2003/08/01 13:53:36 petere Exp $
1818
*
1919
*-------------------------------------------------------------------------
2020
*/
@@ -169,8 +169,7 @@ PerformPortalFetch(FetchStmt *stmt,
169169
/* FIXME: shouldn't this be an ERROR? */
170170
ereport(WARNING,
171171
(errcode(ERRCODE_UNDEFINED_CURSOR),
172-
errmsg("portal \"%s\" does not exist", stmt->portalname),
173-
errfunction("PerformPortalFetch"))); /* for ecpg */
172+
errmsg("portal \"%s\" does not exist", stmt->portalname)));
174173
if (completionTag)
175174
strcpy(completionTag, stmt->ismove ? "MOVE 0" : "FETCH 0");
176175
return;

src/interfaces/ecpg/compatlib/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#
55
# Copyright (c) 1994, Regents of the University of California
66
#
7-
# $Header: /cvsroot/pgsql/src/interfaces/ecpg/compatlib/Makefile,v 1.5 2003/06/24 14:45:46 momjian Exp $
7+
# $Header: /cvsroot/pgsql/src/interfaces/ecpg/compatlib/Makefile,v 1.6 2003/08/01 13:53:36 petere Exp $
88
#
99
#-------------------------------------------------------------------------
1010

@@ -16,7 +16,7 @@ NAME= ecpg_compat
1616
SO_MAJOR_VERSION= 1
1717
SO_MINOR_VERSION= 0.0
1818

19-
override CPPFLAGS := -I$(top_srcdir)/src/interfaces/ecpg/include -I$(top_srcdir)/src/include/utils $(CPPFLAGS)
19+
override CPPFLAGS := -I$(top_srcdir)/src/interfaces/ecpg/include -I$(libpq_srcdir) -I$(top_srcdir)/src/include/utils $(CPPFLAGS)
2020
SHLIB_LINK = -L../pgtypeslib -lpgtypes -L../ecpglib -lecpg
2121

2222
OBJS= informix.o

src/interfaces/ecpg/ecpglib/connect.c

Lines changed: 35 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/connect.c,v 1.13 2003/08/01 08:21:04 meskes Exp $ */
1+
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/connect.c,v 1.14 2003/08/01 13:53:36 petere Exp $ */
22

33
#define POSTGRES_ECPG_INTERNAL
44
#include "postgres_fe.h"
@@ -116,7 +116,7 @@ ECPGsetcommit(int lineno, const char *mode, const char *connection_name)
116116
{
117117
if ((results = PQexec(con->connection, "begin transaction")) == NULL)
118118
{
119-
ECPGraise(lineno, ECPG_TRANS, NULL, ECPG_COMPAT_PGSQL);
119+
ECPGraise(lineno, ECPG_TRANS, ECPG_SQLSTATE_TRANSACTION_RESOLUTION_UNKNOWN, NULL);
120120
return false;
121121
}
122122
PQclear(results);
@@ -130,7 +130,7 @@ ECPGsetcommit(int lineno, const char *mode, const char *connection_name)
130130
{
131131
if ((results = PQexec(con->connection, "commit")) == NULL)
132132
{
133-
ECPGraise(lineno, ECPG_TRANS, NULL, ECPG_COMPAT_PGSQL);
133+
ECPGraise(lineno, ECPG_TRANS, ECPG_SQLSTATE_TRANSACTION_RESOLUTION_UNKNOWN, NULL);
134134
return false;
135135
}
136136
PQclear(results);
@@ -154,151 +154,47 @@ ECPGsetconn(int lineno, const char *connection_name)
154154
return true;
155155
}
156156

157-
static void
158-
ECPGnoticeProcessor_raise(int code, const char *message)
159-
{
160-
struct sqlca_t *sqlca = ECPGget_sqlca();
161-
sqlca->sqlcode = code;
162-
strncpy(sqlca->sqlerrm.sqlerrmc, message, sizeof(sqlca->sqlerrm.sqlerrmc));
163-
sqlca->sqlerrm.sqlerrmc[sizeof(sqlca->sqlerrm.sqlerrmc) - 1] = 0;
164-
sqlca->sqlerrm.sqlerrml = strlen(sqlca->sqlerrm.sqlerrmc);
165-
166-
/* remove trailing newline */
167-
if (sqlca->sqlerrm.sqlerrml
168-
&& sqlca->sqlerrm.sqlerrmc[sqlca->sqlerrm.sqlerrml - 1] == '\n')
169-
{
170-
sqlca->sqlerrm.sqlerrmc[sqlca->sqlerrm.sqlerrml - 1] = 0;
171-
sqlca->sqlerrm.sqlerrml--;
172-
}
173-
174-
ECPGlog("raising sqlcode %d\n", code);
175-
}
176-
177-
/*
178-
* I know this is a mess, but we can't redesign the backend
179-
*/
180157

181158
static void
182-
ECPGnoticeProcessor(void *arg, const char *message)
159+
ECPGnoticeReceiver(void *arg, const PGresult *result)
183160
{
161+
char *sqlstate = PQresultErrorField(result, 'C');
162+
char *message = PQresultErrorField(result, 'M');
184163
struct sqlca_t *sqlca = ECPGget_sqlca();
185164

186-
/* these notices raise an error */
187-
if (strncmp(message, "WARNING: ", 9) && strncmp(message, "NOTICE: ", 8))
188-
{
189-
ECPGlog("ECPGnoticeProcessor: strange warning '%s'\n", message);
190-
ECPGnoticeProcessor_raise(ECPG_WARNING_UNRECOGNIZED, message);
191-
return;
192-
}
193-
194-
message += 8;
195-
while (*message == ' ')
196-
message++;
197-
ECPGlog("WARNING: %s", message);
198-
199-
/* WARNING: (transaction aborted): queries ignored until END */
200-
201-
/*
202-
* WARNING: current transaction is aborted, queries ignored until end
203-
* of transaction block
204-
*/
205-
if (strstr(message, "queries ignored") && strstr(message, "transaction")
206-
&& strstr(message, "aborted"))
207-
{
208-
ECPGnoticeProcessor_raise(ECPG_WARNING_QUERY_IGNORED, message);
209-
return;
210-
}
165+
int sqlcode;
211166

212-
/* WARNING: PerformPortalClose: portal "*" not found */
213-
if ((!strncmp(message, "PerformPortalClose: portal", 26)
214-
|| !strncmp(message, "PerformPortalFetch: portal", 26))
215-
&& strstr(message + 26, "not found"))
216-
{
217-
ECPGnoticeProcessor_raise(ECPG_WARNING_UNKNOWN_PORTAL, message);
167+
/* these are not warnings */
168+
if (strncmp(sqlstate, "00", 2)==0)
218169
return;
219-
}
220170

221-
/* WARNING: BEGIN: already a transaction in progress */
222-
if (!strncmp(message, "BEGIN: already a transaction in progress", 40))
223-
{
224-
ECPGnoticeProcessor_raise(ECPG_WARNING_IN_TRANSACTION, message);
225-
return;
226-
}
227-
228-
/* WARNING: AbortTransaction and not in in-progress state */
229-
/* WARNING: COMMIT: no transaction in progress */
230-
/* WARNING: ROLLBACK: no transaction in progress */
231-
if (!strncmp(message, "AbortTransaction and not in in-progress state", 45)
232-
|| !strncmp(message, "COMMIT: no transaction in progress", 34)
233-
|| !strncmp(message, "ROLLBACK: no transaction in progress", 36))
234-
{
235-
ECPGnoticeProcessor_raise(ECPG_WARNING_NO_TRANSACTION, message);
236-
return;
237-
}
238-
239-
/* WARNING: BlankPortalAssignName: portal * already exists */
240-
if (!strncmp(message, "BlankPortalAssignName: portal", 29)
241-
&& strstr(message + 29, "already exists"))
242-
{
243-
ECPGnoticeProcessor_raise(ECPG_WARNING_PORTAL_EXISTS, message);
244-
return;
245-
}
246-
247-
/* these are harmless - do nothing */
248-
249-
/*
250-
* WARNING: CREATE TABLE / PRIMARY KEY will create implicit index '*'
251-
* for table '*'
252-
*/
253-
254-
/*
255-
* WARNING: ALTER TABLE ... ADD CONSTRAINT will create implicit
256-
* trigger(s) for FOREIGN KEY check(s)
257-
*/
258-
259-
/*
260-
* WARNING: CREATE TABLE will create implicit sequence '*' for SERIAL
261-
* column '*.*'
262-
*/
263-
264-
/*
265-
* WARNING: CREATE TABLE will create implicit trigger(s) for FOREIGN
266-
* KEY check(s)
267-
*/
268-
if ((!strncmp(message, "CREATE TABLE", 12) || !strncmp(message, "ALTER TABLE", 11))
269-
&& strstr(message + 11, "will create implicit"))
270-
return;
271-
272-
/* WARNING: QUERY PLAN: */
273-
if (!strncmp(message, "QUERY PLAN:", 11)) /* do we really see these? */
274-
return;
275-
276-
/*
277-
* WARNING: DROP TABLE implicitly drops referential integrity trigger
278-
* from table "*"
279-
*/
280-
if (!strncmp(message, "DROP TABLE implicitly drops", 27))
281-
return;
282-
283-
/*
284-
* WARNING: Caution: DROP INDEX cannot be rolled back, so don't abort
285-
* now
286-
*/
287-
if (strstr(message, "cannot be rolled back"))
288-
return;
171+
ECPGlog("%s", message);
172+
173+
/* map to SQLCODE for backward compatibility */
174+
if (strcmp(sqlstate, ECPG_SQLSTATE_INVALID_CURSOR_NAME)==0)
175+
sqlcode = ECPG_WARNING_UNKNOWN_PORTAL;
176+
else if (strcmp(sqlstate, ECPG_SQLSTATE_ACTIVE_SQL_TRANSACTION)==0)
177+
sqlcode = ECPG_WARNING_IN_TRANSACTION;
178+
else if (strcmp(sqlstate, ECPG_SQLSTATE_NO_ACTIVE_SQL_TRANSACTION)==0)
179+
sqlcode = ECPG_WARNING_NO_TRANSACTION;
180+
else if (strcmp(sqlstate, ECPG_SQLSTATE_DUPLICATE_CURSOR)==0)
181+
sqlcode = ECPG_WARNING_PORTAL_EXISTS;
182+
else
183+
sqlcode = 0;
289184

290-
/* these and other unmentioned should set sqlca->sqlwarn[2] */
291-
/* WARNING: The ':' operator is deprecated. Use exp(x) instead. */
292-
/* WARNING: Rel *: Uninitialized page 0 - fixing */
293-
/* WARNING: PortalHeapMemoryFree: * not in alloc set! */
294-
/* WARNING: Too old parent tuple found - can't continue vc_repair_frag */
295-
/* WARNING: identifier "*" will be truncated to "*" */
296-
/* WARNING: InvalidateSharedInvalid: cache state reset */
297-
/* WARNING: RegisterSharedInvalid: SI buffer overflow */
185+
strncpy(sqlca->sqlstate, sqlstate, sizeof(sqlca->sqlstate));
186+
sqlca->sqlcode = sqlcode;
298187
sqlca->sqlwarn[2] = 'W';
299188
sqlca->sqlwarn[0] = 'W';
189+
190+
strncpy(sqlca->sqlerrm.sqlerrmc, message, sizeof(sqlca->sqlerrm.sqlerrmc));
191+
sqlca->sqlerrm.sqlerrmc[sizeof(sqlca->sqlerrm.sqlerrmc) - 1] = 0;
192+
sqlca->sqlerrm.sqlerrml = strlen(sqlca->sqlerrm.sqlerrmc);
193+
194+
ECPGlog("raising sqlcode %d\n", sqlcode);
300195
}
301196

197+
302198
/* this contains some quick hacks, needs to be cleaned up, but it works */
303199
bool
304200
ECPGconnect(int lineno, int c, const char *name, const char *user, const char *passwd, const char *connection_name, int autocommit)
@@ -406,7 +302,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
406302
if (strncmp(dbname, "unix:", 5) != 0)
407303
{
408304
ECPGlog("connect: socketname %s given for TCP connection in line %d\n", host, lineno);
409-
ECPGraise(lineno, ECPG_CONNECT, realname ? realname : "<DEFAULT>", ECPG_COMPAT_PGSQL);
305+
ECPGraise(lineno, ECPG_CONNECT, ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION, realname ? realname : "<DEFAULT>");
410306
if (host)
411307
ECPGfree(host);
412308
if (port)
@@ -429,7 +325,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
429325
if (strcmp(dbname + offset, "localhost") != 0 && strcmp(dbname + offset, "127.0.0.1") != 0)
430326
{
431327
ECPGlog("connect: non-localhost access via sockets in line %d\n", lineno);
432-
ECPGraise(lineno, ECPG_CONNECT, realname ? realname : "<DEFAULT>", ECPG_COMPAT_PGSQL);
328+
ECPGraise(lineno, ECPG_CONNECT, ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION, realname ? realname : "<DEFAULT>");
433329
if (host)
434330
ECPGfree(host);
435331
if (port)
@@ -497,7 +393,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
497393
user ? "for user " : "", user ? user : "",
498394
lineno, errmsg);
499395

500-
ECPGraise(lineno, ECPG_CONNECT, db, ECPG_COMPAT_PGSQL);
396+
ECPGraise(lineno, ECPG_CONNECT, ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION, db);
501397
if (host)
502398
ECPGfree(host);
503399
if (port)
@@ -528,7 +424,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
528424
this->committed = true;
529425
this->autocommit = autocommit;
530426

531-
PQsetNoticeProcessor(this->connection, &ECPGnoticeProcessor, (void *) this);
427+
PQsetNoticeReceiver(this->connection, &ECPGnoticeReceiver, (void *) this);
532428

533429
return true;
534430
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy