[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