Skip to content

Commit 4db9689

Browse files
committed
Add transaction status field to ReadyForQuery messages, and make room
for tableID/columnID in RowDescription. (The latter isn't really implemented yet though --- the backend always sends zeroes, and libpq just throws away the data.)
1 parent 2b1e36c commit 4db9689

File tree

8 files changed

+118
-41
lines changed

8 files changed

+118
-41
lines changed

doc/src/sgml/protocol.sgml

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/protocol.sgml,v 1.31 2003/04/25 19:45:08 tgl Exp $ -->
1+
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/protocol.sgml,v 1.32 2003/04/26 20:22:57 tgl Exp $ -->
22

33
<chapter id="protocol">
44
<title>Frontend/Backend Protocol</title>
@@ -3870,14 +3870,19 @@ individual fields will typically not end with a newline, whereas the single
38703870
string sent in the older protocol always did.
38713871
</para>
38723872

3873+
<para>
3874+
The ReadyForQuery ('<literal>Z</>') message includes a transaction status
3875+
indicator.
3876+
</para>
3877+
38733878
<para>
38743879
COPY data is now encapsulated into CopyData and CopyDone messages. There
38753880
is a well-defined way to recover from errors during COPY. The special
38763881
<quote><literal>\.</></quote> last line is not needed anymore, and is not sent
38773882
during COPY OUT.
38783883
(It is still recognized as a terminator during COPY IN, but its use is
38793884
deprecated and will eventually be removed.) Binary COPY is supported.
3880-
The CopyInResponse and CopyOutResponse messages carry a field indicating
3885+
The CopyInResponse and CopyOutResponse messages include a field indicating
38813886
whether the COPY operation is text or binary.
38823887
</para>
38833888

@@ -3888,6 +3893,11 @@ Subsequently, a ParameterStatus message is sent whenever the active value
38883893
changes for any of these parameters.
38893894
</para>
38903895

3896+
<para>
3897+
The RowDescription ('<literal>T</>') message carries new table OID and column
3898+
number fields for each column of the described row.
3899+
</para>
3900+
38913901
<para>
38923902
The CursorResponse ('<literal>P</>') message is no longer generated by
38933903
the backend.

src/backend/access/common/printtup.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* Portions Copyright (c) 1994, Regents of the University of California
1010
*
1111
* IDENTIFICATION
12-
* $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.66 2003/04/22 00:08:06 tgl Exp $
12+
* $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.67 2003/04/26 20:22:58 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -98,6 +98,7 @@ printtup_setup(DestReceiver *self, int operation,
9898
{
9999
Form_pg_attribute *attrs = typeinfo->attrs;
100100
int natts = typeinfo->natts;
101+
int proto = PG_PROTOCOL_MAJOR(FrontendProtocol);
101102
int i;
102103
StringInfoData buf;
103104

@@ -107,11 +108,19 @@ printtup_setup(DestReceiver *self, int operation,
107108
for (i = 0; i < natts; ++i)
108109
{
109110
pq_sendstring(&buf, NameStr(attrs[i]->attname));
111+
/* column ID info appears in protocol 3.0 and up */
112+
if (proto >= 3)
113+
{
114+
/* XXX not yet implemented, send zeroes */
115+
pq_sendint(&buf, 0, 4);
116+
pq_sendint(&buf, 0, 2);
117+
}
110118
pq_sendint(&buf, (int) attrs[i]->atttypid,
111119
sizeof(attrs[i]->atttypid));
112120
pq_sendint(&buf, attrs[i]->attlen,
113121
sizeof(attrs[i]->attlen));
114-
if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 2)
122+
/* typmod appears in protocol 2.0 and up */
123+
if (proto >= 2)
115124
pq_sendint(&buf, attrs[i]->atttypmod,
116125
sizeof(attrs[i]->atttypmod));
117126
}

src/backend/access/transam/xact.c

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.145 2003/03/27 16:51:27 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.146 2003/04/26 20:22:59 tgl Exp $
1212
*
1313
* NOTES
1414
* Transaction aborts can now occur two ways:
@@ -1705,17 +1705,44 @@ AbortOutOfAnyTransaction(void)
17051705
s->blockState = TBLOCK_DEFAULT;
17061706
}
17071707

1708+
/*
1709+
* IsTransactionBlock --- are we within a transaction block?
1710+
*/
17081711
bool
17091712
IsTransactionBlock(void)
17101713
{
17111714
TransactionState s = CurrentTransactionState;
17121715

1713-
if (s->blockState == TBLOCK_INPROGRESS
1714-
|| s->blockState == TBLOCK_ABORT
1715-
|| s->blockState == TBLOCK_ENDABORT)
1716-
return true;
1716+
if (s->blockState == TBLOCK_DEFAULT)
1717+
return false;
17171718

1718-
return false;
1719+
return true;
1720+
}
1721+
1722+
/*
1723+
* TransactionBlockStatusCode - return status code to send in ReadyForQuery
1724+
*/
1725+
char
1726+
TransactionBlockStatusCode(void)
1727+
{
1728+
TransactionState s = CurrentTransactionState;
1729+
1730+
switch (s->blockState)
1731+
{
1732+
case TBLOCK_DEFAULT:
1733+
return 'I'; /* idle --- not in transaction */
1734+
case TBLOCK_BEGIN:
1735+
case TBLOCK_INPROGRESS:
1736+
case TBLOCK_END:
1737+
return 'T'; /* in transaction */
1738+
case TBLOCK_ABORT:
1739+
case TBLOCK_ENDABORT:
1740+
return 'E'; /* in failed transaction */
1741+
}
1742+
1743+
/* should never get here */
1744+
elog(ERROR, "bogus transaction block state");
1745+
return 0; /* keep compiler quiet */
17191746
}
17201747

17211748

src/backend/tcop/dest.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/tcop/dest.c,v 1.53 2003/04/22 00:08:07 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/tcop/dest.c,v 1.54 2003/04/26 20:22:59 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -29,6 +29,7 @@
2929
#include "postgres.h"
3030

3131
#include "access/printtup.h"
32+
#include "access/xact.h"
3233
#include "executor/tstoreReceiver.h"
3334
#include "libpq/libpq.h"
3435
#include "libpq/pqformat.h"
@@ -177,6 +178,7 @@ NullCommand(CommandDest dest)
177178
*
178179
* The ReadyForQuery message is sent in protocol versions 2.0 and up
179180
* so that the FE can tell when we are done processing a query string.
181+
* In versions 3.0 and up, it also carries a transaction state indicator.
180182
*
181183
* Note that by flushing the stdio buffer here, we can avoid doing it
182184
* most other places and thus reduce the number of separate packets sent.
@@ -189,7 +191,15 @@ ReadyForQuery(CommandDest dest)
189191
{
190192
case RemoteInternal:
191193
case Remote:
192-
if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 2)
194+
if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3)
195+
{
196+
StringInfoData buf;
197+
198+
pq_beginmessage(&buf, 'Z');
199+
pq_sendbyte(&buf, TransactionBlockStatusCode());
200+
pq_endmessage(&buf);
201+
}
202+
else if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 2)
193203
pq_putemptymessage('Z');
194204
/* Flush output at end of cycle in any case. */
195205
pq_flush();

