Allow SET to not start a transaction - Mailing list pgsql-patches

From Bruce Momjian
Subject Allow SET to not start a transaction
Date
Msg-id 200210060436.g964a7v11355@candle.pha.pa.us
Whole thread Raw
Responses Re: Allow SET to not start a transaction  (Bruce Momjian <pgman@candle.pha.pa.us>)
List pgsql-patches
We have on the open items list:

    Make SET not start a transaction with autocommit off, document it

The attached patch does exactly that (though without documentation).  It
checks for the TRANS_DEFAULT transaction state, which is the state right
after a COMMIT.  If the backend is in that state, and autocommit is off,
and the command is SET/SHOW/RESET, then a COMMIT will be forced, rather
than keeping the transaction open for the next command.  It seems to
work, but i want to test it more before applying to CVS.

---------------------------------------------------------------------------

test=> set autocommit = off;
SET
test=> commit;
WARNING:  COMMIT: no transaction in progress
COMMIT
test=> set statement_timeout = 9999999;
SET
test=> select 1;
 ?column?
----------
        1
(1 row)

test=> abort;
ROLLBACK
test=> show statement_timeout;
 statement_timeout
-------------------
 9999999
(1 row)

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073
Index: src/backend/tcop/postgres.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/tcop/postgres.c,v
retrieving revision 1.298
diff -c -c -r1.298 postgres.c
*** src/backend/tcop/postgres.c    6 Oct 2002 03:56:03 -0000    1.298
--- src/backend/tcop/postgres.c    6 Oct 2002 04:28:54 -0000
***************
*** 76,81 ****
--- 76,82 ----
  CommandDest whereToSendOutput = Debug;

  extern int    StatementTimeout;
+ extern bool autocommit;

  static bool dontExecute = false;

***************
*** 122,128 ****
  static List *pg_parse_query(StringInfo query_string, Oid *typev, int nargs);
  static List *pg_analyze_and_rewrite(Node *parsetree);
  static void start_xact_command(void);
! static void finish_xact_command(void);
  static void SigHupHandler(SIGNAL_ARGS);
  static void FloatExceptionHandler(SIGNAL_ARGS);
  static const char *CreateCommandTag(Node *parsetree);
--- 123,129 ----
  static List *pg_parse_query(StringInfo query_string, Oid *typev, int nargs);
  static List *pg_analyze_and_rewrite(Node *parsetree);
  static void start_xact_command(void);
! static void finish_xact_command(bool forceCommit);
  static void SigHupHandler(SIGNAL_ARGS);
  static void FloatExceptionHandler(SIGNAL_ARGS);
  static const char *CreateCommandTag(Node *parsetree);
***************
*** 806,812 ****
               */
              if (isTransactionStmt)
              {
!                 finish_xact_command();
                  xact_started = false;
              }
          }                        /* end loop over queries generated from a
--- 807,813 ----
               */
              if (isTransactionStmt)
              {
!                 finish_xact_command(false);
                  xact_started = false;
              }
          }                        /* end loop over queries generated from a
***************
*** 824,830 ****
           */
          if (lnext(parsetree_item) == NIL && xact_started)
          {
!             finish_xact_command();
              xact_started = false;
          }

--- 825,843 ----
           */
          if (lnext(parsetree_item) == NIL && xact_started)
          {
!             /*
!              *    Don't allow SET/SHOW/RESET to start a new transaction
!              *    with autocommit off.  We do this by forcing a COMMIT
!              *    when these commands start a transaction.
!              */
!             if (autocommit ||
!                 IsTransactionState() ||
!                 (strcmp(commandTag, "SET") != 0 &&
!                  strcmp(commandTag, "SHOW") != 0 &&
!                  strcmp(commandTag, "RESET") != 0))
!                 finish_xact_command(false);
!             else
!                 finish_xact_command(true);
              xact_started = false;
          }

***************
*** 859,865 ****
       * will only happen if the querystring was empty.)
       */
      if (xact_started)
!         finish_xact_command();

      if (save_Log_duration)
      {
--- 872,878 ----
       * will only happen if the querystring was empty.)
       */
      if (xact_started)
!         finish_xact_command(false);

      if (save_Log_duration)
      {
***************
*** 888,894 ****
  }

  static void
! finish_xact_command(void)
  {
      /* Invoke IMMEDIATE constraint triggers */
      DeferredTriggerEndQuery();
--- 901,907 ----
  }

  static void
! finish_xact_command(bool forceCommit)
  {
      /* Invoke IMMEDIATE constraint triggers */
      DeferredTriggerEndQuery();
***************
*** 896,902 ****
      /* Now commit the command */
      elog(DEBUG1, "CommitTransactionCommand");

!     CommitTransactionCommand(false);

  #ifdef SHOW_MEMORY_STATS
      /* Print mem stats at each commit for leak tracking */
--- 909,915 ----
      /* Now commit the command */
      elog(DEBUG1, "CommitTransactionCommand");

!     CommitTransactionCommand(forceCommit);

  #ifdef SHOW_MEMORY_STATS
      /* Print mem stats at each commit for leak tracking */
***************
*** 1901,1907 ****
                  }

                  /* commit the function-invocation transaction */
!                 finish_xact_command();
                  break;

                  /*
--- 1914,1920 ----
                  }

                  /* commit the function-invocation transaction */
!                 finish_xact_command(false);
                  break;

                  /*

pgsql-patches by date:

Previous
From: Alvaro Herrera
Date:
Subject: Re: [HACKERS] ALTER TABLE ... ADD COLUMN
Next
From: Tom Lane
Date:
Subject: Suggested change to pgbench