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

📄 pathnode.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------- * * pathnode.c *	  Routines to manipulate pathlists and create path nodes * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION *	  $Header: /usr/local/cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.42.2.1 1999/08/02 06:27:08 scrappy Exp $ * *------------------------------------------------------------------------- */#include <math.h>#include "postgres.h"#include "optimizer/cost.h"#include "optimizer/keys.h"#include "optimizer/ordering.h"#include "optimizer/pathnode.h"#include "optimizer/paths.h"#include "optimizer/plancat.h"#include "optimizer/restrictinfo.h"#include "parser/parsetree.h"static Path *better_path(Path *new_path, List *unique_paths, bool *is_new);/***************************************************************************** *		MISC. PATH UTILITIES *****************************************************************************//* * path_is_cheaper *	  Returns t iff 'path1' is cheaper than 'path2'. * */boolpath_is_cheaper(Path *path1, Path *path2){	Cost		cost1 = path1->path_cost;	Cost		cost2 = path2->path_cost;	return (bool) (cost1 < cost2);}/* * set_cheapest *	  Finds the minimum cost path from among a relation's paths. * * 'parent_rel' is the parent relation * 'pathlist' is a list of path nodes corresponding to 'parent_rel' * * Returns and sets the relation entry field with the pathnode that * is minimum. * */Path *set_cheapest(RelOptInfo *parent_rel, List *pathlist){	List	   *p;	Path	   *cheapest_so_far;	Assert(pathlist != NIL);	Assert(IsA(parent_rel, RelOptInfo));	cheapest_so_far = (Path *) lfirst(pathlist);	foreach(p, lnext(pathlist))	{		Path	   *path = (Path *) lfirst(p);		if (path_is_cheaper(path, cheapest_so_far))			cheapest_so_far = path;	}	parent_rel->cheapestpath = cheapest_so_far;	return cheapest_so_far;}/* * add_pathlist *	  For each path in the list 'new_paths', add to the list 'unique_paths' *	  only those paths that are unique (i.e., unique ordering and ordering *	  keys).  Should a conflict arise, the more expensive path is thrown out, *	  thereby pruning the plan space.  But we don't prune if xfunc *	  told us not to. * * 'parent_rel' is the relation entry to which these paths correspond. * * Returns the list of unique pathnodes. * */List *add_pathlist(RelOptInfo *parent_rel, List *unique_paths, List *new_paths){	List	   *p1;	foreach(p1, new_paths)	{		Path	   *new_path = (Path *) lfirst(p1);		Path	   *old_path;		bool		is_new;		/* Is this new path already in unique_paths? */		if (member(new_path, unique_paths))			continue;		/* Find best matching path */		old_path = better_path(new_path, unique_paths, &is_new);		if (is_new)		{			/* This is a brand new path.  */			new_path->parent = parent_rel;			unique_paths = lcons(new_path, unique_paths);		}		else if (old_path == NULL)		{			;					/* do nothing if path is not cheaper */		}		else if (old_path != NULL)		{						/* (IsA(old_path,Path)) { */			new_path->parent = parent_rel;			if (!parent_rel->pruneable)				unique_paths = lcons(new_path, unique_paths);			else				unique_paths = lcons(new_path,									 LispRemove(old_path, unique_paths));		}	}	return unique_paths;}/* * better_path *	  Determines whether 'new_path' has the same ordering and keys as some *	  path in the list 'unique_paths'.	If there is a redundant path, *	  eliminate the more expensive path. * * Returns: *	  The old path - if 'new_path' matches some path in 'unique_paths' and is *				cheaper *	  nil - if 'new_path' matches but isn't cheaper *	  t - if there is no path in the list with the same ordering and keys * */static Path *better_path(Path *new_path, List *unique_paths, bool *is_new){	Path	   *path = (Path *) NULL;	List	   *temp = NIL;	int			better_key;	int			better_sort;#ifdef OPTDUP_DEBUG	printf("better_path entry\n");	printf("new\n");	pprint(new_path);	printf("unique_paths\n");	pprint(unique_paths);#endif	foreach(temp, unique_paths)	{		path = (Path *) lfirst(temp);#ifdef OPTDUP_DEBUG		if (!pathkeys_match(new_path->pathkeys, path->pathkeys, &better_key) ||			better_key != 0)		{			printf("betterkey = %d\n", better_key);			printf("newpath\n");			pprint(new_path->pathkeys);			printf("oldpath\n");			pprint(path->pathkeys);			if (path->pathkeys && new_path->pathkeys &&				length(lfirst(path->pathkeys)) >= 2		/* &&														 * length(lfirst(path->pa														 * thkeys)) <														 * length(lfirst(new_path					->pathkeys)) */ )				sleep(0);		/* set breakpoint here */		}		if (!pathorder_match(new_path->pathorder, path->pathorder,							 &better_sort) ||			better_sort != 0)		{			printf("neword\n");			pprint(new_path->pathorder);			printf("oldord\n");			pprint(path->pathorder);		}#endif		if (pathkeys_match(new_path->pathkeys, path->pathkeys,						   &better_key) &&			pathorder_match(new_path->pathorder, path->pathorder,							&better_sort))		{			/*			 * Replace pathkeys that match exactly, {{1,2}}, {{1,2}}			 * Replace pathkeys {{1,2}} with {{1,2,3}}} if the latter is			 * not more expensive and replace unordered path with ordered			 * path if it is not more expensive.  Favor sorted keys over			 * unsorted keys in the same way.			 */			/* same keys, and new is cheaper, use it */			if ((better_key == 0 && better_sort == 0 &&				 new_path->path_cost < path->path_cost) ||			/* new is better, and cheaper, use it */				(((better_key == 1 && better_sort != 2) ||				  (better_key != 2 && better_sort == 1)) &&				 new_path->path_cost <= path->path_cost))			{#ifdef OPTDUP_DEBUG				printf("replace with new %p old %p better key %d better sort %d\n", &new_path, &path, better_key, better_sort);				printf("new\n");				pprint(new_path);				printf("old\n");				pprint(path);#endif				*is_new = false;				return path;			}			/* same keys, new is more expensive, stop */			if ((better_key == 0 && better_sort == 0 &&				 new_path->path_cost >= path->path_cost) ||			/* old is better, and less expensive, stop */				(((better_key == 2 && better_sort != 1) ||				  (better_key != 1 && better_sort == 2)) &&				 new_path->path_cost >= path->path_cost))			{#ifdef OPTDUP_DEBUG				printf("skip new %p old %p better key %d better sort %d\n", &new_path, &path, better_key, better_sort);				printf("new\n");				pprint(new_path);				printf("old\n");				pprint(path);#endif				*is_new = false;				return NULL;			}		}	}#ifdef OPTDUP_DEBUG	printf("add new %p old %p better key %d better sort %d\n", &new_path, &path, better_key, better_sort);	printf("new\n");	pprint(new_path);#endif	*is_new = true;	return NULL;}/***************************************************************************** *		PATH NODE CREATION ROUTINES *****************************************************************************//* * create_seqscan_path *	  Creates a path corresponding to a sequential scan, returning the *	  pathnode. * */Path *create_seqscan_path(RelOptInfo *rel){	int			relid = 0;	Path	   *pathnode = makeNode(Path);	pathnode->pathtype = T_SeqScan;	pathnode->parent = rel;	pathnode->path_cost = 0.0;	pathnode->pathorder = makeNode(PathOrder);	pathnode->pathorder->ordtype = SORTOP_ORDER;	pathnode->pathorder->ord.sortop = NULL;	pathnode->pathkeys = NIL;	/*	 * copy restrictinfo list into path for expensive function processing	 * JMH, 7/7/92	 */	pathnode->loc_restrictinfo = (List *) copyObject((Node *) rel->restrictinfo);	if (rel->relids != NULL)		relid = lfirsti(rel->relids);	pathnode->path_cost = cost_seqscan(relid,									   rel->pages, rel->tuples);	/* add in expensive functions cost!  -- JMH, 7/7/92 */#ifdef NOT_USED	if (XfuncMode != XFUNC_OFF)		pathnode->path_cost += xfunc_get_path_cost(pathnode);#endif	return pathnode;}/* * create_index_path *	  Creates a single path node for an index scan. * * 'rel' is the parent rel * 'index' is the pathnode for the index on 'rel' * 'restriction_clauses' is a list of restriction clause nodes. * 'is_join_scan' is a flag indicating whether or not the index is being *		considered because of its sort order. * * Returns the new path node. * */IndexPath  *create_index_path(Query *root,

⌨️ 快捷键说明

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