tlist.c

来自「postgresql8.3.4源码,开源数据库」· C语言 代码 · 共 247 行

C
247
字号
/*------------------------------------------------------------------------- * * tlist.c *	  Target list manipulation routines * * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION *	  $PostgreSQL: pgsql/src/backend/optimizer/util/tlist.c,v 1.78 2008/01/01 19:45:50 momjian Exp $ * *------------------------------------------------------------------------- */#include "postgres.h"#include "nodes/makefuncs.h"#include "optimizer/tlist.h"#include "optimizer/var.h"#include "parser/parse_expr.h"/***************************************************************************** *		Target list creation and searching utilities *****************************************************************************//* * tlist_member *	  Finds the (first) member of the given tlist whose expression is *	  equal() to the given expression.	Result is NULL if no such member. */TargetEntry *tlist_member(Node *node, List *targetlist){	ListCell   *temp;	foreach(temp, targetlist)	{		TargetEntry *tlentry = (TargetEntry *) lfirst(temp);		if (equal(node, tlentry->expr))			return tlentry;	}	return NULL;}/* * tlist_member_ignore_relabel *	  Same as above, except that we ignore top-level RelabelType nodes *	  while checking for a match.  This is needed for some scenarios *	  involving binary-compatible sort operations. */TargetEntry *tlist_member_ignore_relabel(Node *node, List *targetlist){	ListCell   *temp;	while (node && IsA(node, RelabelType))		node = (Node *) ((RelabelType *) node)->arg;	foreach(temp, targetlist)	{		TargetEntry *tlentry = (TargetEntry *) lfirst(temp);		Expr	   *tlexpr = tlentry->expr;		while (tlexpr && IsA(tlexpr, RelabelType))			tlexpr = ((RelabelType *) tlexpr)->arg;		if (equal(node, tlexpr))			return tlentry;	}	return NULL;}/* * flatten_tlist *	  Create a target list that only contains unique variables. * * Note that Vars with varlevelsup > 0 are not included in the output * tlist.  We expect that those will eventually be replaced with Params, * but that probably has not happened at the time this routine is called. * * 'tlist' is the current target list * * Returns the "flattened" new target list. * * The result is entirely new structure sharing no nodes with the original. * Copying the Var nodes is probably overkill, but be safe for now. */List *flatten_tlist(List *tlist){	List	   *vlist = pull_var_clause((Node *) tlist, false);	List	   *new_tlist;	new_tlist = add_to_flat_tlist(NIL, vlist);	list_free(vlist);	return new_tlist;}/* * add_to_flat_tlist *		Add more vars to a flattened tlist (if they're not already in it) * * 'tlist' is the flattened tlist * 'vars' is a list of var nodes * * Returns the extended tlist. */List *add_to_flat_tlist(List *tlist, List *vars){	int			next_resno = list_length(tlist) + 1;	ListCell   *v;	foreach(v, vars)	{		Var		   *var = (Var *) lfirst(v);		if (!tlist_member((Node *) var, tlist))		{			TargetEntry *tle;			tle = makeTargetEntry(copyObject(var),		/* copy needed?? */								  next_resno++,								  NULL,								  false);			tlist = lappend(tlist, tle);		}	}	return tlist;}/* * get_sortgroupref_tle *		Find the targetlist entry matching the given SortGroupRef index, *		and return it. */TargetEntry *get_sortgroupref_tle(Index sortref, List *targetList){	ListCell   *l;	foreach(l, targetList)	{		TargetEntry *tle = (TargetEntry *) lfirst(l);		if (tle->ressortgroupref == sortref)			return tle;	}	elog(ERROR, "ORDER/GROUP BY expression not found in targetlist");	return NULL;				/* keep compiler quiet */}/* * get_sortgroupclause_tle *		Find the targetlist entry matching the given SortClause *		(or GroupClause) by ressortgroupref, and return it. * * Because GroupClause is typedef'd as SortClause, either kind of * node can be passed without casting. */TargetEntry *get_sortgroupclause_tle(SortClause *sortClause,						List *targetList){	return get_sortgroupref_tle(sortClause->tleSortGroupRef, targetList);}/* * get_sortgroupclause_expr *		Find the targetlist entry matching the given SortClause *		(or GroupClause) by ressortgroupref, and return its expression. * * Because GroupClause is typedef'd as SortClause, either kind of * node can be passed without casting. */Node *get_sortgroupclause_expr(SortClause *sortClause, List *targetList){	TargetEntry *tle = get_sortgroupclause_tle(sortClause, targetList);	return (Node *) tle->expr;}/* * get_sortgrouplist_exprs *		Given a list of SortClauses (or GroupClauses), build a list *		of the referenced targetlist expressions. */List *get_sortgrouplist_exprs(List *sortClauses, List *targetList){	List	   *result = NIL;	ListCell   *l;	foreach(l, sortClauses)	{		SortClause *sortcl = (SortClause *) lfirst(l);		Node	   *sortexpr;		sortexpr = get_sortgroupclause_expr(sortcl, targetList);		result = lappend(result, sortexpr);	}	return result;}/* * Does tlist have same output datatypes as listed in colTypes? * * Resjunk columns are ignored if junkOK is true; otherwise presence of * a resjunk column will always cause a 'false' result. * * Note: currently no callers care about comparing typmods. */booltlist_same_datatypes(List *tlist, List *colTypes, bool junkOK){	ListCell   *l;	ListCell   *curColType = list_head(colTypes);	foreach(l, tlist)	{		TargetEntry *tle = (TargetEntry *) lfirst(l);		if (tle->resjunk)		{			if (!junkOK)				return false;		}		else		{			if (curColType == NULL)				return false;	/* tlist longer than colTypes */			if (exprType((Node *) tle->expr) != lfirst_oid(curColType))				return false;			curColType = lnext(curColType);		}	}	if (curColType != NULL)		return false;			/* tlist shorter than colTypes */	return true;}

⌨️ 快捷键说明

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