| 64 | } |
| 65 | |
| 66 | static TupleTableSlot * |
| 67 | RuntimeFilterTupleNext(RuntimeFilterState *node) |
| 68 | { |
| 69 | ExprContext *econtext; |
| 70 | HashJoinState *hjstate; |
| 71 | PlanState *outerPlan; |
| 72 | HashJoinTable hashtable; |
| 73 | List *hashkeys; |
| 74 | FmgrInfo *hashfunctions; |
| 75 | Oid *hashcollations; |
| 76 | ListCell *hk; |
| 77 | MemoryContext oldContext; |
| 78 | TupleTableSlot *slot; |
| 79 | |
| 80 | CHECK_FOR_INTERRUPTS(); |
| 81 | |
| 82 | outerPlan = outerPlanState(node); |
| 83 | hjstate = node->hjstate; |
| 84 | econtext = hjstate->js.ps.ps_ExprContext; |
| 85 | hashkeys = hjstate->hj_OuterHashKeys; |
| 86 | hashtable = hjstate->hj_HashTable; |
| 87 | hashfunctions = hashtable->outer_hashfunctions; |
| 88 | hashcollations = hashtable->collations; |
| 89 | |
| 90 | for (;;) |
| 91 | { |
| 92 | int idx = 0; |
| 93 | bool hasnull = false; |
| 94 | |
| 95 | slot = ExecProcNode(outerPlan); |
| 96 | if (TupIsNull(slot)) |
| 97 | return slot; |
| 98 | |
| 99 | ResetExprContext(econtext); |
| 100 | oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory); |
| 101 | |
| 102 | econtext->ecxt_outertuple = slot; |
| 103 | |
| 104 | foreach(hk, hashkeys) |
| 105 | { |
| 106 | ExprState *keyexpr = (ExprState *) lfirst(hk); |
| 107 | Datum keyval; |
| 108 | bool isNull = false; |
| 109 | |
| 110 | /* Get the join attribute value of the tuple */ |
| 111 | keyval = ExecEvalExpr(keyexpr, econtext, &isNull); |
| 112 | hasnull = hasnull || isNull; |
| 113 | if (hasnull) |
| 114 | break; |
| 115 | |
| 116 | if (node->raw_value[idx]) |
| 117 | node->value_buf[idx] = keyval; |
| 118 | else |
| 119 | { |
| 120 | uint32 hkey; |
| 121 | |
| 122 | /* Compute the hash function */ |
| 123 | hkey = DatumGetUInt32(FunctionCall1Coll(&hashfunctions[idx], hashcollations[idx], keyval)); |
no test coverage detected