mirror of https://github.com/postgres/postgres
If we're cleaning out _deadcode, might as well zap this one too.
This commit is contained in:
parent
45e584a445
commit
76099408f6
|
@ -1,223 +0,0 @@
|
|||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* prepkeyset.c
|
||||
* Special preparation for keyset queries (KSQO).
|
||||
*
|
||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* THIS FILE WAS USED FOR KSQO, WHICH IS DISABLED NOW. bjm 2002-06-15 */
|
||||
|
||||
#include "postgres.h"
|
||||
#include "optimizer/planmain.h"
|
||||
|
||||
bool _use_keyset_query_optimizer = FALSE;
|
||||
|
||||
#ifdef ENABLE_KEY_SET_QUERY
|
||||
|
||||
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 exponential
|
||||
* 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.
|
||||
*
|
||||
* XXX: this code is currently not compiled because it has not been
|
||||
* updated to work with the re-implementation of UNION/INTERSECT/EXCEPT
|
||||
* in PostgreSQL 7.1. However, it is of questionable value in any
|
||||
* case, because it changes the semantics of the original query:
|
||||
* UNION will add an implicit SELECT DISTINCT, which might change
|
||||
* the results that are returned.
|
||||
**********************************************************************/
|
||||
void
|
||||
transformKeySetQuery(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->jointree->quals) || TotalExpr < 9)
|
||||
return;
|
||||
|
||||
/* Copy essential elements into a union node */
|
||||
while (((Expr *) origNode->jointree->quals)->opType == OR_EXPR)
|
||||
{
|
||||
Query *unionNode = makeNode(Query);
|
||||
List *qualargs = ((Expr *) origNode->jointree->quals)->args;
|
||||
|
||||
unionNode->commandType = origNode->commandType;
|
||||
unionNode->resultRelation = origNode->resultRelation;
|
||||
unionNode->isPortal = origNode->isPortal;
|
||||
unionNode->isBinary = origNode->isBinary;
|
||||
|
||||
Node_Copy(origNode, unionNode, distinctClause);
|
||||
Node_Copy(origNode, unionNode, sortClause);
|
||||
Node_Copy(origNode, unionNode, rtable);
|
||||
origNode->jointree->quals = NULL; /* avoid unnecessary
|
||||
* copying */
|
||||
Node_Copy(origNode, unionNode, jointree);
|
||||
Node_Copy(origNode, unionNode, targetList);
|
||||
|
||||
/* Pull up Expr = */
|
||||
unionNode->jointree->quals = lsecond(qualargs);
|
||||
|
||||
/* Pull up balance of tree */
|
||||
origNode->jointree->quals = lfirst(qualargs);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
#endif /* ENABLE_KEY_SET_QUERY */
|
Loading…
Reference in New Issue