Fix memory arrangement of tsquery after removing stop words. It causes
authorTeodor Sigaev <teodor@sigaev.ru>
Fri, 7 Mar 2008 14:30:20 +0000 (14:30 +0000)
committerTeodor Sigaev <teodor@sigaev.ru>
Fri, 7 Mar 2008 14:30:20 +0000 (14:30 +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. So, in HEAD it's enough to
fix to_tsquery function, but for previous version it's needed to
remove optimization in CompareTSQ to prevent requirement of renew all
stored tsquery.

src/backend/tsearch/to_tsany.c

index 06855fb025b587f8a8d41ada4b3cc0c740320647..f629025e449c349edf64a13b9ae98ee0deb48bd8 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);
 }