PostgreSQL Source Code  git master
tsvector.c File Reference
#include "postgres.h"
#include "libpq/pqformat.h"
#include "tsearch/ts_locale.h"
#include "tsearch/ts_utils.h"
#include "utils/builtins.h"
#include "utils/memutils.h"
Include dependency graph for tsvector.c:

Go to the source code of this file.

Data Structures

struct  WordEntryIN
 

Functions

int compareWordEntryPos (const void *a, const void *b)
 
static int uniquePos (WordEntryPos *a, int l)
 
static int compareentry (const void *va, const void *vb, void *arg)
 
static int uniqueentry (WordEntryIN *a, int l, char *buf, int *outbuflen)
 
static int WordEntryCMP (WordEntry *a, WordEntry *b, char *buf)
 
Datum tsvectorin (PG_FUNCTION_ARGS)
 
Datum tsvectorout (PG_FUNCTION_ARGS)
 
Datum tsvectorsend (PG_FUNCTION_ARGS)
 
Datum tsvectorrecv (PG_FUNCTION_ARGS)
 

Function Documentation

◆ compareentry()

static int compareentry ( const void *  va,
const void *  vb,
void *  arg 
)
static

Definition at line 83 of file tsvector.c.

References WordEntryIN::entry, WordEntry::len, WordEntry::pos, and tsCompareString().

Referenced by tsvectorrecv(), uniqueentry(), and WordEntryCMP().

84 {
85  const WordEntryIN *a = (const WordEntryIN *) va;
86  const WordEntryIN *b = (const WordEntryIN *) vb;
87  char *BufferStr = (char *) arg;
88 
89  return tsCompareString(&BufferStr[a->entry.pos], a->entry.len,
90  &BufferStr[b->entry.pos], b->entry.len,
91  false);
92 }
uint32 len
Definition: ts_type.h:44
WordEntry entry
Definition: tsvector.c:25
int32 tsCompareString(char *a, int lena, char *b, int lenb, bool prefix)
Definition: tsvector_op.c:1147
uint32 pos
Definition: ts_type.h:44
void * arg

◆ compareWordEntryPos()

int compareWordEntryPos ( const void *  a,
const void *  b 
)

Definition at line 33 of file tsvector.c.

References WEP_GETPOS.

Referenced by checkcondition_str(), and uniquePos().

34 {
35  int apos = WEP_GETPOS(*(const WordEntryPos *) a);
36  int bpos = WEP_GETPOS(*(const WordEntryPos *) b);
37 
38  if (apos == bpos)
39  return 0;
40  return (apos > bpos) ? 1 : -1;
41 }
uint16 WordEntryPos
Definition: ts_type.h:63
#define WEP_GETPOS(x)
Definition: ts_type.h:80

◆ tsvectorin()

Datum tsvectorin ( PG_FUNCTION_ARGS  )

Definition at line 178 of file tsvector.c.

References ARRPTR, Assert, buf, CALCDATASIZE, close_tsvector_parser(), cur, elog, WordEntryIN::entry, ereport, errcode(), errmsg(), ERROR, gettoken_tsvector(), WordEntry::haspos, i, init_tsvector_parser(), WordEntry::len, MAXSTRLEN, MAXSTRPOS, palloc(), palloc0(), pfree(), PG_GETARG_CSTRING, PG_RETURN_TSVECTOR, WordEntryIN::pos, WordEntry::pos, WordEntryIN::poslen, repalloc(), SET_VARSIZE, SHORTALIGN, TSVectorData::size, STRPTR, tmpbuf, and uniqueentry().

