Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita393fbf

Browse files
committed
Restructure error handling as recently discussed. It is now really
possible to trap an error inside a function rather than letting itpropagate out to PostgresMain. You still have to use AbortCurrentTransactionto clean up, but at least the error handling itself will cooperate.
1 parent94f8f63 commita393fbf

File tree

20 files changed

+1566
-1493
lines changed

20 files changed

+1566
-1493
lines changed

‎src/backend/bootstrap/bootstrap.c

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,14 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.189 2004/07/21 20:34:45 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.190 2004/07/31 00:45:30 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
1515
#include"postgres.h"
1616

1717
#include<unistd.h>
1818
#include<signal.h>
19-
#include<setjmp.h>
2019
#ifdefHAVE_GETOPT_H
2120
#include<getopt.h>
2221
#endif
@@ -458,15 +457,6 @@ BootstrapMain(int argc, char *argv[])
458457
for (i=0;i<HASHTABLESIZE;++i)
459458
hashtable[i]=NULL;
460459

461-
/*
462-
* abort processing resumes here (this is probably dead code?)
463-
*/
464-
if (sigsetjmp(Warn_restart,1)!=0)
465-
{
466-
Warnings++;
467-
AbortCurrentTransaction();
468-
}
469-
470460
/*
471461
* Process bootstrap input.
472462
*

‎src/backend/commands/copy.c

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,12 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.227 2004/06/16 01:26:42 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.228 2004/07/31 00:45:31 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
1515
#include"postgres.h"
1616

17-
#include<errno.h>
1817
#include<unistd.h>
1918
#include<sys/stat.h>
2019
#include<netinet/in.h>
@@ -130,6 +129,9 @@ static StringInfoData line_buf;
130129
staticboolline_buf_converted;
131130

132131
/* non-export function prototypes */
132+
staticvoidDoCopyTo(Relationrel,List*attnumlist,boolbinary,booloids,
133+
char*delim,char*null_print,boolcsv_mode,char*quote,
134+
char*escape,List*force_quote_atts,boolfe_copy);
133135
staticvoidCopyTo(Relationrel,List*attnumlist,boolbinary,booloids,
134136
char*delim,char*null_print,boolcsv_mode,char*quote,char*escape,
135137
List*force_quote_atts);
@@ -688,6 +690,7 @@ DoCopy(const CopyStmt *stmt)
688690
ListCell*option;
689691
List*attnamelist=stmt->attlist;
690692
List*attnumlist;
693+
boolfe_copy= false;
691694
boolbinary= false;
692695
booloids= false;
693696
boolcsv_mode= false;
@@ -1062,7 +1065,7 @@ DoCopy(const CopyStmt *stmt)
10621065
if (pipe)
10631066
{
10641067
if (whereToSendOutput==Remote)
1065-
SendCopyBegin(binary,list_length(attnumlist));
1068+
fe_copy= true;
10661069
else
10671070
copy_file=stdout;
10681071
}
@@ -1099,8 +1102,9 @@ DoCopy(const CopyStmt *stmt)
10991102
errmsg("\"%s\" is a directory",filename)));
11001103
}
11011104
}
1102-
CopyTo(rel,attnumlist,binary,oids,delim,null_print,csv_mode,
1103-
quote,escape,force_quote_atts);
1105+
1106+
DoCopyTo(rel,attnumlist,binary,oids,delim,null_print,csv_mode,
1107+
quote,escape,force_quote_atts,fe_copy);
11041108
}
11051109

11061110
if (!pipe)
@@ -1112,8 +1116,6 @@ DoCopy(const CopyStmt *stmt)
11121116
errmsg("could not write to file \"%s\": %m",
11131117
filename)));
11141118
}
1115-
elseif (whereToSendOutput==Remote&& !is_from)
1116-
SendCopyEnd(binary);
11171119
pfree(attribute_buf.data);
11181120
pfree(line_buf.data);
11191121

@@ -1127,6 +1129,39 @@ DoCopy(const CopyStmt *stmt)
11271129
}
11281130

11291131

