Commit f25d07d9 authored by Teodor Sigaev's avatar Teodor Sigaev

Fix lossy KNN GiST when ordering operator returns non-float8 value.

KNN GiST with recheck flag should return to executor the same type as ordering
operator, GiST detects this type by looking to return type of function which
implements ordering operator. But occasionally detecting code works after
replacing ordering operator function to distance support function.
Distance support function always returns float8, so, detecting code get float8
instead of actual return type of ordering operator.

Built-in opclasses don't have ordering operator which doesn't return
non-float8 value, so, tests are impossible here, at least now.

Backpatch to 9.5 where lozzy KNN was introduced.

Author: Alexander Korotkov
Report by: Artur Zakirov
parent 7191ce8b
...@@ -229,6 +229,10 @@ gistrescan(IndexScanDesc scan, ScanKey key, int nkeys, ...@@ -229,6 +229,10 @@ gistrescan(IndexScanDesc scan, ScanKey key, int nkeys,
{ {
ScanKey skey = scan->keyData + i; ScanKey skey = scan->keyData + i;
/*
* Copy consistent support function to ScanKey structure
* instead of function implementing filtering operator.
*/
fmgr_info_copy(&(skey->sk_func), fmgr_info_copy(&(skey->sk_func),
&(so->giststate->consistentFn[skey->sk_attno - 1]), &(so->giststate->consistentFn[skey->sk_attno - 1]),
so->giststate->scanCxt); so->giststate->scanCxt);
...@@ -284,8 +288,6 @@ gistrescan(IndexScanDesc scan, ScanKey key, int nkeys, ...@@ -284,8 +288,6 @@ gistrescan(IndexScanDesc scan, ScanKey key, int nkeys,
GIST_DISTANCE_PROC, skey->sk_attno, GIST_DISTANCE_PROC, skey->sk_attno,
RelationGetRelationName(scan->indexRelation)); RelationGetRelationName(scan->indexRelation));
fmgr_info_copy(&(skey->sk_func), finfo, so->giststate->scanCxt);
/* /*
* Look up the datatype returned by the original ordering * Look up the datatype returned by the original ordering
* operator. GiST always uses a float8 for the distance function, * operator. GiST always uses a float8 for the distance function,
...@@ -300,6 +302,12 @@ gistrescan(IndexScanDesc scan, ScanKey key, int nkeys, ...@@ -300,6 +302,12 @@ gistrescan(IndexScanDesc scan, ScanKey key, int nkeys,
*/ */
so->orderByTypes[i] = get_func_rettype(skey->sk_func.fn_oid); so->orderByTypes[i] = get_func_rettype(skey->sk_func.fn_oid);
/*
* Copy distance support function to ScanKey structure
* instead of function implementing ordering operator.
*/
fmgr_info_copy(&(skey->sk_func), finfo, so->giststate->scanCxt);
/* Restore prior fn_extra pointers, if not first time */ /* Restore prior fn_extra pointers, if not first time */
if (!first_time) if (!first_time)
skey->sk_func.fn_extra = fn_extras[i]; skey->sk_func.fn_extra = fn_extras[i];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment