aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/src/sgml/protocol.sgml14
-rw-r--r--src/backend/access/common/printtup.c13
-rw-r--r--src/backend/access/transam/xact.c39
-rw-r--r--src/backend/tcop/dest.c14
-rw-r--r--src/include/access/xact.h55
-rw-r--r--src/include/libpq/pqcomm.h4
-rw-r--r--src/interfaces/libpq/fe-exec.c15
-rw-r--r--src/interfaces/libpq/libpq-int.h5
8 files changed, 118 insertions, 41 deletions
diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index 70c255f00ce..635fc7715b4 100644
--- a/doc/src/sgml/protocol.sgml
+++ b/doc/src/sgml/protocol.sgml
@@ -1,4 +1,4 @@
-<!-- $Header: /cvsroot/pgsql/doc/src/sgml/protocol.sgml,v 1.31 2003/04/25 19:45:08 tgl Exp $ -->
+<!-- $Header: /cvsroot/pgsql/doc/src/sgml/protocol.sgml,v 1.32 2003/04/26 20:22:57 tgl Exp $ -->
<chapter id="protocol">
<title>Frontend/Backend Protocol</title>
@@ -3871,13 +3871,18 @@ string sent in the older protocol always did.
</para>
<para>
+The ReadyForQuery ('<literal>Z</>') message includes a transaction status
+indicator.
+</para>
+
+<para>
COPY data is now encapsulated into CopyData and CopyDone messages. There
is a well-defined way to recover from errors during COPY. The special
<quote><literal>\.</></quote> last line is not needed anymore, and is not sent
during COPY OUT.
(It is still recognized as a terminator during COPY IN, but its use is
deprecated and will eventually be removed.) Binary COPY is supported.
-The CopyInResponse and CopyOutResponse messages carry a field indicating
+The CopyInResponse and CopyOutResponse messages include a field indicating
whether the COPY operation is text or binary.
</para>
@@ -3889,6 +3894,11 @@ changes for any of these parameters.
</para>
<para>
+The RowDescription ('<literal>T</>') message carries new table OID and column
+number fields for each column of the described row.
+</para>
+
+<para>
The CursorResponse ('<literal>P</>') message is no longer generated by
the backend.
</para>
diff --git a/src/backend/access/common/printtup.c b/src/backend/access/common/printtup.c
index c88dedd93fd..160b703223f 100644
--- a/src/backend/access/common/printtup.c
+++ b/src/backend/access/common/printtup.c
@@ -9,7 +9,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.66 2003/04/22 00:08:06 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.67 2003/04/26 20:22:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -98,6 +98,7 @@ printtup_setup(DestReceiver *self, int operation,
{
Form_pg_attribute *attrs = typeinfo->attrs;
int natts = typeinfo->natts;
+ int proto = PG_PROTOCOL_MAJOR(FrontendProtocol);
int i;
StringInfoData buf;
@@ -107,11 +108,19 @@ printtup_setup(DestReceiver *self, int operation,
for (i = 0; i < natts; ++i)
{
pq_sendstring(&buf, NameStr(attrs[i]->attname));
+ /* column ID info appears in protocol 3.0 and up */
+ if (proto >= 3)
+ {
+ /* XXX not yet implemented, send zeroes */
+ pq_sendint(&buf, 0, 4);
+ pq_sendint(&buf, 0, 2);
+ }
pq_sendint(&buf, (int) attrs[i]->atttypid,
sizeof(attrs[i]->atttypid));
pq_sendint(&buf, attrs[i]->attlen,
sizeof(attrs[i]->attlen));
- if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 2)
+ /* typmod appears in protocol 2.0 and up */
+ if (proto >= 2)
pq_sendint(&buf, attrs[i]->atttypmod,
sizeof(attrs[i]->atttypmod));
}
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index 598e3c880e5..a15985d3bd7 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.145 2003/03/27 16:51:27 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.146 2003/04/26 20:22:59 tgl Exp $
*
* NOTES
* Transaction aborts can now occur two ways:
@@ -1705,17 +1705,44 @@ AbortOutOfAnyTransaction(void)
s->blockState = TBLOCK_DEFAULT;
}
+/*
+ * IsTransactionBlock --- are we within a transaction block?
+ */
bool
IsTransactionBlock(void)
{
TransactionState s = CurrentTransactionState;
- if (s->blockState == TBLOCK_INPROGRESS
- || s->blockState == TBLOCK_ABORT
- || s->blockState == TBLOCK_ENDABORT)
- return true;
+ if (s->blockState == TBLOCK_DEFAULT)
+ return false;
- return false;
+ return true;
+}
+
+/*
+ * TransactionBlockStatusCode - return status code to send in ReadyForQuery
+ */
+char
+TransactionBlockStatusCode(void)
+{
+ TransactionState s = CurrentTransactionState;
+
+ switch (s->blockState)
+ {
+ case TBLOCK_DEFAULT:
+ return 'I'; /* idle --- not in transaction */
+ case TBLOCK_BEGIN:
+ case TBLOCK_INPROGRESS:
+ case TBLOCK_END:
+ return 'T'; /* in transaction */
+ case TBLOCK_ABORT:
+ case TBLOCK_ENDABORT:
+ return 'E'; /* in failed transaction */
+ }
+
+ /* should never get here */
+ elog(ERROR, "bogus transaction block state");
+ return 0; /* keep compiler quiet */
}
diff --git a/src/backend/tcop/dest.c b/src/backend/tcop/dest.c
index 5ccaa60995c..41906a348a4 100644
--- a/src/backend/tcop/dest.c
+++ b/src/backend/tcop/dest.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/tcop/dest.c,v 1.53 2003/04/22 00:08:07 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/tcop/dest.c,v 1.54 2003/04/26 20:22:59 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -29,6 +29,7 @@
#include "postgres.h"
#include "access/printtup.h"
+#include "access/xact.h"
#include "executor/tstoreReceiver.h"
#include "libpq/libpq.h"
#include "libpq/pqformat.h"
@@ -177,6 +178,7 @@ NullCommand(CommandDest dest)
*
* The ReadyForQuery message is sent in protocol versions 2.0 and up
* so that the FE can tell when we are done processing a query string.
+ * In versions 3.0 and up, it also carries a transaction state indicator.
*
* Note that by flushing the stdio buffer here, we can avoid doing it
* most other places and thus reduce the number of separate packets sent.
@@ -189,7 +191,15 @@ ReadyForQuery(CommandDest dest)
{
case RemoteInternal:
case Remote:
- if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 2)
+ if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3)
+ {
+ StringInfoData buf;
+
+ pq_beginmessage(&buf, 'Z');
+ pq_sendbyte(&buf, TransactionBlockStatusCode());
+ pq_endmessage(&buf);
+ }
+ else if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 2)
pq_putemptymessage('Z');
/* Flush output at end of cycle in any case. */
pq_flush();
diff --git a/src/include/access/xact.h b/src/include/access/xact.h
index b3938c869e1..5525ce74457 100644
--- a/src/include/access/xact.h
+++ b/src/include/access/xact.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: xact.h,v 1.49 2003/01/10 22:03:30 petere Exp $
+ * $Id: xact.h,v 1.50 2003/04/26 20:22:59 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -29,9 +29,35 @@
extern int DefaultXactIsoLevel;
extern int XactIsoLevel;
+
+/* Xact read-only state */
extern bool DefaultXactReadOnly;
extern bool XactReadOnly;
+/*
+ * transaction states - transaction state from server perspective
+ */
+typedef enum TransState
+{
+ TRANS_DEFAULT,
+ TRANS_START,
+ TRANS_INPROGRESS,
+ TRANS_COMMIT,
+ TRANS_ABORT
+} TransState;
+
+/*
+ * transaction block states - transaction state of client queries
+ */
+typedef enum TBlockState
+{
+ TBLOCK_DEFAULT,
+ TBLOCK_BEGIN,
+ TBLOCK_INPROGRESS,
+ TBLOCK_END,
+ TBLOCK_ABORT,
+ TBLOCK_ENDABORT
+} TBlockState;
/* ----------------
* transaction state structure
@@ -43,33 +69,17 @@ typedef struct TransactionStateData
CommandId commandId;
AbsoluteTime startTime;
int startTimeUsec;
- int state;
- int blockState;
+ TransState state;
+ TBlockState blockState;
} TransactionStateData;
typedef TransactionStateData *TransactionState;
-/*
- * transaction states - transaction state from server perspective
- *
- * Syntax error could cause transaction to abort, but client code thinks
- * it is still in a transaction, so we have to wait for COMMIT/ROLLBACK.
- */
-#define TRANS_DEFAULT 0
-#define TRANS_START 1
-#define TRANS_INPROGRESS 2
-#define TRANS_COMMIT 3
-#define TRANS_ABORT 4
-/*
- * transaction block states - transaction state of client queries
+/* ----------------
+ * transaction-related XLOG entries
+ * ----------------
*/
-#define TBLOCK_DEFAULT 0
-#define TBLOCK_BEGIN 1
-#define TBLOCK_INPROGRESS 2
-#define TBLOCK_END 3
-#define TBLOCK_ABORT 4
-#define TBLOCK_ENDABORT 5
/*
* XLOG allows to store some information in high 4 bits of log
@@ -115,6 +125,7 @@ extern void AbortCurrentTransaction(void);
extern void BeginTransactionBlock(void);
extern void EndTransactionBlock(void);
extern bool IsTransactionBlock(void);
+extern char TransactionBlockStatusCode(void);
extern void UserAbortTransactionBlock(void);
extern void AbortOutOfAnyTransaction(void);
extern void PreventTransactionChain(void *stmtNode, const char *stmtType);
diff --git a/src/include/libpq/pqcomm.h b/src/include/libpq/pqcomm.h
index 6a871c7c6f6..d5374a68fe6 100644
--- a/src/include/libpq/pqcomm.h
+++ b/src/include/libpq/pqcomm.h
@@ -9,7 +9,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: pqcomm.h,v 1.80 2003/04/25 19:45:09 tgl Exp $
+ * $Id: pqcomm.h,v 1.81 2003/04/26 20:22:59 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -106,7 +106,7 @@ typedef union SockAddr
/* The earliest and latest frontend/backend protocol version supported. */
#define PG_PROTOCOL_EARLIEST PG_PROTOCOL(1,0)
-#define PG_PROTOCOL_LATEST PG_PROTOCOL(3,104) /* XXX temporary value */
+#define PG_PROTOCOL_LATEST PG_PROTOCOL(3,105) /* XXX temporary value */
typedef uint32 ProtocolVersion; /* FE/BE protocol version number */
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 53c4e288622..db513d64ef5 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.133 2003/04/25 19:45:09 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.134 2003/04/26 20:22:59 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1027,6 +1027,8 @@ parseInput(PGconn *conn)
conn->asyncStatus = PGASYNC_READY;
break;
case 'Z': /* backend is ready for new query */
+ if (pqGetc(&conn->xact_status, conn))
+ return;
conn->asyncStatus = PGASYNC_IDLE;
break;
case 'I': /* empty query */
@@ -1222,11 +1224,15 @@ getRowDescriptions(PGconn *conn)
/* get type info */
for (i = 0; i < nfields; i++)
{
+ int tableid;
+ int columnid;
int typid;
int typlen;
int atttypmod;
if (pqGets(&conn->workBuffer, conn) ||
+ pqGetInt(&tableid, 4, conn) ||
+ pqGetInt(&columnid, 2, conn) ||
pqGetInt(&typid, 4, conn) ||
pqGetInt(&typlen, 2, conn) ||
pqGetInt(&atttypmod, 4, conn))
@@ -1237,8 +1243,9 @@ getRowDescriptions(PGconn *conn)
/*
* Since pqGetInt treats 2-byte integers as unsigned, we need to
- * coerce the result to signed form.
+ * coerce these results to signed form.
*/
+ columnid = (int) ((int16) columnid);
typlen = (int) ((int16) typlen);
result->attDescs[i].name = pqResultStrdup(result,
@@ -1246,6 +1253,7 @@ getRowDescriptions(PGconn *conn)
result->attDescs[i].typid = typid;
result->attDescs[i].typlen = typlen;
result->attDescs[i].atttypmod = atttypmod;
+ /* XXX todo: save tableid/columnid too */
}
/* Success! */
@@ -2289,9 +2297,10 @@ PQfn(PGconn *conn,
continue;
break;
case 'Z': /* backend is ready for new query */
+ if (pqGetc(&conn->xact_status, conn))
+ continue;
/* consume the message and exit */
conn->inStart += 5 + msgLength;
- /* XXX expect additional fields here */
/* if we saved a result object (probably an error), use it */
if (conn->result)
return prepareAsyncResult(conn);
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index 12670f3a0a4..a5e6bceef42 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -12,7 +12,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: libpq-int.h,v 1.65 2003/04/25 19:45:10 tgl Exp $
+ * $Id: libpq-int.h,v 1.66 2003/04/26 20:23:00 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -56,7 +56,7 @@ typedef int ssize_t; /* ssize_t doesn't exist in VC (atleast
* pqcomm.h describe what the backend knows, not what libpq knows.
*/
-#define PG_PROTOCOL_LIBPQ PG_PROTOCOL(3,104) /* XXX temporary value */
+#define PG_PROTOCOL_LIBPQ PG_PROTOCOL(3,105) /* XXX temporary value */
/*
* POSTGRES backend dependent Constants.
@@ -241,6 +241,7 @@ struct pg_conn
/* Status indicators */
ConnStatusType status;
PGAsyncStatusType asyncStatus;
+ char xact_status; /* status flag from latest ReadyForQuery */
char copy_is_binary; /* 1 = copy binary, 0 = copy text */
int copy_already_done; /* # bytes already returned in COPY OUT */
int nonblocking; /* whether this connection is using a