1132+
/*
1133+
* This intermediate routine just exists to localize the effects of setjmp
1134+
* so we don't need to plaster a lot of variables with "volatile".
1135+
*/
1136+
staticvoid
1137+
DoCopyTo(Relationrel,List*attnumlist,boolbinary,booloids,
1138+
char*delim,char*null_print,boolcsv_mode,char*quote,
1139+
char*escape,List*force_quote_atts,boolfe_copy)
1140+
{
1141+
PG_TRY();
1142+
{
1143+
if (fe_copy)
1144+
SendCopyBegin(binary,list_length(attnumlist));
1145+
1146+
CopyTo(rel,attnumlist,binary,oids,delim,null_print,csv_mode,
1147+
quote,escape,force_quote_atts);
1148+
1149+
if (fe_copy)
1150+
SendCopyEnd(binary);
1151+
}
1152+
PG_CATCH();
1153+
{
1154+
/*
1155+
* Make sure we turn off old-style COPY OUT mode upon error.
1156+
* It is okay to do this in all cases, since it does nothing
1157+
* if the mode is not on.
1158+
*/
1159+
pq_endcopyout(true);
1160+
PG_RE_THROW();
1161+
}
1162+
PG_END_TRY();
1163+
}
1164+
11301165
/*
11311166
* Copy from relation TO file.
11321167
*/

‎src/backend/commands/portalcmds.c

Lines changed: 92 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
*
1515
*
1616
* IDENTIFICATION
17-
* $PostgreSQL: pgsql/src/backend/commands/portalcmds.c,v 1.29 2004/07/17 03:28:47 tgl Exp $
17+
* $PostgreSQL: pgsql/src/backend/commands/portalcmds.c,v 1.30 2004/07/31 00:45:31 tgl Exp $
1818
*
1919
*-------------------------------------------------------------------------
2020
*/
@@ -259,8 +259,18 @@ PortalCleanup(Portal portal)
259259

260260
/* We must make the portal's resource owner current */
261261
saveResourceOwner=CurrentResourceOwner;
262-
CurrentResourceOwner=portal->resowner;
263-
ExecutorEnd(queryDesc);
262+
PG_TRY();
263+
{
264+
CurrentResourceOwner=portal->resowner;
265+
ExecutorEnd(queryDesc);
266+
}
267+
PG_CATCH();
268+
{
269+
/* Ensure CurrentResourceOwner is restored on error */
270+
CurrentResourceOwner=saveResourceOwner;
271+
PG_RE_THROW();
272+
}
273+
PG_END_TRY();
264274
CurrentResourceOwner=saveResourceOwner;
265275
}
266276
}
@@ -317,91 +327,108 @@ PersistHoldablePortal(Portal portal)
317327
portal->status=PORTAL_ACTIVE;
318328

319329
/*
320-
* Set global portal context pointers.
330+
* Setupglobal portal context pointers.
321331
*/
322332
saveActivePortal=ActivePortal;
323-
ActivePortal=portal;
324333
saveResourceOwner=CurrentResourceOwner;
325-
CurrentResourceOwner=portal->resowner;
326334
savePortalContext=PortalContext;
327-
PortalContext=PortalGetHeapMemory(portal);
328335
saveQueryContext=QueryContext;
329-
QueryContext=portal->queryContext;
336+
PG_TRY();
337+
{
338+
ActivePortal=portal;
339+
CurrentResourceOwner=portal->resowner;
340+
PortalContext=PortalGetHeapMemory(portal);
341+
QueryContext=portal->queryContext;
342+
343+
MemoryContextSwitchTo(PortalContext);
344+
345+
/*
346+
* Rewind the executor: we need to store the entire result set in the
347+
* tuplestore, so that subsequent backward FETCHs can be processed.
348+
*/
349+
ExecutorRewind(queryDesc);
350+
351+
/* Change the destination to output to the tuplestore */
352+
queryDesc->dest=CreateDestReceiver(Tuplestore,portal);
353+
354+
/* Fetch the result set into the tuplestore */
355+
ExecutorRun(queryDesc,ForwardScanDirection,0L);
356+
357+
(*queryDesc->dest->rDestroy) (queryDesc->dest);
358+
queryDesc->dest=NULL;
359+
360+
/*
361+
* Now shut down the inner executor.
362+
*/
363+
portal->queryDesc=NULL;/* prevent double shutdown */
364+
ExecutorEnd(queryDesc);
365+
366+
/*
367+
* Reset the position in the result set: ideally, this could be
368+
* implemented by just skipping straight to the tuple # that we need
369+
* to be at, but the tuplestore API doesn't support that. So we start
370+
* at the beginning of the tuplestore and iterate through it until we
371+
* reach where we need to be. FIXME someday?
372+
*/
373+
MemoryContextSwitchTo(portal->holdContext);
374+
375+
if (!portal->atEnd)
376+
{
377+
longstore_pos;
330378

331-
MemoryContextSwitchTo(PortalContext);
379+
if (portal->posOverflow)/* oops, cannot trust portalPos */
380+
ereport(ERROR,
381+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
382+
errmsg("could not reposition held cursor")));
332383

333-
/*
334-
* Rewind the executor: we need to store the entire result set in the
335-
* tuplestore, so that subsequent backward FETCHs can be processed.
336-
*/
337-
ExecutorRewind(queryDesc);
384+
tuplestore_rescan(portal->holdStore);
338385

339-
/* Change the destination to output to the tuplestore */
340-
queryDesc->dest=CreateDestReceiver(Tuplestore,portal);
386+
for (store_pos=0;store_pos<portal->portalPos;store_pos++)
387+
{
388+
HeapTupletup;
389+
boolshould_free;
341390

342-
/* Fetch the result set into the tuplestore */
343-
ExecutorRun(queryDesc,ForwardScanDirection,0L);
391+
tup=tuplestore_gettuple(portal->holdStore, true,
392+
&should_free);
344393

345-
(*queryDesc->dest->rDestroy) (queryDesc->dest);
346-
queryDesc->dest=NULL;
394+
if (tup==NULL)
395+
elog(ERROR,"unexpected end of tuple stream");
347396

348-
/*
349-
* Now shut down the inner executor.
350-
*/
351-
portal->queryDesc=NULL;/* prevent double shutdown */
352-
ExecutorEnd(queryDesc);
353-
354-
/*
355-
* Reset the position in the result set: ideally, this could be
356-
* implemented by just skipping straight to the tuple # that we need
357-
* to be at, but the tuplestore API doesn't support that. So we start
358-
* at the beginning of the tuplestore and iterate through it until we
359-
* reach where we need to be. FIXME someday?
360-
*/
361-
MemoryContextSwitchTo(portal->holdContext);
362-
363-
if (!portal->atEnd)
397+
if (should_free)
398+
pfree(tup);
399+
}
400+
}
401+
}
402+
PG_CATCH();
364403
{
365-
longstore_pos;
366-
367-
if (portal->posOverflow)/* oops, cannot trust portalPos */
368-
ereport(ERROR,
369-
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
370-
errmsg("could not reposition held cursor")));
371-
372-
tuplestore_rescan(portal->holdStore);
373-
374-
for (store_pos=0;store_pos<portal->portalPos;store_pos++)
375-
{
376-
HeapTupletup;
377-
boolshould_free;
378-
379-
tup=tuplestore_gettuple(portal->holdStore, true,
380-
&should_free);
404+
/* Uncaught error while executing portal: mark it dead */
405+
portal->status=PORTAL_FAILED;
381406

382-
if (tup==NULL)
383-
elog(ERROR,"unexpected end of tuple stream");
407+
/* Restore global vars and propagate error */
408+
ActivePortal=saveActivePortal;
409+
CurrentResourceOwner=saveResourceOwner;
410+
PortalContext=savePortalContext;
411+
QueryContext=saveQueryContext;
384412

385-
if (should_free)
386-
pfree(tup);
387-
}
413+
PG_RE_THROW();
388414
}
415+
PG_END_TRY();
389416

390417
MemoryContextSwitchTo(oldcxt);
391418

392-
/*
393-
* We can now release any subsidiary memory of the portal's heap
394-
* context; we'll never use it again. The executor already dropped
395-
* its context, but this will clean up anything that glommed onto the
396-
* portal's heap via PortalContext.
397-
*/
398-
MemoryContextDeleteChildren(PortalGetHeapMemory(portal));
399-
400419
/* Mark portal not active */
401420
portal->status=PORTAL_READY;
402421

403422
ActivePortal=saveActivePortal;
404423
CurrentResourceOwner=saveResourceOwner;
405424
PortalContext=savePortalContext;
406425
QueryContext=saveQueryContext;
426+
427+
/*
428+
* We can now release any subsidiary memory of the portal's heap
429+
* context; we'll never use it again. The executor already dropped
430+
* its context, but this will clean up anything that glommed onto the
431+
* portal's heap via PortalContext.
432+
*/
433+
MemoryContextDeleteChildren(PortalGetHeapMemory(portal));
407434
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp