11
11
#include <string.h>
12
12
13
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
14
#include "optimizer/planmain.h"
15
+
27
16
/*
28
17
* Node_Copy--
29
18
* a macro to simplify calling of copyObject on the specified field
30
19
*/
31
20
#define Node_Copy (from , newnode , field ) newnode->field = copyObject(from->field)
32
21
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
22
bool _use_keyset_query_optimizer = FALSE;
39
23
40
24
static int inspectOpNode (Expr * expr );
41
25
static int inspectAndNode (Expr * expr );
42
26
static int inspectOrNode (Expr * expr );
27
+ static int TotalExpr ;
43
28
44
29
/**********************************************************************
45
30
* This routine transforms query trees with the following form:
@@ -73,8 +58,7 @@ static int inspectOrNode(Expr *expr);
73
58
*
74
59
* daveh@insightdist.com 1998-08-31
75
60
*
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.
78
62
**********************************************************************/
79
63
void
80
64
transformKeySetQuery (Query * origNode )
@@ -92,18 +76,20 @@ transformKeySetQuery(Query *origNode)
92
76
return ;
93
77
94
78
/* 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
+ /*************************/
96
87
/* Qualify where clause */
97
- if ( ! inspectOrNode ((Expr * )origNode -> qual )) {
88
+ /*************************/
89
+ if ( ! inspectOrNode ((Expr * )origNode -> qual ) || TotalExpr < 9 )
98
90
return ;
99
- }
100
91
101
92
/* 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
93
while (((Expr * )origNode -> qual )-> opType == OR_EXPR ) {
108
94
Query * unionNode = makeNode (Query );
109
95
@@ -113,11 +99,6 @@ transformKeySetQuery(Query *origNode)
113
99
/* Pull up balance of tree */
114
100
origNode -> qual = lfirst (((Expr * )origNode -> qual )-> args );
115
101
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
102
unionNode -> commandType = origNode -> commandType ;
122
103
unionNode -> resultRelation = origNode -> resultRelation ;
123
104
unionNode -> isPortal = origNode -> isPortal ;
@@ -139,9 +120,14 @@ transformKeySetQuery(Query *origNode)
139
120
140
121
141
122
static 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
+ **********************************************************************/
142
128
inspectOrNode (Expr * expr )
143
129
{
144
- int fr = 0 , sr = 0 ;
130
+ int rc ;
145
131
Expr * firstExpr , * secondExpr ;
146
132
147
133
if ( ! (expr && nodeTag (expr ) == T_Expr && expr -> opType == OR_EXPR ))
@@ -152,27 +138,35 @@ inspectOrNode(Expr *expr)
152
138
if (nodeTag (firstExpr ) != T_Expr || nodeTag (secondExpr ) != T_Expr )
153
139
return 0 ;
154
140
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 ;
162
145
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 ;
167
154
168
- return (fr && sr );
155
+ }
156
+
157
+ return 0 ;
169
158
}
170
159
171
160
172
161
static 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
+ **********************************************************************/
173
167
inspectAndNode (Expr * expr )
174
168
{
175
- int fr = 0 , sr = 0 ;
169
+ int rc ;
176
170
Expr * firstExpr , * secondExpr ;
177
171
178
172
if ( ! (expr && nodeTag (expr ) == T_Expr && expr -> opType == AND_EXPR ))
@@ -183,15 +177,19 @@ inspectAndNode(Expr *expr)
183
177
if (nodeTag (firstExpr ) != T_Expr || nodeTag (secondExpr ) != T_Expr )
184
178
return 0 ;
185
179
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
+ }
190
191
191
- if (secondExpr -> opType == OP_EXPR )
192
- sr = inspectOpNode (secondExpr );
193
-
194
- return (fr && sr );
192
+ return 0 ;
195
193
}
196
194
197
195
@@ -205,7 +203,9 @@ inspectOpNode(Expr *expr)
205
203
Expr * firstExpr , * secondExpr ;
206
204
207
205
if (nodeTag (expr ) != T_Expr || expr -> opType != OP_EXPR )
208
- return 0 ;
206
+ return FALSE;
207
+
208
+ TotalExpr ++ ;
209
209
210
210
firstExpr = lfirst (expr -> args );
211
211
secondExpr = lsecond (expr -> args );
0 commit comments