* ExecInitJunkFilterConversion * * Initialize a JunkFilter for rowtype conversions. * * Here, we are given the target "clean" tuple descriptor rather than * inferring it from the targetlist. The target descriptor can contain * deleted columns. It is assumed that the caller has checked that the * non-deleted columns match up with the non-junk columns of the targetlist. */
| 142 | * non-deleted columns match up with the non-junk columns of the targetlist. |
| 143 | */ |
| 144 | JunkFilter * |
| 145 | ExecInitJunkFilterConversion(List *targetList, |
| 146 | TupleDesc cleanTupType, |
| 147 | TupleTableSlot *slot, |
| 148 | ExecFilterJunkFunc execFilterJunkFunc) |
| 149 | { |
| 150 | JunkFilter *junkfilter; |
| 151 | int cleanLength; |
| 152 | AttrNumber *cleanMap; |
| 153 | ListCell *t; |
| 154 | int i; |
| 155 | |
| 156 | /* |
| 157 | * Use the given slot, or make a new slot if we weren't given one. |
| 158 | */ |
| 159 | if (slot) |
| 160 | ExecSetSlotDescriptor(slot, cleanTupType); |
| 161 | else |
| 162 | slot = MakeSingleTupleTableSlot(cleanTupType, &TTSOpsVirtual); |
| 163 | |
| 164 | /* |
| 165 | * Calculate the mapping between the original tuple's attributes and the |
| 166 | * "clean" tuple's attributes. |
| 167 | * |
| 168 | * The "map" is an array of "cleanLength" attribute numbers, i.e. one |
| 169 | * entry for every attribute of the "clean" tuple. The value of this entry |
| 170 | * is the attribute number of the corresponding attribute of the |
| 171 | * "original" tuple. We store zero for any deleted attributes, marking |
| 172 | * that a NULL is needed in the output tuple. |
| 173 | */ |
| 174 | cleanLength = cleanTupType->natts; |
| 175 | if (cleanLength > 0) |
| 176 | { |
| 177 | cleanMap = (AttrNumber *) palloc0(cleanLength * sizeof(AttrNumber)); |
| 178 | t = list_head(targetList); |
| 179 | for (i = 0; i < cleanLength; i++) |
| 180 | { |
| 181 | if (TupleDescAttr(cleanTupType, i)->attisdropped) |
| 182 | continue; /* map entry is already zero */ |
| 183 | for (;;) |
| 184 | { |
| 185 | TargetEntry *tle = lfirst(t); |
| 186 | |
| 187 | t = lnext(targetList, t); |
| 188 | if (!tle->resjunk) |
| 189 | { |
| 190 | cleanMap[i] = tle->resno; |
| 191 | break; |
| 192 | } |
| 193 | } |
| 194 | } |
| 195 | } |
| 196 | else |
| 197 | cleanMap = NULL; |
| 198 | |
| 199 | /* |
| 200 | * Finally create and initialize the JunkFilter struct. |
| 201 | */ |
no test coverage detected