diff options
author | Alexander Korotkov <akorotkov@postgresql.org> | 2018-09-19 01:54:10 +0300 |
---|---|---|
committer | Alexander Korotkov <akorotkov@postgresql.org> | 2018-09-19 01:54:10 +0300 |
commit | 2a6368343ff43743ddd90d0f4c2d0ac03e18aa85 (patch) | |
tree | cfe7805a40c662e0962965aa1f263ec44e6d1eff /src/backend/access/spgist/spgvalidate.c | |
parent | d0cfc3d6a44af1756ca5be8cb2414da7b8bf20d5 (diff) | |
download | postgresql-2a6368343ff43743ddd90d0f4c2d0ac03e18aa85.tar.gz postgresql-2a6368343ff43743ddd90d0f4c2d0ac03e18aa85.zip |
Add support for nearest-neighbor (KNN) searches to SP-GiST
Currently, KNN searches were supported only by GiST. SP-GiST also capable to
support them. This commit implements that support. SP-GiST scan stack is
replaced with queue, which serves as stack if no ordering is specified. KNN
support is provided for three SP-GIST opclasses: quad_point_ops, kd_point_ops
and poly_ops (catversion is bumped). Some common parts between GiST and SP-GiST
KNNs are extracted into separate functions.
Discussion: https://postgr.es/m/570825e8-47d0-4732-2bf6-88d67d2d51c8%40postgrespro.ru
Author: Nikita Glukhov, Alexander Korotkov based on GSoC work by Vlad Sterzhanov
Review: Andrey Borodin, Alexander Korotkov
Diffstat (limited to 'src/backend/access/spgist/spgvalidate.c')
-rw-r--r-- | src/backend/access/spgist/spgvalidate.c | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/src/backend/access/spgist/spgvalidate.c b/src/backend/access/spgist/spgvalidate.c index c7acc7fc025..8ba6c26f0c6 100644 --- a/src/backend/access/spgist/spgvalidate.c +++ b/src/backend/access/spgist/spgvalidate.c @@ -187,6 +187,7 @@ spgvalidate(Oid opclassoid) { HeapTuple oprtup = &oprlist->members[i]->tuple; Form_pg_amop oprform = (Form_pg_amop) GETSTRUCT(oprtup); + Oid op_rettype; /* TODO: Check that only allowed strategy numbers exist */ if (oprform->amopstrategy < 1 || oprform->amopstrategy > 63) @@ -200,20 +201,26 @@ spgvalidate(Oid opclassoid) result = false; } - /* spgist doesn't support ORDER BY operators */ - if (oprform->amoppurpose != AMOP_SEARCH || - OidIsValid(oprform->amopsortfamily)) + /* spgist supports ORDER BY operators */ + if (oprform->amoppurpose != AMOP_SEARCH) { - ereport(INFO, - (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("operator family \"%s\" of access method %s contains invalid ORDER BY specification for operator %s", - opfamilyname, "spgist", - format_operator(oprform->amopopr)))); - result = false; + /* ... and operator result must match the claimed btree opfamily */ + op_rettype = get_op_rettype(oprform->amopopr); + if (!opfamily_can_sort_type(oprform->amopsortfamily, op_rettype)) + { + ereport(INFO, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("operator family \"%s\" of access method %s contains invalid ORDER BY specification for operator %s", + opfamilyname, "spgist", + format_operator(oprform->amopopr)))); + result = false; + } } + else + op_rettype = BOOLOID; /* Check operator signature --- same for all spgist strategies */ - if (!check_amop_signature(oprform->amopopr, BOOLOID, + if (!check_amop_signature(oprform->amopopr, op_rettype, oprform->amoplefttype, oprform->amoprighttype)) { |