diff options
author | Tom Lane | 2011-12-07 05:18:38 +0000 |
---|---|---|
committer | Tom Lane | 2011-12-07 05:19:39 +0000 |
commit | c6e3ac11b60ac4a8942ab964252d51c1c0bd8845 (patch) | |
tree | fa9ffffed5b31d01a007f447368fd9479bba3aef /src/backend/commands/opclasscmds.c | |
parent | d2a662182eac1069ff3874a1db499508a13c6bca (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.c | 88 |
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); } |