* execCurrentOf * * Given a CURRENT OF expression and the OID of a table, determine which row * of the table is currently being scanned by the cursor named by CURRENT OF, * and return the row's TID into *current_tid. * * Returns true if a row was identified. Returns false if the cursor is valid * for the table but is not currently scanning a row of the table (this is a * legal situation i
| 47 | * In GPDB, we also check that the tuple came from the current segment. |
| 48 | */ |
| 49 | bool |
| 50 | execCurrentOf(CurrentOfExpr *cexpr, |
| 51 | ExprContext *econtext, |
| 52 | Oid table_oid, |
| 53 | ItemPointer current_tid) |
| 54 | { |
| 55 | int current_gp_segment_id = -1; |
| 56 | Oid current_table_oid; |
| 57 | |
| 58 | /* |
| 59 | * In an executor node, the dispatcher should've included the current |
| 60 | * position of the cursor along with the query plan. Find and return it |
| 61 | * from there. |
| 62 | */ |
| 63 | if (Gp_role == GP_ROLE_EXECUTE) |
| 64 | { |
| 65 | ListCell *lc; |
| 66 | char *cursor_name; |
| 67 | bool found = false; |
| 68 | |
| 69 | /* Get the cursor name --- may have to look up a parameter reference */ |
| 70 | if (cexpr->cursor_name) |
| 71 | cursor_name = cexpr->cursor_name; |
| 72 | else |
| 73 | cursor_name = fetch_cursor_param_value(econtext, cexpr->cursor_param); |
| 74 | |
| 75 | foreach (lc, econtext->ecxt_estate->es_cursorPositions) |
| 76 | { |
| 77 | CursorPosInfo *cpos = (CursorPosInfo *) lfirst(lc); |
| 78 | |
| 79 | if (strcmp(cpos->cursor_name, cursor_name) == 0) |
| 80 | { |
| 81 | current_gp_segment_id = cpos->gp_segment_id; |
| 82 | current_table_oid = cpos->table_oid; |
| 83 | ItemPointerCopy(&cpos->ctid, current_tid); |
| 84 | found = true; |
| 85 | break; |
| 86 | } |
| 87 | } |
| 88 | |
| 89 | /* Not found. Odd, the dispatcher should've checked for this already. */ |
| 90 | if (!found) |
| 91 | elog(ERROR, "no cursor position information found for cursor \"%s\"", |
| 92 | cursor_name); |
| 93 | } |
| 94 | else |
| 95 | { |
| 96 | bool res = getCurrentOf(cexpr, econtext, table_oid, current_tid, |
| 97 | ¤t_gp_segment_id, ¤t_table_oid, NULL); |
| 98 | /* |
| 99 | * In singlenode mode, we don't bother to check segment match. |
| 100 | * And if we have partitioned table, we will do the table oid check inside getCurrentOf. |
| 101 | */ |
| 102 | if (IS_SINGLENODE()) |
| 103 | return res; |
| 104 | } |
| 105 | |
| 106 | /* |
no test coverage detected