Produce a record by joining records coming from the left and right hand side of this operation
| 257 | // records coming from the left and right hand side |
| 258 | // of this operation |
| 259 | static Record ValueHashJoinConsume |
| 260 | ( |
| 261 | OpBase *opBase |
| 262 | ) { |
| 263 | OpValueHashJoin *op = (OpValueHashJoin *)opBase; |
| 264 | OpBase *right_child = op->op.children[1]; |
| 265 | |
| 266 | // eager, pull from left branch until depleted |
| 267 | if(op->cached_records == NULL) { |
| 268 | _cache_records(op); |
| 269 | // sort cache on intersect node ID |
| 270 | _sort_cached_records(op); |
| 271 | } |
| 272 | |
| 273 | // try to produce a record: |
| 274 | // given a right hand side record R, |
| 275 | // evaluate V = exp on R, |
| 276 | // see if there are any cached records |
| 277 | // which V evaluated to V: |
| 278 | // X in cached_records and X[idx] = V |
| 279 | // return merged record: |
| 280 | // X merged with R |
| 281 | |
| 282 | Record l; |
| 283 | if(op->number_of_intersections > 0) { |
| 284 | while((l = _get_intersecting_record(op))) { |
| 285 | // clone cached record before merging rhs |
| 286 | Record c = OpBase_CloneRecord(l); |
| 287 | Record_Merge(c, op->rhs_rec); |
| 288 | return c; |
| 289 | } |
| 290 | } |
| 291 | |
| 292 | // if we're here there are no more |
| 293 | // left hand side records which intersect with R |
| 294 | // discard R |
| 295 | if(op->rhs_rec) OpBase_DeleteRecord(op->rhs_rec); |
| 296 | |
| 297 | // try to get new right hand side record |
| 298 | // which intersect with a left hand side record |
| 299 | while(true) { |
| 300 | // pull from right branch |
| 301 | op->rhs_rec = right_child->consume(right_child); |
| 302 | if(!op->rhs_rec) return NULL; |
| 303 | |
| 304 | // get value on which we're intersecting |
| 305 | SIValue v = AR_EXP_Evaluate(op->rhs_exp, op->rhs_rec); |
| 306 | |
| 307 | bool found_intersection = _set_intersection_idx(op, v); |
| 308 | SIValue_Free(v); |
| 309 | // no intersection, discard R |
| 310 | if(!found_intersection) { |
| 311 | OpBase_DeleteRecord(op->rhs_rec); |
| 312 | continue; |
| 313 | } |
| 314 | |
| 315 | // found atleast one intersecting record |
| 316 | l = _get_intersecting_record(op); |
nothing calls this directly
no test coverage detected