diff -u src/backend/access/transam/xact.c src/backend/access/transam/xact.c --- src/backend/access/transam/xact.c 16 Jul 2004 05:40:09 -0000 +++ src/backend/access/transam/xact.c 16 Jul 2004 07:04:35 -0000 @@ -159,6 +159,8 @@ #include "commands/user.h" #include "executor/spi.h" #include "libpq/be-fsstubs.h" +#include "lib/stringinfo.h" +#include "libpq/pqformat.h" #include "miscadmin.h" #include "storage/fd.h" #include "storage/proc.h" @@ -341,6 +343,7 @@ static void ShowTransactionStateRec(TransactionState state); static const char *BlockStateAsString(TBlockState blockState); static const char *TransStateAsString(TransState state); +static void SendTransactionNestingLevel(void); /* ---------------------------------------------------------------- * transaction state accessors @@ -1360,6 +1369,8 @@ */ s->state = TRANS_INPROGRESS; + SendTransactionNestingLevel(); + ShowTransactionState("StartTransaction"); } @@ -1486,6 +1508,8 @@ */ s->state = TRANS_DEFAULT; + SendTransactionNestingLevel(); + RESUME_INTERRUPTS(); } @@ -1627,6 +1651,8 @@ s->nestingLevel = 0; s->childXids = NIL; + SendTransactionNestingLevel(); + /* * done with abort processing, set current transaction state back to * default @@ -2741,6 +2767,8 @@ s->blockState != TBLOCK_SUBENDABORT_ALL) AbortSubTransaction(); s->blockState = TBLOCK_SUBABORT; + + SendTransactionNestingLevel(); } /* @@ -2762,6 +2790,8 @@ PopTransaction(); s = CurrentTransactionState; /* changed by pop */ } + + SendTransactionNestingLevel(); } /* @@ -2893,15 +2930,17 @@ /* Initialize the various transaction subsystems */ AtSubStart_Memory(); AtSubStart_Inval(); AtSubStart_RelationCache(); AtSubStart_CatCache(); AtSubStart_Buffers(); AtSubStart_smgr(); AtSubStart_Notify(); DeferredTriggerBeginSubXact(); s->state = TRANS_INPROGRESS; + SendTransactionNestingLevel(); + ShowTransactionState("StartSubTransaction"); } @@ -2942,11 +2981,13 @@ AtEOSubXact_on_commit_actions(true, s->transactionIdData, s->parent->transactionIdData); AtEOSubXact_CatCache(true); AtEOSubXact_RelationCache(true); AtEOSubXact_Buffers(true); AtSubCommit_Memory(); + SendTransactionNestingLevel(); + s->state = TRANS_DEFAULT; } @@ -3045,6 +3087,8 @@ AtSubCleanup_Portals(); AtSubCleanup_Memory(); + SendTransactionNestingLevel(); + s->state = TRANS_DEFAULT; } @@ -3160,6 +3204,22 @@ pfree(s); } +static void +SendTransactionNestingLevel(void) +{ + char *val = (char *)palloc(12); + StringInfoData msgbuf; + + snprintf(val, 12, "%d", CurrentTransactionState->nestingLevel); + + pq_beginmessage(&msgbuf, 'S'); + pq_sendstring(&msgbuf, "nesting_level"); + pq_sendstring(&msgbuf, val); + pq_endmessage(&msgbuf); + + pfree(val); +} + /* * ShowTransactionState * Debug support --- src/bin/psql/prompt.c 24 Feb 2004 21:45:18 -0000 1.35 +++ src/bin/psql/prompt.c 16 Jul 2004 06:39:33 -0000 @@ -46,6 +46,7 @@ * in prompt2 -, *, ', or "; * in prompt3 nothing * %x - transaction status: empty, *, !, ? (unknown or no connection) + * %d - transaction nesting level * %? - the error code of the last query (not yet implemented) * %% - a percent sign * @@ -237,6 +238,13 @@ } break; + case 'd': + if (!pset.db) + buf[0] = '?'; + else + snprintf(buf, MAX_PROMPT_SIZE, "%d", PQnestingLevel(pset.db)); + break; + case '?': /* not here yet */ break; --- src/interfaces/libpq/fe-connect.c 12 Jul 2004 14:23:28 -0000 1.278 +++ src/interfaces/libpq/fe-connect.c 16 Jul 2004 06:35:31 -0000 @@ -2847,6 +2847,14 @@ return conn->xactStatus; } +int +PQnestingLevel(const PGconn *conn) +{ + if (!conn || conn->status != CONNECTION_OK) + return -1; + return conn->nestingLevel; +} + const char * PQparameterStatus(const PGconn *conn, const char *paramName) { only in patch2: unchanged: --- src/interfaces/libpq/fe-exec.c 7 May 2004 00:24:59 -0000 1.159 +++ src/interfaces/libpq/fe-exec.c 16 Jul 2004 06:59:53 -0000 @@ -613,6 +613,8 @@ */ if (strcmp(name, "client_encoding") == 0) conn->client_encoding = pg_char_to_encoding(value); + else if (strcmp(name, "nesting_level") == 0) + conn->nestingLevel = atoi(value); else if (strcmp(name, "server_version") == 0) { int cnt; only in patch2: unchanged: --- src/interfaces/libpq/libpq-fe.h 24 Mar 2004 03:44:59 -0000 1.104 +++ src/interfaces/libpq/libpq-fe.h 16 Jul 2004 06:37:06 -0000 @@ -245,6 +245,7 @@ extern char *PQoptions(const PGconn *conn); extern ConnStatusType PQstatus(const PGconn *conn); extern PGTransactionStatusType PQtransactionStatus(const PGconn *conn); +extern int PQnestingLevel(const PGconn *conn); extern const char *PQparameterStatus(const PGconn *conn, const char *paramName); extern int PQprotocolVersion(const PGconn *conn); only in patch2: unchanged: --- src/interfaces/libpq/libpq-int.h 31 May 2004 18:42:40 -0000 1.88 +++ src/interfaces/libpq/libpq-int.h 16 Jul 2004 06:36:07 -0000 @@ -265,6 +265,7 @@ PGAsyncStatusType asyncStatus; PGTransactionStatusType xactStatus; /* note: xactStatus never changes to ACTIVE */ + int nestingLevel; /* transaction nesting level */ bool nonblocking; /* whether this connection is using * nonblock sending semantics */ bool ext_query; /* was our last query sent with extended