* create_window_paths * * Build a new upperrel containing Paths for window-function evaluation. * * input_rel: contains the source-data Paths * input_target: result of make_window_input_target * output_target: what the topmost WindowAggPath should return * wflists: result of find_window_functions * activeWindows: result of select_active_windows * * Note: all Paths in input_rel are expect
| 4834 | * Note: all Paths in input_rel are expected to return input_target. |
| 4835 | */ |
| 4836 | static RelOptInfo * |
| 4837 | create_window_paths(PlannerInfo *root, |
| 4838 | RelOptInfo *input_rel, |
| 4839 | PathTarget *input_target, |
| 4840 | PathTarget *output_target, |
| 4841 | bool output_target_parallel_safe, |
| 4842 | WindowFuncLists *wflists, |
| 4843 | List *activeWindows) |
| 4844 | { |
| 4845 | RelOptInfo *window_rel; |
| 4846 | ListCell *lc; |
| 4847 | |
| 4848 | /* For now, do all work in the (WINDOW, NULL) upperrel */ |
| 4849 | window_rel = fetch_upper_rel(root, UPPERREL_WINDOW, NULL); |
| 4850 | |
| 4851 | /* |
| 4852 | * If the input relation is not parallel-safe, then the window relation |
| 4853 | * can't be parallel-safe, either. Otherwise, we need to examine the |
| 4854 | * target list and active windows for non-parallel-safe constructs. |
| 4855 | */ |
| 4856 | if (input_rel->consider_parallel && output_target_parallel_safe && |
| 4857 | is_parallel_safe(root, (Node *) activeWindows)) |
| 4858 | window_rel->consider_parallel = true; |
| 4859 | |
| 4860 | /* |
| 4861 | * If the input rel belongs to a single FDW, so does the window rel. |
| 4862 | */ |
| 4863 | window_rel->serverid = input_rel->serverid; |
| 4864 | window_rel->userid = input_rel->userid; |
| 4865 | window_rel->useridiscurrent = input_rel->useridiscurrent; |
| 4866 | window_rel->fdwroutine = input_rel->fdwroutine; |
| 4867 | window_rel->exec_location = input_rel->exec_location; |
| 4868 | |
| 4869 | /* |
| 4870 | * Consider computing window functions starting from the existing |
| 4871 | * cheapest-total path (which will likely require a sort) as well as any |
| 4872 | * existing paths that satisfy or partially satisfy root->window_pathkeys. |
| 4873 | */ |
| 4874 | foreach(lc, input_rel->pathlist) |
| 4875 | { |
| 4876 | Path *path = (Path *) lfirst(lc); |
| 4877 | int presorted_keys; |
| 4878 | |
| 4879 | if (path == input_rel->cheapest_total_path || |
| 4880 | pathkeys_count_contained_in(root->window_pathkeys, path->pathkeys, |
| 4881 | &presorted_keys) || |
| 4882 | presorted_keys > 0) |
| 4883 | create_one_window_path(root, |
| 4884 | window_rel, |
| 4885 | path, |
| 4886 | input_target, |
| 4887 | output_target, |
| 4888 | wflists, |
| 4889 | activeWindows); |
| 4890 | } |
| 4891 | |
| 4892 | /* |
| 4893 | * Unlike Upstream, we could make window function parallel by redistributing |
no test coverage detected