Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit b3f8bbb

Browse files
committed
Oops missing file.
1 parent 9d8d647 commit b3f8bbb

File tree

1 file changed

+213
-0
lines changed

1 file changed

+213
-0
lines changed
+213
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* prepkeyset.c--
4+
* Special preperation for keyset queries.
5+
*
6+
* Copyright (c) 1994, Regents of the University of California
7+
*
8+
*-------------------------------------------------------------------------
9+
*/
10+
#include <stdio.h>
11+
#include <string.h>
12+
13+
#include "postgres.h"
14+
#include "nodes/pg_list.h"
15+
#include "nodes/parsenodes.h"
16+
#include "utils/elog.h"
17+
18+
#include "nodes/nodes.h"
19+
#include "nodes/execnodes.h"
20+
#include "nodes/plannodes.h"
21+
#include "nodes/primnodes.h"
22+
#include "nodes/relation.h"
23+
24+
#include "catalog/pg_type.h"
25+
#include "lib/stringinfo.h"
26+
#include "optimizer/planmain.h"
27+
/*
28+
* Node_Copy--
29+
* a macro to simplify calling of copyObject on the specified field
30+
*/
31+
#define Node_Copy(from, newnode, field) newnode->field = copyObject(from->field)
32+
33+
/***** DEBUG stuff
34+
#define TABS {int i; printf("\n"); for (i = 0; i<level; i++) printf("\t"); }
35+
static int level = 0;
36+
******/
37+
38+
bool _use_keyset_query_optimizer = FALSE;
39+
40+
static int inspectOpNode(Expr *expr);
41+
static int inspectAndNode(Expr *expr);
42+
static int inspectOrNode(Expr *expr);
43+
44+
/**********************************************************************
45+
* This routine transforms query trees with the following form:
46+
* SELECT a,b, ... FROM one_table WHERE
47+
* (v1 = const1 AND v2 = const2 [ vn = constn ]) OR
48+
* (v1 = const3 AND v2 = const4 [ vn = constn ]) OR
49+
* (v1 = const5 AND v2 = const6 [ vn = constn ]) OR
50+
* ...
51+
* [(v1 = constn AND v2 = constn [ vn = constn ])]
52+
*
53+
* into
54+
*
55+
* SELECT a,b, ... FROM one_table WHERE
56+
* (v1 = const1 AND v2 = const2 [ vn = constn ]) UNION
57+
* SELECT a,b, ... FROM one_table WHERE
58+
* (v1 = const3 AND v2 = const4 [ vn = constn ]) UNION
59+
* SELECT a,b, ... FROM one_table WHERE
60+
* (v1 = const5 AND v2 = const6 [ vn = constn ]) UNION
61+
* ...
62+
* SELECT a,b, ... FROM one_table WHERE
63+
* [(v1 = constn AND v2 = constn [ vn = constn ])]
64+
*
65+
*
66+
* To qualify for transformation the query must not be a sub select,
67+
* a HAVING, or a GROUP BY. It must be a single table and have KSQO
68+
* set to 'on'.
69+
*
70+
* The primary use of this transformation is to avoid the exponrntial
71+
* memory consumption of cnfify() and to make use of index access
72+
* methods.
73+
*
74+
* daveh@insightdist.com 1998-08-31
75+
*
76+
* Needs to better identify the signeture WHERE clause.
77+
* May want to also prune out duplicate where clauses.
78+
**********************************************************************/
79+
void
80+
transformKeySetQuery(Query *origNode)
81+
{
82+
/* Qualify as a key set query candidate */
83+
if (_use_keyset_query_optimizer == FALSE ||
84+
origNode->groupClause ||
85+
origNode->havingQual ||
86+
origNode->hasAggs ||
87+
origNode->utilityStmt ||
88+
origNode->unionClause ||
89+
origNode->unionall ||
90+
origNode->hasSubLinks ||
91+
origNode->commandType != CMD_SELECT)
92+
return;
93+
94+
/* Qualify single table query */
95+
96+
/* Qualify where clause */
97+
if ( ! inspectOrNode((Expr*)origNode->qual)) {
98+
return;
99+
}
100+
101+
/* Copy essential elements into a union node */
102+
/*
103+
elog(NOTICE, "OR_EXPR=%d, OP_EXPR=%d, AND_EXPR=%d", OR_EXPR, OP_EXPR, AND_EXPR);
104+
elog(NOTICE, "T_List=%d, T_Expr=%d, T_Var=%d, T_Const=%d", T_List, T_Expr, T_Var, T_Const);
105+
elog(NOTICE, "opType=%d", ((Expr*)origNode->qual)->opType);
106+
*/
107+
while (((Expr*)origNode->qual)->opType == OR_EXPR) {
108+
Query *unionNode = makeNode(Query);
109+
110+
/* Pull up Expr = */
111+
unionNode->qual = lsecond(((Expr*)origNode->qual)->args);
112+
113+
/* Pull up balance of tree */
114+
origNode->qual = lfirst(((Expr*)origNode->qual)->args);
115+
116+
/*
117+
elog(NOTICE, "origNode: opType=%d, nodeTag=%d", ((Expr*)origNode->qual)->opType, nodeTag(origNode->qual));
118+
elog(NOTICE, "unionNode: opType=%d, nodeTag=%d", ((Expr*)unionNode->qual)->opType, nodeTag(unionNode->qual));
119+
*/
120+
121+
unionNode->commandType = origNode->commandType;
122+
unionNode->resultRelation = origNode->resultRelation;
123+
unionNode->isPortal = origNode->isPortal;
124+
unionNode->isBinary = origNode->isBinary;
125+
126+
if (origNode->uniqueFlag)
127+
unionNode->uniqueFlag = pstrdup(origNode->uniqueFlag);
128+
129+
Node_Copy(origNode, unionNode, sortClause);
130+
Node_Copy(origNode, unionNode, rtable);
131+
Node_Copy(origNode, unionNode, targetList);
132+
133+
origNode->unionClause = lappend(origNode->unionClause, unionNode);
134+
}
135+
return;
136+
}
137+
138+
139+
140+
141+
static int
142+
inspectOrNode(Expr *expr)
143+
{
144+
int fr = 0, sr = 0;
145+
Expr *firstExpr, *secondExpr;
146+
147+
if ( ! (expr && nodeTag(expr) == T_Expr && expr->opType == OR_EXPR))
148+
return 0;
149+
150+
firstExpr = lfirst(expr->args);
151+
secondExpr = lsecond(expr->args);
152+
if (nodeTag(firstExpr) != T_Expr || nodeTag(secondExpr) != T_Expr)
153+
return 0;
154+
155+
if (firstExpr->opType == OR_EXPR)
156+
fr = inspectOrNode(firstExpr);
157+
else if (firstExpr->opType == OP_EXPR) /* Need to make sure it is last */
158+
fr = inspectOpNode(firstExpr);
159+
else if (firstExpr->opType == AND_EXPR) /* Need to make sure it is last */
160+
fr = inspectAndNode(firstExpr);
161+
162+
163+
if (secondExpr->opType == AND_EXPR)
164+
sr = inspectAndNode(secondExpr);
165+
else if (secondExpr->opType == OP_EXPR)
166+
sr = inspectOpNode(secondExpr);
167+
168+
return (fr && sr);
169+
}
170+
171+
172+
static int
173+
inspectAndNode(Expr *expr)
174+
{
175+
int fr = 0, sr = 0;
176+
Expr *firstExpr, *secondExpr;
177+
178+
if ( ! (expr && nodeTag(expr) == T_Expr && expr->opType == AND_EXPR))
179+
return 0;
180+
181+
firstExpr = lfirst(expr->args);
182+
secondExpr = lsecond(expr->args);
183+
if (nodeTag(firstExpr) != T_Expr || nodeTag(secondExpr) != T_Expr)
184+
return 0;
185+
186+
if (firstExpr->opType == AND_EXPR)
187+
fr = inspectAndNode(firstExpr);
188+
else if (firstExpr->opType == OP_EXPR)
189+
fr = inspectOpNode(firstExpr);
190+
191+
if (secondExpr->opType == OP_EXPR)
192+
sr = inspectOpNode(secondExpr);
193+
194+
return (fr && sr);
195+
}
196+
197+
198+
static int
199+
/******************************************************************
200+
* Return TRUE if T_Var = T_Const, else FALSE
201+
* Actually it does not test for =. Need to do this!
202+
******************************************************************/
203+
inspectOpNode(Expr *expr)
204+
{
205+
Expr *firstExpr, *secondExpr;
206+
207+
if (nodeTag(expr) != T_Expr || expr->opType != OP_EXPR)
208+
return 0;
209+
210+
firstExpr = lfirst(expr->args);
211+
secondExpr = lsecond(expr->args);
212+
return (firstExpr && secondExpr && nodeTag(firstExpr) == T_Var && nodeTag(secondExpr) == T_Const);
213+
}

0 commit comments

Comments
 (0)