src/include/access/xact.h

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: xact.h,v 1.49 2003/01/10 22:03:30 petere Exp $
10+
* $Id: xact.h,v 1.50 2003/04/26 20:22:59 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -29,9 +29,35 @@
2929

3030
extern int DefaultXactIsoLevel;
3131
extern int XactIsoLevel;
32+
33+
/* Xact read-only state */
3234
extern bool DefaultXactReadOnly;
3335
extern bool XactReadOnly;
3436

37+
/*
38+
* transaction states - transaction state from server perspective
39+
*/
40+
typedef enum TransState
41+
{
42+
TRANS_DEFAULT,
43+
TRANS_START,
44+
TRANS_INPROGRESS,
45+
TRANS_COMMIT,
46+
TRANS_ABORT
47+
} TransState;
48+
49+
/*
50+
* transaction block states - transaction state of client queries
51+
*/
52+
typedef enum TBlockState
53+
{
54+
TBLOCK_DEFAULT,
55+
TBLOCK_BEGIN,
56+
TBLOCK_INPROGRESS,
57+
TBLOCK_END,
58+
TBLOCK_ABORT,
59+
TBLOCK_ENDABORT
60+
} TBlockState;
3561

3662
/* ----------------
3763
* transaction state structure
@@ -43,33 +69,17 @@ typedef struct TransactionStateData
4369
CommandId commandId;
4470
AbsoluteTime startTime;
4571
int startTimeUsec;
46-
int state;
47-
int blockState;
72+
TransState state;
73+
TBlockState blockState;
4874
} TransactionStateData;
4975

5076
typedef TransactionStateData *TransactionState;
5177

52-
/*
53-
* transaction states - transaction state from server perspective
54-
*
55-
* Syntax error could cause transaction to abort, but client code thinks
56-
* it is still in a transaction, so we have to wait for COMMIT/ROLLBACK.
57-
*/
58-
#define TRANS_DEFAULT 0
59-
#define TRANS_START 1
60-
#define TRANS_INPROGRESS 2
61-
#define TRANS_COMMIT 3
62-
#define TRANS_ABORT 4
6378

64-
/*
65-
* transaction block states - transaction state of client queries
79+
/* ----------------
80+
* transaction-related XLOG entries
81+
* ----------------
6682
*/
67-
#define TBLOCK_DEFAULT 0
68-
#define TBLOCK_BEGIN 1
69-
#define TBLOCK_INPROGRESS 2
70-
#define TBLOCK_END 3
71-
#define TBLOCK_ABORT 4
72-
#define TBLOCK_ENDABORT 5
7383

