This is just the fix for hstore's silent truncation, including doc patch and regression test. Actual new functionality will follow later in another patch.
-- Andrew.
Index: contrib/hstore/hstore.h =================================================================== RCS file: /projects/cvsroot/pgsql/contrib/hstore/hstore.h,v retrieving revision 1.6 diff -c -r1.6 hstore.h *** contrib/hstore/hstore.h 12 May 2008 00:00:42 -0000 1.6 --- contrib/hstore/hstore.h 14 Mar 2009 19:48:24 -0000 *************** *** 16,21 **** --- 16,23 ---- pos:31; } HEntry; + #define HSTORE_MAX_KEY 65535 + #define HSTORE_MAX_VALUE 65535 typedef struct { *************** *** 45,50 **** --- 47,55 ---- int comparePairs(const void *a, const void *b); int uniquePairs(Pairs * a, int4 l, int4 *buflen); + uint16 hstoreCheckKeyLen(size_t len); + uint16 hstoreCheckValLen(size_t len); + #define HStoreContainsStrategyNumber 7 #define HStoreExistsStrategyNumber 9 Index: contrib/hstore/hstore_io.c =================================================================== RCS file: /projects/cvsroot/pgsql/contrib/hstore/hstore_io.c,v retrieving revision 1.8 diff -c -r1.8 hstore_io.c *** contrib/hstore/hstore_io.c 12 May 2008 00:00:42 -0000 1.8 --- contrib/hstore/hstore_io.c 14 Mar 2009 19:48:25 -0000 *************** *** 9,14 **** --- 9,36 ---- PG_MODULE_MAGIC; + + uint16 + hstoreCheckKeyLen(size_t len) + { + if (len > HSTORE_MAX_KEY) + ereport(ERROR, + (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION), + errmsg("string too long for hstore key"))); + return len; + } + + uint16 + hstoreCheckValLen(size_t len) + { + if (len > HSTORE_MAX_VALUE) + ereport(ERROR, + (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION), + errmsg("string too long for hstore value"))); + return len; + } + + typedef struct { char *begin; *************** *** 188,194 **** state->pairs = (Pairs *) repalloc(state->pairs, sizeof(Pairs) * state->plen); } state->pairs[state->pcur].key = state->word; ! state->pairs[state->pcur].keylen = state->cur - state->word; state->pairs[state->pcur].val = NULL; state->word = NULL; st = WEQ; --- 210,216 ---- state->pairs = (Pairs *) repalloc(state->pairs, sizeof(Pairs) * state->plen); } state->pairs[state->pcur].key = state->word; ! state->pairs[state->pcur].keylen = hstoreCheckKeyLen(state->cur - state->word); state->pairs[state->pcur].val = NULL; state->word = NULL; st = WEQ; *************** *** 228,234 **** if (!get_val(state, true, &escaped)) elog(ERROR, "Unexpected end of string"); state->pairs[state->pcur].val = state->word; ! state->pairs[state->pcur].vallen = state->cur - state->word; state->pairs[state->pcur].isnull = false; state->pairs[state->pcur].needfree = true; if (state->cur - state->word == 4 && !escaped) --- 250,256 ---- if (!get_val(state, true, &escaped)) elog(ERROR, "Unexpected end of string"); state->pairs[state->pcur].val = state->word; ! state->pairs[state->pcur].vallen = hstoreCheckValLen(state->cur - state->word); state->pairs[state->pcur].isnull = false; state->pairs[state->pcur].needfree = true; if (state->cur - state->word == 4 && !escaped) Index: contrib/hstore/hstore_op.c =================================================================== RCS file: /projects/cvsroot/pgsql/contrib/hstore/hstore_op.c,v retrieving revision 1.11 diff -c -r1.11 hstore_op.c *** contrib/hstore/hstore_op.c 2 Nov 2008 01:45:26 -0000 1.11 --- contrib/hstore/hstore_op.c 14 Mar 2009 19:48:25 -0000 *************** *** 295,301 **** SET_VARSIZE(out, len); out->size = 1; ! ARRPTR(out)->keylen = VARSIZE(key) - VARHDRSZ; if (PG_ARGISNULL(1)) { ARRPTR(out)->vallen = 0; --- 295,301 ---- SET_VARSIZE(out, len); out->size = 1; ! ARRPTR(out)->keylen = hstoreCheckKeyLen(VARSIZE(key) - VARHDRSZ); if (PG_ARGISNULL(1)) { ARRPTR(out)->vallen = 0; *************** *** 303,309 **** } else { ! ARRPTR(out)->vallen = VARSIZE(val) - VARHDRSZ; ARRPTR(out)->valisnull = false; } ARRPTR(out)->pos = 0; --- 303,309 ---- } else { ! ARRPTR(out)->vallen = hstoreCheckValLen(VARSIZE(val) - VARHDRSZ); ARRPTR(out)->valisnull = false; } ARRPTR(out)->pos = 0; Index: contrib/hstore/expected/hstore.out =================================================================== RCS file: /projects/cvsroot/pgsql/contrib/hstore/expected/hstore.out,v retrieving revision 1.4 diff -c -r1.4 hstore.out *** contrib/hstore/expected/hstore.out 14 Mar 2007 14:21:53 -0000 1.4 --- contrib/hstore/expected/hstore.out 14 Mar 2009 19:48:26 -0000 *************** *** 241,246 **** --- 241,254 ---- (1 row) + select hstore_in(textout('a=>' || repeat('a',65537))); + ERROR: string too long for hstore value + select hstore_in(textout(repeat('a',65537) || '=>a')); + ERROR: string too long for hstore key + select repeat('a',65537) => 'a'; + ERROR: string too long for hstore key + select 'a' => repeat('a',65537); + ERROR: string too long for hstore value -- -> operator select 'aa=>b, c=>d , b=>16'::hstore->'c'; ?column? Index: contrib/hstore/sql/hstore.sql =================================================================== RCS file: /projects/cvsroot/pgsql/contrib/hstore/sql/hstore.sql,v retrieving revision 1.4 diff -c -r1.4 hstore.sql *** contrib/hstore/sql/hstore.sql 14 Mar 2007 14:21:53 -0000 1.4 --- contrib/hstore/sql/hstore.sql 14 Mar 2009 19:48:26 -0000 *************** *** 56,61 **** --- 56,67 ---- select ''::hstore; select ' '::hstore; + select hstore_in(textout('a=>' || repeat('a',65537))); + select hstore_in(textout(repeat('a',65537) || '=>a')); + + select repeat('a',65537) => 'a'; + select 'a' => repeat('a',65537); + -- -> operator select 'aa=>b, c=>d , b=>16'::hstore->'c'; Index: doc/src/sgml/hstore.sgml =================================================================== RCS file: /projects/cvsroot/pgsql/doc/src/sgml/hstore.sgml,v retrieving revision 1.2 diff -c -r1.2 hstore.sgml *** doc/src/sgml/hstore.sgml 6 Dec 2007 04:12:10 -0000 1.2 --- doc/src/sgml/hstore.sgml 14 Mar 2009 19:48:27 -0000 *************** *** 14,19 **** --- 14,25 ---- that are rarely examined, or semi-structured data. </para> + <para> + Note that in the current implementation, neither the key nor the value + strings can exceed 65535 bytes in length; an error will be thrown if this + limit is exceeded. The maximum length may change in future releases. + </para> + <sect2> <title><type>hstore</> External Representation</title>
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers