]> granicus.if.org Git - postgresql/commitdiff
Fix freeing old values in index_store_float8_orderby_distances()
authorAlexander Korotkov <akorotkov@postgresql.org>
Thu, 19 Sep 2019 22:10:56 +0000 (01:10 +0300)
committerAlexander Korotkov <akorotkov@postgresql.org>
Thu, 19 Sep 2019 22:20:07 +0000 (01:20 +0300)
6cae9d2c10 has added an error in freeing old values in
index_store_float8_orderby_distances() function.  It looks for old value in
scan->xs_orderbynulls[i] after setting a new value there.
This commit fixes that.  Also it removes short-circuit in handling
distances == NULL situation.  Now distances == NULL will be treated the same
way as array with all null distances.  That is, previous values will be freed
if any.

Reported-by: Tom Lane, Nikita Glukhov
Discussion: https://postgr.es/m/CAPpHfdu2wcoAVAm3Ek66rP%3Duo_C-D84%2B%2Buf1VEcbyi_caBXWCA%40mail.gmail.com
Discussion: https://postgr.es/m/426580d3-a668-b9d1-7b8e-f74d1a6524e0%40postgrespro.ru
Backpatch-through: 12

src/backend/access/index/indexam.c

index 442f41425d4b85325c095dfca0d90f122a90dd36..9dfa0ddfbb6052be623876ad3ab3807b7d71b6eb 100644 (file)
@@ -852,28 +852,12 @@ index_store_float8_orderby_distances(IndexScanDesc scan, Oid *orderByTypes,
 {
        int                     i;
 
-       scan->xs_recheckorderby = recheckOrderBy;
-
-       if (!distances)
-       {
-               Assert(!scan->xs_recheckorderby);
-
-               for (i = 0; i < scan->numberOfOrderBys; i++)
-               {
-                       scan->xs_orderbyvals[i] = (Datum) 0;
-                       scan->xs_orderbynulls[i] = true;
-               }
+       Assert(distances || !recheckOrderBy);
 
-               return;
-       }
+       scan->xs_recheckorderby = recheckOrderBy;
 
        for (i = 0; i < scan->numberOfOrderBys; i++)
        {
-               scan->xs_orderbynulls[i] = distances[i].isnull;
-
-               if (scan->xs_orderbynulls[i])
-                       scan->xs_orderbyvals[i] = (Datum) 0;
-
                if (orderByTypes[i] == FLOAT8OID)
                {
 #ifndef USE_FLOAT8_BYVAL
@@ -881,8 +865,16 @@ index_store_float8_orderby_distances(IndexScanDesc scan, Oid *orderByTypes,
                        if (!scan->xs_orderbynulls[i])
                                pfree(DatumGetPointer(scan->xs_orderbyvals[i]));
 #endif
-                       if (!scan->xs_orderbynulls[i])
+                       if (distances && !distances[i].isnull)
+                       {
                                scan->xs_orderbyvals[i] = Float8GetDatum(distances[i].value);
+                               scan->xs_orderbynulls[i] = false;
+                       }
+                       else
+                       {
+                               scan->xs_orderbyvals[i] = (Datum) 0;
+                               scan->xs_orderbynulls[i] = true;
+                       }
                }
                else if (orderByTypes[i] == FLOAT4OID)
                {
@@ -892,8 +884,16 @@ index_store_float8_orderby_distances(IndexScanDesc scan, Oid *orderByTypes,
                        if (!scan->xs_orderbynulls[i])
                                pfree(DatumGetPointer(scan->xs_orderbyvals[i]));
 #endif
-                       if (!scan->xs_orderbynulls[i])
+                       if (distances && !distances[i].isnull)
+                       {
                                scan->xs_orderbyvals[i] = Float4GetDatum((float4) distances[i].value);
+                               scan->xs_orderbynulls[i] = false;
+                       }
+                       else
+                       {
+                               scan->xs_orderbyvals[i] = (Datum) 0;
+                               scan->xs_orderbynulls[i] = true;
+                       }
                }
                else
                {