diff options
author | Alexander Korotkov <akorotkov@postgresql.org> | 2019-09-20 01:10:56 +0300 |
---|---|---|
committer | Alexander Korotkov <akorotkov@postgresql.org> | 2019-09-20 01:19:08 +0300 |
commit | 8c8a267201bebb0edeaab2a76b7d3bcc9739924f (patch) | |
tree | 2d8b34940beeeee24fb2e5825ee593575e8dc069 | |
parent | 6cae9d2c10e151f741e7bc64a8b70bb2615c367c (diff) | |
download | postgresql-8c8a267201bebb0edeaab2a76b7d3bcc9739924f.tar.gz postgresql-8c8a267201bebb0edeaab2a76b7d3bcc9739924f.zip |
Fix freeing old values in index_store_float8_orderby_distances()
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
-rw-r--r-- | src/backend/access/index/indexam.c | 40 |
1 files changed, 20 insertions, 20 deletions
diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c index 442f41425d4..9dfa0ddfbb6 100644 --- a/src/backend/access/index/indexam.c +++ b/src/backend/access/index/indexam.c @@ -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 { |