* postgresExplainForeignScan * Produce extra output for EXPLAIN of a ForeignScan on a foreign table */
| 2819 | * Produce extra output for EXPLAIN of a ForeignScan on a foreign table |
| 2820 | */ |
| 2821 | static void |
| 2822 | postgresExplainForeignScan(ForeignScanState *node, ExplainState *es) |
| 2823 | { |
| 2824 | ForeignScan *plan = castNode(ForeignScan, node->ss.ps.plan); |
| 2825 | List *fdw_private = plan->fdw_private; |
| 2826 | |
| 2827 | /* |
| 2828 | * Identify foreign scans that are really joins or upper relations. The |
| 2829 | * input looks something like "(1) LEFT JOIN (2)", and we must replace the |
| 2830 | * digit string(s), which are RT indexes, with the correct relation names. |
| 2831 | * We do that here, not when the plan is created, because we can't know |
| 2832 | * what aliases ruleutils.c will assign at plan creation time. |
| 2833 | */ |
| 2834 | if (list_length(fdw_private) > FdwScanPrivateRelations) |
| 2835 | { |
| 2836 | StringInfo relations; |
| 2837 | char *rawrelations; |
| 2838 | char *ptr; |
| 2839 | int minrti, |
| 2840 | rtoffset; |
| 2841 | |
| 2842 | rawrelations = strVal(list_nth(fdw_private, FdwScanPrivateRelations)); |
| 2843 | |
| 2844 | /* |
| 2845 | * A difficulty with using a string representation of RT indexes is |
| 2846 | * that setrefs.c won't update the string when flattening the |
| 2847 | * rangetable. To find out what rtoffset was applied, identify the |
| 2848 | * minimum RT index appearing in the string and compare it to the |
| 2849 | * minimum member of plan->fs_relids. (We expect all the relids in |
| 2850 | * the join will have been offset by the same amount; the Asserts |
| 2851 | * below should catch it if that ever changes.) |
| 2852 | */ |
| 2853 | minrti = INT_MAX; |
| 2854 | ptr = rawrelations; |
| 2855 | while (*ptr) |
| 2856 | { |
| 2857 | if (isdigit((unsigned char) *ptr)) |
| 2858 | { |
| 2859 | int rti = strtol(ptr, &ptr, 10); |
| 2860 | |
| 2861 | if (rti < minrti) |
| 2862 | minrti = rti; |
| 2863 | } |
| 2864 | else |
| 2865 | ptr++; |
| 2866 | } |
| 2867 | rtoffset = bms_next_member(plan->fs_relids, -1) - minrti; |
| 2868 | |
| 2869 | /* Now we can translate the string */ |
| 2870 | relations = makeStringInfo(); |
| 2871 | ptr = rawrelations; |
| 2872 | while (*ptr) |
| 2873 | { |
| 2874 | if (isdigit((unsigned char) *ptr)) |
| 2875 | { |
| 2876 | int rti = strtol(ptr, &ptr, 10); |
| 2877 | RangeTblEntry *rte; |
| 2878 | char *relname; |
nothing calls this directly
no test coverage detected