* transformWindowDefinitions - * transform window definitions (WindowDef to WindowClause) * * There's a fair bit to do here: column references in the PARTITION and * ORDER clauses must be valid; ORDER clause must present if the function * requires; the frame clause must be checked to ensure that the function * supports framing, that the framed column is of the right type, that the * offset
| 2857 | * part of the clause. |
| 2858 | */ |
| 2859 | List * |
| 2860 | transformWindowDefinitions(ParseState *pstate, |
| 2861 | List *windowdefs, |
| 2862 | List **targetlist) |
| 2863 | { |
| 2864 | List *result = NIL; |
| 2865 | Index winref = 0; |
| 2866 | ListCell *lc; |
| 2867 | |
| 2868 | /* |
| 2869 | * We have two lists of window specs: one in the ParseState -- put there |
| 2870 | * when we find the OVER(...) clause in the targetlist and the other |
| 2871 | * is windowClause, a list of named window clauses. So, we concatenate |
| 2872 | * them together. |
| 2873 | * |
| 2874 | * Note that we're careful place those found in the target list at |
| 2875 | * the end because the spec might refer to a named clause and we'll |
| 2876 | * after to know about those first. |
| 2877 | */ |
| 2878 | foreach(lc, windowdefs) |
| 2879 | { |
| 2880 | WindowDef *windef = (WindowDef *) lfirst(lc); |
| 2881 | WindowClause *refwc = NULL; |
| 2882 | List *partitionClause; |
| 2883 | List *orderClause; |
| 2884 | Oid rangeopfamily = InvalidOid; |
| 2885 | Oid rangeopcintype = InvalidOid; |
| 2886 | WindowClause *wc; |
| 2887 | |
| 2888 | winref++; |
| 2889 | |
| 2890 | /* |
| 2891 | * Check for duplicate window names. |
| 2892 | */ |
| 2893 | if (windef->name && |
| 2894 | findWindowClause(result, windef->name) != NULL) |
| 2895 | ereport(ERROR, |
| 2896 | (errcode(ERRCODE_WINDOWING_ERROR), |
| 2897 | errmsg("window \"%s\" is already defined", windef->name), |
| 2898 | parser_errposition(pstate, windef->location))); |
| 2899 | |
| 2900 | /* |
| 2901 | * If it references a previous window, look that up. |
| 2902 | */ |
| 2903 | if (windef->refname) |
| 2904 | { |
| 2905 | refwc = findWindowClause(result, windef->refname); |
| 2906 | if (refwc == NULL) |
| 2907 | ereport(ERROR, |
| 2908 | (errcode(ERRCODE_UNDEFINED_OBJECT), |
| 2909 | errmsg("window \"%s\" does not exist", |
| 2910 | windef->refname), |
| 2911 | parser_errposition(pstate, windef->location))); |
| 2912 | } |
| 2913 | |
| 2914 | /* |
| 2915 | * Transform PARTITION and ORDER specs, if any. These are treated |
| 2916 | * almost exactly like top-level GROUP BY and ORDER BY clauses, |
no test coverage detected