⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtstrat.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
字号:
/*------------------------------------------------------------------------- * * rtstrat.c *	  strategy map data for rtrees. * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION *	  $Header: /usr/local/cvsroot/pgsql/src/backend/access/rtree/rtstrat.c,v 1.11.2.1 1999/08/02 05:24:44 scrappy Exp $ * *------------------------------------------------------------------------- */#include "postgres.h"#include "access/istrat.h"#include "access/rtree.h"static StrategyNumber RelationGetRTStrategy(Relation r,					  AttrNumber attnum, RegProcedure proc);/* *	Note:  negate, commute, and negatecommute all assume that operators are *		   ordered as follows in the strategy map: * *		left, left-or-overlap, overlap, right-or-overlap, right, same, *		contains, contained-by * *	The negate, commute, and negatecommute arrays are used by the planner *	to plan indexed scans over data that appears in the qualificiation in *	a boolean negation, or whose operands appear in the wrong order.  For *	example, if the operator "<%" means "contains", and the user says * *		where not rel.box <% "(10,10,20,20)"::box * *	the planner can plan an index scan by noting that rtree indices have *	an operator in their operator class for negating <%. * *	Similarly, if the user says something like * *		where "(10,10,20,20)"::box <% rel.box * *	the planner can see that the rtree index on rel.box has an operator in *	its opclass for commuting <%, and plan the scan using that operator. *	This added complexity in the access methods makes the planner a lot easier *	to write. *//* if a op b, what operator tells us if (not a op b)? */static StrategyNumber RTNegate[RTNStrategies] = {	InvalidStrategy,	InvalidStrategy,	InvalidStrategy,	InvalidStrategy,	InvalidStrategy,	InvalidStrategy,	InvalidStrategy,	InvalidStrategy};/* if a op_1 b, what is the operator op_2 such that b op_2 a? */static StrategyNumber RTCommute[RTNStrategies] = {	InvalidStrategy,	InvalidStrategy,	InvalidStrategy,	InvalidStrategy,	InvalidStrategy,	InvalidStrategy,	InvalidStrategy,	InvalidStrategy};/* if a op_1 b, what is the operator op_2 such that (b !op_2 a)? */static StrategyNumber RTNegateCommute[RTNStrategies] = {	InvalidStrategy,	InvalidStrategy,	InvalidStrategy,	InvalidStrategy,	InvalidStrategy,	InvalidStrategy,	InvalidStrategy,	InvalidStrategy};/* *	Now do the TermData arrays.  These exist in case the user doesn't give *	us a full set of operators for a particular operator class.  The idea *	is that by making multiple comparisons using any one of the supplied *	operators, we can decide whether two n-dimensional polygons are equal. *	For example, if a contains b and b contains a, we may conclude that *	a and b are equal. * *	The presence of the TermData arrays in all this is a historical accident. *	Early in the development of the POSTGRES access methods, it was believed *	that writing functions was harder than writing arrays.	This is wrong; *	TermData is hard to understand and hard to get right.  In general, when *	someone populates a new operator class, the populate it completely.  If *	Mike Hirohama had forced Cimarron Taylor to populate the strategy map *	for btree int2_ops completely in 1988, you wouldn't have to deal with *	all this now.  Too bad for you. * *	Since you can't necessarily do this in all cases (for example, you can't *	do it given only "intersects" or "disjoint"), TermData arrays for some *	operators don't appear below. * *	Note that if you DO supply all the operators required in a given opclass *	by inserting them into the pg_opclass system catalog, you can get away *	without doing all this TermData stuff.	Since the rtree code is intended *	to be a reference for access method implementors, I'm doing TermData *	correctly here. * *	Note on style:	these are all actually of type StrategyTermData, but *	since those have variable-length data at the end of the struct we can't *	properly initialize them if we declare them to be what they are. *//* if you only have "contained-by", how do you determine equality? */static uint16 RTContainedByTermData[] = {	2,							/* make two comparisons */	RTContainedByStrategyNumber,/* use "a contained-by b" */	0x0,						/* without any magic */	RTContainedByStrategyNumber,/* then use contained-by, */	SK_COMMUTE					/* swapping a and b */};/* if you only have "contains", how do you determine equality? */static uint16 RTContainsTermData[] = {	2,							/* make two comparisons */	RTContainsStrategyNumber,	/* use "a contains b" */	0x0,						/* without any magic */	RTContainsStrategyNumber,	/* then use contains again, */	SK_COMMUTE					/* swapping a and b */};/* now put all that together in one place for the planner */static StrategyTerm RTEqualExpressionData[] = {	(StrategyTerm) RTContainedByTermData,	(StrategyTerm) RTContainsTermData,	NULL};/* *	If you were sufficiently attentive to detail, you would go through *	the ExpressionData pain above for every one of the seven strategies *	we defined.  I am not.	Now we declare the StrategyEvaluationData *	structure that gets shipped around to help the planner and the access *	method decide what sort of scan it should do, based on (a) what the *	user asked for, (b) what operators are defined for a particular opclass, *	and (c) the reams of information we supplied above. * *	The idea of all of this initialized data is to make life easier on the *	user when he defines a new operator class to use this access method. *	By filling in all the data, we let him get away with leaving holes in his *	operator class, and still let him use the index.  The added complexity *	in the access methods just isn't worth the trouble, though. */static StrategyEvaluationData RTEvaluationData = {	RTNStrategies,				/* # of strategies */	(StrategyTransformMap) RTNegate,	/* how to do (not qual) */	(StrategyTransformMap) RTCommute,	/* how to swap operands */	(StrategyTransformMap) RTNegateCommute,		/* how to do both */	{		NULL,					/* express left */		NULL,					/* express overleft */		NULL,					/* express over */		NULL,					/* express overright */		NULL,					/* express right */		(StrategyExpression) RTEqualExpressionData,		/* express same */		NULL,					/* express contains */		NULL,					/* express contained-by */		NULL,		NULL,		NULL	}};/* *	Okay, now something peculiar to rtrees that doesn't apply to most other *	indexing structures:  When we're searching a tree for a given value, we *	can't do the same sorts of comparisons on internal node entries as we *	do at leaves.  The reason is that if we're looking for (say) all boxes *	that are the same as (0,0,10,10), then we need to find all leaf pages *	that overlap that region.  So internally we search for overlap, and at *	the leaf we search for equality. * *	This array maps leaf search operators to the internal search operators. *	We assume the normal ordering on operators: * *		left, left-or-overlap, overlap, right-or-overlap, right, same, *		contains, contained-by */static StrategyNumber RTOperMap[RTNStrategies] = {	RTOverLeftStrategyNumber,	RTOverLeftStrategyNumber,	RTOverlapStrategyNumber,	RTOverRightStrategyNumber,	RTOverRightStrategyNumber,	RTContainsStrategyNumber,	RTContainsStrategyNumber,	RTOverlapStrategyNumber};static StrategyNumberRelationGetRTStrategy(Relation r,					  AttrNumber attnum,					  RegProcedure proc){	return RelationGetStrategy(r, attnum, &RTEvaluationData, proc);}#ifdef NOT_USEDboolRelationInvokeRTStrategy(Relation r,						 AttrNumber attnum,						 StrategyNumber s,						 Datum left,						 Datum right){	return (RelationInvokeStrategy(r, &RTEvaluationData, attnum, s,								   left, right));}#endifRegProcedureRTMapOperator(Relation r,			  AttrNumber attnum,			  RegProcedure proc){	StrategyNumber procstrat;	StrategyMap strategyMap;	procstrat = RelationGetRTStrategy(r, attnum, proc);	strategyMap = IndexStrategyGetStrategyMap(RelationGetIndexStrategy(r),											  RTNStrategies,											  attnum);	return strategyMap->entry[RTOperMap[procstrat - 1] - 1].sk_procedure;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -