1- /* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/connect.c,v 1.13 2003/08/0108:21:04 meskes Exp $ */
1+ /* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/connect.c,v 1.14 2003/08/0113: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{
117117if ((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 );
120120return false;
121121}
122122PQclear (results );
@@ -130,7 +130,7 @@ ECPGsetcommit(int lineno, const char *mode, const char *connection_name)
130130{
131131if ((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 );
134134return false;
135135}
136136PQclear (results );
@@ -154,151 +154,47 @@ ECPGsetconn(int lineno, const char *connection_name)
154154return 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
181158static 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' );
184163struct 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 )
218169return ;
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 ;
298187sqlca -> sqlwarn [2 ]= 'W' ;
299188sqlca -> 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 */
303199bool
304200ECPGconnect (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
406302if (strncmp (dbname ,"unix:" ,5 )!= 0 )
407303{
408304ECPGlog ("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>" );
410306if (host )
411307ECPGfree (host );
412308if (port )
@@ -429,7 +325,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
429325if (strcmp (dbname + offset ,"localhost" )!= 0 && strcmp (dbname + offset ,"127.0.0.1" )!= 0 )
430326{
431327ECPGlog ("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>" );
433329if (host )
434330ECPGfree (host );
435331if (port )
@@ -497,7 +393,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
497393user ?"for user " :"" ,user ?user :"" ,
498394lineno ,errmsg );
499395
500- ECPGraise (lineno ,ECPG_CONNECT ,db , ECPG_COMPAT_PGSQL );
396+ ECPGraise (lineno ,ECPG_CONNECT ,ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION , db );
501397if (host )
502398ECPGfree (host );
503399if (port )
@@ -528,7 +424,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
528424this -> committed = true;
529425this -> autocommit = autocommit ;
530426
531- PQsetNoticeProcessor (this -> connection ,& ECPGnoticeProcessor , (void * )this );
427+ PQsetNoticeReceiver (this -> connection ,& ECPGnoticeReceiver , (void * )this );
532428
533429return true;
534430}