* Splits every TupleTableSlot into two TupleTableSlots: DELETE and INSERT. */
| 167 | * Splits every TupleTableSlot into two TupleTableSlots: DELETE and INSERT. |
| 168 | */ |
| 169 | static TupleTableSlot * |
| 170 | ExecSplitUpdate(PlanState *pstate) |
| 171 | { |
| 172 | SplitUpdateState *node = castNode(SplitUpdateState, pstate); |
| 173 | PlanState *outerNode = outerPlanState(node); |
| 174 | SplitUpdate *plannode = (SplitUpdate *) node->ps.plan; |
| 175 | |
| 176 | TupleTableSlot *slot = NULL; |
| 177 | TupleTableSlot *result = NULL; |
| 178 | |
| 179 | Assert(outerNode != NULL); |
| 180 | |
| 181 | /* Returns INSERT TupleTableSlot. */ |
| 182 | if (!node->processInsert) |
| 183 | { |
| 184 | result = node->insertTuple; |
| 185 | |
| 186 | node->processInsert = true; |
| 187 | } |
| 188 | else |
| 189 | { |
| 190 | /* Creates both TupleTableSlots. Returns DELETE TupleTableSlots.*/ |
| 191 | slot = ExecProcNode(outerNode); |
| 192 | |
| 193 | if (TupIsNull(slot)) |
| 194 | { |
| 195 | return NULL; |
| 196 | } |
| 197 | |
| 198 | /* `Split' update into delete and insert */ |
| 199 | slot_getallattrs(slot); |
| 200 | Datum *values = slot->tts_values; |
| 201 | bool *nulls = slot->tts_isnull; |
| 202 | |
| 203 | ExecStoreAllNullTuple(node->deleteTuple); |
| 204 | ExecStoreAllNullTuple(node->insertTuple); |
| 205 | |
| 206 | SplitTupleTableSlot(slot, plannode->plan.targetlist, plannode, node, values, nulls); |
| 207 | |
| 208 | result = node->deleteTuple; |
| 209 | node->processInsert = false; |
| 210 | |
| 211 | } |
| 212 | |
| 213 | return result; |
| 214 | } |
| 215 | |
| 216 | /* |
| 217 | * Init SplitUpdate Node. A memory context is created to hold Split Tuples. |
nothing calls this directly
no test coverage detected