179 {
180  char *buf = PG_GETARG_CSTRING(0);
182  WordEntryIN *arr;
183  int totallen;
184  int arrlen; /* allocated size of arr */
185  WordEntry *inarr;
186  int len = 0;
187  TSVector in;
188  int i;
189  char *token;
190  int toklen;
191  WordEntryPos *pos;
192  int poslen;
193  char *strbuf;
194  int stroff;
195 
196  /*
197  * Tokens are appended to tmpbuf, cur is a pointer to the end of used
198  * space in tmpbuf.
199  */
200  char *tmpbuf;
201  char *cur;
202  int buflen = 256; /* allocated size of tmpbuf */
203 
204  state = init_tsvector_parser(buf, 0);
205 
206  arrlen = 64;
207  arr = (WordEntryIN *) palloc(sizeof(WordEntryIN) * arrlen);
208  cur = tmpbuf = (char *) palloc(buflen);
209 
210  while (gettoken_tsvector(state, &token, &toklen, &pos, &poslen, NULL))
211  {
212  if (toklen >= MAXSTRLEN)
213  ereport(ERROR,
214  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
215  errmsg("word is too long (%ld bytes, max %ld bytes)",
216  (long) toklen,
217  (long) (MAXSTRLEN - 1))));
218 
219  if (cur - tmpbuf > MAXSTRPOS)
220  ereport(ERROR,
221  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
222  errmsg("string is too long for tsvector (%ld bytes, max %ld bytes)",
223  (long) (cur - tmpbuf), (long) MAXSTRPOS)));
224 
225  /*
226  * Enlarge buffers if needed
227  */
228  if (len >= arrlen)
229  {
230  arrlen *= 2;
231  arr = (WordEntryIN *)
232  repalloc((void *) arr, sizeof(WordEntryIN) * arrlen);
233  }
234  while ((cur - tmpbuf) + toklen >= buflen)
235  {
236  int dist = cur - tmpbuf;
237 
238  buflen *= 2;
239  tmpbuf = (char *) repalloc((void *) tmpbuf, buflen);
240  cur = tmpbuf + dist;
241  }
242  arr[len].entry.len = toklen;
243  arr[len].entry.pos = cur - tmpbuf;
244  memcpy((void *) cur, (void *) token, toklen);
245  cur += toklen;
246 
247  if (poslen != 0)
248  {
249  arr[len].entry.haspos = 1;
250  arr[len].pos = pos;
251  arr[len].poslen = poslen;
252  }
253  else
254  {
255  arr[len].entry.haspos = 0;
256  arr[len].pos = NULL;
257  arr[len].poslen = 0;
258  }
259  len++;
260  }
261 
262  close_tsvector_parser(state);
263 
264  if (len > 0)
265  len = uniqueentry(arr, len, tmpbuf, &buflen);
266  else
267  buflen = 0;
268 
269  if (buflen > MAXSTRPOS)
270  ereport(ERROR,
271  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
272  errmsg("string is too long for tsvector (%d bytes, max %d bytes)", buflen, MAXSTRPOS)));
273 
274  totallen = CALCDATASIZE(len, buflen);
275  in = (TSVector) palloc0(totallen);
276  SET_VARSIZE(in, totallen);
277  in->size = len;
278  inarr = ARRPTR(in);
279  strbuf = STRPTR(in);
280  stroff = 0;
281  for (i = 0; i < len; i++)
282  {
283  memcpy(strbuf + stroff, &tmpbuf[arr[i].entry.pos], arr[i].entry.len);
284  arr[i].entry.pos = stroff;
285  stroff += arr[i].entry.len;
286  if (arr[i].entry.haspos)
287  {
288  if (arr[i].poslen > 0xFFFF)
289  elog(ERROR, "positions array too long");
290 
291  /* Copy number of positions */
292  stroff = SHORTALIGN(stroff);
293  *(uint16 *) (strbuf + stroff) = (uint16) arr[i].poslen;
294  stroff += sizeof(uint16);
295 
296  /* Copy positions */
297  memcpy(strbuf + stroff, arr[i].pos, arr[i].poslen * sizeof(WordEntryPos));
298  stroff += arr[i].poslen * sizeof(WordEntryPos);
299 
300  pfree(arr[i].pos);
301  }
302  inarr[i] = arr[i].entry;
303  }
304 
305  Assert((strbuf + stroff - (char *) in) == totallen);
306 
307  PG_RETURN_TSVECTOR(in);
308 }
uint16 WordEntryPos
Definition: ts_type.h:63
bool gettoken_tsvector(TSVectorParseState state, char **strval, int *lenval, WordEntryPos **pos_ptr, int *poslen, char **endptr)
void close_tsvector_parser(TSVectorParseState state)
uint32 len
Definition: ts_type.h:44
#define PG_RETURN_TSVECTOR(x)
Definition: ts_type.h:122
struct cursor * cur
Definition: ecpg.c:28
int errcode(int sqlerrcode)
Definition: elog.c:608
#define MAXSTRPOS
Definition: ts_type.h:50
WordEntry entry
Definition: tsvector.c:25
unsigned short uint16
Definition: c.h:358
void pfree(void *pointer)
Definition: mcxt.c:1056
#define ERROR
Definition: elog.h:43
static char * buf
Definition: pg_test_fsync.c:67
int32 size
Definition: ts_type.h:93
uint32 haspos
Definition: ts_type.h:44
#define ereport(elevel, rest)
Definition: elog.h:141
int poslen
Definition: tsvector.c:27
static int uniqueentry(WordEntryIN *a, int l, char *buf, int *outbuflen)
Definition: tsvector.c:99
#define CALCDATASIZE(x, lenstr)
Definition: hstore.h:72
ts_parserstate state
Definition: tsquery.c:81
void * palloc0(Size size)
Definition: mcxt.c:980
TSVectorData * TSVector
Definition: ts_type.h:98
#define Assert(condition)
Definition: c.h:739
TSVectorParseState init_tsvector_parser(char *input, int flags)
uint32 pos
Definition: ts_type.h:44
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1069
static StringInfoData tmpbuf
Definition: walsender.c:154
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:822
#define STRPTR(x)
Definition: hstore.h:76
#define elog(elevel,...)
Definition: elog.h:228
int i
WordEntryPos * pos
Definition: tsvector.c:26
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:272
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:329
#define ARRPTR(x)
Definition: cube.c:24
#define SHORTALIGN(LEN)
Definition: c.h:688
#define MAXSTRLEN
Definition: ts_type.h:49

