]> granicus.if.org Git - postgresql/commitdiff
Fix compare bug for tsvector: problem was in aligment. Per Stefan Kaltenbrunner ...
authorTeodor Sigaev <teodor@sigaev.ru>
Thu, 24 Aug 2006 17:37:34 +0000 (17:37 +0000)
committerTeodor Sigaev <teodor@sigaev.ru>
Thu, 24 Aug 2006 17:37:34 +0000 (17:37 +0000)
contrib/tsearch2/tsvector.c

index 4999b30d785efbc06cfd0dff857a2cc2fbfa6fb2..a52da49f0c98117f7183e3fd88a8271995805c14 100644 (file)
@@ -966,17 +966,43 @@ silly_cmp_tsvector(const tsvector * a, const tsvector * b)
                return 1;
        else
        {
-               unsigned char *aptr = (unsigned char *) (a->data) + DATAHDRSIZE;
-               unsigned char *bptr = (unsigned char *) (b->data) + DATAHDRSIZE;
+               WordEntry  *aptr = ARRPTR(a);
+               WordEntry  *bptr = ARRPTR(b);
+               int             i       = 0;
+               int             res;
+
+
+               for(i=0;i<a->size;i++) {
+                       if ( aptr->haspos != bptr->haspos ) {
+                               return ( aptr->haspos > bptr->haspos ) ? -1 : 1;
+                       } else if ( aptr->pos != bptr->pos ) {
+                               return ( aptr->pos > bptr->pos ) ? -1 : 1;
+                       } else if ( aptr->len != bptr->len ) {
+                               return ( aptr->len > bptr->len ) ? -1 : 1;
+                       } else if ( (res=strncmp(STRPTR(a) + aptr->pos, STRPTR(b) + bptr->pos, b->len))!= 0 ) {
+                               return res;
+                       } else if ( aptr->haspos ) {
+                               WordEntryPos    *ap = POSDATAPTR(a, aptr);
+                               WordEntryPos    *bp = POSDATAPTR(b, bptr);
+                               int                             j;
+
+                               if ( POSDATALEN(a, aptr) != POSDATALEN(b, bptr) )
+                                       return ( POSDATALEN(a, aptr) > POSDATALEN(b, bptr) ) ? -1 : 1;
+
+                               for(j=0;j<POSDATALEN(a, aptr);j++) {
+                                       if ( WEP_GETPOS(*ap) != WEP_GETPOS(*bp) ) {
+                                               return ( WEP_GETPOS(*ap) > WEP_GETPOS(*bp) ) ? -1 : 1;
+                                       } else if ( WEP_GETWEIGHT(*ap) != WEP_GETWEIGHT(*bp) ) {
+                                               return ( WEP_GETWEIGHT(*ap) > WEP_GETWEIGHT(*bp) ) ? -1 : 1;
+                                       }
+                                       ap++, bp++;
+                               }
+                       }
 
-               while (aptr - ((unsigned char *) (a->data)) < a->len)
-               {
-                       if (*aptr != *bptr)
-                               return (*aptr < *bptr) ? -1 : 1;
-                       aptr++;
-                       bptr++;
+                       aptr++; bptr++;
                }
        }
+
        return 0;
 }