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

📄 rewritehandler.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 5 页
字号:
			break;		case T_Expr:			{				Expr	   *exp = (Expr *) node;				modifyAggrefUplevel(									(Node *) (exp->args));			}			break;		case T_Iter:			{				Iter	   *iter = (Iter *) node;				modifyAggrefUplevel(									(Node *) (iter->iterexpr));			}			break;		case T_ArrayRef:			{				ArrayRef   *ref = (ArrayRef *) node;				modifyAggrefUplevel(									(Node *) (ref->refupperindexpr));				modifyAggrefUplevel(									(Node *) (ref->reflowerindexpr));				modifyAggrefUplevel(									(Node *) (ref->refexpr));				modifyAggrefUplevel(									(Node *) (ref->refassgnexpr));			}			break;		case T_Var:			{				Var		   *var = (Var *) node;				var->varlevelsup++;			}			break;		case T_Param:			break;		case T_Const:			break;		case T_List:			{				List	   *l;				foreach(l, (List *) node)					modifyAggrefUplevel(										(Node *) lfirst(l));			}			break;		case T_SubLink:			{				SubLink    *sub = (SubLink *) node;				modifyAggrefUplevel(									(Node *) (sub->lefthand));				modifyAggrefUplevel(									(Node *) (sub->oper));				modifyAggrefUplevel(									(Node *) (sub->subselect));			}			break;		case T_Query:			{				Query	   *qry = (Query *) node;				modifyAggrefUplevel(									(Node *) (qry->targetList));				modifyAggrefUplevel(									(Node *) (qry->qual));				modifyAggrefUplevel(									(Node *) (qry->havingQual));			}			break;		default:			elog(NOTICE, "unknown node tag %d in modifyAggrefUplevel()", nodeTag(node));			elog(NOTICE, "Node is: %s", nodeToString(node));			break;	}}/* * modifyAggrefChangeVarnodes - *	Change the var nodes in a sublink created for an aggregate column *	used in the qualification that is subject of the aggregate *	function to point to the correct local RTE. */static voidmodifyAggrefChangeVarnodes(Node **nodePtr, int rt_index, int new_index, int sublevels_up){	Node	   *node = *nodePtr;	if (node == NULL)		return;	switch (nodeTag(node))	{		case T_TargetEntry:			{				TargetEntry *tle = (TargetEntry *) node;				modifyAggrefChangeVarnodes(										   (Node **) (&(tle->expr)),										   rt_index,										   new_index,										   sublevels_up);			}			break;		case T_Aggref:			{				Aggref	   *aggref = (Aggref *) node;				modifyAggrefChangeVarnodes(										   (Node **) (&(aggref->target)),										   rt_index,										   new_index,										   sublevels_up);			}			break;		case T_GroupClause:			break;		case T_Expr:			{				Expr	   *exp = (Expr *) node;				modifyAggrefChangeVarnodes(										   (Node **) (&(exp->args)),										   rt_index,										   new_index,										   sublevels_up);			}			break;		case T_Iter:			{				Iter	   *iter = (Iter *) node;				modifyAggrefChangeVarnodes(										   (Node **) (&(iter->iterexpr)),										   rt_index,										   new_index,										   sublevels_up);			}			break;		case T_ArrayRef:			{				ArrayRef   *ref = (ArrayRef *) node;				modifyAggrefChangeVarnodes(									 (Node **) (&(ref->refupperindexpr)),										   rt_index,										   new_index,										   sublevels_up);				modifyAggrefChangeVarnodes(									 (Node **) (&(ref->reflowerindexpr)),										   rt_index,										   new_index,										   sublevels_up);				modifyAggrefChangeVarnodes(										   (Node **) (&(ref->refexpr)),										   rt_index,										   new_index,										   sublevels_up);				modifyAggrefChangeVarnodes(										(Node **) (&(ref->refassgnexpr)),										   rt_index,										   new_index,										   sublevels_up);			}			break;		case T_Var:			{				Var		   *var = (Var *) node;				if (var->varlevelsup == sublevels_up &&					var->varno == rt_index)				{					var = copyObject(var);					var->varno = new_index;					var->varnoold = new_index;					var->varlevelsup = 0;					*nodePtr = (Node *) var;				}			}			break;		case T_Param:			break;		case T_Const:			break;		case T_List:			{				List	   *l;				foreach(l, (List *) node)					modifyAggrefChangeVarnodes(											   (Node **) (&lfirst(l)),											   rt_index,											   new_index,											   sublevels_up);			}			break;		case T_SubLink:			{				SubLink    *sub = (SubLink *) node;				modifyAggrefChangeVarnodes(										   (Node **) (&(sub->lefthand)),										   rt_index,										   new_index,										   sublevels_up);				modifyAggrefChangeVarnodes(										   (Node **) (&(sub->oper)),										   rt_index,										   new_index,										   sublevels_up);				modifyAggrefChangeVarnodes(										   (Node **) (&(sub->subselect)),										   rt_index,										   new_index,										   sublevels_up + 1);			}			break;		case T_Query:			{				Query	   *qry = (Query *) node;				modifyAggrefChangeVarnodes(										   (Node **) (&(qry->targetList)),										   rt_index,										   new_index,										   sublevels_up);				modifyAggrefChangeVarnodes(										   (Node **) (&(qry->qual)),										   rt_index,										   new_index,										   sublevels_up);				modifyAggrefChangeVarnodes(										   (Node **) (&(qry->havingQual)),										   rt_index,										   new_index,										   sublevels_up);			}			break;		default:			elog(NOTICE, "unknown node tag %d in modifyAggrefChangeVarnodes()", nodeTag(node));			elog(NOTICE, "Node is: %s", nodeToString(node));			break;	}}/* * modifyAggrefDropQual - *	remove the pure aggref clase from a qualification */static voidmodifyAggrefDropQual(Node **nodePtr, Node *orignode, Expr *expr){	Node	   *node = *nodePtr;	if (node == NULL)		return;	switch (nodeTag(node))	{		case T_Var:			break;		case T_Aggref:			{				Aggref	   *aggref = (Aggref *) node;				Aggref	   *oaggref = (Aggref *) orignode;				modifyAggrefDropQual(									 (Node **) (&(aggref->target)),									 (Node *) (oaggref->target),									 expr);			}			break;		case T_Param:			break;		case T_Const:			break;		case T_GroupClause:			break;		case T_Expr:			{				Expr	   *this_expr = (Expr *) node;				Expr	   *orig_expr = (Expr *) orignode;				if (orig_expr == expr)				{					Const	   *ctrue;					if (expr->typeOid != BOOLOID)						elog(ERROR,							 "aggregate expression in qualification isn't of type bool");					ctrue = makeNode(Const);					ctrue->consttype = BOOLOID;					ctrue->constlen = 1;					ctrue->constisnull = FALSE;					ctrue->constvalue = (Datum) TRUE;					ctrue->constbyval = TRUE;					*nodePtr = (Node *) ctrue;				}				else					modifyAggrefDropQual(										 (Node **) (&(this_expr->args)),										 (Node *) (orig_expr->args),										 expr);			}			break;		case T_Iter:			{				Iter	   *iter = (Iter *) node;				Iter	   *oiter = (Iter *) orignode;				modifyAggrefDropQual(									 (Node **) (&(iter->iterexpr)),									 (Node *) (oiter->iterexpr),									 expr);			}			break;		case T_ArrayRef:			{				ArrayRef   *ref = (ArrayRef *) node;				ArrayRef   *oref = (ArrayRef *) orignode;				modifyAggrefDropQual(									 (Node **) (&(ref->refupperindexpr)),									 (Node *) (oref->refupperindexpr),									 expr);				modifyAggrefDropQual(									 (Node **) (&(ref->reflowerindexpr)),									 (Node *) (oref->reflowerindexpr),									 expr);				modifyAggrefDropQual(									 (Node **) (&(ref->refexpr)),									 (Node *) (oref->refexpr),									 expr);				modifyAggrefDropQual(									 (Node **) (&(ref->refassgnexpr)),									 (Node *) (oref->refassgnexpr),									 expr);			}			break;		case T_List:			{				List	   *l;				List	   *ol = (List *) orignode;				int			li = 0;				foreach(l, (List *) node)				{					modifyAggrefDropQual(										 (Node **) (&(lfirst(l))),										 (Node *) nth(li, ol),										 expr);					li++;				}			}			break;		case T_SubLink:			{				SubLink    *sub = (SubLink *) node;				SubLink    *osub = (SubLink *) orignode;				modifyAggrefDropQual(									 (Node **) (&(sub->subselect)),									 (Node *) (osub->subselect),									 expr);			}			break;		case T_Query:			{				Query	   *qry = (Query *) node;				Query	   *oqry = (Query *) orignode;				modifyAggrefDropQual(									 (Node **) (&(qry->qual)),									 (Node *) (oqry->qual),									 expr);				modifyAggrefDropQual(									 (Node **) (&(qry->havingQual)),									 (Node *) (oqry->havingQual),									 expr);			}			break;		default:			elog(NOTICE, "unknown node tag %d in modifyAggrefDropQual()", nodeTag(node));			elog(NOTICE, "Node is: %s", nodeToString(node));			break;	}}/* * modifyAggrefMakeSublink - *	Create a sublink node for a qualification expression that *	uses an aggregate column of a view */static SubLink *modifyAggrefMakeSublink(Expr *origexp, Query *parsetree){	SubLink    *sublink;	Query	   *subquery;	Node	   *subqual;	RangeTblEntry *rte;	Aggref	   *aggref;	Var		   *target;	TargetEntry *tle;	Resdom	   *resdom;	Expr	   *exp = copyObject(origexp);	if (nodeTag(nth(0, exp->args)) == T_Aggref)	{		if (nodeTag(nth(1, exp->args)) == T_Aggref)			elog(ERROR, "rewrite: comparision of 2 aggregate columns not supported");		else			elog(ERROR, "rewrite: aggregate column of view must be at rigth side in qual");	}	aggref = (Aggref *) nth(1, exp->args);	target = (Var *) (aggref->target);	rte = (RangeTblEntry *) nth(target->varno - 1, parsetree->rtable);	tle = makeNode(TargetEntry);	resdom = makeNode(Resdom);	aggref->usenulls = TRUE;	resdom->resno = 1;	resdom->restype = ((Oper *) (exp->oper))->opresulttype;	resdom->restypmod = -1;	resdom->resname = pstrdup("<noname>");	resdom->reskey = 0;	resdom->reskeyop = 0;	resdom->resjunk = false;	tle->resdom = resdom;	tle->expr = (Node *) aggref;	subqual = copyObject(parsetree->qual);	modifyAggrefDropQual((Node **) &subqual, (Node *) parsetree->qual, origexp);	sublink = makeNode(SubLink);	sublink->subLinkType = EXPR_SUBLINK;	sublink->useor = FALSE;	sublink->lefthand = lappend(NIL, copyObject(lfirst(exp->args)));	sublink->oper = lappend(NIL, copyObject(exp));	sublink->subselect = NULL;	subquery = makeNode(Query);	sublink->subselect = (Node *) subquery;	subquery->commandType = CMD_SELECT;	subquery->utilityStmt = NULL;	subquery->resultRelation = 0;	subquery->into = NULL;	subquery->isPortal = FALSE;	subquery->isBinary = FALSE;	subquery->isTemp = FALSE;	subquery->unionall = FALSE;	subquery->uniqueFlag = NULL;	subquery->sortClause = NULL;	subquery->rtable = lappend(NIL, rte);	subquery->targetList = lappend(NIL, tle);	subquery->qual = subqual;	subquery->groupClause = NIL;	subquery->havingQual = NULL;	subquery->hasAggs = TRUE;	subquery->hasSubLinks = FALSE;	subquery->unionClause = NULL;	modifyAggrefUplevel((Node *) sublink);	modifyAggrefChangeVarnodes((Node **) &(sublink->lefthand), target->varno,							   1, target->varlevelsup);	modifyAggrefChangeVarnodes((Node **) &(sublink->oper), target->varno,							   1, target->varlevelsup);	modifyAggrefChangeVarnodes((Node **) &(sublink->subselect), target->varno,							   1, target->varlevelsup);	return sublink;}/* * modifyAggrefQual - *	Search for qualification expressions that contain aggregate *	functions and substiture them by sublinks. These expressions *	originally come from qualifications that use aggregate columns *	of a view. */static voidmodifyAggrefQual(Node **nodePtr, Query *parsetree){	Node	   *node = *nodePtr;	if (node == NULL)		return;	switch (nodeTag(node))	{		case T_Var:			break;		case T_Param:			break;		case T_Const:			break;		case T_GroupClause:			break;		case T_Expr:			{				Expr	   *exp = (Expr *) node;				SubLink    *sub;				if (length(exp->args) != 2)				{					modifyAggrefQual(									 (Node **) (&(exp->args)),									 parsetree);					break;				}				if (nodeTag(nth(0, exp->args)) != T_Aggref &&					nodeTag(nth(1, exp->args)) != T_Aggref)				{					modifyAggrefQual(									 (Node **) (&(exp->args)),									 parsetree);					break;				}				sub = modifyAggrefMakeSublink(exp,											  parsetree);				*nodePtr = (Node *) sub;				parsetree->hasSubLinks = TRUE;			}

⌨️ 快捷键说明

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