Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "postgres.h"
00038
00039 #include "access/sysattr.h"
00040 #include "catalog/pg_operator.h"
00041 #include "catalog/pg_type.h"
00042 #include "nodes/nodeFuncs.h"
00043 #include "optimizer/clauses.h"
00044 #include "optimizer/pathnode.h"
00045 #include "optimizer/paths.h"
00046
00047
00048 static bool IsTidEqualClause(OpExpr *node, int varno);
00049 static bool IsTidEqualAnyClause(ScalarArrayOpExpr *node, int varno);
00050 static List *TidQualFromExpr(Node *expr, int varno);
00051 static List *TidQualFromRestrictinfo(List *restrictinfo, int varno);
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 static bool
00065 IsTidEqualClause(OpExpr *node, int varno)
00066 {
00067 Node *arg1,
00068 *arg2,
00069 *other;
00070 Var *var;
00071
00072
00073 if (node->opno != TIDEqualOperator)
00074 return false;
00075 if (list_length(node->args) != 2)
00076 return false;
00077 arg1 = linitial(node->args);
00078 arg2 = lsecond(node->args);
00079
00080
00081 other = NULL;
00082 if (arg1 && IsA(arg1, Var))
00083 {
00084 var = (Var *) arg1;
00085 if (var->varattno == SelfItemPointerAttributeNumber &&
00086 var->vartype == TIDOID &&
00087 var->varno == varno &&
00088 var->varlevelsup == 0)
00089 other = arg2;
00090 }
00091 if (!other && arg2 && IsA(arg2, Var))
00092 {
00093 var = (Var *) arg2;
00094 if (var->varattno == SelfItemPointerAttributeNumber &&
00095 var->vartype == TIDOID &&
00096 var->varno == varno &&
00097 var->varlevelsup == 0)
00098 other = arg1;
00099 }
00100 if (!other)
00101 return false;
00102 if (exprType(other) != TIDOID)
00103 return false;
00104
00105
00106 if (!is_pseudo_constant_clause(other))
00107 return false;
00108
00109 return true;
00110 }
00111
00112
00113
00114
00115
00116 static bool
00117 IsTidEqualAnyClause(ScalarArrayOpExpr *node, int varno)
00118 {
00119 Node *arg1,
00120 *arg2;
00121
00122
00123 if (node->opno != TIDEqualOperator)
00124 return false;
00125 if (!node->useOr)
00126 return false;
00127 Assert(list_length(node->args) == 2);
00128 arg1 = linitial(node->args);
00129 arg2 = lsecond(node->args);
00130
00131
00132 if (arg1 && IsA(arg1, Var))
00133 {
00134 Var *var = (Var *) arg1;
00135
00136 if (var->varattno == SelfItemPointerAttributeNumber &&
00137 var->vartype == TIDOID &&
00138 var->varno == varno &&
00139 var->varlevelsup == 0)
00140 {
00141
00142 if (is_pseudo_constant_clause(arg2))
00143 return true;
00144 }
00145 }
00146
00147 return false;
00148 }
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 static List *
00166 TidQualFromExpr(Node *expr, int varno)
00167 {
00168 List *rlst = NIL;
00169 ListCell *l;
00170
00171 if (is_opclause(expr))
00172 {
00173
00174 if (IsTidEqualClause((OpExpr *) expr, varno))
00175 rlst = list_make1(expr);
00176 }
00177 else if (expr && IsA(expr, ScalarArrayOpExpr))
00178 {
00179
00180 if (IsTidEqualAnyClause((ScalarArrayOpExpr *) expr, varno))
00181 rlst = list_make1(expr);
00182 }
00183 else if (expr && IsA(expr, CurrentOfExpr))
00184 {
00185
00186 if (((CurrentOfExpr *) expr)->cvarno == varno)
00187 rlst = list_make1(expr);
00188 }
00189 else if (and_clause(expr))
00190 {
00191 foreach(l, ((BoolExpr *) expr)->args)
00192 {
00193 rlst = TidQualFromExpr((Node *) lfirst(l), varno);
00194 if (rlst)
00195 break;
00196 }
00197 }
00198 else if (or_clause(expr))
00199 {
00200 foreach(l, ((BoolExpr *) expr)->args)
00201 {
00202 List *frtn = TidQualFromExpr((Node *) lfirst(l), varno);
00203
00204 if (frtn)
00205 rlst = list_concat(rlst, frtn);
00206 else
00207 {
00208 if (rlst)
00209 list_free(rlst);
00210 rlst = NIL;
00211 break;
00212 }
00213 }
00214 }
00215 return rlst;
00216 }
00217
00218
00219
00220
00221
00222
00223
00224 static List *
00225 TidQualFromRestrictinfo(List *restrictinfo, int varno)
00226 {
00227 List *rlst = NIL;
00228 ListCell *l;
00229
00230 foreach(l, restrictinfo)
00231 {
00232 RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);
00233
00234 if (!IsA(rinfo, RestrictInfo))
00235 continue;
00236 rlst = TidQualFromExpr((Node *) rinfo->clause, varno);
00237 if (rlst)
00238 break;
00239 }
00240 return rlst;
00241 }
00242
00243
00244
00245
00246
00247
00248
00249 void
00250 create_tidscan_paths(PlannerInfo *root, RelOptInfo *rel)
00251 {
00252 Relids required_outer;
00253 List *tidquals;
00254
00255
00256
00257
00258
00259
00260
00261 required_outer = rel->lateral_relids;
00262
00263 tidquals = TidQualFromRestrictinfo(rel->baserestrictinfo, rel->relid);
00264
00265 if (tidquals)
00266 add_path(rel, (Path *) create_tidscan_path(root, rel, tidquals,
00267 required_outer));
00268 }