summaryrefslogtreecommitdiff
path: root/src/backend/commands/opclasscmds.c
diff options
context:
space:
mode:
authorTom Lane2011-12-07 05:18:38 +0000
committerTom Lane2011-12-07 05:19:39 +0000
commitc6e3ac11b60ac4a8942ab964252d51c1c0bd8845 (patch)
treefa9ffffed5b31d01a007f447368fd9479bba3aef /src/backend/commands/opclasscmds.c
parentd2a662182eac1069ff3874a1db499508a13c6bca (diff)
Create a "sort support" interface API for faster sorting.
This patch creates an API whereby a btree index opclass can optionally provide non-SQL-callable support functions for sorting. In the initial patch, we only use this to provide a directly-callable comparator function, which can be invoked with a bit less overhead than the traditional SQL-callable comparator. While that should be of value in itself, the real reason for doing this is to provide a datatype-extensible framework for more aggressive optimizations, as in Peter Geoghegan's recent work. Robert Haas and Tom Lane
Diffstat (limited to 'src/backend/commands/opclasscmds.c')
-rw-r--r--src/backend/commands/opclasscmds.c88
1 files changed, 54 insertions, 34 deletions
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index 0ef3584bb2f..b7ab0e3203e 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -19,6 +19,7 @@
#include "access/genam.h"
#include "access/heapam.h"
+#include "access/nbtree.h"
#include "access/sysattr.h"
#include "catalog/dependency.h"
#include "catalog/indexing.h"
@@ -1151,27 +1152,48 @@ assignProcTypes(OpFamilyMember *member, Oid amoid, Oid typeoid)
procform = (Form_pg_proc) GETSTRUCT(proctup);
/*
- * btree support procs must be 2-arg procs returning int4; hash support
- * procs must be 1-arg procs returning int4; otherwise we don't know.
+ * btree comparison procs must be 2-arg procs returning int4, while btree
+ * sortsupport procs must take internal and return void. hash support
+ * procs must be 1-arg procs returning int4. Otherwise we don't know.
*/
if (amoid == BTREE_AM_OID)
{
- if (procform->pronargs != 2)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
- errmsg("btree procedures must have two arguments")));
- if (procform->prorettype != INT4OID)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
- errmsg("btree procedures must return integer")));
+ if (member->number == BTORDER_PROC)
+ {
+ if (procform->pronargs != 2)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("btree comparison procedures must have two arguments")));
+ if (procform->prorettype != INT4OID)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("btree comparison procedures must return integer")));
- /*
- * If lefttype/righttype isn't specified, use the proc's input types
- */
- if (!OidIsValid(member->lefttype))
- member->lefttype = procform->proargtypes.values[0];
- if (!OidIsValid(member->righttype))
- member->righttype = procform->proargtypes.values[1];
+ /*
+ * If lefttype/righttype isn't specified, use the proc's input
+ * types
+ */
+ if (!OidIsValid(member->lefttype))
+ member->lefttype = procform->proargtypes.values[0];
+ if (!OidIsValid(member->righttype))
+ member->righttype = procform->proargtypes.values[1];
+ }
+ else if (member->number == BTSORTSUPPORT_PROC)
+ {
+ if (procform->pronargs != 1 ||
+ procform->proargtypes.values[0] != INTERNALOID)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("btree sort support procedures must accept type \"internal\"")));
+ if (procform->prorettype != VOIDOID)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("btree sort support procedures must return void")));
+
+ /*
+ * Can't infer lefttype/righttype from proc, so use default rule
+ */
+ }
}
else if (amoid == HASH_AM_OID)
{
@@ -1192,23 +1214,21 @@ assignProcTypes(OpFamilyMember *member, Oid amoid, Oid typeoid)
if (!OidIsValid(member->righttype))
member->righttype = procform->proargtypes.values[0];
}
- else
- {
- /*
- * The default for GiST and GIN in CREATE OPERATOR CLASS is to use the
- * class' opcintype as lefttype and righttype. In CREATE or ALTER
- * OPERATOR FAMILY, opcintype isn't available, so make the user
- * specify the types.
- */
- if (!OidIsValid(member->lefttype))
- member->lefttype = typeoid;
- if (!OidIsValid(member->righttype))
- member->righttype = typeoid;
- if (!OidIsValid(member->lefttype) || !OidIsValid(member->righttype))
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
- errmsg("associated data types must be specified for index support procedure")));
- }
+
+ /*
+ * The default in CREATE OPERATOR CLASS is to use the class' opcintype as
+ * lefttype and righttype. In CREATE or ALTER OPERATOR FAMILY, opcintype
+ * isn't available, so make the user specify the types.
+ */
+ if (!OidIsValid(member->lefttype))
+ member->lefttype = typeoid;
+ if (!OidIsValid(member->righttype))
+ member->righttype = typeoid;
+
+ if (!OidIsValid(member->lefttype) || !OidIsValid(member->righttype))
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("associated data types must be specified for index support procedure")));
ReleaseSysCache(proctup);
}