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

📄 prepkeyset.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
字号:
/*------------------------------------------------------------------------- * * prepkeyset.c *	  Special preperation for keyset queries. * * Copyright (c) 1994, Regents of the University of California * *------------------------------------------------------------------------- */#include "postgres.h"#include "optimizer/planmain.h"/* * Node_Copy *		  a macro to simplify calling of copyObject on the specified field */#define Node_Copy(from, newnode, field) newnode->field = copyObject(from->field)bool		_use_keyset_query_optimizer = FALSE;static int	inspectOpNode(Expr *expr);static int	inspectAndNode(Expr *expr);static int	inspectOrNode(Expr *expr);static int	TotalExpr;/********************************************************************** *	 This routine transforms query trees with the following form: *		 SELECT a,b, ... FROM one_table WHERE *		  (v1 = const1 AND v2 = const2 [ vn = constn ]) OR *		  (v1 = const3 AND v2 = const4 [ vn = constn ]) OR *		  (v1 = const5 AND v2 = const6 [ vn = constn ]) OR *						   ... *		  [(v1 = constn AND v2 = constn [ vn = constn ])] * *							   into * *		 SELECT a,b, ... FROM one_table WHERE *		  (v1 = const1 AND v2 = const2 [ vn = constn ]) UNION *		 SELECT a,b, ... FROM one_table WHERE *		  (v1 = const3 AND v2 = const4 [ vn = constn ]) UNION *		 SELECT a,b, ... FROM one_table WHERE *		  (v1 = const5 AND v2 = const6 [ vn = constn ]) UNION *						   ... *		 SELECT a,b, ... FROM one_table WHERE *		  [(v1 = constn AND v2 = constn [ vn = constn ])] * * *	 To qualify for transformation the query must not be a sub select, *	 a HAVING, or a GROUP BY.	It must be a single table and have KSQO *	 set to 'on'. * *	 The primary use of this transformation is to avoid the exponrntial *	 memory consumption of cnfify() and to make use of index access *	 methods. * *		  daveh@insightdist.com   1998-08-31 * *	 May want to also prune out duplicate terms. **********************************************************************/voidtransformKeySetQuery(Query *origNode){	/* Qualify as a key set query candidate  */	if (_use_keyset_query_optimizer == FALSE ||		origNode->groupClause ||		origNode->havingQual ||		origNode->hasAggs ||		origNode->utilityStmt ||		origNode->unionClause ||		origNode->unionall ||		origNode->hasSubLinks ||		origNode->commandType != CMD_SELECT)		return;	/* Qualify single table query	*/	if (length(origNode->rtable) != 1)		return;	/* Sorry about the global, not worth passing around		*/	/* 9 expressions seems like a good number.	More than 9 */	/* and it starts to slow down quite a bit				*/	TotalExpr = 0;	/*************************/	/* Qualify where clause */	/*************************/	if (!inspectOrNode((Expr *) origNode->qual) || TotalExpr < 9)		return;	/* Copy essential elements into a union node */	while (((Expr *) origNode->qual)->opType == OR_EXPR)	{		Query	   *unionNode = makeNode(Query);		/* Pull up Expr =  */		unionNode->qual = lsecond(((Expr *) origNode->qual)->args);		/* Pull up balance of tree	*/		origNode->qual = lfirst(((Expr *) origNode->qual)->args);		unionNode->commandType = origNode->commandType;		unionNode->resultRelation = origNode->resultRelation;		unionNode->isPortal = origNode->isPortal;		unionNode->isBinary = origNode->isBinary;		if (origNode->uniqueFlag)			unionNode->uniqueFlag = pstrdup(origNode->uniqueFlag);		Node_Copy(origNode, unionNode, sortClause);		Node_Copy(origNode, unionNode, rtable);		Node_Copy(origNode, unionNode, targetList);		origNode->unionClause = lappend(origNode->unionClause, unionNode);	}	return;}static int/********************************************************************** *	 Checks for 1 or more OR terms w/ 1 or more AND terms. *	 AND terms must be equal in size. *	 Returns the number of each AND term. **********************************************************************/inspectOrNode(Expr *expr){	int			rc;	Expr	   *firstExpr,			   *secondExpr;	if (!(expr && nodeTag(expr) == T_Expr && expr->opType == OR_EXPR))		return 0;	firstExpr = lfirst(expr->args);	secondExpr = lsecond(expr->args);	if (nodeTag(firstExpr) != T_Expr || nodeTag(secondExpr) != T_Expr)		return 0;	if (firstExpr->opType == OR_EXPR && secondExpr->opType == AND_EXPR)	{		if ((rc = inspectOrNode(firstExpr)) == 0)			return 0;		return (rc == inspectAndNode(secondExpr)) ? rc : 0;	}	else if (firstExpr->opType == AND_EXPR && secondExpr->opType == AND_EXPR)	{		if ((rc = inspectAndNode(firstExpr)) == 0)			return 0;		return (rc == inspectAndNode(secondExpr)) ? rc : 0;	}	return 0;}static int/********************************************************************** *	Check for one or more AND terms.   Each sub-term must be a T_Const *	T_Var expression. *	Returns the number of AND terms. **********************************************************************/inspectAndNode(Expr *expr){	int			rc;	Expr	   *firstExpr,			   *secondExpr;	if (!(expr && nodeTag(expr) == T_Expr && expr->opType == AND_EXPR))		return 0;	firstExpr = lfirst(expr->args);	secondExpr = lsecond(expr->args);	if (nodeTag(firstExpr) != T_Expr || nodeTag(secondExpr) != T_Expr)		return 0;	if (firstExpr->opType == AND_EXPR &&		secondExpr->opType == OP_EXPR && inspectOpNode(secondExpr))	{		rc = inspectAndNode(firstExpr);		return ((rc) ? (rc + 1) : 0);	/* Add up the AND nodes */	}	else if (firstExpr->opType == OP_EXPR && inspectOpNode(firstExpr) &&			 secondExpr->opType == OP_EXPR && inspectOpNode(secondExpr))		return 1;	return 0;}static int/****************************************************************** *	Return TRUE if T_Var = T_Const, else FALSE *	Actually it does not test for =.	Need to do this! ******************************************************************/inspectOpNode(Expr *expr){	Expr	   *firstExpr,			   *secondExpr;	if (nodeTag(expr) != T_Expr || expr->opType != OP_EXPR)		return FALSE;	TotalExpr++;	firstExpr = lfirst(expr->args);	secondExpr = lsecond(expr->args);	return (firstExpr && secondExpr && nodeTag(firstExpr) == T_Var && nodeTag(secondExpr) == T_Const);}

⌨️ 快捷键说明

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