Mark Wong wrote:
Tom Lane wrote:
Mark Wong <[EMAIL PROTECTED]> writes:
Curious, I'm still seeing the same behavior. Maybe I'll take another snapshot from CVS.

Hm, maybe I need to try a bit harder here.  Does the "not registered"
error happen immediately/reliably for you, or do you need to run the
test awhile?

I did a gross test and my kit appears broken between the 8.0 and 8.1 releases. I'll try to narrow down the exact date.

I've narrowed it down between cvs pulls from Dec 14, 2005 and Dec 15, 2005. Does the attached diff appear to be a plausible cause?

Thanks,
Mark
diff -urN pgsql-2005-12-14/src/backend/commands/prepare.c 
pgsql-2005-12-15/src/backend/commands/prepare.c
--- pgsql-2005-12-14/src/backend/commands/prepare.c     2005-11-28 
17:25:49.000000000 -0800
+++ pgsql-2005-12-15/src/backend/commands/prepare.c     2005-12-14 
09:06:27.000000000 -0800
@@ -10,7 +10,7 @@
  * Copyright (c) 2002-2005, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/prepare.c,v 1.43 2005/11/29 
01:25:49 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/prepare.c,v 1.44 2005/12/14 
17:06:27 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -448,6 +448,30 @@
 }
 
 /*
+ * Given a prepared statement, determine whether it will return tuples.
+ *
+ * Note: this is used rather than just testing the result of
+ * FetchPreparedStatementResultDesc() because that routine can fail if
+ * invoked in an aborted transaction.  This one is safe to use in any
+ * context.  Be sure to keep the two routines in sync!
+ */
+bool
+PreparedStatementReturnsTuples(PreparedStatement *stmt)
+{
+       switch (ChoosePortalStrategy(stmt->query_list))
+       {
+               case PORTAL_ONE_SELECT:
+               case PORTAL_UTIL_SELECT:
+                       return true;
+
+               case PORTAL_MULTI_QUERY:
+                       /* will not return tuples */
+                       break;
+       }
+       return false;
+}
+
+/*
  * Given a prepared statement that returns tuples, extract the query
  * targetlist. Returns NIL if the statement doesn't have a determinable
  * targetlist.
diff -urN pgsql-2005-12-14/src/backend/executor/execQual.c 
pgsql-2005-12-15/src/backend/executor/execQual.c
--- pgsql-2005-12-14/src/backend/executor/execQual.c    2005-11-22 
10:17:10.000000000 -0800
+++ pgsql-2005-12-15/src/backend/executor/execQual.c    2005-12-14 
08:28:32.000000000 -0800
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.185 2005/11/22 
18:17:10 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.186 2005/12/14 
16:28:32 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -523,7 +523,7 @@
        Assert(variable->varno != OUTER);
        slot = econtext->ecxt_scantuple;
 
-       tuple = slot->tts_tuple;
+       tuple = ExecFetchSlotTuple(slot);
        tupleDesc = slot->tts_tupleDescriptor;
 
        /*
diff -urN pgsql-2005-12-14/src/backend/tcop/postgres.c 
pgsql-2005-12-15/src/backend/tcop/postgres.c
--- pgsql-2005-12-14/src/backend/tcop/postgres.c        2005-11-22 
10:17:21.000000000 -0800
+++ pgsql-2005-12-15/src/backend/tcop/postgres.c        2005-12-14 
09:06:27.000000000 -0800
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.470 2005/11/22 
18:17:21 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.471 2005/12/14 
17:06:27 tgl Exp $
  *
  * NOTES
  *       this is the "main" module of the postgres backend and
@@ -1849,6 +1849,15 @@
        ListCell   *l;
        StringInfoData buf;
 
+       /*
+        * Start up a transaction command. (Note that this will normally change
+        * current memory context.) Nothing happens if we are already in one.
+        */
+       start_xact_command();
+
+       /* Switch back to message context */
+       MemoryContextSwitchTo(MessageContext);
+
        /* Find prepared statement */
        if (stmt_name[0] != '\0')
                pstmt = FetchPreparedStatement(stmt_name, true);
@@ -1862,6 +1871,22 @@
                                         errmsg("unnamed prepared statement 
does not exist")));
        }
 
+       /*
+        * If we are in aborted transaction state, we can't safely create a 
result
+        * tupledesc, because that needs catalog accesses.  Hence, refuse to
+        * Describe statements that return data.  (We shouldn't just refuse all
+        * Describes, since that might break the ability of some clients to 
issue
+        * COMMIT or ROLLBACK commands, if they use code that blindly Describes
+        * whatever it does.)  We can Describe parameters without doing anything
+        * dangerous, so we don't restrict that.
+        */
+       if (IsAbortedTransactionBlockState() &&
+               PreparedStatementReturnsTuples(pstmt))
+               ereport(ERROR,
+                               (errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION),
+                                errmsg("current transaction is aborted, "
+                                               "commands ignored until end of 
transaction block")));
+
        if (whereToSendOutput != DestRemote)
                return;                                 /* can't actually do 
anything... */
 
@@ -1902,12 +1927,36 @@
 {
        Portal          portal;
 
+       /*
+        * Start up a transaction command. (Note that this will normally change
+        * current memory context.) Nothing happens if we are already in one.
+        */
+       start_xact_command();
+
+       /* Switch back to message context */
+       MemoryContextSwitchTo(MessageContext);
+
        portal = GetPortalByName(portal_name);
        if (!PortalIsValid(portal))
                ereport(ERROR,
                                (errcode(ERRCODE_UNDEFINED_CURSOR),
                                 errmsg("portal \"%s\" does not exist", 
portal_name)));
 
+       /*
+        * If we are in aborted transaction state, we can't run
+        * SendRowDescriptionMessage(), because that needs catalog accesses.
+        * Hence, refuse to Describe portals that return data.  (We shouldn't 
just
+        * refuse all Describes, since that might break the ability of some
+        * clients to issue COMMIT or ROLLBACK commands, if they use code that
+        * blindly Describes whatever it does.)
+        */
+       if (IsAbortedTransactionBlockState() &&
+               portal->tupDesc)
+               ereport(ERROR,
+                               (errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION),
+                                errmsg("current transaction is aborted, "
+                                               "commands ignored until end of 
transaction block")));
+
        if (whereToSendOutput != DestRemote)
                return;                                 /* can't actually do 
anything... */
 
diff -urN pgsql-2005-12-14/src/include/commands/prepare.h 
pgsql-2005-12-15/src/include/commands/prepare.h
--- pgsql-2005-12-14/src/include/commands/prepare.h     2005-11-28 
17:25:50.000000000 -0800
+++ pgsql-2005-12-15/src/include/commands/prepare.h     2005-12-14 
09:06:28.000000000 -0800
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 2002-2005, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/include/commands/prepare.h,v 1.15 2005/11/29 
01:25:50 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/commands/prepare.h,v 1.16 2005/12/14 
17:06:28 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -60,6 +60,7 @@
 extern void DropPreparedStatement(const char *stmt_name, bool showError);
 extern List *FetchPreparedStatementParams(const char *stmt_name);
 extern TupleDesc FetchPreparedStatementResultDesc(PreparedStatement *stmt);
+extern bool PreparedStatementReturnsTuples(PreparedStatement *stmt);
 extern List *FetchPreparedStatementTargetList(PreparedStatement *stmt);
 
 #endif   /* PREPARE_H */
diff -urN pgsql-2005-12-14/src/interfaces/libpq/libpq.rc 
pgsql-2005-12-15/src/interfaces/libpq/libpq.rc
--- pgsql-2005-12-14/src/interfaces/libpq/libpq.rc      2006-09-20 
10:05:18.000000000 -0700
+++ pgsql-2005-12-15/src/interfaces/libpq/libpq.rc      2006-09-19 
17:31:48.000000000 -0700
@@ -1,8 +1,8 @@
 #include <winver.h>
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 8,2,0,6263
- PRODUCTVERSION 8,2,0,6263
+ FILEVERSION 8,2,0,6262
+ PRODUCTVERSION 8,2,0,6262
  FILEFLAGSMASK 0x3fL
  FILEFLAGS 0
  FILEOS VOS__WINDOWS32
diff -urN pgsql-2005-12-14/src/test/regress/expected/select.out 
pgsql-2005-12-15/src/test/regress/expected/select.out
--- pgsql-2005-12-14/src/test/regress/expected/select.out       2005-04-06 
18:51:40.000000000 -0700
+++ pgsql-2005-12-15/src/test/regress/expected/select.out       2005-12-14 
08:28:32.000000000 -0800
@@ -431,3 +431,24 @@
  mary    |   8
 (58 rows)
 
+--
+-- Test some cases involving whole-row Var referencing a subquery
+--
+select foo from (select 1) as foo;
+ foo 
+-----
+ (1)
+(1 row)
+
+select foo from (select null) as foo;
+ foo 
+-----
+ ()
+(1 row)
+
+select foo from (select 'xyzzy',1,null) as foo;
+    foo     
+------------
+ (xyzzy,1,)
+(1 row)
+
diff -urN pgsql-2005-12-14/src/test/regress/sql/select.sql 
pgsql-2005-12-15/src/test/regress/sql/select.sql
--- pgsql-2005-12-14/src/test/regress/sql/select.sql    2005-04-06 
18:51:41.000000000 -0700
+++ pgsql-2005-12-15/src/test/regress/sql/select.sql    2005-12-14 
08:28:32.000000000 -0800
@@ -104,3 +104,9 @@
 --
 SELECT p.name, p.age FROM person* p ORDER BY age using >, name;
 
+--
+-- Test some cases involving whole-row Var referencing a subquery
+--
+select foo from (select 1) as foo;
+select foo from (select null) as foo;
+select foo from (select 'xyzzy',1,null) as foo;
---------------------------(end of broadcast)---------------------------
TIP 2: Don't 'kill -9' the postmaster

Reply via email to