Re: Lock partitions - Mailing list pgsql-hackers

From Mark Wong
Subject Re: Lock partitions
Date
Msg-id 45117859.4090507@osdl.org
Whole thread Raw
In response to Re: Lock partitions  (Mark Wong <markw@osdl.org>)
Responses Re: Lock partitions  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-hackers
Mark Wong wrote:
> Tom Lane wrote:
>> Mark Wong <markw@osdl.org> 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;

pgsql-hackers by date:

Previous
From: "Magnus Hagander"
Date:
Subject: Re: pdfs of the conference
Next
From: Gregory Stark
Date:
Subject: Re: Release Notes: Major Changes in 8.2