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

📄 tidpath.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
字号:
/*------------------------------------------------------------------------- * * tidpath.c *	  Routines to determine which TID conditions are usable for scanning *	  a given relation, and create TidPaths accordingly. * * What we are looking for here is WHERE conditions of the form * "CTID = pseudoconstant", which can be implemented by just fetching * the tuple directly via heap_fetch().  We can also handle OR conditions * if each OR arm contains such a condition; in particular this allows *		WHERE ctid IN (tid1, tid2, ...) * * There is currently no special support for joins involving CTID; in * particular nothing corresponding to best_inner_indexscan().	Since it's * not very useful to store TIDs of one table in another table, there * doesn't seem to be enough use-case to justify adding a lot of code * for that. * * * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION *	  $PostgreSQL: pgsql/src/backend/optimizer/path/tidpath.c,v 1.25 2005/10/15 02:49:20 momjian Exp $ * *------------------------------------------------------------------------- */#include "postgres.h"#include "access/htup.h"#include "catalog/pg_operator.h"#include "catalog/pg_type.h"#include "optimizer/clauses.h"#include "optimizer/pathnode.h"#include "optimizer/paths.h"#include "parser/parse_expr.h"static Node *IsTidEqualClause(int varno, OpExpr *node);static List *TidQualFromExpr(int varno, Node *expr);static List *TidQualFromRestrictinfo(int varno, List *restrictinfo);/* * Check to see if an opclause is of the form *		CTID = pseudoconstant * or *		pseudoconstant = CTID * * If it is, return the pseudoconstant subnode; if not, return NULL. * * We check that the CTID Var belongs to relation "varno".	That is probably * redundant considering this is only applied to restriction clauses, but * let's be safe. */static Node *IsTidEqualClause(int varno, OpExpr *node){	Node	   *arg1,			   *arg2,			   *other;	Var		   *var;	/* Operator must be tideq */	if (node->opno != TIDEqualOperator)		return NULL;	if (list_length(node->args) != 2)		return NULL;	arg1 = linitial(node->args);	arg2 = lsecond(node->args);	/* Look for CTID as either argument */	other = NULL;	if (arg1 && IsA(arg1, Var))	{		var = (Var *) arg1;		if (var->varattno == SelfItemPointerAttributeNumber &&			var->vartype == TIDOID &&			var->varno == varno &&			var->varlevelsup == 0)			other = arg2;	}	if (!other && arg2 && IsA(arg2, Var))	{		var = (Var *) arg2;		if (var->varattno == SelfItemPointerAttributeNumber &&			var->vartype == TIDOID &&			var->varno == varno &&			var->varlevelsup == 0)			other = arg1;	}	if (!other)		return NULL;	if (exprType(other) != TIDOID)		return NULL;			/* probably can't happen */	/* The other argument must be a pseudoconstant */	if (!is_pseudo_constant_clause(other))		return NULL;	return other;				/* success */}/* *	Extract a set of CTID conditions from the given qual expression * *	If the expression is an AND clause, we can use a CTID condition *	from any sub-clause.  If it is an OR clause, we must be able to *	extract a CTID condition from every sub-clause, or we can't use it. * *	In theory, in the AND case we could get CTID conditions from different *	sub-clauses, in which case we could try to pick the most efficient one. *	In practice, such usage seems very unlikely, so we don't bother; we *	just exit as soon as we find the first candidate. * *	Returns a List of pseudoconstant TID expressions, or NIL if no match. *	(Has to be a list for the OR case.) */static List *TidQualFromExpr(int varno, Node *expr){	List	   *rlst = NIL,			   *frtn;	ListCell   *l;	Node	   *rnode;	if (is_opclause(expr))	{		/* base case: check for tideq opclause */		rnode = IsTidEqualClause(varno, (OpExpr *) expr);		if (rnode)			rlst = list_make1(rnode);	}	else if (and_clause(expr))	{		foreach(l, ((BoolExpr *) expr)->args)		{			rlst = TidQualFromExpr(varno, (Node *) lfirst(l));			if (rlst)				break;		}	}	else if (or_clause(expr))	{		foreach(l, ((BoolExpr *) expr)->args)		{			frtn = TidQualFromExpr(varno, (Node *) lfirst(l));			if (frtn)				rlst = list_concat(rlst, frtn);			else			{				if (rlst)					list_free(rlst);				rlst = NIL;				break;			}		}	}	return rlst;}/* *	Extract a set of CTID conditions from the given restrictinfo list * *	This is essentially identical to the AND case of TidQualFromExpr, *	except for the format of the input. */static List *TidQualFromRestrictinfo(int varno, List *restrictinfo){	List	   *rlst = NIL;	ListCell   *l;	foreach(l, restrictinfo)	{		RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);		if (!IsA(rinfo, RestrictInfo))			continue;			/* probably should never happen */		rlst = TidQualFromExpr(varno, (Node *) rinfo->clause);		if (rlst)			break;	}	return rlst;}/* * create_tidscan_paths *	  Create paths corresponding to direct TID scans of the given rel. * *	  Candidate paths are added to the rel's pathlist (using add_path). */voidcreate_tidscan_paths(PlannerInfo *root, RelOptInfo *rel){	List	   *tideval;	tideval = TidQualFromRestrictinfo(rel->relid, rel->baserestrictinfo);	if (tideval)		add_path(rel, (Path *) create_tidscan_path(root, rel, tideval));}

⌨️ 快捷键说明

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