1111#include <string.h>
1212
1313#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"
2614#include "optimizer/planmain.h"
15+
2716/*
2817 * Node_Copy--
2918 * a macro to simplify calling of copyObject on the specified field
3019 */
3120#define Node_Copy (from ,newnode ,field ) newnode->field = copyObject(from->field)
3221
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-
3822bool _use_keyset_query_optimizer = FALSE;
3923
4024static int inspectOpNode (Expr * expr );
4125static int inspectAndNode (Expr * expr );
4226static int inspectOrNode (Expr * expr );
27+ static int TotalExpr ;
4328
4429/**********************************************************************
4530 * This routine transforms query trees with the following form:
@@ -73,8 +58,7 @@ static int inspectOrNode(Expr *expr);
7358 *
7459 * daveh@insightdist.com 1998-08-31
7560 *
76- * Needs to better identify the signeture WHERE clause.
77- * May want to also prune out duplicate where clauses.
61+ * May want to also prune out duplicate terms.
7862 **********************************************************************/
7963void
8064transformKeySetQuery (Query * origNode )
@@ -92,18 +76,20 @@ transformKeySetQuery(Query *origNode)
9276return ;
9377
9478/* Qualify single table query */
95-
79+ if (length (origNode -> rtable )!= 1 )
80+ return ;
81+
82+ /* Sorry about the global, not worth passing around */
83+ /* 9 expressions seems like a good number. More than 9 */
84+ /* and it starts to slow down quite a bit */
85+ TotalExpr = 0 ;
86+ /*************************/
9687/* Qualify where clause */
97- if ( !inspectOrNode ((Expr * )origNode -> qual )) {
88+ /*************************/
89+ if ( !inspectOrNode ((Expr * )origNode -> qual )|| TotalExpr < 9 )
9890return ;
99- }
10091
10192/* 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- */
10793while (((Expr * )origNode -> qual )-> opType == OR_EXPR ) {
10894Query * unionNode = makeNode (Query );
10995
@@ -113,11 +99,6 @@ transformKeySetQuery(Query *origNode)
11399/* Pull up balance of tree */
114100origNode -> qual = lfirst (((Expr * )origNode -> qual )-> args );
115101
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-
121102unionNode -> commandType = origNode -> commandType ;
122103unionNode -> resultRelation = origNode -> resultRelation ;
123104unionNode -> isPortal = origNode -> isPortal ;
@@ -139,9 +120,14 @@ transformKeySetQuery(Query *origNode)
139120
140121
141122static int
123+ /**********************************************************************
124+ * Checks for 1 or more OR terms w/ 1 or more AND terms.
125+ * AND terms must be equal in size.
126+ * Returns the number of each AND term.
127+ **********************************************************************/
142128inspectOrNode (Expr * expr )
143129{
144- int fr = 0 , sr = 0 ;
130+ int rc ;
145131Expr * firstExpr ,* secondExpr ;
146132
147133if ( ! (expr && nodeTag (expr )== T_Expr && expr -> opType == OR_EXPR ))
@@ -152,27 +138,35 @@ inspectOrNode(Expr *expr)
152138if (nodeTag (firstExpr )!= T_Expr || nodeTag (secondExpr )!= T_Expr )
153139return 0 ;
154140
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-
141+ if (firstExpr -> opType == OR_EXPR && secondExpr -> opType == AND_EXPR )
142+ {
143+ if ((rc = inspectOrNode (firstExpr ))== 0 )
144+ return 0 ;
162145
163- if (secondExpr -> opType == AND_EXPR )
164- sr = inspectAndNode (secondExpr );
165- else if (secondExpr -> opType == OP_EXPR )
166- sr = inspectOpNode (secondExpr );
146+ return (rc == inspectAndNode (secondExpr )) ?rc :0 ;
147+ }
148+ else if (firstExpr -> opType == AND_EXPR && secondExpr -> opType == AND_EXPR )
149+ {
150+ if ((rc = inspectAndNode (firstExpr ))== 0 )
151+ return 0 ;
152+
153+ return (rc == inspectAndNode (secondExpr )) ?rc :0 ;
167154
168- return (fr && sr );
155+ }
156+
157+ return 0 ;
169158}
170159
171160
172161static int
162+ /**********************************************************************
163+ * Check for one or more AND terms. Each sub-term must be a T_Const
164+ * T_Var expression.
165+ * Returns the number of AND terms.
166+ **********************************************************************/
173167inspectAndNode (Expr * expr )
174168{
175- int fr = 0 , sr = 0 ;
169+ int rc ;
176170Expr * firstExpr ,* secondExpr ;
177171
178172if ( ! (expr && nodeTag (expr )== T_Expr && expr -> opType == AND_EXPR ))
@@ -183,15 +177,19 @@ inspectAndNode(Expr *expr)
183177if (nodeTag (firstExpr )!= T_Expr || nodeTag (secondExpr )!= T_Expr )
184178return 0 ;
185179
186- if (firstExpr -> opType == AND_EXPR )
187- fr = inspectAndNode (firstExpr );
188- else if (firstExpr -> opType == OP_EXPR )
189- fr = inspectOpNode (firstExpr );
180+ if (firstExpr -> opType == AND_EXPR &&
181+ secondExpr -> opType == OP_EXPR && inspectOpNode (secondExpr ))
182+ {
183+ rc = inspectAndNode (firstExpr );
184+ return ((rc ) ? (rc + 1 ) :0 );/* Add up the AND nodes */
185+ }
186+ else if (firstExpr -> opType == OP_EXPR && inspectOpNode (firstExpr )&&
187+ secondExpr -> opType == OP_EXPR && inspectOpNode (secondExpr ))
188+ {
189+ return 1 ;
190+ }
190191
191- if (secondExpr -> opType == OP_EXPR )
192- sr = inspectOpNode (secondExpr );
193-
194- return (fr && sr );
192+ return 0 ;
195193}
196194
197195
@@ -205,7 +203,9 @@ inspectOpNode(Expr *expr)
205203Expr * firstExpr ,* secondExpr ;
206204
207205if (nodeTag (expr )!= T_Expr || expr -> opType != OP_EXPR )
208- return 0 ;
206+ return FALSE;
207+
208+ TotalExpr ++ ;
209209
210210firstExpr = lfirst (expr -> args );
211211secondExpr = lsecond (expr -> args );