◆ tsvectorout()

Datum tsvectorout ( PG_FUNCTION_ARGS  )

Definition at line 311 of file tsvector.c.

References ARRPTR, i, WordEntry::len, palloc(), pg_database_encoding_max_length(), PG_FREE_IF_COPY, PG_GETARG_TSVECTOR, pg_mblen(), PG_RETURN_CSTRING, WordEntry::pos, POSDATALEN, POSDATAPTR, TSVectorData::size, sprintf, STRPTR, t_iseq, WEP_GETPOS, and WEP_GETWEIGHT.

312 {
313  TSVector out = PG_GETARG_TSVECTOR(0);
314  char *outbuf;
315  int32 i,
316  lenbuf = 0,
317  pp;
318  WordEntry *ptr = ARRPTR(out);
319  char *curbegin,
320  *curin,
321  *curout;
322 
323  lenbuf = out->size * 2 /* '' */ + out->size - 1 /* space */ + 2 /* \0 */ ;
324  for (i = 0; i < out->size; i++)
325  {
326  lenbuf += ptr[i].len * 2 * pg_database_encoding_max_length() /* for escape */ ;
327  if (ptr[i].haspos)
328  lenbuf += 1 /* : */ + 7 /* int2 + , + weight */ * POSDATALEN(out, &(ptr[i]));
329  }
330 
331  curout = outbuf = (char *) palloc(lenbuf);
332  for (i = 0; i < out->size; i++)
333  {
334  curbegin = curin = STRPTR(out) + ptr->pos;
335  if (i != 0)
336  *curout++ = ' ';
337  *curout++ = '\'';
338  while (curin - curbegin < ptr->len)
339  {
340  int len = pg_mblen(curin);
341 
342  if (t_iseq(curin, '\''))
343  *curout++ = '\'';
344  else if (t_iseq(curin, '\\'))
345  *curout++ = '\\';
346 
347  while (len--)
348  *curout++ = *curin++;
349  }
350 
351  *curout++ = '\'';
352  if ((pp = POSDATALEN(out, ptr)) != 0)
353  {
354  WordEntryPos *wptr;
355 
356  *curout++ = ':';
357  wptr = POSDATAPTR(out, ptr);
358  while (pp)
359  {
360  curout += sprintf(curout, "%d", WEP_GETPOS(*wptr));
361  switch (WEP_GETWEIGHT(*wptr))
362  {
363  case 3:
364  *curout++ = 'A';
365  break;
366  case 2:
367  *curout++ = 'B';
368  break;
369  case 1:
370  *curout++ = 'C';
371  break;
372  case 0:
373  default:
374  break;
375  }
376 
377  if (pp > 1)
378  *curout++ = ',';
379  pp--;
380  wptr++;
381  }
382  }
383  ptr++;
384  }
385 
386  *curout = '\0';
387  PG_FREE_IF_COPY(out, 0);
388  PG_RETURN_CSTRING(outbuf);
389 }
uint16 WordEntryPos
Definition: ts_type.h:63
#define POSDATALEN(x, e)
Definition: ts_type.h:110
uint32 len
Definition: ts_type.h:44
signed int int32
Definition: c.h:347
#define POSDATAPTR(x, e)
Definition: ts_type.h:111
#define sprintf
Definition: port.h:194
#define WEP_GETPOS(x)
Definition: ts_type.h:80
int pg_database_encoding_max_length(void)
Definition: wchar.c:1881
#define t_iseq(x, c)
Definition: ts_locale.h:45
int32 size
Definition: ts_type.h:93
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:352
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
int pg_mblen(const char *mbstr)
Definition: mbutils.c:802
uint32 pos
Definition: ts_type.h:44
void * palloc(Size size)
Definition: mcxt.c:949
#define STRPTR(x)
Definition: hstore.h:76
int i
#define PG_GETARG_TSVECTOR(n)
Definition: ts_type.h:120
#define ARRPTR(x)
Definition: cube.c:24
#define WEP_GETWEIGHT(x)
Definition: ts_type.h:79

◆ tsvectorrecv()

Datum tsvectorrecv ( PG_FUNCTION_ARGS  )

Definition at line 443 of file tsvector.c.

References ARRPTR, buf, compareentry(), DATAHDRSIZE, elog, TSVectorData::entries, ERROR, WordEntry::haspos, i, WordEntry::len, MaxAllocSize, MAXNUMPOS, MAXSTRLEN, MAXSTRPOS, palloc0(), PG_GETARG_POINTER, PG_RETURN_TSVECTOR, WordEntry::pos, POSDATAPTR, pq_getmsgint(), pq_getmsgstring(), qsort_arg(), repalloc(), SET_VARSIZE, SHORTALIGN, TSVectorData::size, STRPTR, WEP_GETPOS, and WordEntryCMP().

444 {
446  TSVector vec;
447  int i;
448  int32 nentries;
449  int datalen; /* number of bytes used in the variable size
450  * area after fixed size TSVector header and
451  * WordEntries */
452  Size hdrlen;
453  Size len; /* allocated size of vec */
454  bool needSort = false;
455 
456  nentries = pq_getmsgint(buf, sizeof(int32));
457  if (nentries < 0 || nentries > (MaxAllocSize / sizeof(WordEntry)))
458  elog(ERROR, "invalid size of tsvector");
459 
460  hdrlen = DATAHDRSIZE + sizeof(WordEntry) * nentries;
461 
462  len = hdrlen * 2; /* times two to make room for lexemes */
463  vec = (TSVector) palloc0(len);
464  vec->size = nentries;
465 
466  datalen = 0;
467  for (i = 0; i < nentries; i++)
468  {
469  const char *lexeme;
470  uint16 npos;
471  size_t lex_len;
472 
473  lexeme = pq_getmsgstring(buf);
474  npos = (uint16) pq_getmsgint(buf, sizeof(uint16));
475 
476  /* sanity checks */
477 
478  lex_len = strlen(lexeme);
479  if (lex_len > MAXSTRLEN)
480  elog(ERROR, "invalid tsvector: lexeme too long");
481 
482  if (datalen > MAXSTRPOS)
483  elog(ERROR, "invalid tsvector: maximum total lexeme length exceeded");
484 
485  if (npos > MAXNUMPOS)
486  elog(ERROR, "unexpected number of tsvector positions");
487 
488  /*
489  * Looks valid. Fill the WordEntry struct, and copy lexeme.
490  *
491  * But make sure the buffer is large enough first.
492  */
493  while (hdrlen + SHORTALIGN(datalen + lex_len) +
494  (npos + 1) * sizeof(WordEntryPos) >= len)
495  {
496  len *= 2;
497  vec = (TSVector) repalloc(vec, len);
498  }
499 
500  vec->entries[i].haspos = (npos > 0) ? 1 : 0;
501  vec->entries[i].len = lex_len;
502  vec->entries[i].pos = datalen;
503 
504  memcpy(STRPTR(vec) + datalen, lexeme, lex_len);
505 
506  datalen += lex_len;
507 
508  if (i > 0 && WordEntryCMP(&vec->entries[i],
509  &vec->entries[i - 1],
510  STRPTR(vec)) <= 0)
511  needSort = true;
512 
513  /* Receive positions */
514  if (npos > 0)
515  {
516  uint16 j;
517  WordEntryPos *wepptr;
518 
519  /*
520  * Pad to 2-byte alignment if necessary. Though we used palloc0
521  * for the initial allocation, subsequent repalloc'd memory areas
522  * are not initialized to zero.
523  */
524  if (datalen != SHORTALIGN(datalen))
525  {
526  *(STRPTR(vec) + datalen) = '\0';
527  datalen = SHORTALIGN(datalen);
528  }
529 
530  memcpy(STRPTR(vec) + datalen, &npos, sizeof(uint16));
531 
532  wepptr = POSDATAPTR(vec, &vec->entries[i]);
533  for (j = 0; j < npos; j++)
534  {
535  wepptr[j] = (WordEntryPos) pq_getmsgint(buf, sizeof(WordEntryPos));
536  if (j > 0 && WEP_GETPOS(wepptr[j]) <= WEP_GETPOS(wepptr[j - 1]))
537  elog(ERROR, "position information is misordered");
538  }
539 
540  datalen += (npos + 1) * sizeof(WordEntry);
541  }
542  }
543 
544  SET_VARSIZE(vec, hdrlen + datalen);
545 
546  if (needSort)
547  qsort_arg((void *) ARRPTR(vec), vec->size, sizeof(WordEntry),
548  compareentry, (void *) STRPTR(vec));
549 
550  PG_RETURN_TSVECTOR(vec);
551 }
uint16 WordEntryPos
Definition: ts_type.h:63
const char * pq_getmsgstring(StringInfo msg)
Definition: pqformat.c:581
StringInfoData * StringInfo
Definition: stringinfo.h:44
uint32 len
Definition: ts_type.h:44
#define PG_RETURN_TSVECTOR(x)
Definition: ts_type.h:122
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:271
#define MAXSTRPOS
Definition: ts_type.h:50
signed int int32
Definition: c.h:347
#define POSDATAPTR(x, e)
Definition: ts_type.h:111
unsigned short uint16
Definition: c.h:358
#define ERROR
Definition: elog.h:43
#define MAXNUMPOS
Definition: ts_type.h:86
#define WEP_GETPOS(x)
Definition: ts_type.h:80
static char * buf
Definition: pg_test_fsync.c:67
int32 size
Definition: ts_type.h:93
WordEntry entries[FLEXIBLE_ARRAY_MEMBER]
Definition: ts_type.h:94
static int compareentry(const void *va, const void *vb, void *arg)
Definition: tsvector.c:83
uint32 haspos
Definition: ts_type.h:44
static int WordEntryCMP(WordEntry *a, WordEntry *b, char *buf)
Definition: tsvector.c:171
#define MaxAllocSize
Definition: memutils.h:40
void qsort_arg(void *base, size_t nel, size_t elsize, qsort_arg_comparator cmp, void *arg)
Definition: qsort_arg.c:113
void * palloc0(Size size)
Definition: mcxt.c:980
TSVectorData * TSVector
Definition: ts_type.h:98
size_t Size
Definition: c.h:467
uint32 pos
Definition: ts_type.h:44
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1069
#define STRPTR(x)
Definition: hstore.h:76
#define elog(elevel,...)
Definition: elog.h:228
int i
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition: pqformat.c:417
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:329
#define ARRPTR(x)
Definition: cube.c:24
#define SHORTALIGN(LEN)
Definition: c.h:688
#define DATAHDRSIZE
Definition: ts_type.h:100
#define MAXSTRLEN
Definition: ts_type.h:49

◆ tsvectorsend()

Datum tsvectorsend ( PG_FUNCTION_ARGS  )

Definition at line 404 of file tsvector.c.

References ARRPTR, buf, i, WordEntry::len, PG_GETARG_TSVECTOR, PG_RETURN_BYTEA_P, WordEntry::pos, POSDATALEN, POSDATAPTR, pq_begintypsend(), pq_endtypsend(), pq_sendbyte(), pq_sendint16(), pq_sendint32(), pq_sendtext(), TSVectorData::size, and STRPTR.

405 {
406  TSVector vec = PG_GETARG_TSVECTOR(0);
408  int i,
409  j;
410  WordEntry *weptr = ARRPTR(vec);
411 
412  pq_begintypsend(&buf);
413 
414  pq_sendint32(&buf, vec->size);
415  for (i = 0; i < vec->size; i++)
416  {
417  uint16 npos;
418 
419  /*
420  * the strings in the TSVector array are not null-terminated, so we
421  * have to send the null-terminator separately
422  */
423  pq_sendtext(&buf, STRPTR(vec) + weptr->pos, weptr->len);
424  pq_sendbyte(&buf, '\0');
425 
426  npos = POSDATALEN(vec, weptr);
427  pq_sendint16(&buf, npos);
428 
429  if (npos > 0)
430  {
431  WordEntryPos *wepptr = POSDATAPTR(vec, weptr);
432 
433  for (j = 0; j < npos; j++)
434  pq_sendint16(&buf, wepptr[j]);
435  }
436  weptr++;
437  }
438 
440 }
uint16 WordEntryPos
Definition: ts_type.h:63
static void pq_sendint16(StringInfo buf, uint16 i)
Definition: pqformat.h:137
#define POSDATALEN(x, e)
Definition: ts_type.h:110
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:328
uint32 len
Definition: ts_type.h:44
void pq_sendtext(StringInfo buf, const char *str, int slen)
Definition: pqformat.c:174
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:360
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:348
#define POSDATAPTR(x, e)
Definition: ts_type.h:111
static void pq_sendbyte(StringInfo buf, uint8 byt)
Definition: pqformat.h:161
static void pq_sendint32(StringInfo buf, uint32 i)
Definition: pqformat.h:145
unsigned short uint16
Definition: c.h:358
static char * buf
Definition: pg_test_fsync.c:67
int32 size
Definition: ts_type.h:93
uint32 pos
Definition: ts_type.h:44
#define STRPTR(x)
Definition: hstore.h:76
int i
#define PG_GETARG_TSVECTOR(n)
Definition: ts_type.h:120
#define ARRPTR(x)
Definition: cube.c:24

◆ uniqueentry()

static int uniqueentry ( WordEntryIN a,
int  l,
char *  buf,
int *  outbuflen 
)
static

Definition at line 99 of file tsvector.c.

References Assert, compareentry(), WordEntryIN::entry, WordEntry::haspos, WordEntry::len, pfree(), WordEntryIN::pos, WordEntry::pos, WordEntryIN::poslen, qsort_arg(), repalloc(), SHORTALIGN, and uniquePos().

Referenced by tsvectorin().

100 {
101  int buflen;
102  WordEntryIN *ptr,
103  *res;
104 
105  Assert(l >= 1);
106 
107  if (l > 1)
108  qsort_arg((void *) a, l, sizeof(WordEntryIN), compareentry,
109  (void *) buf);
110 
111  buflen = 0;
112  res = a;
113  ptr = a + 1;
114  while (ptr - a < l)
115  {
116  if (!(ptr->entry.len == res->entry.len &&
117  strncmp(&buf[ptr->entry.pos], &buf[res->entry.pos],
118  res->entry.len) == 0))
119  {
120  /* done accumulating data into *res, count space needed */
121  buflen += res->entry.len;
122  if (res->entry.haspos)
123  {
124  res->poslen = uniquePos(res->pos, res->poslen);
125  buflen = SHORTALIGN(buflen);
126  buflen += res->poslen * sizeof(WordEntryPos) + sizeof(uint16);
127  }
128  res++;
129  if (res != ptr)
130  memcpy(res, ptr, sizeof(WordEntryIN));
131  }
132  else if (ptr->entry.haspos)
133  {
134  if (res->entry.haspos)
135  {
136  /* append ptr's positions to res's positions */
137  int newlen = ptr->poslen + res->poslen;
138 
139  res->pos = (WordEntryPos *)
140  repalloc(res->pos, newlen * sizeof(WordEntryPos));
141  memcpy(&res->pos[res->poslen], ptr->pos,
142  ptr->poslen * sizeof(WordEntryPos));
143  res->poslen = newlen;
144  pfree(ptr->pos);
145  }
146  else
147  {
148  /* just give ptr's positions to pos */
149  res->entry.haspos = 1;
150  res->pos = ptr->pos;
151  res->poslen = ptr->poslen;
152  }
153  }
154  ptr++;
155  }
156 
157  /* count space needed for last item */
158  buflen += res->entry.len;
159  if (res->entry.haspos)
160  {
161  res->poslen = uniquePos(res->pos, res->poslen);
162  buflen = SHORTALIGN(buflen);
163  buflen += res->poslen * sizeof(WordEntryPos) + sizeof(uint16);
164  }
165 
166  *outbuflen = buflen;
167  return res + 1 - a;
168 }
uint16 WordEntryPos
Definition: ts_type.h:63
uint32 len
Definition: ts_type.h:44
WordEntry entry
Definition: tsvector.c:25
unsigned short uint16
Definition: c.h:358
void pfree(void *pointer)
Definition: mcxt.c:1056
static char * buf
Definition: pg_test_fsync.c:67
static int compareentry(const void *va, const void *vb, void *arg)
Definition: tsvector.c:83
uint32 haspos
Definition: ts_type.h:44
int poslen
Definition: tsvector.c:27
void qsort_arg(void *base, size_t nel, size_t elsize, qsort_arg_comparator cmp, void *arg)
Definition: qsort_arg.c:113
static int uniquePos(WordEntryPos *a, int l)
Definition: tsvector.c:51
#define Assert(condition)
Definition: c.h:739
uint32 pos
Definition: ts_type.h:44
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1069
WordEntryPos * pos
Definition: tsvector.c:26
#define SHORTALIGN(LEN)
Definition: c.h:688

◆ uniquePos()

static int uniquePos ( WordEntryPos a,
int  l 
)
static

Definition at line 51 of file tsvector.c.

References compareWordEntryPos(), MAXENTRYPOS, MAXNUMPOS, qsort, WEP_GETPOS, WEP_GETWEIGHT, and WEP_SETWEIGHT.

Referenced by uniqueentry().

52 {
53  WordEntryPos *ptr,
54  *res;
55 
56  if (l <= 1)
57  return l;
58 
59  qsort((void *) a, l, sizeof(WordEntryPos), compareWordEntryPos);
60 
61  res = a;
62  ptr = a + 1;
63  while (ptr - a < l)
64  {
65  if (WEP_GETPOS(*ptr) != WEP_GETPOS(*res))
66  {
67  res++;
68  *res = *ptr;
69  if (res - a >= MAXNUMPOS - 1 ||
70  WEP_GETPOS(*res) == MAXENTRYPOS - 1)
71  break;
72  }
73  else if (WEP_GETWEIGHT(*ptr) > WEP_GETWEIGHT(*res))
74  WEP_SETWEIGHT(*res, WEP_GETWEIGHT(*ptr));
75  ptr++;
76  }
77 
78  return res + 1 - a;
79 }
uint16 WordEntryPos
Definition: ts_type.h:63
int compareWordEntryPos(const void *a, const void *b)
Definition: tsvector.c:33
#define MAXNUMPOS
Definition: ts_type.h:86
#define WEP_GETPOS(x)
Definition: ts_type.h:80
#define WEP_SETWEIGHT(x, v)
Definition: ts_type.h:82
#define WEP_GETWEIGHT(x)
Definition: ts_type.h:79
#define qsort(a, b, c, d)
Definition: port.h:488
#define MAXENTRYPOS
Definition: ts_type.h:85

◆ WordEntryCMP()

static int WordEntryCMP ( WordEntry a,
WordEntry b,
char *  buf 
)
static

Definition at line 171 of file tsvector.c.

References compareentry().

Referenced by tsvectorrecv().

172 {
173  return compareentry(a, b, buf);
174 }
static char * buf
Definition: pg_test_fsync.c:67
static int compareentry(const void *va, const void *vb, void *arg)
Definition: tsvector.c:83