Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "postgres.h"
00016
00017 #include "executor/executor.h"
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 JunkFilter *
00061 ExecInitJunkFilter(List *targetList, bool hasoid, TupleTableSlot *slot)
00062 {
00063 JunkFilter *junkfilter;
00064 TupleDesc cleanTupType;
00065 int cleanLength;
00066 AttrNumber *cleanMap;
00067 ListCell *t;
00068 AttrNumber cleanResno;
00069
00070
00071
00072
00073 cleanTupType = ExecCleanTypeFromTL(targetList, hasoid);
00074
00075
00076
00077
00078 if (slot)
00079 ExecSetSlotDescriptor(slot, cleanTupType);
00080 else
00081 slot = MakeSingleTupleTableSlot(cleanTupType);
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 cleanLength = cleanTupType->natts;
00094 if (cleanLength > 0)
00095 {
00096 cleanMap = (AttrNumber *) palloc(cleanLength * sizeof(AttrNumber));
00097 cleanResno = 1;
00098 foreach(t, targetList)
00099 {
00100 TargetEntry *tle = lfirst(t);
00101
00102 if (!tle->resjunk)
00103 {
00104 cleanMap[cleanResno - 1] = tle->resno;
00105 cleanResno++;
00106 }
00107 }
00108 }
00109 else
00110 cleanMap = NULL;
00111
00112
00113
00114
00115 junkfilter = makeNode(JunkFilter);
00116
00117 junkfilter->jf_targetList = targetList;
00118 junkfilter->jf_cleanTupType = cleanTupType;
00119 junkfilter->jf_cleanMap = cleanMap;
00120 junkfilter->jf_resultSlot = slot;
00121
00122 return junkfilter;
00123 }
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 JunkFilter *
00136 ExecInitJunkFilterConversion(List *targetList,
00137 TupleDesc cleanTupType,
00138 TupleTableSlot *slot)
00139 {
00140 JunkFilter *junkfilter;
00141 int cleanLength;
00142 AttrNumber *cleanMap;
00143 ListCell *t;
00144 int i;
00145
00146
00147
00148
00149 if (slot)
00150 ExecSetSlotDescriptor(slot, cleanTupType);
00151 else
00152 slot = MakeSingleTupleTableSlot(cleanTupType);
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 cleanLength = cleanTupType->natts;
00165 if (cleanLength > 0)
00166 {
00167 cleanMap = (AttrNumber *) palloc0(cleanLength * sizeof(AttrNumber));
00168 t = list_head(targetList);
00169 for (i = 0; i < cleanLength; i++)
00170 {
00171 if (cleanTupType->attrs[i]->attisdropped)
00172 continue;
00173 for (;;)
00174 {
00175 TargetEntry *tle = lfirst(t);
00176
00177 t = lnext(t);
00178 if (!tle->resjunk)
00179 {
00180 cleanMap[i] = tle->resno;
00181 break;
00182 }
00183 }
00184 }
00185 }
00186 else
00187 cleanMap = NULL;
00188
00189
00190
00191
00192 junkfilter = makeNode(JunkFilter);
00193
00194 junkfilter->jf_targetList = targetList;
00195 junkfilter->jf_cleanTupType = cleanTupType;
00196 junkfilter->jf_cleanMap = cleanMap;
00197 junkfilter->jf_resultSlot = slot;
00198
00199 return junkfilter;
00200 }
00201
00202
00203
00204
00205
00206
00207
00208 AttrNumber
00209 ExecFindJunkAttribute(JunkFilter *junkfilter, const char *attrName)
00210 {
00211 return ExecFindJunkAttributeInTlist(junkfilter->jf_targetList, attrName);
00212 }
00213
00214
00215
00216
00217
00218
00219
00220 AttrNumber
00221 ExecFindJunkAttributeInTlist(List *targetlist, const char *attrName)
00222 {
00223 ListCell *t;
00224
00225 foreach(t, targetlist)
00226 {
00227 TargetEntry *tle = lfirst(t);
00228
00229 if (tle->resjunk && tle->resname &&
00230 (strcmp(tle->resname, attrName) == 0))
00231 {
00232
00233 return tle->resno;
00234 }
00235 }
00236
00237 return InvalidAttrNumber;
00238 }
00239
00240
00241
00242
00243
00244
00245
00246
00247 Datum
00248 ExecGetJunkAttribute(TupleTableSlot *slot, AttrNumber attno,
00249 bool *isNull)
00250 {
00251 Assert(attno > 0);
00252
00253 return slot_getattr(slot, attno, isNull);
00254 }
00255
00256
00257
00258
00259
00260
00261 TupleTableSlot *
00262 ExecFilterJunk(JunkFilter *junkfilter, TupleTableSlot *slot)
00263 {
00264 TupleTableSlot *resultSlot;
00265 AttrNumber *cleanMap;
00266 TupleDesc cleanTupType;
00267 int cleanLength;
00268 int i;
00269 Datum *values;
00270 bool *isnull;
00271 Datum *old_values;
00272 bool *old_isnull;
00273
00274
00275
00276
00277 slot_getallattrs(slot);
00278 old_values = slot->tts_values;
00279 old_isnull = slot->tts_isnull;
00280
00281
00282
00283
00284 cleanTupType = junkfilter->jf_cleanTupType;
00285 cleanLength = cleanTupType->natts;
00286 cleanMap = junkfilter->jf_cleanMap;
00287 resultSlot = junkfilter->jf_resultSlot;
00288
00289
00290
00291
00292 ExecClearTuple(resultSlot);
00293 values = resultSlot->tts_values;
00294 isnull = resultSlot->tts_isnull;
00295
00296
00297
00298
00299 for (i = 0; i < cleanLength; i++)
00300 {
00301 int j = cleanMap[i];
00302
00303 if (j == 0)
00304 {
00305 values[i] = (Datum) 0;
00306 isnull[i] = true;
00307 }
00308 else
00309 {
00310 values[i] = old_values[j - 1];
00311 isnull[i] = old_isnull[j - 1];
00312 }
00313 }
00314
00315
00316
00317
00318 return ExecStoreVirtualTuple(resultSlot);
00319 }