postgres 9.0 beta libpq empty binary array error

From: <vshahov(at)alliedtesting(dot)com>
To: <pgsql-bugs(at)postgresql(dot)org>
Cc: <pgagarinov(at)alliedtesting(dot)com>, <depstein(at)alliedtesting(dot)com>
Subject: postgres 9.0 beta libpq empty binary array error
Date: 2010-08-09 14:43:12
Message-ID: ACD5CA75ACCCFA4599E033DD674453037AE5AADD6D@mail2a.alliedtesting.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

Hi,

I'm using libpq PQexecParams ability to send query parameters as binary data,
more specific - a binary representation of an empty array.

I have the problem:
the code sending empty binary array works on 8.3 and 8.4
but stopped working on postgres 9.0 beta2/3/4, it fails with '22003','integer out of range error'.

Here is the test code:

char *command="INSERT INTO test.arraytypes(nullarr) VALUES($1)";
// ndims hassnull typeid ((dim+lbound)*ndims)
const int empty_array_length = 4 + 4 + 4 + (8*1);

// constructing empty array representation:
char * buf = (char *)malloc(empty_array_length);
memset(buf,0,empty_array_length);
char * out = buf;
// ndims
*((int*)out) = htonl(1);
out+=4;
// hassnull
*((int*)out) = 0;
out+=4;
// typeid 'int4'
*((int*)out) = htonl(23);
out+=4;

const Oid oids[] = {1007};// _int4 oid
const int paramFormats[]={1};
const int lens[] = {empty_array_length};
const char * const * vals = {&buf};
PGresult* re = PQexecParams(conn, command, 1, oids,
(const char *const * ) vals, lens, paramFormats, 1);

char *err1=PQresultErrorMessage(re); // ERROR: integer out of range for 9.0 beta

// sql creation code:
//CREATE TABLE test.arraytypes( nullarr int[])

I've traced the error down to array_recv function, and found this overflow check to be offending.
/src/backend/utils/adt/arrayfuncs.c: Line 1214

for (i = 0; i < ndim; i++)
{
int ub;
dim[i] = pq_getmsgint(buf, 4);
lBound[i] = pq_getmsgint(buf, 4);
ub = lBound[i] + dim[i] - 1;

/* overflow? */
if (lBound[i] > ub)
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("integer out of range")));
}

In the empty array case, the ndim==1, and dim[0]==0, so lBound[0] > ub[0]

Seems that the overflow check was introduced fairly recently, here is the discussion of it:
http://archives.postgresql.org/pgsql-hackers/2009-08/msg02073.php

The array with dim[i] = 0 seems legitimate, since this situation is handled by the code below:
if (nitems == 0)
{
/* Return empty array ... but not till we've validated element_type */
PG_RETURN_ARRAYTYPE_P(construct_empty_array(element_type));
}

So, is it really a bug in 9.0? Or maybe the array representation rules changed somehow?

Vladimir Shakhov | Developer
www.alliedtesting.com

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Tom Lane 2010-08-09 14:56:15 Re: postgres 9.0 beta libpq empty binary array error
Previous Message Heikki Linnakangas 2010-08-09 11:42:45 Assertion failure with assignment to array elem