aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/brin/brin.c
diff options
context:
space:
mode:
authorTomas Vondra <tomas.vondra@postgresql.org>2021-03-26 13:17:56 +0100
committerTomas Vondra <tomas.vondra@postgresql.org>2021-03-26 13:17:58 +0100
commita681e3c107aa97eb554f118935c4d2278892c3dd (patch)
tree809c76743781816de3c34de27d95c742499307de /src/backend/access/brin/brin.c
parenta68dfa27d42fb7b7611fd1206d2356fc124ed390 (diff)
downloadpostgresql-a681e3c107aa97eb554f118935c4d2278892c3dd.tar.gz
postgresql-a681e3c107aa97eb554f118935c4d2278892c3dd.zip
Support the old signature of BRIN consistent function
Commit a1c649d889 changed the signature of the BRIN consistent function by adding a new required parameter. Treating the parameter as optional, which would make the change backwards incompatibile, was rejected with the justification that there are few out-of-core extensions, so it's not worth adding making the code more complex, and it's better to deal with that in the extension. But after further thought, that would be rather problematic, because pg_upgrade simply dumps catalog contents and the same version of an extension needs to work on both PostgreSQL versions. Supporting both variants of the consistent function (with 3 or 4 arguments) makes that possible. The signature is not the only thing that changed, as commit 72ccf55cb9 moved handling of IS [NOT] NULL keys from the support procedures. But this change is backward compatible - handling the keys in exension is unnecessary, but harmless. The consistent function will do a bit of unnecessary work, but it should be very cheap. This also undoes most of the changes to the existing opclasses (minmax and inclusion), making them use the old signature again. This should make backpatching simpler. Catversion bump, because of changes in pg_amproc. Author: Tomas Vondra <tomas.vondra@postgresql.org> Author: Nikita Glukhov <n.gluhov@postgrespro.ru> Reviewed-by: Mark Dilger <hornschnorter@gmail.com> Reviewed-by: Alexander Korotkov <aekorotkov@gmail.com> Reviewed-by: Masahiko Sawada <masahiko.sawada@enterprisedb.com> Reviewed-by: John Naylor <john.naylor@enterprisedb.com> Discussion: https://postgr.es/m/c1138ead-7668-f0e1-0638-c3be3237e812@2ndquadrant.com
Diffstat (limited to 'src/backend/access/brin/brin.c')
-rw-r--r--src/backend/access/brin/brin.c60
1 files changed, 46 insertions, 14 deletions
diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c
index 0bf25fd05bd..2d8759c6c1a 100644
--- a/src/backend/access/brin/brin.c
+++ b/src/backend/access/brin/brin.c
@@ -635,25 +635,57 @@ bringetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
}
/*
+ * Collation from the first key (has to be the same for
+ * all keys for the same attribue).
+ */
+ collation = keys[attno - 1][0]->sk_collation;
+
+ /*
* Check whether the scan key is consistent with the page
* range values; if so, have the pages in the range added
* to the output bitmap.
*
- * XXX We simply use the collation from the first key (it
- * has to be the same for all keys for the same attribue).
+ * The opclass may or may not support processing of multiple
+ * scan keys. We can determine that based on the number of
+ * arguments - functions with extra parameter (number of scan
+ * keys) do support this, otherwise we have to simply pass the
+ * scan keys one by one.
*/
- collation = keys[attno - 1][0]->sk_collation;
-
- /* Check all keys at once */
- add = FunctionCall4Coll(&consistentFn[attno - 1],
- collation,
- PointerGetDatum(bdesc),
- PointerGetDatum(bval),
- PointerGetDatum(keys[attno - 1]),
- Int32GetDatum(nkeys[attno - 1]));
- addrange = DatumGetBool(add);
- if (!addrange)
- break;
+ if (consistentFn[attno - 1].fn_nargs >= 4)
+ {
+ /* Check all keys at once */
+ add = FunctionCall4Coll(&consistentFn[attno - 1],
+ collation,
+ PointerGetDatum(bdesc),
+ PointerGetDatum(bval),
+ PointerGetDatum(keys[attno - 1]),
+ Int32GetDatum(nkeys[attno - 1]));
+ addrange = DatumGetBool(add);
+ }
+ else
+ {
+ /*
+ * Check keys one by one
+ *
+ * When there are multiple scan keys, failure to meet the
+ * criteria for a single one of them is enough to discard
+ * the range as a whole, so break out of the loop as soon
+ * as a false return value is obtained.
+ */
+ int keyno;
+
+ for (keyno = 0; keyno < nkeys[attno - 1]; keyno++)
+ {
+ add = FunctionCall3Coll(&consistentFn[attno - 1],
+ keys[attno - 1][keyno]->sk_collation,
+ PointerGetDatum(bdesc),
+ PointerGetDatum(bval),
+ PointerGetDatum(keys[attno - 1][keyno]));
+ addrange = DatumGetBool(add);
+ if (!addrange)
+ break;
+ }
+ }
}
}
}