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

📄 predmig.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 2 页
字号:
{	Stream		temp,				parent;	int			lowest = xfunc_num_relids((Stream) xfunc_get_upjoin(bottom));	bool		progress;	LispValue	primjoin;	int			whichchild;	if (!lowest)		return;					/* no joins in stream, so no groups */	/* initialize groups to be single nodes */	for (temp = root;		 temp != (Stream) NULL && temp != bottom;		 temp = (Stream) get_downstream(temp))	{		/* if a Join node */		if (!is_clause(temp))		{			if (get_pathptr((Stream) get_downstream(temp))			== (pathPtr) get_outerjoinpath((JoinPath) get_pathptr(temp)))				whichchild = OUTER;			else				whichchild = INNER;			set_groupcost(temp,						  xfunc_join_expense((JoinPath) get_pathptr(temp),											 whichchild));			if (primjoin = xfunc_primary_join((JoinPath) get_pathptr(temp)))			{				set_groupsel(temp,							 compute_clause_selec(queryInfo,												  primjoin, NIL));			}			else				set_groupsel(temp, 1.0);		}		else/* a restriction, or 2-ary join pred */		{			set_groupcost(temp,						  xfunc_expense(queryInfo,										get_clause(get_cinfo(temp))));			set_groupsel(temp,						 compute_clause_selec(queryInfo,											  get_clause(get_cinfo(temp)),											  NIL));		}		set_groupup(temp, false);	}	/* make passes upwards, forming groups */	do	{		progress = false;		for (temp = (Stream) get_upstream(bottom);			 temp != (Stream) NULL;			 temp = (Stream) get_upstream(temp))		{			/* check for grouping with node upstream */			if (!get_groupup(temp) &&	/* not already grouped */				(parent = (Stream) get_upstream(temp)) != (Stream) NULL &&			/* temp is a join or temp is the top of a group */				(is_join((Path) get_pathptr(temp)) ||				 get_downstream(temp) &&				 get_groupup((Stream) get_downstream(temp))) &&				get_grouprank(parent) < get_grouprank(temp))			{				progress = true;/* we formed a new group */				set_groupup(temp, true);				set_groupcost(temp,							  get_groupcost(temp) +							  get_groupsel(temp) * get_groupcost(parent));				set_groupsel(temp, get_groupsel(temp) * get_groupsel(parent));				/* fix costs and sels of all members of group */				xfunc_setup_group(temp, bottom);			}		}	} while (progress);}/* -------------------					 UTILITY FUNCTIONS	   ------------------------- *//* ** xfunc_free_stream **   walk down a stream and pfree it */static voidxfunc_free_stream(Stream root){	Stream		cur,				next;	Assert(xfunc_check_stream(root));	if (root != (Stream) NULL)		for (cur = root; cur != (Stream) NULL; cur = next)		{			next = (Stream) get_downstream(cur);			pfree(cur);		}}/* ** xfunc_add<_clauses **    find any clauses above current, and insert them into stream as ** appropriate.  Return uppermost clause inserted, or current if none. */static Streamxfunc_add_clauses(Stream current){	Stream		topnode = current;	LispValue	temp;	LispValue	primjoin;	/* first add in the local clauses */	foreach(temp, get_loc_restrictinfo((Path) get_pathptr(current)))	{		topnode = xfunc_streaminsert((RestrictInfo) lfirst(temp), topnode,									 XFUNC_LOCPRD);	}	/* and add in the join clauses */	if (IsA(get_pathptr(current), JoinPath))	{		primjoin = xfunc_primary_join((JoinPath) get_pathptr(current));		foreach(temp, get_pathrestrictinfo((JoinPath) get_pathptr(current)))		{			if (!equal(get_clause((RestrictInfo) lfirst(temp)), primjoin))				topnode = xfunc_streaminsert((RestrictInfo) lfirst(temp), topnode,											 XFUNC_JOINPRD);		}	}	return topnode;}/* ** xfunc_setup_group **   find all elements of stream that are grouped with node and are above ** bottom, and set their groupcost and groupsel to be the same as node's. */static voidxfunc_setup_group(Stream node, Stream bottom){	Stream		temp;	if (node != bottom)		/* traverse downwards */		for (temp = (Stream) get_downstream(node);			 temp != (Stream) NULL && temp != bottom;			 temp = (Stream) get_downstream(temp))		{			if (!get_groupup(temp))				break;			else			{				set_groupcost(temp, get_groupcost(node));				set_groupsel(temp, get_groupsel(node));			}		}	/* traverse upwards */	for (temp = (Stream) get_upstream(node); temp != (Stream) NULL;		 temp = (Stream) get_upstream(temp))	{		if (!get_groupup((Stream) get_downstream(temp)))			break;		else		{			set_groupcost(temp, get_groupcost(node));			set_groupsel(temp, get_groupsel(node));		}	}}/* ** xfunc_streaminsert **    Make a new Stream node to hold clause, and insert it above current. ** Return new node. */static Streamxfunc_streaminsert(RestrictInfo restrictinfo,				   Stream current,				   int clausetype)		/* XFUNC_LOCPRD or XFUNC_JOINPRD */{	Stream		newstream = RMakeStream();	set_upstream(newstream, get_upstream(current));	if (get_upstream(current))		set_downstream((Stream) (get_upstream(current)), (StreamPtr) newstream);	set_upstream(current, (StreamPtr) newstream);	set_downstream(newstream, (StreamPtr) current);	set_pathptr(newstream, get_pathptr(current));	set_cinfo(newstream, restrictinfo);	set_clausetype(newstream, clausetype);	return newstream;}/* ** Given a Stream node, find the number of relids referenced in the pathnode ** associated with the stream node.  The number of relids gives a unique ** ordering on the joins in a stream, which we use to compare the height of ** join nodes. */static intxfunc_num_relids(Stream node){	if (!node || !IsA(get_pathptr(node), JoinPath))		return 0;	else		return (length				(get_relids(get_parent((JoinPath) get_pathptr(node)))));}/* ** xfunc_get_downjoin **    Given a stream node, find the next lowest node which points to a ** join predicate or a scan node. */static StreamPtrxfunc_get_downjoin(Stream node){	Stream		temp;	if (!is_clause(node))		/* if this is a join */		node = (Stream) get_downstream(node);	for (temp = node; temp && is_clause(temp);		 temp = (Stream) get_downstream(temp))		 /* empty body in for loop */ ;	return (StreamPtr) temp;}/* ** xfunc_get_upjoin **   same as above, but upwards. */static StreamPtrxfunc_get_upjoin(Stream node){	Stream		temp;	if (!is_clause(node))		/* if this is a join */		node = (Stream) get_upstream(node);	for (temp = node; temp && is_clause(temp);		 temp = (Stream) get_upstream(temp))		 /* empty body in for loop */ ;	return (StreamPtr) temp;}/* ** xfunc_stream_qsort **   Given a stream, sort by group rank the elements in the stream from the ** node "bottom" up.  DESTRUCTIVELY MODIFIES STREAM!  Returns new root. */static Streamxfunc_stream_qsort(Stream root, Stream bottom){	int			i;	size_t		num;	Stream	   *nodearray,				output;	Stream		tmp;	/* find size of list */	for (num = 0, tmp = root; tmp != bottom;		 tmp = (Stream) get_downstream(tmp))		num++;	if (num <= 1)		return root;	/* copy elements of the list into an array */	nodearray = (Stream *) palloc(num * sizeof(Stream));	for (tmp = root, i = 0; tmp != bottom;		 tmp = (Stream) get_downstream(tmp), i++)		nodearray[i] = tmp;	/* sort the array */	qsort(nodearray, num, sizeof(LispValue), xfunc_stream_compare);	/* paste together the array elements */	output = nodearray[num - 1];	set_upstream(output, (StreamPtr) NULL);	for (i = num - 2; i >= 0; i--)	{		set_downstream(nodearray[i + 1], (StreamPtr) nodearray[i]);		set_upstream(nodearray[i], (StreamPtr) nodearray[i + 1]);	}	set_downstream(nodearray[0], (StreamPtr) bottom);	if (bottom)		set_upstream(bottom, (StreamPtr) nodearray[0]);	Assert(xfunc_check_stream(output));	return output;}/* ** xfunc_stream_compare **    comparison function for xfunc_stream_qsort. ** Compare nodes by group rank.  If group ranks are equal, ensure that ** join nodes appear in same order as in plan tree. */static intxfunc_stream_compare(void *arg1, void *arg2){	Stream		stream1 = *(Stream *) arg1;	Stream		stream2 = *(Stream *) arg2;	Cost		rank1,				rank2;	rank1 = get_grouprank(stream1);	rank2 = get_grouprank(stream2);	if (rank1 > rank2)		return 1;	else if (rank1 < rank2)		return -1;	else	{		if (is_clause(stream1) && is_clause(stream2))			return 0;			/* doesn't matter what order if both are								 * restrictions */		else if (!is_clause(stream1) && !is_clause(stream2))		{			if (xfunc_num_relids(stream1) < xfunc_num_relids(stream2))				return -1;			else				return 1;		}		else if (is_clause(stream1) && !is_clause(stream2))		{			if (xfunc_num_relids(stream1) == xfunc_num_relids(stream2))				/* stream1 is a restriction over stream2 */				return 1;			else				return -1;		}		else if (!is_clause(stream1) && is_clause(stream2))		{			/* stream2 is a restriction over stream1: never push down */			return -1;		}	}}/* ------------------  DEBUGGING ROUTINES ---------------------------- *//* ** Make sure all pointers in stream make sense.  Make sure no joins are ** out of order. */static boolxfunc_check_stream(Stream node){	Stream		temp;	int			numrelids,				tmp;	/* set numrelids higher than max */	if (!is_clause(node))		numrelids = xfunc_num_relids(node) + 1;	else if (xfunc_get_downjoin(node))		numrelids = xfunc_num_relids((Stream) xfunc_get_downjoin(node)) + 1;	else		numrelids = 1;	for (temp = node; get_downstream(temp); temp = (Stream) get_downstream(temp))	{		if ((Stream) get_upstream((Stream) get_downstream(temp)) != temp)		{			elog(ERROR, "bad pointers in stream");			return false;		}		if (!is_clause(temp))		{			if ((tmp = xfunc_num_relids(temp)) >= numrelids)			{				elog(ERROR, "Joins got reordered!");				return false;			}			numrelids = tmp;		}	}	return true;}/* ** xfunc_in_stream **   check if node is in stream */static boolxfunc_in_stream(Stream node, Stream stream){	Stream		temp;	for (temp = stream; temp; temp = (Stream) get_downstream(temp))		if (temp == node)			return 1;	return 0;}

⌨️ 快捷键说明

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