amroutine->amestimateparallelscan = NULL;
amroutine->aminitparallelscan = NULL;
amroutine->amparallelrescan = NULL;
+ amroutine->amtranslatestrategy = NULL;
+ amroutine->amtranslatecmptype = NULL;
PG_RETURN_POINTER(amroutine);
}
amestimateparallelscan_function amestimateparallelscan; /* can be NULL */
aminitparallelscan_function aminitparallelscan; /* can be NULL */
amparallelrescan_function amparallelrescan; /* can be NULL */
+
+ /* interface functions to support planning */
+ amtranslate_strategy_function amtranslatestrategy; /* can be NULL */
+ amtranslate_cmptype_function amtranslatecmptype; /* can be NULL */
} IndexAmRoutine;
</programlisting>
</para>
the beginning.
</para>
+ <para>
+<programlisting>
+CompareType
+amtranslatestrategy (StrategyNumber strategy, Oid opfamily, Oid opcintype);
+
+StrategyNumber
+amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype);
+</programlisting>
+ These functions, if implemented, will be called by the planer and executor
+ to convert between fixed <type>CompareType</type> values and the specific
+ strategy numbers used by the access method. These functions can be
+ implemented by access methods that implement functionality similar to the
+ built-in btree or hash access methods, and by implementing these
+ translations, the system can learn about the semantics of the access
+ method's operations and can use them in place of btree or hash indexes in
+ various places. If the functionality of the access method is not similar
+ to those built-in access methods, these functions do not need to be
+ implemented. If the functions are not implemented, the access method will
+ be ignored for certain planner and executor decisions, but is otherwise
+ fully functional.
+ </para>
+
</sect1>
<sect1 id="index-scanning">
amroutine->amestimateparallelscan = NULL;
amroutine->aminitparallelscan = NULL;
amroutine->amparallelrescan = NULL;
+ amroutine->amtranslatestrategy = NULL;
+ amroutine->amtranslatecmptype = NULL;
PG_RETURN_POINTER(amroutine);
}
amroutine->amestimateparallelscan = NULL;
amroutine->aminitparallelscan = NULL;
amroutine->amparallelrescan = NULL;
+ amroutine->amtranslatestrategy = NULL;
+ amroutine->amtranslatecmptype = NULL;
PG_RETURN_POINTER(amroutine);
}
#include "access/hash.h"
#include "access/hash_xlog.h"
#include "access/relscan.h"
+#include "access/stratnum.h"
#include "access/tableam.h"
#include "access/xloginsert.h"
#include "commands/progress.h"
amroutine->amestimateparallelscan = NULL;
amroutine->aminitparallelscan = NULL;
amroutine->amparallelrescan = NULL;
+ amroutine->amtranslatestrategy = hashtranslatestrategy;
+ amroutine->amtranslatecmptype = hashtranslatecmptype;
PG_RETURN_POINTER(amroutine);
}
else
LockBuffer(bucket_buf, BUFFER_LOCK_UNLOCK);
}
+
+CompareType
+hashtranslatestrategy(StrategyNumber strategy, Oid opfamily, Oid opcintype)
+{
+ if (strategy == HTEqualStrategyNumber)
+ return COMPARE_EQ;
+ return COMPARE_INVALID;
+}
+
+StrategyNumber
+hashtranslatecmptype(CompareType cmptype, Oid opfamily, Oid opcintype)
+{
+ if (cmptype == COMPARE_EQ)
+ return HTEqualStrategyNumber;
+ return InvalidStrategy;
+}
}
+/*
+ * IndexAmTranslateStrategy - given an access method and strategy, get the
+ * corresponding compare type.
+ *
+ * If missing_ok is false, throw an error if no compare type is found. If
+ * true, just return COMPARE_INVALID.
+ */
+CompareType
+IndexAmTranslateStrategy(StrategyNumber strategy, Oid amoid, Oid opfamily, Oid opcintype, bool missing_ok)
+{
+ CompareType result;
+ IndexAmRoutine *amroutine;
+
+ amroutine = GetIndexAmRoutineByAmId(amoid, false);
+ if (amroutine->amtranslatestrategy)
+ result = amroutine->amtranslatestrategy(strategy, opfamily, opcintype);
+ else
+ result = COMPARE_INVALID;
+
+ if (!missing_ok && result == COMPARE_INVALID)
+ elog(ERROR, "could not translate strategy number %d for index AM %u", strategy, amoid);
+
+ return result;
+}
+
+/*
+ * IndexAmTranslateCompareType - given an access method and compare type, get
+ * the corresponding strategy number.
+ *
+ * If missing_ok is false, throw an error if no strategy is found correlating
+ * to the given cmptype. If true, just return InvalidStrategy.
+ */
+StrategyNumber
+IndexAmTranslateCompareType(CompareType cmptype, Oid amoid, Oid opfamily, Oid opcintype, bool missing_ok)
+{
+ StrategyNumber result;
+ IndexAmRoutine *amroutine;
+
+ amroutine = GetIndexAmRoutineByAmId(amoid, false);
+ if (amroutine->amtranslatecmptype)
+ result = amroutine->amtranslatecmptype(cmptype, opfamily, opcintype);
+ else
+ result = InvalidStrategy;
+
+ if (!missing_ok && result == InvalidStrategy)
+ elog(ERROR, "could not translate compare type %u for index AM %u", cmptype, amoid);
+
+ return result;
+}
+
/*
* Ask appropriate access method to validate the specified opclass.
*/
#include "access/nbtree.h"
#include "access/relscan.h"
+#include "access/stratnum.h"
#include "commands/progress.h"
#include "commands/vacuum.h"
#include "nodes/execnodes.h"
amroutine->amestimateparallelscan = btestimateparallelscan;
amroutine->aminitparallelscan = btinitparallelscan;
amroutine->amparallelrescan = btparallelrescan;
+ amroutine->amtranslatestrategy = bttranslatestrategy;
+ amroutine->amtranslatecmptype = bttranslatecmptype;
PG_RETURN_POINTER(amroutine);
}
{
return _bt_getrootheight(rel);
}
+
+CompareType
+bttranslatestrategy(StrategyNumber strategy, Oid opfamily, Oid opcintype)
+{
+ switch (strategy)
+ {
+ case BTLessStrategyNumber:
+ return COMPARE_LT;
+ case BTLessEqualStrategyNumber:
+ return COMPARE_LE;
+ case BTEqualStrategyNumber:
+ return COMPARE_EQ;
+ case BTGreaterEqualStrategyNumber:
+ return COMPARE_GE;
+ case BTGreaterStrategyNumber:
+ return COMPARE_GT;
+ default:
+ return COMPARE_INVALID;
+ }
+}
+
+StrategyNumber
+bttranslatecmptype(CompareType cmptype, Oid opfamily, Oid opcintype)
+{
+ switch (cmptype)
+ {
+ case COMPARE_LT:
+ return BTLessStrategyNumber;
+ case COMPARE_LE:
+ return BTLessEqualStrategyNumber;
+ case COMPARE_EQ:
+ return BTEqualStrategyNumber;
+ case COMPARE_GE:
+ return BTGreaterEqualStrategyNumber;
+ case COMPARE_GT:
+ return BTGreaterStrategyNumber;
+ default:
+ return InvalidStrategy;
+ }
+}
amroutine->amestimateparallelscan = NULL;
amroutine->aminitparallelscan = NULL;
amroutine->amparallelrescan = NULL;
+ amroutine->amtranslatestrategy = NULL;
+ amroutine->amtranslatecmptype = NULL;
PG_RETURN_POINTER(amroutine);
}
#ifndef AMAPI_H
#define AMAPI_H
+#include "access/cmptype.h"
#include "access/genam.h"
+#include "access/stratnum.h"
/*
* We don't wish to include planner header files here, since most of an index
* Callback function signatures --- see indexam.sgml for more info.
*/
+/* translate AM-specific strategies to general operator types */
+typedef CompareType (*amtranslate_strategy_function) (StrategyNumber strategy, Oid opfamily, Oid opcintype);
+
+/* translate general operator types to AM-specific strategies */
+typedef StrategyNumber (*amtranslate_cmptype_function) (CompareType cmptype, Oid opfamily, Oid opcintype);
+
/* build new index */
typedef IndexBuildResult *(*ambuild_function) (Relation heapRelation,
Relation indexRelation,
amestimateparallelscan_function amestimateparallelscan; /* can be NULL */
aminitparallelscan_function aminitparallelscan; /* can be NULL */
amparallelrescan_function amparallelrescan; /* can be NULL */
+
+ /* interface functions to support planning */
+ amtranslate_strategy_function amtranslatestrategy; /* can be NULL */
+ amtranslate_cmptype_function amtranslatecmptype; /* can be NULL */
} IndexAmRoutine;
/* Functions in access/index/amapi.c */
extern IndexAmRoutine *GetIndexAmRoutine(Oid amhandler);
extern IndexAmRoutine *GetIndexAmRoutineByAmId(Oid amoid, bool noerror);
+extern CompareType IndexAmTranslateStrategy(StrategyNumber strategy, Oid amoid, Oid opfamily, Oid opcintype, bool missing_ok);
+extern StrategyNumber IndexAmTranslateCompareType(CompareType cmptype, Oid amoid, Oid opfamily, Oid opcintype, bool missing_ok);
#endif /* AMAPI_H */
*/
typedef enum CompareType
{
+ COMPARE_INVALID = 0,
COMPARE_LT = 1, /* BTLessStrategyNumber */
COMPARE_LE = 2, /* BTLessEqualStrategyNumber */
COMPARE_EQ = 3, /* BTEqualStrategyNumber */
List *operators,
List *functions);
+extern CompareType hashtranslatestrategy(StrategyNumber strategy, Oid opfamily, Oid opcintype);
+extern StrategyNumber hashtranslatecmptype(CompareType cmptype, Oid opfamily, Oid opcintype);
+
/* private routines */
/* hashinsert.c */
extern bool btcanreturn(Relation index, int attno);
extern int btgettreeheight(Relation rel);
+extern CompareType bttranslatestrategy(StrategyNumber strategy, Oid opfamily, Oid opcintype);
+extern StrategyNumber bttranslatecmptype(CompareType cmptype, Oid opfamily, Oid opcintype);
+
/*
* prototypes for internal functions in nbtree.c
*/
amproperty_function
amrescan_function
amrestrpos_function
+amtranslate_strategy_function amtranslatestrategy;
+amtranslate_cmptype_function amtranslatecmptype;
amvacuumcleanup_function
amvalidate_function
array_iter