* Prepare step for the evaluation of a whole-row variable. * The caller still has to push the step. */
| 2864 | * The caller still has to push the step. |
| 2865 | */ |
| 2866 | static void |
| 2867 | ExecInitWholeRowVar(ExprEvalStep *scratch, Var *variable, ExprState *state) |
| 2868 | { |
| 2869 | PlanState *parent = state->parent; |
| 2870 | |
| 2871 | /* fill in all but the target */ |
| 2872 | scratch->opcode = EEOP_WHOLEROW; |
| 2873 | scratch->d.wholerow.var = variable; |
| 2874 | scratch->d.wholerow.first = true; |
| 2875 | scratch->d.wholerow.slow = false; |
| 2876 | scratch->d.wholerow.tupdesc = NULL; /* filled at runtime */ |
| 2877 | scratch->d.wholerow.junkFilter = NULL; |
| 2878 | |
| 2879 | /* |
| 2880 | * If the input tuple came from a subquery, it might contain "resjunk" |
| 2881 | * columns (such as GROUP BY or ORDER BY columns), which we don't want to |
| 2882 | * keep in the whole-row result. We can get rid of such columns by |
| 2883 | * passing the tuple through a JunkFilter --- but to make one, we have to |
| 2884 | * lay our hands on the subquery's targetlist. Fortunately, there are not |
| 2885 | * very many cases where this can happen, and we can identify all of them |
| 2886 | * by examining our parent PlanState. We assume this is not an issue in |
| 2887 | * standalone expressions that don't have parent plans. (Whole-row Vars |
| 2888 | * can occur in such expressions, but they will always be referencing |
| 2889 | * table rows.) |
| 2890 | */ |
| 2891 | if (parent) |
| 2892 | { |
| 2893 | PlanState *subplan = NULL; |
| 2894 | |
| 2895 | switch (nodeTag(parent)) |
| 2896 | { |
| 2897 | case T_SubqueryScanState: |
| 2898 | subplan = ((SubqueryScanState *) parent)->subplan; |
| 2899 | break; |
| 2900 | case T_CteScanState: |
| 2901 | subplan = ((CteScanState *) parent)->cteplanstate; |
| 2902 | break; |
| 2903 | default: |
| 2904 | break; |
| 2905 | } |
| 2906 | |
| 2907 | if (subplan) |
| 2908 | { |
| 2909 | bool junk_filter_needed = false; |
| 2910 | ListCell *tlist; |
| 2911 | |
| 2912 | /* Detect whether subplan tlist actually has any junk columns */ |
| 2913 | foreach(tlist, subplan->plan->targetlist) |
| 2914 | { |
| 2915 | TargetEntry *tle = (TargetEntry *) lfirst(tlist); |
| 2916 | |
| 2917 | if (tle->resjunk) |
| 2918 | { |
| 2919 | junk_filter_needed = true; |
| 2920 | break; |
| 2921 | } |
| 2922 | } |
| 2923 |
no test coverage detected