7484
/*
7585
* XLOG allows to store some information in high 4 bits of log
@@ -115,6 +125,7 @@ extern void AbortCurrentTransaction(void);
115125
extern void BeginTransactionBlock(void);
116126
extern void EndTransactionBlock(void);
117127
extern bool IsTransactionBlock(void);
128+
extern char TransactionBlockStatusCode(void);
118129
extern void UserAbortTransactionBlock(void);
119130
extern void AbortOutOfAnyTransaction(void);
120131
extern void PreventTransactionChain(void *stmtNode, const char *stmtType);

src/include/libpq/pqcomm.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
1010
* Portions Copyright (c) 1994, Regents of the University of California
1111
*
12-
* $Id: pqcomm.h,v 1.80 2003/04/25 19:45:09 tgl Exp $
12+
* $Id: pqcomm.h,v 1.81 2003/04/26 20:22:59 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -106,7 +106,7 @@ typedef union SockAddr
106106
/* The earliest and latest frontend/backend protocol version supported. */
107107

108108
#define PG_PROTOCOL_EARLIEST PG_PROTOCOL(1,0)
109-
#define PG_PROTOCOL_LATEST PG_PROTOCOL(3,104) /* XXX temporary value */
109+
#define PG_PROTOCOL_LATEST PG_PROTOCOL(3,105) /* XXX temporary value */
110110

111111
typedef uint32 ProtocolVersion; /* FE/BE protocol version number */
112112

src/interfaces/libpq/fe-exec.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.133 2003/04/25 19:45:09 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.134 2003/04/26 20:22:59 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1027,6 +1027,8 @@ parseInput(PGconn *conn)
10271027
conn->asyncStatus = PGASYNC_READY;
10281028
break;
10291029
case 'Z': /* backend is ready for new query */
1030+
if (pqGetc(&conn->xact_status, conn))
1031+
return;
10301032
conn->asyncStatus = PGASYNC_IDLE;
10311033
break;
10321034
case 'I': /* empty query */
@@ -1222,11 +1224,15 @@ getRowDescriptions(PGconn *conn)
12221224
/* get type info */
12231225
for (i = 0; i < nfields; i++)
12241226
{
1227+
int tableid;
1228+
int columnid;
12251229
int typid;
12261230
int typlen;
12271231
int atttypmod;
12281232

12291233
if (pqGets(&conn->workBuffer, conn) ||
1234+
pqGetInt(&tableid, 4, conn) ||
1235+
pqGetInt(&columnid, 2, conn) ||
12301236
pqGetInt(&typid, 4, conn) ||
12311237
pqGetInt(&typlen, 2, conn) ||
12321238
pqGetInt(&atttypmod, 4, conn))
@@ -1237,15 +1243,17 @@ getRowDescriptions(PGconn *conn)
12371243

12381244
/*
12391245
* Since pqGetInt treats 2-byte integers as unsigned, we need to
1240-
* coerce the result to signed form.
1246+
* coerce these results to signed form.
12411247
*/
1248+
columnid = (int) ((int16) columnid);
12421249
typlen = (int) ((int16) typlen);
12431250

12441251
result->attDescs[i].name = pqResultStrdup(result,
12451252
conn->workBuffer.data);
12461253
result->attDescs[i].typid = typid;
12471254
result->attDescs[i].typlen = typlen;
12481255
result->attDescs[i].atttypmod = atttypmod;
1256+
/* XXX todo: save tableid/columnid too */
12491257
}
12501258

12511259
/* Success! */
@@ -2289,9 +2297,10 @@ PQfn(PGconn *conn,
22892297
continue;
22902298
break;
22912299
case 'Z': /* backend is ready for new query */
2300+
if (pqGetc(&conn->xact_status, conn))
2301+
continue;
22922302
/* consume the message and exit */
22932303
conn->inStart += 5 + msgLength;
2294-
/* XXX expect additional fields here */
22952304
/* if we saved a result object (probably an error), use it */
22962305
if (conn->result)
22972306
return prepareAsyncResult(conn);

src/interfaces/libpq/libpq-int.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
1313
* Portions Copyright (c) 1994, Regents of the University of California
1414
*
15-
* $Id: libpq-int.h,v 1.65 2003/04/25 19:45:10 tgl Exp $
15+
* $Id: libpq-int.h,v 1.66 2003/04/26 20:23:00 tgl Exp $
1616
*
1717
*-------------------------------------------------------------------------
1818
*/
@@ -56,7 +56,7 @@ typedef int ssize_t; /* ssize_t doesn't exist in VC (atleast
5656
* pqcomm.h describe what the backend knows, not what libpq knows.
5757
*/
5858

59-
#define PG_PROTOCOL_LIBPQ PG_PROTOCOL(3,104) /* XXX temporary value */
59+
#define PG_PROTOCOL_LIBPQ PG_PROTOCOL(3,105) /* XXX temporary value */
6060

6161
/*
6262
* POSTGRES backend dependent Constants.
@@ -241,6 +241,7 @@ struct pg_conn
241241
/* Status indicators */
242242
ConnStatusType status;
243243
PGAsyncStatusType asyncStatus;
244+
char xact_status; /* status flag from latest ReadyForQuery */
244245
char copy_is_binary; /* 1 = copy binary, 0 = copy text */
245246
int copy_already_done; /* # bytes already returned in COPY OUT */
246247
int nonblocking; /* whether this connection is using a

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy