Fix varatt versus Datum type confusions

Macros like VARDATA() and VARSIZE() should be thought of as taking
values of type pointer to struct varlena or some other related struct.
The way they are implemented, you can pass anything to it and it will
cast it right.  But this is in principle incorrect.  To fix, add the
required DatumGetPointer() calls.  Or in a couple of cases, remove
superfluous PointerGetDatum() calls.

It is planned in a subsequent patch to change macros like VARDATA()
and VARSIZE() to inline functions, which will enforce stricter typing.
This is in preparation for that.

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://www.postgresql.org/message-id/flat/928ea48f-77c6-417b-897c-621ef16685a6%40eisentraut.org
pull/239/head
Peter Eisentraut 1 month ago
parent 2ad6e80de9
commit 0f5ade7a36
  1. 2
      contrib/hstore/hstore_gin.c
  2. 4
      contrib/hstore/hstore_gist.c
  3. 24
      contrib/hstore/hstore_io.c
  4. 4
      contrib/hstore/hstore_op.c
  5. 2
      contrib/test_decoding/test_decoding.c
  6. 2
      src/backend/access/brin/brin_minmax_multi.c
  7. 4
      src/backend/access/common/heaptuple.c
  8. 8
      src/backend/access/common/reloptions.c
  9. 2
      src/backend/access/common/toast_internals.c
  10. 2
      src/backend/access/gin/gininsert.c
  11. 4
      src/backend/access/spgist/spgutils.c
  12. 2
      src/backend/access/table/toast_helper.c
  13. 2
      src/backend/replication/logical/proto.c
  14. 4
      src/backend/replication/pgoutput/pgoutput.c
  15. 2
      src/backend/statistics/mcv.c
  16. 2
      src/backend/tsearch/ts_selfuncs.c
  17. 4
      src/backend/utils/adt/jsonb_gin.c
  18. 8
      src/backend/utils/adt/jsonb_op.c
  19. 4
      src/backend/utils/adt/jsonfuncs.c
  20. 4
      src/backend/utils/adt/jsonpath_exec.c
  21. 7
      src/backend/utils/adt/multirangetypes.c
  22. 6
      src/backend/utils/adt/rangetypes.c
  23. 24
      src/backend/utils/adt/tsvector_op.c

@ -127,7 +127,7 @@ gin_extract_hstore_query(PG_FUNCTION_ARGS)
/* Nulls in the array are ignored, cf hstoreArrayToPairs */ /* Nulls in the array are ignored, cf hstoreArrayToPairs */
if (key_nulls[i]) if (key_nulls[i])
continue; continue;
item = makeitem(VARDATA(key_datums[i]), VARSIZE(key_datums[i]) - VARHDRSZ, KEYFLAG); item = makeitem(VARDATA(DatumGetPointer(key_datums[i])), VARSIZE(DatumGetPointer(key_datums[i])) - VARHDRSZ, KEYFLAG);
entries[j++] = PointerGetDatum(item); entries[j++] = PointerGetDatum(item);
} }

@ -576,7 +576,7 @@ ghstore_consistent(PG_FUNCTION_ARGS)
if (key_nulls[i]) if (key_nulls[i])
continue; continue;
crc = crc32_sz(VARDATA(key_datums[i]), VARSIZE(key_datums[i]) - VARHDRSZ); crc = crc32_sz(VARDATA(DatumGetPointer(key_datums[i])), VARSIZE(DatumGetPointer(key_datums[i])) - VARHDRSZ);
if (!(GETBIT(sign, HASHVAL(crc, siglen)))) if (!(GETBIT(sign, HASHVAL(crc, siglen))))
res = false; res = false;
} }
@ -599,7 +599,7 @@ ghstore_consistent(PG_FUNCTION_ARGS)
if (key_nulls[i]) if (key_nulls[i])
continue; continue;
crc = crc32_sz(VARDATA(key_datums[i]), VARSIZE(key_datums[i]) - VARHDRSZ); crc = crc32_sz(VARDATA(DatumGetPointer(key_datums[i])), VARSIZE(DatumGetPointer(key_datums[i])) - VARHDRSZ);
if (GETBIT(sign, HASHVAL(crc, siglen))) if (GETBIT(sign, HASHVAL(crc, siglen)))
res = true; res = true;
} }

@ -684,22 +684,22 @@ hstore_from_arrays(PG_FUNCTION_ARGS)
if (!value_nulls || value_nulls[i]) if (!value_nulls || value_nulls[i])
{ {
pairs[i].key = VARDATA(key_datums[i]); pairs[i].key = VARDATA(DatumGetPointer(key_datums[i]));
pairs[i].val = NULL; pairs[i].val = NULL;
pairs[i].keylen = pairs[i].keylen =
hstoreCheckKeyLen(VARSIZE(key_datums[i]) - VARHDRSZ); hstoreCheckKeyLen(VARSIZE(DatumGetPointer(key_datums[i])) - VARHDRSZ);
pairs[i].vallen = 4; pairs[i].vallen = 4;
pairs[i].isnull = true; pairs[i].isnull = true;
pairs[i].needfree = false; pairs[i].needfree = false;
} }
else else
{ {
pairs[i].key = VARDATA(key_datums[i]); pairs[i].key = VARDATA(DatumGetPointer(key_datums[i]));
pairs[i].val = VARDATA(value_datums[i]); pairs[i].val = VARDATA(DatumGetPointer(value_datums[i]));
pairs[i].keylen = pairs[i].keylen =
hstoreCheckKeyLen(VARSIZE(key_datums[i]) - VARHDRSZ); hstoreCheckKeyLen(VARSIZE(DatumGetPointer(key_datums[i])) - VARHDRSZ);
pairs[i].vallen = pairs[i].vallen =
hstoreCheckValLen(VARSIZE(value_datums[i]) - VARHDRSZ); hstoreCheckValLen(VARSIZE(DatumGetPointer(value_datums[i])) - VARHDRSZ);
pairs[i].isnull = false; pairs[i].isnull = false;
pairs[i].needfree = false; pairs[i].needfree = false;
} }
@ -778,22 +778,22 @@ hstore_from_array(PG_FUNCTION_ARGS)
if (in_nulls[i * 2 + 1]) if (in_nulls[i * 2 + 1])
{ {
pairs[i].key = VARDATA(in_datums[i * 2]); pairs[i].key = VARDATA(DatumGetPointer(in_datums[i * 2]));
pairs[i].val = NULL; pairs[i].val = NULL;
pairs[i].keylen = pairs[i].keylen =
hstoreCheckKeyLen(VARSIZE(in_datums[i * 2]) - VARHDRSZ); hstoreCheckKeyLen(VARSIZE(DatumGetPointer(in_datums[i * 2])) - VARHDRSZ);
pairs[i].vallen = 4; pairs[i].vallen = 4;
pairs[i].isnull = true; pairs[i].isnull = true;
pairs[i].needfree = false; pairs[i].needfree = false;
} }
else else
{ {
pairs[i].key = VARDATA(in_datums[i * 2]); pairs[i].key = VARDATA(DatumGetPointer(in_datums[i * 2]));
pairs[i].val = VARDATA(in_datums[i * 2 + 1]); pairs[i].val = VARDATA(DatumGetPointer(in_datums[i * 2 + 1]));
pairs[i].keylen = pairs[i].keylen =
hstoreCheckKeyLen(VARSIZE(in_datums[i * 2]) - VARHDRSZ); hstoreCheckKeyLen(VARSIZE(DatumGetPointer(in_datums[i * 2])) - VARHDRSZ);
pairs[i].vallen = pairs[i].vallen =
hstoreCheckValLen(VARSIZE(in_datums[i * 2 + 1]) - VARHDRSZ); hstoreCheckValLen(VARSIZE(DatumGetPointer(in_datums[i * 2 + 1])) - VARHDRSZ);
pairs[i].isnull = false; pairs[i].isnull = false;
pairs[i].needfree = false; pairs[i].needfree = false;
} }

@ -107,8 +107,8 @@ hstoreArrayToPairs(ArrayType *a, int *npairs)
{ {
if (!key_nulls[i]) if (!key_nulls[i])
{ {
key_pairs[j].key = VARDATA(key_datums[i]); key_pairs[j].key = VARDATA(DatumGetPointer(key_datums[i]));
key_pairs[j].keylen = VARSIZE(key_datums[i]) - VARHDRSZ; key_pairs[j].keylen = VARSIZE(DatumGetPointer(key_datums[i])) - VARHDRSZ;
key_pairs[j].val = NULL; key_pairs[j].val = NULL;
key_pairs[j].vallen = 0; key_pairs[j].vallen = 0;
key_pairs[j].needfree = 0; key_pairs[j].needfree = 0;

@ -581,7 +581,7 @@ tuple_to_stringinfo(StringInfo s, TupleDesc tupdesc, HeapTuple tuple, bool skip_
/* print data */ /* print data */
if (isnull) if (isnull)
appendStringInfoString(s, "null"); appendStringInfoString(s, "null");
else if (typisvarlena && VARATT_IS_EXTERNAL_ONDISK(origval)) else if (typisvarlena && VARATT_IS_EXTERNAL_ONDISK(DatumGetPointer(origval)))
appendStringInfoString(s, "unchanged-toast-datum"); appendStringInfoString(s, "unchanged-toast-datum");
else if (!typisvarlena) else if (!typisvarlena)
print_literal(s, typid, print_literal(s, typid,

@ -624,7 +624,7 @@ brin_range_serialize(Ranges *range)
for (i = 0; i < nvalues; i++) for (i = 0; i < nvalues; i++)
{ {
len += VARSIZE_ANY(range->values[i]); len += VARSIZE_ANY(DatumGetPointer(range->values[i]));
} }
} }
else if (typlen == -2) /* cstring */ else if (typlen == -2) /* cstring */

@ -189,7 +189,7 @@ getmissingattr(TupleDesc tupleDesc,
if (att->attlen > 0) if (att->attlen > 0)
key.len = att->attlen; key.len = att->attlen;
else else
key.len = VARSIZE_ANY(attrmiss->am_value); key.len = VARSIZE_ANY(DatumGetPointer(attrmiss->am_value));
key.value = attrmiss->am_value; key.value = attrmiss->am_value;
entry = hash_search(missing_cache, &key, HASH_ENTER, &found); entry = hash_search(missing_cache, &key, HASH_ENTER, &found);
@ -901,7 +901,7 @@ expand_tuple(HeapTuple *targetHeapTuple,
att->attlen, att->attlen,
attrmiss[attnum].am_value); attrmiss[attnum].am_value);
targetDataLen = att_addlength_pointer(targetDataLen, targetDataLen = att_addlength_datum(targetDataLen,
att->attlen, att->attlen,
attrmiss[attnum].am_value); attrmiss[attnum].am_value);
} }

@ -1190,8 +1190,8 @@ transformRelOptions(Datum oldOptions, List *defList, const char *namspace,
for (i = 0; i < noldoptions; i++) for (i = 0; i < noldoptions; i++)
{ {
char *text_str = VARDATA(oldoptions[i]); char *text_str = VARDATA(DatumGetPointer(oldoptions[i]));
int text_len = VARSIZE(oldoptions[i]) - VARHDRSZ; int text_len = VARSIZE(DatumGetPointer(oldoptions[i])) - VARHDRSZ;
/* Search for a match in defList */ /* Search for a match in defList */
foreach(cell, defList) foreach(cell, defList)
@ -1456,8 +1456,8 @@ parseRelOptionsInternal(Datum options, bool validate,
for (i = 0; i < noptions; i++) for (i = 0; i < noptions; i++)
{ {
char *text_str = VARDATA(optiondatums[i]); char *text_str = VARDATA(DatumGetPointer(optiondatums[i]));
int text_len = VARSIZE(optiondatums[i]) - VARHDRSZ; int text_len = VARSIZE(DatumGetPointer(optiondatums[i])) - VARHDRSZ;
int j; int j;
/* Search for a match in reloptions */ /* Search for a match in reloptions */

@ -144,7 +144,7 @@ toast_save_datum(Relation rel, Datum value,
int num_indexes; int num_indexes;
int validIndex; int validIndex;
Assert(!VARATT_IS_EXTERNAL(value)); Assert(!VARATT_IS_EXTERNAL(dval));
/* /*
* Open the toast relation and its indexes. We can use the index to check * Open the toast relation and its indexes. We can use the index to check

@ -2233,7 +2233,7 @@ _gin_build_tuple(OffsetNumber attrnum, unsigned char category,
else if (typlen > 0) else if (typlen > 0)
keylen = typlen; keylen = typlen;
else if (typlen == -1) else if (typlen == -1)
keylen = VARSIZE_ANY(key); keylen = VARSIZE_ANY(DatumGetPointer(key));
else if (typlen == -2) else if (typlen == -2)
keylen = strlen(DatumGetPointer(key)) + 1; keylen = strlen(DatumGetPointer(key)) + 1;
else else

@ -785,7 +785,7 @@ SpGistGetInnerTypeSize(SpGistTypeDesc *att, Datum datum)
else if (att->attlen > 0) else if (att->attlen > 0)
size = att->attlen; size = att->attlen;
else else
size = VARSIZE_ANY(datum); size = VARSIZE_ANY(DatumGetPointer(datum));
return MAXALIGN(size); return MAXALIGN(size);
} }
@ -804,7 +804,7 @@ memcpyInnerDatum(void *target, SpGistTypeDesc *att, Datum datum)
} }
else else
{ {
size = (att->attlen > 0) ? att->attlen : VARSIZE_ANY(datum); size = (att->attlen > 0) ? att->attlen : VARSIZE_ANY(DatumGetPointer(datum));
memcpy(target, DatumGetPointer(datum), size); memcpy(target, DatumGetPointer(datum), size);
} }
} }

@ -330,7 +330,7 @@ toast_delete_external(Relation rel, const Datum *values, const bool *isnull,
if (isnull[i]) if (isnull[i])
continue; continue;
else if (VARATT_IS_EXTERNAL_ONDISK(value)) else if (VARATT_IS_EXTERNAL_ONDISK(DatumGetPointer(value)))
toast_delete_datum(rel, value, is_speculative); toast_delete_datum(rel, value, is_speculative);
} }
} }

@ -809,7 +809,7 @@ logicalrep_write_tuple(StringInfo out, Relation rel, TupleTableSlot *slot,
continue; continue;
} }
if (att->attlen == -1 && VARATT_IS_EXTERNAL_ONDISK(values[i])) if (att->attlen == -1 && VARATT_IS_EXTERNAL_ONDISK(DatumGetPointer(values[i])))
{ {
/* /*
* Unchanged toasted datum. (Note that we don't promise to detect * Unchanged toasted datum. (Note that we don't promise to detect

@ -1374,8 +1374,8 @@ pgoutput_row_filter(Relation relation, TupleTableSlot *old_slot,
* VARTAG_INDIRECT. See ReorderBufferToastReplace. * VARTAG_INDIRECT. See ReorderBufferToastReplace.
*/ */
if (att->attlen == -1 && if (att->attlen == -1 &&
VARATT_IS_EXTERNAL_ONDISK(new_slot->tts_values[i]) && VARATT_IS_EXTERNAL_ONDISK(DatumGetPointer(new_slot->tts_values[i])) &&
!VARATT_IS_EXTERNAL_ONDISK(old_slot->tts_values[i])) !VARATT_IS_EXTERNAL_ONDISK(DatumGetPointer(old_slot->tts_values[i])))
{ {
if (!tmp_new_slot) if (!tmp_new_slot)
{ {

@ -767,7 +767,7 @@ statext_mcv_serialize(MCVList *mcvlist, VacAttrStats **stats)
values[dim][i] = PointerGetDatum(PG_DETOAST_DATUM(values[dim][i])); values[dim][i] = PointerGetDatum(PG_DETOAST_DATUM(values[dim][i]));
/* serialized length (uint32 length + data) */ /* serialized length (uint32 length + data) */
len = VARSIZE_ANY_EXHDR(values[dim][i]); len = VARSIZE_ANY_EXHDR(DatumGetPointer(values[dim][i]));
info[dim].nbytes += sizeof(uint32); /* length */ info[dim].nbytes += sizeof(uint32); /* length */
info[dim].nbytes += len; /* value (no header) */ info[dim].nbytes += len; /* value (no header) */

@ -233,7 +233,7 @@ mcelem_tsquery_selec(TSQuery query, Datum *mcelem, int nmcelem,
* The text Datums came from an array, so it cannot be compressed or * The text Datums came from an array, so it cannot be compressed or
* stored out-of-line -- it's safe to use VARSIZE_ANY*. * stored out-of-line -- it's safe to use VARSIZE_ANY*.
*/ */
Assert(!VARATT_IS_COMPRESSED(mcelem[i]) && !VARATT_IS_EXTERNAL(mcelem[i])); Assert(!VARATT_IS_COMPRESSED(DatumGetPointer(mcelem[i])) && !VARATT_IS_EXTERNAL(DatumGetPointer(mcelem[i])));
lookup[i].element = (text *) DatumGetPointer(mcelem[i]); lookup[i].element = (text *) DatumGetPointer(mcelem[i]);
lookup[i].frequency = numbers[i]; lookup[i].frequency = numbers[i];
} }

@ -896,8 +896,8 @@ gin_extract_jsonb_query(PG_FUNCTION_ARGS)
continue; continue;
/* We rely on the array elements not being toasted */ /* We rely on the array elements not being toasted */
entries[j++] = make_text_key(JGINFLAG_KEY, entries[j++] = make_text_key(JGINFLAG_KEY,
VARDATA_ANY(key_datums[i]), VARDATA_ANY(DatumGetPointer(key_datums[i])),
VARSIZE_ANY_EXHDR(key_datums[i])); VARSIZE_ANY_EXHDR(DatumGetPointer(key_datums[i])));
} }
*nentries = j; *nentries = j;

@ -63,8 +63,8 @@ jsonb_exists_any(PG_FUNCTION_ARGS)
strVal.type = jbvString; strVal.type = jbvString;
/* We rely on the array elements not being toasted */ /* We rely on the array elements not being toasted */
strVal.val.string.val = VARDATA_ANY(key_datums[i]); strVal.val.string.val = VARDATA_ANY(DatumGetPointer(key_datums[i]));
strVal.val.string.len = VARSIZE_ANY_EXHDR(key_datums[i]); strVal.val.string.len = VARSIZE_ANY_EXHDR(DatumGetPointer(key_datums[i]));
if (findJsonbValueFromContainer(&jb->root, if (findJsonbValueFromContainer(&jb->root,
JB_FOBJECT | JB_FARRAY, JB_FOBJECT | JB_FARRAY,
@ -96,8 +96,8 @@ jsonb_exists_all(PG_FUNCTION_ARGS)
strVal.type = jbvString; strVal.type = jbvString;
/* We rely on the array elements not being toasted */ /* We rely on the array elements not being toasted */
strVal.val.string.val = VARDATA_ANY(key_datums[i]); strVal.val.string.val = VARDATA_ANY(DatumGetPointer(key_datums[i]));
strVal.val.string.len = VARSIZE_ANY_EXHDR(key_datums[i]); strVal.val.string.len = VARSIZE_ANY_EXHDR(DatumGetPointer(key_datums[i]));
if (findJsonbValueFromContainer(&jb->root, if (findJsonbValueFromContainer(&jb->root,
JB_FOBJECT | JB_FARRAY, JB_FOBJECT | JB_FARRAY,

@ -4766,8 +4766,8 @@ jsonb_delete_array(PG_FUNCTION_ARGS)
continue; continue;
/* We rely on the array elements not being toasted */ /* We rely on the array elements not being toasted */
keyptr = VARDATA_ANY(keys_elems[i]); keyptr = VARDATA_ANY(DatumGetPointer(keys_elems[i]));
keylen = VARSIZE_ANY_EXHDR(keys_elems[i]); keylen = VARSIZE_ANY_EXHDR(DatumGetPointer(keys_elems[i]));
if (keylen == v.val.string.len && if (keylen == v.val.string.len &&
memcmp(keyptr, v.val.string.val, keylen) == 0) memcmp(keyptr, v.val.string.val, keylen) == 0)
{ {

@ -3074,8 +3074,8 @@ JsonItemFromDatum(Datum val, Oid typid, int32 typmod, JsonbValue *res)
case TEXTOID: case TEXTOID:
case VARCHAROID: case VARCHAROID:
res->type = jbvString; res->type = jbvString;
res->val.string.val = VARDATA_ANY(val); res->val.string.val = VARDATA_ANY(DatumGetPointer(val));
res->val.string.len = VARSIZE_ANY_EXHDR(val); res->val.string.len = VARSIZE_ANY_EXHDR(DatumGetPointer(val));
break; break;
case DATEOID: case DATEOID:
case TIMEOID: case TIMEOID:

@ -394,12 +394,13 @@ multirange_send(PG_FUNCTION_ARGS)
for (int i = 0; i < range_count; i++) for (int i = 0; i < range_count; i++)
{ {
Datum range; Datum range;
bytea *outputbytes;
range = RangeTypePGetDatum(ranges[i]); range = RangeTypePGetDatum(ranges[i]);
range = PointerGetDatum(SendFunctionCall(&cache->typioproc, range)); outputbytes = SendFunctionCall(&cache->typioproc, range);
pq_sendint32(buf, VARSIZE(range) - VARHDRSZ); pq_sendint32(buf, VARSIZE(outputbytes) - VARHDRSZ);
pq_sendbytes(buf, VARDATA(range), VARSIZE(range) - VARHDRSZ); pq_sendbytes(buf, VARDATA(outputbytes), VARSIZE(outputbytes) - VARHDRSZ);
} }
PG_RETURN_BYTEA_P(pq_endtypsend(buf)); PG_RETURN_BYTEA_P(pq_endtypsend(buf));

@ -285,8 +285,7 @@ range_send(PG_FUNCTION_ARGS)
if (RANGE_HAS_LBOUND(flags)) if (RANGE_HAS_LBOUND(flags))
{ {
Datum bound = PointerGetDatum(SendFunctionCall(&cache->typioproc, bytea *bound = SendFunctionCall(&cache->typioproc, lower.val);
lower.val));
uint32 bound_len = VARSIZE(bound) - VARHDRSZ; uint32 bound_len = VARSIZE(bound) - VARHDRSZ;
char *bound_data = VARDATA(bound); char *bound_data = VARDATA(bound);
@ -296,8 +295,7 @@ range_send(PG_FUNCTION_ARGS)
if (RANGE_HAS_UBOUND(flags)) if (RANGE_HAS_UBOUND(flags))
{ {
Datum bound = PointerGetDatum(SendFunctionCall(&cache->typioproc, bytea *bound = SendFunctionCall(&cache->typioproc, upper.val);
upper.val));
uint32 bound_len = VARSIZE(bound) - VARHDRSZ; uint32 bound_len = VARSIZE(bound) - VARHDRSZ;
char *bound_data = VARDATA(bound); char *bound_data = VARDATA(bound);

@ -329,8 +329,8 @@ tsvector_setweight_by_filter(PG_FUNCTION_ARGS)
if (nulls[i]) if (nulls[i])
continue; continue;
lex = VARDATA(dlexemes[i]); lex = VARDATA(DatumGetPointer(dlexemes[i]));
lex_len = VARSIZE(dlexemes[i]) - VARHDRSZ; lex_len = VARSIZE(DatumGetPointer(dlexemes[i])) - VARHDRSZ;
lex_pos = tsvector_bsearch(tsout, lex, lex_len); lex_pos = tsvector_bsearch(tsout, lex, lex_len);
if (lex_pos >= 0 && (j = POSDATALEN(tsout, entry + lex_pos)) != 0) if (lex_pos >= 0 && (j = POSDATALEN(tsout, entry + lex_pos)) != 0)
@ -443,10 +443,10 @@ compare_text_lexemes(const void *va, const void *vb)
{ {
Datum a = *((const Datum *) va); Datum a = *((const Datum *) va);
Datum b = *((const Datum *) vb); Datum b = *((const Datum *) vb);
char *alex = VARDATA_ANY(a); char *alex = VARDATA_ANY(DatumGetPointer(a));
int alex_len = VARSIZE_ANY_EXHDR(a); int alex_len = VARSIZE_ANY_EXHDR(DatumGetPointer(a));
char *blex = VARDATA_ANY(b); char *blex = VARDATA_ANY(DatumGetPointer(b));
int blex_len = VARSIZE_ANY_EXHDR(b); int blex_len = VARSIZE_ANY_EXHDR(DatumGetPointer(b));
return tsCompareString(alex, alex_len, blex, blex_len, false); return tsCompareString(alex, alex_len, blex, blex_len, false);
} }
@ -605,8 +605,8 @@ tsvector_delete_arr(PG_FUNCTION_ARGS)
if (nulls[i]) if (nulls[i])
continue; continue;
lex = VARDATA(dlexemes[i]); lex = VARDATA(DatumGetPointer(dlexemes[i]));
lex_len = VARSIZE(dlexemes[i]) - VARHDRSZ; lex_len = VARSIZE(DatumGetPointer(dlexemes[i])) - VARHDRSZ;
lex_pos = tsvector_bsearch(tsin, lex, lex_len); lex_pos = tsvector_bsearch(tsin, lex, lex_len);
if (lex_pos >= 0) if (lex_pos >= 0)
@ -770,7 +770,7 @@ array_to_tsvector(PG_FUNCTION_ARGS)
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
errmsg("lexeme array may not contain nulls"))); errmsg("lexeme array may not contain nulls")));
if (VARSIZE(dlexemes[i]) - VARHDRSZ == 0) if (VARSIZE(DatumGetPointer(dlexemes[i])) - VARHDRSZ == 0)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_ZERO_LENGTH_CHARACTER_STRING), (errcode(ERRCODE_ZERO_LENGTH_CHARACTER_STRING),
errmsg("lexeme array may not contain empty strings"))); errmsg("lexeme array may not contain empty strings")));
@ -786,7 +786,7 @@ array_to_tsvector(PG_FUNCTION_ARGS)
/* Calculate space needed for surviving lexemes. */ /* Calculate space needed for surviving lexemes. */
for (i = 0; i < nitems; i++) for (i = 0; i < nitems; i++)
datalen += VARSIZE(dlexemes[i]) - VARHDRSZ; datalen += VARSIZE(DatumGetPointer(dlexemes[i])) - VARHDRSZ;
tslen = CALCDATASIZE(nitems, datalen); tslen = CALCDATASIZE(nitems, datalen);
/* Allocate and fill tsvector. */ /* Allocate and fill tsvector. */
@ -798,8 +798,8 @@ array_to_tsvector(PG_FUNCTION_ARGS)
cur = STRPTR(tsout); cur = STRPTR(tsout);
for (i = 0; i < nitems; i++) for (i = 0; i < nitems; i++)
{ {
char *lex = VARDATA(dlexemes[i]); char *lex = VARDATA(DatumGetPointer(dlexemes[i]));
int lex_len = VARSIZE(dlexemes[i]) - VARHDRSZ; int lex_len = VARSIZE(DatumGetPointer(dlexemes[i])) - VARHDRSZ;
memcpy(cur, lex, lex_len); memcpy(cur, lex, lex_len);
arrout[i].haspos = 0; arrout[i].haspos = 0;

Loading…
Cancel
Save