Re: [GENERAL] DECLARE CURSOR - Mailing list pgsql-hackers

From Tom Lane
Subject Re: [GENERAL] DECLARE CURSOR
Date
Msg-id 16145.1037579431@sss.pgh.pa.us
Whole thread Raw
In response to Re: [GENERAL] DECLARE CURSOR  (Bruce Momjian <pgman@candle.pha.pa.us>)
Responses Re: [GENERAL] DECLARE CURSOR  (snpe <snpe@snpe.co.yu>)
List pgsql-hackers
Bruce Momjian <pgman@candle.pha.pa.us> writes:
> Let's just fix it and roll an RC2 with the fix.  If not, we can just fix
> it in 7.3.1 but I see little problem in rolling an RC2.

Here is the patch I am testing (in current sources; I don't think it
needs any adjustments for REL7_3, but haven't tried to apply it yet).
Basically it moves the test that was originally done in parse/analyze.c
into the execution-time setup of a cursor, and enlarges the test to
understand about autocommit-off and inside-a-function exceptions.
Anyone see a problem?
        regards, tom lane

*** src/backend/access/transam/xact.c.orig    Wed Nov 13 10:51:46 2002
--- src/backend/access/transam/xact.c    Sun Nov 17 19:10:20 2002
***************
*** 1488,1493 ****
--- 1488,1537 ----     } } 
+ /* --------------------------------
+  *    RequireTransactionChain
+  *
+  *    This routine is to be called by statements that must run inside
+  *    a transaction block, because they have no effects that persist past
+  *    transaction end (and so calling them outside a transaction block
+  *    is presumably an error).  DECLARE CURSOR is an example.
+  *
+  *    If we appear to be running inside a user-defined function, we do not
+  *    issue an error, since the function could issue more commands that make
+  *    use of the current statement's results.  Thus this is an inverse for
+  *    PreventTransactionChain.
+  *
+  *    stmtNode: pointer to parameter block for statement; this is used in
+  *    a very klugy way to determine whether we are inside a function.
+  *    stmtType: statement type name for error messages.
+  * --------------------------------
+  */
+ void
+ RequireTransactionChain(void *stmtNode, const char *stmtType)
+ {
+     /*
+      * xact block already started?
+      */
+     if (IsTransactionBlock())
+         return;
+     /*
+      * Are we inside a function call?  If the statement's parameter block
+      * was allocated in QueryContext, assume it is an interactive command.
+      * Otherwise assume it is coming from a function.
+      */
+     if (!MemoryContextContains(QueryContext, stmtNode))
+         return;
+     /*
+      * If we are in autocommit-off mode then it's okay, because this
+      * statement will itself start a transaction block.
+      */
+     if (!autocommit && !suppressChain)
+         return;
+     /* translator: %s represents an SQL statement name */
+     elog(ERROR, "%s may only be used in begin/end transaction blocks",
+          stmtType);
+ }
+   /* ----------------------------------------------------------------  *                       transaction block
support
*** /home/postgres/pgsql/src/backend/tcop/pquery.c.orig    Wed Sep  4 17:30:43 2002
--- /home/postgres/pgsql/src/backend/tcop/pquery.c    Sun Nov 17 19:10:26 2002
***************
*** 161,166 ****
--- 161,168 ----             /* If binary portal, switch to alternate output format */             if (dest == Remote
&&parsetree->isBinary)                 dest = RemoteInternal;
 
+             /* Check for invalid context (must be in transaction block) */
+             RequireTransactionChain((void *) parsetree, "DECLARE CURSOR");         }         else if (parsetree->into
!=NULL)         {
 
*** /home/postgres/pgsql/src/include/access/xact.h.orig    Wed Nov 13 10:52:07 2002
--- /home/postgres/pgsql/src/include/access/xact.h    Sun Nov 17 19:10:13 2002
***************
*** 115,120 ****
--- 115,121 ---- extern void UserAbortTransactionBlock(void); extern void AbortOutOfAnyTransaction(void); extern void
PreventTransactionChain(void*stmtNode, const char *stmtType);
 
+ extern void RequireTransactionChain(void *stmtNode, const char *stmtType);  extern void
RecordTransactionCommit(void);
 


pgsql-hackers by date:

Previous
From: Tom Lane
Date:
Subject: Re: [GENERAL] DECLARE CURSOR
Next
From: Alvaro Herrera
Date:
Subject: Re: CLUSTER ALL syntax