Fix memory arrangement of tsquery after removing stop words. It causes
authorTeodor Sigaev <teodor@sigaev.ru>
Fri, 7 Mar 2008 15:29:27 +0000 (15:29 +0000)
committerTeodor Sigaev <teodor@sigaev.ru>
Fri, 7 Mar 2008 15:29:27 +0000 (15:29 +0000)
a unused memory holes in tsquery.

Per report by Richard Huxton <dev@archonet.com>.

It was working well because in fact tsquery->size is not used for any
kind of operation except comparing tsqueries. To prevent requirement
of renew all stored tsquery optimization in CompareTSQ is removed.

src/backend/tsearch/to_tsany.c
src/backend/utils/adt/tsquery_op.c

index 71f4db3a54e9ff97319aa3611b25f9a9bd101844..9fcae7959e24205df84320fdf63a26151d17b6dc 100644 (file)
@@ -350,6 +350,18 @@ to_tsquery_byid(PG_FUNCTION_ARGS)
                PG_RETURN_POINTER(query);
        }
        memcpy((void *) GETQUERY(query), (void *) res, len * sizeof(QueryItem));
+
+       if ( len != query->size ) {
+               char            *oldoperand = GETOPERAND(query);
+               int4 lenoperand = VARSIZE(query) - (oldoperand - (char*)query);
+
+               Assert( len < query->size );
+
+               query->size = len;
+               memcpy((void *) GETOPERAND(query), oldoperand, VARSIZE(query) - (oldoperand - (char*)query) );
+               SET_VARSIZE(query, COMPUTESIZE( len, lenoperand )); 
+       }
+
        pfree(res);
        PG_RETURN_TSQUERY(query);
 }
@@ -388,6 +400,18 @@ plainto_tsquery_byid(PG_FUNCTION_ARGS)
                PG_RETURN_POINTER(query);
        }
        memcpy((void *) GETQUERY(query), (void *) res, len * sizeof(QueryItem));
+
+       if ( len != query->size ) {
+               char            *oldoperand = GETOPERAND(query);
+               int4 lenoperand = VARSIZE(query) - (oldoperand - (char*)query);
+
+               Assert( len < query->size );
+
+               query->size = len;
+               memcpy((void *) GETOPERAND(query), oldoperand, lenoperand );
+               SET_VARSIZE(query, COMPUTESIZE( len, lenoperand )); 
+       }
+
        pfree(res);
        PG_RETURN_POINTER(query);
 }
index 0af69964e8f413f4dc41cf3cb0a8c14415ca1c36..34889c4b00a775d7f343c0c49843aee4b19602fb 100644 (file)
@@ -141,27 +141,14 @@ tsquery_not(PG_FUNCTION_ARGS)
 static int
 CompareTSQ(TSQuery a, TSQuery b)
 {
-       if (a->size != b->size)
-       {
-               return (a->size < b->size) ? -1 : 1;
-       }
-       else if (VARSIZE(a) != VARSIZE(b))
-       {
-               return (VARSIZE(a) < VARSIZE(b)) ? -1 : 1;
-       }
-       else
-       {
-               QTNode     *an = QT2QTN(GETQUERY(a), GETOPERAND(a));
-               QTNode     *bn = QT2QTN(GETQUERY(b), GETOPERAND(b));
-               int                     res = QTNodeCompare(an, bn);
-
-               QTNFree(an);
-               QTNFree(bn);
+       QTNode     *an = QT2QTN(GETQUERY(a), GETOPERAND(a));
+       QTNode     *bn = QT2QTN(GETQUERY(b), GETOPERAND(b));
+       int                     res = QTNodeCompare(an, bn);
 
-               return res;
-       }
+       QTNFree(an);
+       QTNFree(bn);
 
-       return 0;
+       return res;
 }
 
 Datum