* transformWindowFuncCall - * Finish initial transformation of a window function call * * parse_func.c has recognized the function as a window function, and has set * up all the fields of the WindowFunc except winref. Here we must (1) add * the WindowDef to the pstate (if not a duplicate of one already present) and * set winref to link to it; and (2) mark p_hasWindowFuncs true in the pstat
| 857 | * considered --- there are no "outer window functions" per SQL spec. |
| 858 | */ |
| 859 | void |
| 860 | transformWindowFuncCall(ParseState *pstate, WindowFunc *wfunc, |
| 861 | WindowDef *windef) |
| 862 | { |
| 863 | const char *err; |
| 864 | bool errkind; |
| 865 | char *name; |
| 866 | |
| 867 | /* |
| 868 | * A window function call can't contain another one (but aggs are OK). XXX |
| 869 | * is this required by spec, or just an unimplemented feature? |
| 870 | * |
| 871 | * Note: we don't need to check the filter expression here, because the |
| 872 | * context checks done below and in transformAggregateCall would have |
| 873 | * already rejected any window funcs or aggs within the filter. |
| 874 | */ |
| 875 | if (pstate->p_hasWindowFuncs && |
| 876 | contain_windowfuncs((Node *) wfunc->args)) |
| 877 | ereport(ERROR, |
| 878 | (errcode(ERRCODE_WINDOWING_ERROR), |
| 879 | errmsg("window function calls cannot be nested"), |
| 880 | parser_errposition(pstate, |
| 881 | locate_windowfunc((Node *) wfunc->args)))); |
| 882 | |
| 883 | /* |
| 884 | * Check to see if the window function is in an invalid place within the |
| 885 | * query. |
| 886 | * |
| 887 | * For brevity we support two schemes for reporting an error here: set |
| 888 | * "err" to a custom message, or set "errkind" true if the error context |
| 889 | * is sufficiently identified by what ParseExprKindName will return, *and* |
| 890 | * what it will return is just a SQL keyword. (Otherwise, use a custom |
| 891 | * message to avoid creating translation problems.) |
| 892 | */ |
| 893 | err = NULL; |
| 894 | errkind = false; |
| 895 | switch (pstate->p_expr_kind) |
| 896 | { |
| 897 | case EXPR_KIND_NONE: |
| 898 | Assert(false); /* can't happen */ |
| 899 | break; |
| 900 | case EXPR_KIND_OTHER: |
| 901 | /* Accept window func here; caller must throw error if wanted */ |
| 902 | break; |
| 903 | case EXPR_KIND_JOIN_ON: |
| 904 | case EXPR_KIND_JOIN_USING: |
| 905 | err = _("window functions are not allowed in JOIN conditions"); |
| 906 | break; |
| 907 | case EXPR_KIND_FROM_SUBSELECT: |
| 908 | /* can't get here, but just in case, throw an error */ |
| 909 | errkind = true; |
| 910 | break; |
| 911 | case EXPR_KIND_FROM_FUNCTION: |
| 912 | err = _("window functions are not allowed in functions in FROM"); |
| 913 | break; |
| 914 | case EXPR_KIND_WHERE: |
| 915 | errkind = true; |
| 916 | break; |
no test coverage detected