Improved PShandleRowData function

v2.x_pg_PrepStmtBase_240714
Rahim Kanji 2 years ago
parent 2bc6c8ad0a
commit ed6aedd7d9

@ -12,8 +12,52 @@ index 2265ab5..56883ec 100644
+ return psHandleRowData(conn, result);
+}
+
diff --git src/interfaces/libpq/fe-misc.c src/interfaces/libpq/fe-misc.c
index 488f7d6..65beb87 100644
--- src/interfaces/libpq/fe-misc.c
+++ src/interfaces/libpq/fe-misc.c
@@ -1344,3 +1344,39 @@ libpq_append_conn_error(PGconn *conn, const char *fmt,...)
appendPQExpBufferChar(&conn->errorMessage, '\n');
}
+
+/*
+ * psGetInt16
+ * read 2 byte integer and convert from network byte order
+ * to local byte order
+ */
+int
+psGetInt16(int *result, PGconn *conn)
+{
+ uint16 tmp2;
+
+ if (conn->inCursor + 2 > conn->inEnd)
+ return EOF;
+ memcpy(&tmp2, conn->inBuffer + conn->inCursor, 2);
+ conn->inCursor += 2;
+ *result = (int) pg_ntoh16(tmp2);
+ return 0;
+}
+
+/*
+ * psGetInt32
+ * read 4 byte integer and convert from network byte order
+ * to local byte order
+ */
+int
+psGetInt32(int *result, PGconn *conn)
+{
+ uint32 tmp4;
+
+ if (conn->inCursor + 4 > conn->inEnd)
+ return EOF;
+ memcpy(&tmp4, conn->inBuffer + conn->inCursor, 4);
+ conn->inCursor += 4;
+ *result = (int) pg_ntoh32(tmp4);
+ return 0;
+}
diff --git src/interfaces/libpq/fe-protocol3.c src/interfaces/libpq/fe-protocol3.c
index 9c4aa7e..eb08983 100644
index 9c4aa7e..de0746c 100644
--- src/interfaces/libpq/fe-protocol3.c
+++ src/interfaces/libpq/fe-protocol3.c
@@ -2299,3 +2299,102 @@ build_startup_packet(const PGconn *conn, char *packet,
@ -40,6 +84,8 @@ index 9c4aa7e..eb08983 100644
+ int msgLength;
+ int avail;
+
+ if (conn->asyncStatus != PGASYNC_BUSY)
+ return 1;
+ /*
+ * Try to read a message. First get the type code and length. Return
+ * if not enough data.
@ -47,7 +93,11 @@ index 9c4aa7e..eb08983 100644
+ conn->inCursor = conn->inStart;
+ if (pqGetc(&id, conn))
+ return EOF;
+ if (pqGetInt(&msgLength, 4, conn))
+
+ if (id != 'D')
+ return 1;
+
+ if (psGetInt32(&msgLength, conn))
+ return EOF;
+
+ /*
@ -69,52 +119,46 @@ index 9c4aa7e..eb08983 100644
+ if (avail < msgLength)
+ return EOF;
+
+ if (conn->asyncStatus != PGASYNC_BUSY)
+ return 1;
+ if (conn->result != NULL &&
+ conn->result->resultStatus == PGRES_TUPLES_OK)
+ {
+ PGresult *res = conn->result;
+ int nfields = res->numAttributes;
+ int tupnfields; /* # fields from tuple */
+ int vlen; /* length of the current field value */
+ int i;
+
+ if (id == 'D')
+ {
+ if (conn->result != NULL &&
+ conn->result->resultStatus == PGRES_TUPLES_OK)
+ {
+ PGresult *res = conn->result;
+ int nfields = res->numAttributes;
+ int tupnfields; /* # fields from tuple */
+ int vlen; /* length of the current field value */
+ int i;
+
+ /* Get the field count and make sure it's what we expect */
+ if (psGetInt16(&tupnfields, conn))
+ return 1;
+
+ /* Get the field count and make sure it's what we expect */
+ if (pqGetInt(&tupnfields, 2, conn))
+ return 1;
+ if (tupnfields != nfields)
+ return 1;
+
+ if (tupnfields != nfields)
+ /* Scan the fields */
+ for (i = 0; i < nfields; i++)
+ {
+ /* get the value length */
+ if (psGetInt32(&vlen, conn))
+ return 1;
+
+ /* Scan the fields */
+ for (i = 0; i < nfields; i++)
+ /* Skip over the data value */
+ if (vlen > 0)
+ {
+ /* get the value length */
+ if (pqGetInt(&vlen, 4, conn))
+ if (pqSkipnchar(vlen, conn))
+ return 1;
+
+ /* Skip over the data value */
+ if (vlen > 0)
+ {
+ if (pqSkipnchar(vlen, conn))
+ return 1;
+ }
+ }
+
+ result->id = 'D';
+ result->len = msgLength + 5;
+ result->data = conn->inBuffer + conn->inStart;
+ conn->asyncStatus = PGASYNC_BUSY;
+ /* trust the specified message length as what to skip */
+ conn->inStart += 5 + msgLength;
+ conn->inCursor = conn->inStart;
+ return 0;
+ }
+
+ result->id = 'D';
+ result->len = msgLength + 5;
+ result->data = conn->inBuffer + conn->inStart;
+ conn->asyncStatus = PGASYNC_BUSY;
+ /* trust the specified message length as what to skip */
+ conn->inStart += 5 + msgLength;
+ conn->inCursor = conn->inStart;
+ return 0;
+ }
+ return 1;
+}
@ -153,15 +197,32 @@ index c5170d1..3e3cc34 100644
}
#endif
diff --git src/interfaces/libpq/libpq-int.h src/interfaces/libpq/libpq-int.h
index a951f49..210fbc9 100644
index a951f49..e1df8b5 100644
--- src/interfaces/libpq/libpq-int.h
+++ src/interfaces/libpq/libpq-int.h
@@ -755,7 +755,7 @@ extern int pqWaitTimed(int forRead, int forWrite, PGconn *conn,
time_t finish_time);
@@ -727,6 +727,11 @@ extern PGresult *pqFunctionCall3(PGconn *conn, Oid fnid,
int result_is_int,
const PQArgBlock *args, int nargs);
+ /*
+ * ProxySQL light weight routines
+ */
+extern int psHandleRowData(PGconn *conn, PSresult* result);
+
/* === in fe-misc.c === */
/*
@@ -756,6 +761,13 @@ extern int pqWaitTimed(int forRead, int forWrite, PGconn *conn,
extern int pqReadReady(PGconn *conn);
extern int pqWriteReady(PGconn *conn);
-
+extern int psHandleRowData(PGconn *conn, PSresult* result);
+ /*
+ * ProxySQL light weight routines
+ */
+extern int psGetInt16(int *result, PGconn *conn);
+extern int psGetInt32(int *result, PGconn *conn);
+
+
/* === in fe-secure.c === */
extern int pqsecure_initialize(PGconn *, bool, bool);

Loading…
Cancel
Save