diff options
Diffstat (limited to 'contrib/tsearch2/tsvector_op.c')
-rw-r--r-- | contrib/tsearch2/tsvector_op.c | 358 |
1 files changed, 212 insertions, 146 deletions
diff --git a/contrib/tsearch2/tsvector_op.c b/contrib/tsearch2/tsvector_op.c index cfef02db85d..2ffd4ca5848 100644 --- a/contrib/tsearch2/tsvector_op.c +++ b/contrib/tsearch2/tsvector_op.c @@ -33,30 +33,33 @@ Datum concat(PG_FUNCTION_ARGS); Datum strip(PG_FUNCTION_ARGS) { - tsvector *in = (tsvector *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); - tsvector *out; - int i,len=0; - WordEntry *arrin=ARRPTR(in), *arrout; - char *cur; + tsvector *in = (tsvector *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); + tsvector *out; + int i, + len = 0; + WordEntry *arrin = ARRPTR(in), + *arrout; + char *cur; - for(i=0;i<in->size;i++) - len += SHORTALIGN( arrin[i].len ); + for (i = 0; i < in->size; i++) + len += SHORTALIGN(arrin[i].len); len = CALCDATASIZE(in->size, len); - out=(tsvector*)palloc(len); - memset(out,0,len); - out->len=len; - out->size=in->size; - arrout=ARRPTR(out); - cur=STRPTR(out); - for(i=0;i<in->size;i++) { - memcpy(cur, STRPTR(in)+arrin[i].pos, arrin[i].len); + out = (tsvector *) palloc(len); + memset(out, 0, len); + out->len = len; + out->size = in->size; + arrout = ARRPTR(out); + cur = STRPTR(out); + for (i = 0; i < in->size; i++) + { + memcpy(cur, STRPTR(in) + arrin[i].pos, arrin[i].len); arrout[i].haspos = 0; arrout[i].len = arrin[i].len; arrout[i].pos = cur - STRPTR(out); - cur += SHORTALIGN( arrout[i].len ); + cur += SHORTALIGN(arrout[i].len); } - + PG_FREE_IF_COPY(in, 0); PG_RETURN_POINTER(out); } @@ -64,200 +67,263 @@ strip(PG_FUNCTION_ARGS) Datum setweight(PG_FUNCTION_ARGS) { - tsvector *in = (tsvector *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); - char cw = PG_GETARG_CHAR(1); - tsvector *out; - int i,j; - WordEntry *entry; + tsvector *in = (tsvector *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); + char cw = PG_GETARG_CHAR(1); + tsvector *out; + int i, + j; + WordEntry *entry; WordEntryPos *p; - int w=0; + int w = 0; - switch(tolower(cw)) { - case 'a': w=3; break; - case 'b': w=2; break; - case 'c': w=1; break; - case 'd': w=0; break; - /* internal error */ - default: elog(ERROR,"unrecognized weight"); + switch (tolower(cw)) + { + case 'a': + w = 3; + break; + case 'b': + w = 2; + break; + case 'c': + w = 1; + break; + case 'd': + w = 0; + break; + /* internal error */ + default: + elog(ERROR, "unrecognized weight"); } - out=(tsvector*)palloc(in->len); - memcpy(out,in,in->len); - entry=ARRPTR(out); - i=out->size; - while(i--) { - if ( (j=POSDATALEN(out,entry)) != 0 ) { - p=POSDATAPTR(out,entry); - while(j--) { - p->weight=w; + out = (tsvector *) palloc(in->len); + memcpy(out, in, in->len); + entry = ARRPTR(out); + i = out->size; + while (i--) + { + if ((j = POSDATALEN(out, entry)) != 0) + { + p = POSDATAPTR(out, entry); + while (j--) + { + p->weight = w; p++; } } entry++; } - + PG_FREE_IF_COPY(in, 0); PG_RETURN_POINTER(out); } static int -compareEntry(char *ptra, WordEntry* a, char *ptrb, WordEntry* b) +compareEntry(char *ptra, WordEntry * a, char *ptrb, WordEntry * b) { - if ( a->len == b->len) - { - return strncmp( - ptra + a->pos, - ptrb + b->pos, - a->len); - } - return ( a->len > b->len ) ? 1 : -1; + if (a->len == b->len) + { + return strncmp( + ptra + a->pos, + ptrb + b->pos, + a->len); + } + return (a->len > b->len) ? 1 : -1; } static int4 -add_pos(tsvector *src, WordEntry *srcptr, tsvector *dest, WordEntry *destptr, int4 maxpos ) { - uint16 *clen = (uint16*)_POSDATAPTR(dest,destptr); - int i; - uint16 slen = POSDATALEN(src, srcptr), startlen; - WordEntryPos *spos=POSDATAPTR(src, srcptr), *dpos=POSDATAPTR(dest,destptr); +add_pos(tsvector * src, WordEntry * srcptr, tsvector * dest, WordEntry * destptr, int4 maxpos) +{ + uint16 *clen = (uint16 *) _POSDATAPTR(dest, destptr); + int i; + uint16 slen = POSDATALEN(src, srcptr), + startlen; + WordEntryPos *spos = POSDATAPTR(src, srcptr), + *dpos = POSDATAPTR(dest, destptr); - if ( ! destptr->haspos ) - *clen=0; + if (!destptr->haspos) + *clen = 0; startlen = *clen; - for(i=0; i<slen && *clen<MAXNUMPOS && ( *clen==0 || dpos[ *clen-1 ].pos != MAXENTRYPOS-1 ) ;i++) { - dpos[ *clen ].weight = spos[i].weight; - dpos[ *clen ].pos = LIMITPOS(spos[i].pos + maxpos); + for (i = 0; i < slen && *clen < MAXNUMPOS && (*clen == 0 || dpos[*clen - 1].pos != MAXENTRYPOS - 1); i++) + { + dpos[*clen].weight = spos[i].weight; + dpos[*clen].pos = LIMITPOS(spos[i].pos + maxpos); (*clen)++; } - if ( *clen != startlen ) - destptr->haspos=1; - return *clen - startlen; + if (*clen != startlen) + destptr->haspos = 1; + return *clen - startlen; } Datum -concat(PG_FUNCTION_ARGS) { - tsvector *in1 = (tsvector *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); - tsvector *in2 = (tsvector *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); - tsvector *out; - WordEntry *ptr; - WordEntry *ptr1,*ptr2; +concat(PG_FUNCTION_ARGS) +{ + tsvector *in1 = (tsvector *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); + tsvector *in2 = (tsvector *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); + tsvector *out; + WordEntry *ptr; + WordEntry *ptr1, + *ptr2; WordEntryPos *p; - int maxpos=0,i,j,i1,i2; - char *cur; - char *data,*data1,*data2; + int maxpos = 0, + i, + j, + i1, + i2; + char *cur; + char *data, + *data1, + *data2; - ptr=ARRPTR(in1); - i=in1->size; - while(i--) { - if ( (j=POSDATALEN(in1,ptr)) != 0 ) { - p=POSDATAPTR(in1,ptr); - while(j--) { - if ( p->pos > maxpos ) + ptr = ARRPTR(in1); + i = in1->size; + while (i--) + { + if ((j = POSDATALEN(in1, ptr)) != 0) + { + p = POSDATAPTR(in1, ptr); + while (j--) + { + if (p->pos > maxpos) maxpos = p->pos; p++; } } ptr++; } - - ptr1=ARRPTR(in1); ptr2=ARRPTR(in2); - data1=STRPTR(in1); data2=STRPTR(in2); - i1=in1->size; i2=in2->size; - out=(tsvector*)palloc( in1->len + in2->len ); - memset(out,0,in1->len + in2->len); + + ptr1 = ARRPTR(in1); + ptr2 = ARRPTR(in2); + data1 = STRPTR(in1); + data2 = STRPTR(in2); + i1 = in1->size; + i2 = in2->size; + out = (tsvector *) palloc(in1->len + in2->len); + memset(out, 0, in1->len + in2->len); out->len = in1->len + in2->len; out->size = in1->size + in2->size; - data=cur=STRPTR(out); - ptr=ARRPTR(out); - while( i1 && i2 ) { - int cmp=compareEntry(data1,ptr1,data2,ptr2); - if ( cmp < 0 ) { /* in1 first */ + data = cur = STRPTR(out); + ptr = ARRPTR(out); + while (i1 && i2) + { + int cmp = compareEntry(data1, ptr1, data2, ptr2); + + if (cmp < 0) + { /* in1 first */ ptr->haspos = ptr1->haspos; ptr->len = ptr1->len; - memcpy( cur, data1 + ptr1->pos, ptr1->len ); - ptr->pos = cur - data; - cur+=SHORTALIGN(ptr1->len); - if ( ptr->haspos ) { - memcpy(cur, _POSDATAPTR(in1, ptr1), POSDATALEN(in1, ptr1)*sizeof(WordEntryPos) + sizeof(uint16)); - cur+=POSDATALEN(in1, ptr1)*sizeof(WordEntryPos) + sizeof(uint16); + memcpy(cur, data1 + ptr1->pos, ptr1->len); + ptr->pos = cur - data; + cur += SHORTALIGN(ptr1->len); + if (ptr->haspos) + { + memcpy(cur, _POSDATAPTR(in1, ptr1), POSDATALEN(in1, ptr1) * sizeof(WordEntryPos) + sizeof(uint16)); + cur += POSDATALEN(in1, ptr1) * sizeof(WordEntryPos) + sizeof(uint16); } - ptr++; ptr1++; i1--; - } else if ( cmp>0 ) { /* in2 first */ + ptr++; + ptr1++; + i1--; + } + else if (cmp > 0) + { /* in2 first */ ptr->haspos = ptr2->haspos; ptr->len = ptr2->len; - memcpy( cur, data2 + ptr2->pos, ptr2->len ); - ptr->pos = cur - data; - cur+=SHORTALIGN(ptr2->len); - if ( ptr->haspos ) { - int addlen = add_pos(in2, ptr2, out, ptr, maxpos ); - if ( addlen == 0 ) - ptr->haspos=0; + memcpy(cur, data2 + ptr2->pos, ptr2->len); + ptr->pos = cur - data; + cur += SHORTALIGN(ptr2->len); + if (ptr->haspos) + { + int addlen = add_pos(in2, ptr2, out, ptr, maxpos); + + if (addlen == 0) + ptr->haspos = 0; else - cur += addlen*sizeof(WordEntryPos) + sizeof(uint16); + cur += addlen * sizeof(WordEntryPos) + sizeof(uint16); } - ptr++; ptr2++; i2--; - } else { + ptr++; + ptr2++; + i2--; + } + else + { ptr->haspos = ptr1->haspos | ptr2->haspos; ptr->len = ptr1->len; - memcpy( cur, data1 + ptr1->pos, ptr1->len ); - ptr->pos = cur - data; - cur+=SHORTALIGN(ptr1->len); - if ( ptr->haspos ) { - if ( ptr1->haspos ) { - memcpy(cur, _POSDATAPTR(in1, ptr1), POSDATALEN(in1, ptr1)*sizeof(WordEntryPos) + sizeof(uint16)); - cur+=POSDATALEN(in1, ptr1)*sizeof(WordEntryPos) + sizeof(uint16); - if ( ptr2->haspos ) - cur += add_pos(in2, ptr2, out, ptr, maxpos )*sizeof(WordEntryPos); - } else if ( ptr2->haspos ) { - int addlen = add_pos(in2, ptr2, out, ptr, maxpos ); - if ( addlen == 0 ) - ptr->haspos=0; + memcpy(cur, data1 + ptr1->pos, ptr1->len); + ptr->pos = cur - data; + cur += SHORTALIGN(ptr1->len); + if (ptr->haspos) + { + if (ptr1->haspos) + { + memcpy(cur, _POSDATAPTR(in1, ptr1), POSDATALEN(in1, ptr1) * sizeof(WordEntryPos) + sizeof(uint16)); + cur += POSDATALEN(in1, ptr1) * sizeof(WordEntryPos) + sizeof(uint16); + if (ptr2->haspos) + cur += add_pos(in2, ptr2, out, ptr, maxpos) * sizeof(WordEntryPos); + } + else if (ptr2->haspos) + { + int addlen = add_pos(in2, ptr2, out, ptr, maxpos); + + if (addlen == 0) + ptr->haspos = 0; else - cur += addlen*sizeof(WordEntryPos) + sizeof(uint16); + cur += addlen * sizeof(WordEntryPos) + sizeof(uint16); } } - ptr++; ptr1++; ptr2++; i1--; i2--; + ptr++; + ptr1++; + ptr2++; + i1--; + i2--; } } - while(i1) { + while (i1) + { ptr->haspos = ptr1->haspos; ptr->len = ptr1->len; - memcpy( cur, data1 + ptr1->pos, ptr1->len ); - ptr->pos = cur - data; - cur+=SHORTALIGN(ptr1->len); - if ( ptr->haspos ) { - memcpy(cur, _POSDATAPTR(in1, ptr1), POSDATALEN(in1, ptr1)*sizeof(WordEntryPos) + sizeof(uint16)); - cur+=POSDATALEN(in1, ptr1)*sizeof(WordEntryPos) + sizeof(uint16); + memcpy(cur, data1 + ptr1->pos, ptr1->len); + ptr->pos = cur - data; + cur += SHORTALIGN(ptr1->len); + if (ptr->haspos) + { + memcpy(cur, _POSDATAPTR(in1, ptr1), POSDATALEN(in1, ptr1) * sizeof(WordEntryPos) + sizeof(uint16)); + cur += POSDATALEN(in1, ptr1) * sizeof(WordEntryPos) + sizeof(uint16); } - ptr++; ptr1++; i1--; + ptr++; + ptr1++; + i1--; } - while(i2) { + while (i2) + { ptr->haspos = ptr2->haspos; ptr->len = ptr2->len; - memcpy( cur, data2 + ptr2->pos, ptr2->len ); - ptr->pos = cur - data; - cur+=SHORTALIGN(ptr2->len); - if ( ptr->haspos ) { - int addlen = add_pos(in2, ptr2, out, ptr, maxpos ); - if ( addlen == 0 ) - ptr->haspos=0; + memcpy(cur, data2 + ptr2->pos, ptr2->len); + ptr->pos = cur - data; + cur += SHORTALIGN(ptr2->len); + if (ptr->haspos) + { + int addlen = add_pos(in2, ptr2, out, ptr, maxpos); + + if (addlen == 0) + ptr->haspos = 0; else - cur += addlen*sizeof(WordEntryPos) + sizeof(uint16); + cur += addlen * sizeof(WordEntryPos) + sizeof(uint16); } - ptr++; ptr2++; i2--; + ptr++; + ptr2++; + i2--; } - - out->size=ptr-ARRPTR(out); - out->len = CALCDATASIZE( out->size, cur-data ); - if ( data != STRPTR(out) ) - memmove( STRPTR(out), data, cur-data ); + + out->size = ptr - ARRPTR(out); + out->len = CALCDATASIZE(out->size, cur - data); + if (data != STRPTR(out)) + memmove(STRPTR(out), data, cur - data); PG_FREE_IF_COPY(in1, 0); PG_FREE_IF_COPY(in2, 1); PG_RETURN_POINTER(out); } - |