[SR-Dev] git:janakj/postgres: Pass parmeter types to PQexecParams() explicitly, otherwise PostgreSQL

Jan Janak jan at iptel.org
Sun Feb 15 18:55:27 CET 2009


Module: sip-router
Branch: janakj/postgres
Commit: e698c560e636d1fe2eb8b0b26909ffc29f2f2a82
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=e698c560e636d1fe2eb8b0b26909ffc29f2f2a82

Author: Maxim Sobolev <sobomax at sippysoft.com>
Committer: Maxim Sobolev <sobomax at sippysoft.com>
Date:   Wed Jun  6 01:09:34 2007 +0000

Pass parmeter types to PQexecParams() explicitly, otherwise PostgreSQL
will be guessing them based on field type and in the case of mismatch
may bail with cryptic error message:

"ERROR: dbase.c:783: Error: ERROR:  insufficient data left in message"

Particularly, this happens easily with integers - SER is packing 4 bytes,
while PG expects 8 bytes.

Sponsored by:	Sippy Software, Inc. ( http://www.sippysoft.com/ )

---

 modules/db_postgres/dbase.c |   13 ++++++++++++-
 1 files changed, 12 insertions(+), 1 deletions(-)

diff --git a/modules/db_postgres/dbase.c b/modules/db_postgres/dbase.c
index 718d770..4cb5216 100644
--- a/modules/db_postgres/dbase.c
+++ b/modules/db_postgres/dbase.c
@@ -68,6 +68,7 @@ struct pg_params {
 	const char** data;
 	int* len;
 	int* formats;
+	Oid* types;
 };
 
 
@@ -77,6 +78,7 @@ static void free_pg_params(struct pg_params* ptr)
 	if (ptr->data) pkg_free(ptr->data);
 	if (ptr->len) pkg_free(ptr->len);
 	if (ptr->formats) pkg_free(ptr->formats);
+	if (ptr->types) pkg_free(ptr->types);
 	pkg_free(ptr);
 }
 
@@ -96,9 +98,13 @@ static struct pg_params* new_pg_params(int n)
 
 	ptr->len = (int*)pkg_malloc(sizeof(int) * n);
 	if (!ptr->len) goto error;
+
+	ptr->types = (int*)pkg_malloc(sizeof(Oid) * n);
+	if (!ptr->types) goto error;
 	
 	memset((char*)ptr->data, 0, sizeof(const char*) * n);
 	memset(ptr->len, 0, sizeof(int) * n);
+	memset(ptr->types, 0, sizeof(Oid) * n);
 	ptr->n = n;
 	ptr->cur = 0;
 	return ptr;
@@ -141,6 +147,7 @@ static inline int params_add(struct pg_params* p, db_con_t* con, db_val_t* vals,
 			val->val.int_val = ntohl(val->val.int_val);
 			p->data[p->cur] = (const char*)&val->val.int_val;
 			p->len[p->cur] = 4;
+			p->types[p->cur] = INT4OID;
 			break;
 
 		case DB_FLOAT:
@@ -150,6 +157,7 @@ static inline int params_add(struct pg_params* p, db_con_t* con, db_val_t* vals,
 			val->val.int_val = htonl(val->val.int_val);
 			p->data[p->cur] = (const char*)&val->val.int_val;
 			p->len[p->cur] = 4;
+			p->types[p->cur] = FLOAT4OID;
 			break;
 			
 		case DB_DOUBLE:
@@ -162,6 +170,7 @@ static inline int params_add(struct pg_params* p, db_con_t* con, db_val_t* vals,
 			(&val->val.int_val)[1] = i2;
 			p->data[p->cur] = (const char*)&val->val.int_val;
 			p->len[p->cur] = 8;
+			p->types[p->cur] = FLOAT8OID;
 			break;
 			
 		case DB_STRING:
@@ -187,6 +196,7 @@ static inline int params_add(struct pg_params* p, db_con_t* con, db_val_t* vals,
 			(&val->val.int_val)[1] = i2;
 			p->data[p->cur] = (const char*)&val->val.int_val;
 			p->len[p->cur] = 8;
+			p->types[p->cur] = TIMESTAMPOID;
 			break;
 			
 		case DB_BLOB:
@@ -199,6 +209,7 @@ static inline int params_add(struct pg_params* p, db_con_t* con, db_val_t* vals,
 			val->val.int_val = htonl(32);
 			p->data[p->cur] = (const char*)&val->val.int_val;
 			p->len[p->cur] = 8;
+			p->types[p->cur] = BITOID;
 			break;
 		}
 		
@@ -756,7 +767,7 @@ static int submit_query(db_res_t** res, db_con_t* con, const char* query, struct
 	DBG("Executing '%s'\n", query);
 	if (params && params->cur) {
 	        pgres = PQexecParams(CON_CONNECTION(con), query,
-				     params->cur, 0,
+				     params->cur, params->types,
 				     params->data, params->len,
 				     params->formats, 1);
 	} else {




More information about the sr-dev mailing list