Module: sip-router Branch: janakj/postgres Commit: e698c560e636d1fe2eb8b0b26909ffc29f2f2a82 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=e698c560...
Author: Maxim Sobolev sobomax@sippysoft.com Committer: Maxim Sobolev sobomax@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 {