diff options
| author | Tom Lane <tgl@sss.pgh.pa.us> | 2013-12-23 16:11:35 -0500 |
|---|---|---|
| committer | Tom Lane <tgl@sss.pgh.pa.us> | 2013-12-23 16:11:35 -0500 |
| commit | 8d65da1f01c6a4c84fe9c59aeb6b7e3adf870145 (patch) | |
| tree | 9ab9bf5fc1f7a128ff4638d1c7f36a83fc317ca2 /src/include | |
| parent | 37484ad2aacef5ec794f4dd3d5cf814475180a78 (diff) | |
Support ordered-set (WITHIN GROUP) aggregates.
This patch introduces generic support for ordered-set and hypothetical-set
aggregate functions, as well as implementations of the instances defined in
SQL:2008 (percentile_cont(), percentile_disc(), rank(), dense_rank(),
percent_rank(), cume_dist()). We also added mode() though it is not in the
spec, as well as versions of percentile_cont() and percentile_disc() that
can compute multiple percentile values in one pass over the data.
Unlike the original submission, this patch puts full control of the sorting
process in the hands of the aggregate's support functions. To allow the
support functions to find out how they're supposed to sort, a new API
function AggGetAggref() is added to nodeAgg.c. This allows retrieval of
the aggregate call's Aggref node, which may have other uses beyond the
immediate need. There is also support for ordered-set aggregates to
install cleanup callback functions, so that they can be sure that
infrastructure such as tuplesort objects gets cleaned up.
In passing, make some fixes in the recently-added support for variadic
aggregates, and make some editorial adjustments in the recent FILTER
additions for aggregates. Also, simplify use of IsBinaryCoercible() by
allowing it to succeed whenever the target type is ANY or ANYELEMENT.
It was inconsistent that it dealt with other polymorphic target types
but not these.
Atri Sharma and Andrew Gierth; reviewed by Pavel Stehule and Vik Fearing,
and rather heavily editorialized upon by Tom Lane
Diffstat (limited to 'src/include')
| -rw-r--r-- | src/include/catalog/catversion.h | 2 | ||||
| -rw-r--r-- | src/include/catalog/pg_aggregate.h | 296 | ||||
| -rw-r--r-- | src/include/catalog/pg_operator.h | 1 | ||||
| -rw-r--r-- | src/include/catalog/pg_proc.h | 57 | ||||
| -rw-r--r-- | src/include/commands/defrem.h | 1 | ||||
| -rw-r--r-- | src/include/fmgr.h | 13 | ||||
| -rw-r--r-- | src/include/nodes/execnodes.h | 8 | ||||
| -rw-r--r-- | src/include/nodes/parsenodes.h | 4 | ||||
| -rw-r--r-- | src/include/nodes/primnodes.h | 19 | ||||
| -rw-r--r-- | src/include/nodes/relation.h | 9 | ||||
| -rw-r--r-- | src/include/parser/kwlist.h | 1 | ||||
| -rw-r--r-- | src/include/parser/parse_agg.h | 9 | ||||
| -rw-r--r-- | src/include/parser/parse_clause.h | 3 | ||||
| -rw-r--r-- | src/include/parser/parse_func.h | 4 | ||||
| -rw-r--r-- | src/include/utils/builtins.h | 15 | ||||
| -rw-r--r-- | src/include/utils/lsyscache.h | 1 | ||||
| -rw-r--r-- | src/include/utils/tuplesort.h | 3 |
17 files changed, 296 insertions, 150 deletions
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index b7610e8c3f8..e8b60bda7e1 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 201312131 +#define CATALOG_VERSION_NO 201312231 #endif diff --git a/src/include/catalog/pg_aggregate.h b/src/include/catalog/pg_aggregate.h index 034456a315d..f0eaf60a09b 100644 --- a/src/include/catalog/pg_aggregate.h +++ b/src/include/catalog/pg_aggregate.h @@ -28,6 +28,8 @@ * cpp turns this into typedef struct FormData_pg_aggregate * * aggfnoid pg_proc OID of the aggregate itself + * aggkind aggregate kind, see AGGKIND_ categories below + * aggnumdirectargs number of arguments that are "direct" arguments * aggtransfn transition function * aggfinalfn final function (0 if none) * aggsortop associated sort operator (0 if none) @@ -41,6 +43,8 @@ CATALOG(pg_aggregate,2600) BKI_WITHOUT_OIDS { regproc aggfnoid; + char aggkind; + int16 aggnumdirectargs; regproc aggtransfn; regproc aggfinalfn; Oid aggsortop; @@ -64,14 +68,31 @@ typedef FormData_pg_aggregate *Form_pg_aggregate; * ---------------- */ -#define Natts_pg_aggregate 7 -#define Anum_pg_aggregate_aggfnoid 1 -#define Anum_pg_aggregate_aggtransfn 2 -#define Anum_pg_aggregate_aggfinalfn 3 -#define Anum_pg_aggregate_aggsortop 4 -#define Anum_pg_aggregate_aggtranstype 5 -#define Anum_pg_aggregate_aggtransspace 6 -#define Anum_pg_aggregate_agginitval 7 +#define Natts_pg_aggregate 9 +#define Anum_pg_aggregate_aggfnoid 1 +#define Anum_pg_aggregate_aggkind 2 +#define Anum_pg_aggregate_aggnumdirectargs 3 +#define Anum_pg_aggregate_aggtransfn 4 +#define Anum_pg_aggregate_aggfinalfn 5 +#define Anum_pg_aggregate_aggsortop 6 +#define Anum_pg_aggregate_aggtranstype 7 +#define Anum_pg_aggregate_aggtransspace 8 +#define Anum_pg_aggregate_agginitval 9 + +/* + * Symbolic values for aggkind column. We distinguish normal aggregates + * from ordered-set aggregates (which have two sets of arguments, namely + * direct and aggregated arguments) and from hypothetical-set aggregates + * (which are a subclass of ordered-set aggregates in which the last + * direct arguments have to match up in number and datatypes with the + * aggregated arguments). + */ +#define AGGKIND_NORMAL 'n' +#define AGGKIND_ORDERED_SET 'o' +#define AGGKIND_HYPOTHETICAL 'h' + +/* Use this macro to test for "ordered-set agg including hypothetical case" */ +#define AGGKIND_IS_ORDERED_SET(kind) ((kind) != AGGKIND_NORMAL) /* ---------------- @@ -80,175 +101,192 @@ typedef FormData_pg_aggregate *Form_pg_aggregate; */ /* avg */ -DATA(insert ( 2100 int8_avg_accum numeric_avg 0 2281 128 _null_ )); -DATA(insert ( 2101 int4_avg_accum int8_avg 0 1016 0 "{0,0}" )); -DATA(insert ( 2102 int2_avg_accum int8_avg 0 1016 0 "{0,0}" )); -DATA(insert ( 2103 numeric_avg_accum numeric_avg 0 2281 128 _null_ )); -DATA(insert ( 2104 float4_accum float8_avg 0 1022 0 "{0,0,0}" )); -DATA(insert ( 2105 float8_accum float8_avg 0 1022 0 "{0,0,0}" )); -DATA(insert ( 2106 interval_accum interval_avg 0 1187 0 "{0 second,0 second}" )); +DATA(insert ( 2100 n 0 int8_avg_accum numeric_avg 0 2281 128 _null_ )); +DATA(insert ( 2101 n 0 int4_avg_accum int8_avg 0 1016 0 "{0,0}" )); +DATA(insert ( 2102 n 0 int2_avg_accum int8_avg 0 1016 0 "{0,0}" )); +DATA(insert ( 2103 n 0 numeric_avg_accum numeric_avg 0 2281 128 _null_ )); +DATA(insert ( 2104 n 0 float4_accum float8_avg 0 1022 0 "{0,0,0}" )); +DATA(insert ( 2105 n 0 float8_accum float8_avg 0 1022 0 "{0,0,0}" )); +DATA(insert ( 2106 n 0 interval_accum interval_avg 0 1187 0 "{0 second,0 second}" )); /* sum */ -DATA(insert ( 2107 int8_avg_accum numeric_sum 0 2281 128 _null_ )); -DATA(insert ( 2108 int4_sum - 0 20 0 _null_ )); -DATA(insert ( 2109 int2_sum - 0 20 0 _null_ )); -DATA(insert ( 2110 float4pl - 0 700 0 _null_ )); -DATA(insert ( 2111 float8pl - 0 701 0 _null_ )); -DATA(insert ( 2112 cash_pl - 0 790 0 _null_ )); -DATA(insert ( 2113 interval_pl - 0 1186 0 _null_ )); -DATA(insert ( 2114 numeric_avg_accum numeric_sum 0 2281 128 _null_ )); +DATA(insert ( 2107 n 0 int8_avg_accum numeric_sum 0 2281 128 _null_ )); +DATA(insert ( 2108 n 0 int4_sum - 0 20 0 _null_ )); +DATA(insert ( 2109 n 0 int2_sum - 0 20 0 _null_ )); +DATA(insert ( 2110 n 0 float4pl - 0 700 0 _null_ )); +DATA(insert ( 2111 n 0 float8pl - 0 701 0 _null_ )); +DATA(insert ( 2112 n 0 cash_pl - 0 790 0 _null_ )); +DATA(insert ( 2113 n 0 interval_pl - 0 1186 0 _null_ )); +DATA(insert ( 2114 n 0 numeric_avg_accum numeric_sum 0 2281 128 _null_ )); /* max */ -DATA(insert ( 2115 int8larger - 413 20 0 _null_ )); -DATA(insert ( 2116 int4larger - 521 23 0 _null_ )); -DATA(insert ( 2117 int2larger - 520 21 0 _null_ )); -DATA(insert ( 2118 oidlarger - 610 26 0 _null_ )); -DATA(insert ( 2119 float4larger - 623 700 0 _null_ )); -DATA(insert ( 2120 float8larger - 674 701 0 _null_ )); -DATA(insert ( 2121 int4larger - 563 702 0 _null_ )); -DATA(insert ( 2122 date_larger - 1097 1082 0 _null_ )); -DATA(insert ( 2123 time_larger - 1112 1083 0 _null_ )); -DATA(insert ( 2124 timetz_larger - 1554 1266 0 _null_ )); -DATA(insert ( 2125 cashlarger - 903 790 0 _null_ )); -DATA(insert ( 2126 timestamp_larger - 2064 1114 0 _null_ )); -DATA(insert ( 2127 timestamptz_larger - 1324 1184 0 _null_ )); -DATA(insert ( 2128 interval_larger - 1334 1186 0 _null_ )); -DATA(insert ( 2129 text_larger - 666 25 0 _null_ )); -DATA(insert ( 2130 numeric_larger - 1756 1700 0 _null_ )); -DATA(insert ( 2050 array_larger - 1073 2277 0 _null_ )); -DATA(insert ( 2244 bpchar_larger - 1060 1042 0 _null_ )); -DATA(insert ( 2797 tidlarger - 2800 27 0 _null_ )); -DATA(insert ( 3526 enum_larger - 3519 3500 0 _null_ )); +DATA(insert ( 2115 n 0 int8larger - 413 20 0 _null_ )); +DATA(insert ( 2116 n 0 int4larger - 521 23 0 _null_ )); +DATA(insert ( 2117 n 0 int2larger - 520 21 0 _null_ )); +DATA(insert ( 2118 n 0 oidlarger - 610 26 0 _null_ )); +DATA(insert ( 2119 n 0 float4larger - 623 700 0 _null_ )); +DATA(insert ( 2120 n 0 float8larger - 674 701 0 _null_ )); +DATA(insert ( 2121 n 0 int4larger - 563 702 0 _null_ )); +DATA(insert ( 2122 n 0 date_larger - 1097 1082 0 _null_ )); +DATA(insert ( 2123 n 0 time_larger - 1112 1083 0 _null_ )); +DATA(insert ( 2124 n 0 timetz_larger - 1554 1266 0 _null_ )); +DATA(insert ( 2125 n 0 cashlarger - 903 790 0 _null_ )); +DATA(insert ( 2126 n 0 timestamp_larger - 2064 1114 0 _null_ )); +DATA(insert ( 2127 n 0 timestamptz_larger - 1324 1184 0 _null_ )); +DATA(insert ( 2128 n 0 interval_larger - 1334 1186 0 _null_ )); +DATA(insert ( 2129 n 0 text_larger - 666 25 0 _null_ )); +DATA(insert ( 2130 n 0 numeric_larger - 1756 1700 0 _null_ )); +DATA(insert ( 2050 n 0 array_larger - 1073 2277 0 _null_ )); +DATA(insert ( 2244 n 0 bpchar_larger - 1060 1042 0 _null_ )); +DATA(insert ( 2797 n 0 tidlarger - 2800 27 0 _null_ )); +DATA(insert ( 3526 n 0 enum_larger - 3519 3500 0 _null_ )); /* min */ -DATA(insert ( 2131 int8smaller - 412 20 0 _null_ )); -DATA(insert ( 2132 int4smaller - 97 23 0 _null_ )); -DATA(insert ( 2133 int2smaller - 95 21 0 _null_ )); -DATA(insert ( 2134 oidsmaller - 609 26 0 _null_ )); -DATA(insert ( 2135 float4smaller - 622 700 0 _null_ )); -DATA(insert ( 2136 float8smaller - 672 701 0 _null_ )); -DATA(insert ( 2137 int4smaller - 562 702 0 _null_ )); -DATA(insert ( 2138 date_smaller - 1095 1082 0 _null_ )); -DATA(insert ( 2139 time_smaller - 1110 1083 0 _null_ )); -DATA(insert ( 2140 timetz_smaller - 1552 1266 0 _null_ )); -DATA(insert ( 2141 cashsmaller - 902 790 0 _null_ )); -DATA(insert ( 2142 timestamp_smaller - 2062 1114 0 _null_ )); -DATA(insert ( 2143 timestamptz_smaller - 1322 1184 0 _null_ )); -DATA(insert ( 2144 interval_smaller - 1332 1186 0 _null_ )); -DATA(insert ( 2145 text_smaller - 664 25 0 _null_ )); -DATA(insert ( 2146 numeric_smaller - 1754 1700 0 _null_ )); -DATA(insert ( 2051 array_smaller - 1072 2277 0 _null_ )); -DATA(insert ( 2245 bpchar_smaller - 1058 1042 0 _null_ )); -DATA(insert ( 2798 tidsmaller - 2799 27 0 _null_ )); -DATA(insert ( 3527 enum_smaller - 3518 3500 0 _null_ )); +DATA(insert ( 2131 n 0 int8smaller - 412 20 0 _null_ )); +DATA(insert ( 2132 n 0 int4smaller - 97 23 0 _null_ )); +DATA(insert ( 2133 n 0 int2smaller - 95 21 0 _null_ )); +DATA(insert ( 2134 n 0 oidsmaller - 609 26 0 _null_ )); +DATA(insert ( 2135 n 0 float4smaller - 622 700 0 _null_ )); +DATA(insert ( 2136 n 0 float8smaller - 672 701 0 _null_ )); +DATA(insert ( 2137 n 0 int4smaller - 562 702 0 _null_ )); +DATA(insert ( 2138 n 0 date_smaller - 1095 1082 0 _null_ )); +DATA(insert ( 2139 n 0 time_smaller - 1110 1083 0 _null_ )); +DATA(insert ( 2140 n 0 timetz_smaller - 1552 1266 0 _null_ )); +DATA(insert ( 2141 n 0 cashsmaller - 902 790 0 _null_ )); +DATA(insert ( 2142 n 0 timestamp_smaller - 2062 1114 0 _null_ )); +DATA(insert ( 2143 n 0 timestamptz_smaller - 1322 1184 0 _null_ )); +DATA(insert ( 2144 n 0 interval_smaller - 1332 1186 0 _null_ )); +DATA(insert ( 2145 n 0 text_smaller - 664 25 0 _null_ )); +DATA(insert ( 2146 n 0 numeric_smaller - 1754 1700 0 _null_ )); +DATA(insert ( 2051 n 0 array_smaller - 1072 2277 0 _null_ )); +DATA(insert ( 2245 n 0 bpchar_smaller - 1058 1042 0 _null_ )); +DATA(insert ( 2798 n 0 tidsmaller - 2799 27 0 _null_ )); +DATA(insert ( 3527 n 0 enum_smaller - 3518 3500 0 _null_ )); /* count */ -DATA(insert ( 2147 int8inc_any - 0 20 0 "0" )); -DATA(insert ( 2803 int8inc - 0 20 0 "0" )); +DATA(insert ( 2147 n 0 int8inc_any - 0 20 0 "0" )); +DATA(insert ( 2803 n 0 int8inc - 0 20 0 "0" )); /* var_pop */ -DATA(insert ( 2718 int8_accum numeric_var_pop 0 2281 128 _null_ )); -DATA(insert ( 2719 int4_accum numeric_var_pop 0 2281 128 _null_ )); -DATA(insert ( 2720 int2_accum numeric_var_pop 0 2281 128 _null_ )); -DATA(insert ( 2721 float4_accum float8_var_pop 0 1022 0 "{0,0,0}" )); -DATA(insert ( 2722 float8_accum float8_var_pop 0 1022 0 "{0,0,0}" )); -DATA(insert ( 2723 numeric_accum numeric_var_pop 0 2281 128 _null_ )); +DATA(insert ( 2718 n 0 int8_accum numeric_var_pop 0 2281 128 _null_ )); +DATA(insert ( 2719 n 0 int4_accum numeric_var_pop 0 2281 128 _null_ )); +DATA(insert ( 2720 n 0 int2_accum numeric_var_pop 0 2281 128 _null_ )); +DATA(insert ( 2721 n 0 float4_accum float8_var_pop 0 1022 0 "{0,0,0}" )); +DATA(insert ( 2722 n 0 float8_accum float8_var_pop 0 1022 0 "{0,0,0}" )); +DATA(insert ( 2723 n 0 numeric_accum numeric_var_pop 0 2281 128 _null_ )); /* var_samp */ -DATA(insert ( 2641 int8_accum numeric_var_samp 0 2281 128 _null_ )); -DATA(insert ( 2642 int4_accum numeric_var_samp 0 2281 128 _null_ )); -DATA(insert ( 2643 int2_accum numeric_var_samp 0 2281 128 _null_ )); -DATA(insert ( 2644 float4_accum float8_var_samp 0 1022 0 "{0,0,0}" )); -DATA(insert ( 2645 float8_accum float8_var_samp 0 1022 0 "{0,0,0}" )); -DATA(insert ( 2646 numeric_accum numeric_var_samp 0 2281 128 _null_ )); +DATA(insert ( 2641 n 0 int8_accum numeric_var_samp 0 2281 128 _null_ )); +DATA(insert ( 2642 n 0 int4_accum numeric_var_samp 0 2281 128 _null_ )); +DATA(insert ( 2643 n 0 int2_accum numeric_var_samp 0 2281 128 _null_ )); +DATA(insert ( 2644 n 0 float4_accum float8_var_samp 0 1022 0 "{0,0,0}" )); +DATA(insert ( 2645 n 0 float8_accum float8_var_samp 0 1022 0 "{0,0,0}" )); +DATA(insert ( 2646 n 0 numeric_accum numeric_var_samp 0 2281 128 _null_ )); /* variance: historical Postgres syntax for var_samp */ -DATA(insert ( 2148 int8_accum numeric_var_samp 0 2281 128 _null_ )); -DATA(insert ( 2149 int4_accum numeric_var_samp 0 2281 128 _null_ )); -DATA(insert ( 2150 int2_accum numeric_var_samp 0 2281 128 _null_ )); -DATA(insert ( 2151 float4_accum float8_var_samp 0 1022 0 "{0,0,0}" )); -DATA(insert ( 2152 float8_accum float8_var_samp 0 1022 0 "{0,0,0}" )); -DATA(insert ( 2153 numeric_accum numeric_var_samp 0 2281 128 _null_ )); +DATA(insert ( 2148 n 0 int8_accum numeric_var_samp 0 2281 128 _null_ )); +DATA(insert ( 2149 n 0 int4_accum numeric_var_samp 0 2281 128 _null_ )); +DATA(insert ( 2150 n 0 int2_accum numeric_var_samp 0 2281 128 _null_ )); +DATA(insert ( 2151 n 0 float4_accum float8_var_samp 0 1022 0 "{0,0,0}" )); +DATA(insert ( 2152 n 0 float8_accum float8_var_samp 0 1022 0 "{0,0,0}" )); +DATA(insert ( 2153 n 0 numeric_accum numeric_var_samp 0 2281 128 _null_ )); /* stddev_pop */ -DATA(insert ( 2724 int8_accum numeric_stddev_pop 0 2281 128 _null_ )); -DATA(insert ( 2725 int4_accum numeric_stddev_pop 0 2281 128 _null_ )); -DATA(insert ( 2726 int2_accum numeric_stddev_pop 0 2281 128 _null_ )); -DATA(insert ( 2727 float4_accum float8_stddev_pop 0 1022 0 "{0,0,0}" )); -DATA(insert ( 2728 float8_accum float8_stddev_pop 0 1022 0 "{0,0,0}" )); -DATA(insert ( 2729 numeric_accum numeric_stddev_pop 0 2281 128 _null_ )); +DATA(insert ( 2724 n 0 int8_accum numeric_stddev_pop 0 2281 128 _null_ )); +DATA(insert ( 2725 n 0 int4_accum numeric_stddev_pop 0 2281 128 _null_ )); +DATA(insert ( 2726 n 0 int2_accum numeric_stddev_pop 0 2281 128 _null_ )); +DATA(insert ( 2727 n 0 float4_accum float8_stddev_pop 0 1022 0 "{0,0,0}" )); +DATA(insert ( 2728 n 0 float8_accum float8_stddev_pop 0 1022 0 "{0,0,0}" )); +DATA(insert ( 2729 n 0 numeric_accum numeric_stddev_pop 0 2281 128 _null_ )); /* stddev_samp */ -DATA(insert ( 2712 int8_accum numeric_stddev_samp 0 2281 128 _null_ )); -DATA(insert ( 2713 int4_accum numeric_stddev_samp 0 2281 128 _null_ )); -DATA(insert ( 2714 int2_accum numeric_stddev_samp 0 2281 128 _null_ )); -DATA(insert ( 2715 float4_accum float8_stddev_samp 0 1022 0 "{0,0,0}" )); -DATA(insert ( 2716 float8_accum float8_stddev_samp 0 1022 0 "{0,0,0}" )); -DATA(insert ( 2717 numeric_accum numeric_stddev_samp 0 2281 128 _null_ )); +DATA(insert ( 2712 n 0 int8_accum numeric_stddev_samp 0 2281 128 _null_ )); +DATA(insert ( 2713 n 0 int4_accum numeric_stddev_samp 0 2281 128 _null_ )); +DATA(insert ( 2714 n 0 int2_accum numeric_stddev_samp 0 2281 128 _null_ )); +DATA(insert ( 2715 n 0 float4_accum float8_stddev_samp 0 1022 0 "{0,0,0}" )); +DATA(insert ( 2716 n 0 float8_accum float8_stddev_samp 0 1022 0 "{0,0,0}" )); +DATA(insert ( 2717 n 0 numeric_accum numeric_stddev_samp 0 2281 128 _null_ )); /* stddev: historical Postgres syntax for stddev_samp */ -DATA(insert ( 2154 int8_accum numeric_stddev_samp 0 2281 128 _null_ )); -DATA(insert ( 2155 int4_accum numeric_stddev_samp 0 2281 128 _null_ )); -DATA(insert ( 2156 int2_accum numeric_stddev_samp 0 2281 128 _null_ )); -DATA(insert ( 2157 float4_accum float8_stddev_samp 0 1022 0 "{0,0,0}" )); -DATA(insert ( 2158 float8_accum float8_stddev_samp 0 1022 0 "{0,0,0}" )); -DATA(insert ( 2159 numeric_accum numeric_stddev_samp 0 2281 128 _null_ )); +DATA(insert ( 2154 n 0 int8_accum numeric_stddev_samp 0 2281 128 _null_ )); +DATA(insert ( 2155 n 0 int4_accum numeric_stddev_samp 0 2281 128 _null_ )); +DATA(insert ( 2156 n 0 int2_accum numeric_stddev_samp 0 2281 128 _null_ )); +DATA(insert ( 2157 n 0 float4_accum float8_stddev_samp 0 1022 0 "{0,0,0}" )); +DATA(insert ( 2158 n 0 float8_accum float8_stddev_samp 0 1022 0 "{0,0,0}" )); +DATA(insert ( 2159 n 0 numeric_accum numeric_stddev_samp 0 2281 128 _null_ )); /* SQL2003 binary regression aggregates */ -DATA(insert ( 2818 int8inc_float8_float8 - 0 20 0 "0" )); -DATA(insert ( 2819 float8_regr_accum float8_regr_sxx 0 1022 0 "{0,0,0,0,0,0}" )); -DATA(insert ( 2820 float8_regr_accum float8_regr_syy 0 1022 0 "{0,0,0,0,0,0}" )); -DATA(insert ( 2821 float8_regr_accum float8_regr_sxy 0 1022 0 "{0,0,0,0,0,0}" )); -DATA(insert ( 2822 float8_regr_accum float8_regr_avgx 0 1022 0 "{0,0,0,0,0,0}" )); -DATA(insert ( 2823 float8_regr_accum float8_regr_avgy 0 1022 0 "{0,0,0,0,0,0}" )); -DATA(insert ( 2824 float8_regr_accum float8_regr_r2 0 1022 0 "{0,0,0,0,0,0}" )); -DATA(insert ( 2825 float8_regr_accum float8_regr_slope 0 1022 0 "{0,0,0,0,0,0}" )); -DATA(insert ( 2826 float8_regr_accum float8_regr_intercept 0 1022 0 "{0,0,0,0,0,0}" )); -DATA(insert ( 2827 float8_regr_accum float8_covar_pop 0 1022 0 "{0,0,0,0,0,0}" )); -DATA(insert ( 2828 float8_regr_accum float8_covar_samp 0 1022 0 "{0,0,0,0,0,0}" )); -DATA(insert ( 2829 float8_regr_accum float8_corr 0 1022 0 "{0,0,0,0,0,0}" )); +DATA(insert ( 2818 n 0 int8inc_float8_float8 - 0 20 0 "0" )); +DATA(insert ( 2819 n 0 float8_regr_accum float8_regr_sxx 0 1022 0 "{0,0,0,0,0,0}" )); +DATA(insert ( 2820 n 0 float8_regr_accum float8_regr_syy 0 1022 0 "{0,0,0,0,0,0}" )); +DATA(insert ( 2821 n 0 float8_regr_accum float8_regr_sxy 0 1022 0 "{0,0,0,0,0,0}" )); +DATA(insert ( 2822 n 0 float8_regr_accum float8_regr_avgx 0 1022 0 "{0,0,0,0,0,0}" )); +DATA(insert ( 2823 n 0 float8_regr_accum float8_regr_avgy 0 1022 0 "{0,0,0,0,0,0}" )); +DATA(insert ( 2824 n 0 float8_regr_accum float8_regr_r2 0 1022 0 "{0,0,0,0,0,0}" )); +DATA(insert ( 2825 n 0 float8_regr_accum float8_regr_slope 0 1022 0 "{0,0,0,0,0,0}" )); +DATA(insert ( 2826 n 0 float8_regr_accum float8_regr_intercept 0 1022 0 "{0,0,0,0,0,0}" )); +DATA(insert ( 2827 n 0 float8_regr_accum float8_covar_pop 0 1022 0 "{0,0,0,0,0,0}" )); +DATA(insert ( 2828 n 0 float8_regr_accum float8_covar_samp 0 1022 0 "{0,0,0,0,0,0}" )); +DATA(insert ( 2829 n 0 float8_regr_accum float8_corr 0 1022 0 "{0,0,0,0,0,0}" )); /* boolean-and and boolean-or */ -DATA(insert ( 2517 booland_statefunc - 58 16 0 _null_ )); -DATA(insert ( 2518 boolor_statefunc - 59 16 0 _null_ )); -DATA(insert ( 2519 booland_statefunc - 58 16 0 _null_ )); +DATA(insert ( 2517 n 0 booland_statefunc - 58 16 0 _null_ )); +DATA(insert ( 2518 n 0 boolor_statefunc - 59 16 0 _null_ )); +DATA(insert ( 2519 n 0 booland_statefunc - 58 16 0 _null_ )); /* bitwise integer */ -DATA(insert ( 2236 int2and - 0 21 0 _null_ )); -DATA(insert ( 2237 int2or - 0 21 0 _null_ )); -DATA(insert ( 2238 int4and - 0 23 0 _null_ )); -DATA(insert ( 2239 int4or - 0 23 0 _null_ )); -DATA(insert ( 2240 int8and - 0 20 0 _null_ )); -DATA(insert ( 2241 int8or - 0 20 0 _null_ )); -DATA(insert ( 2242 bitand - 0 1560 0 _null_ )); -DATA(insert ( 2243 bitor - 0 1560 0 _null_ )); +DATA(insert ( 2236 n 0 int2and - 0 21 0 _null_ )); +DATA(insert ( 2237 n 0 int2or - 0 21 0 _null_ )); +DATA(insert ( 2238 n 0 int4and - 0 23 0 _null_ )); +DATA(insert ( 2239 n 0 int4or - 0 23 0 _null_ )); +DATA(insert ( 2240 n 0 int8and - 0 20 0 _null_ )); +DATA(insert ( 2241 n 0 int8or - 0 20 0 _null_ )); +DATA(insert ( 2242 n 0 bitand - 0 1560 0 _null_ )); +DATA(insert ( 2243 n 0 bitor - 0 1560 0 _null_ )); /* xml */ -DATA(insert ( 2901 xmlconcat2 - 0 142 0 _null_ )); +DATA(insert ( 2901 n 0 xmlconcat2 - 0 142 0 _null_ )); /* array */ -DATA(insert ( 2335 array_agg_transfn array_agg_finalfn 0 2281 0 _null_ )); +DATA(insert ( 2335 n 0 array_agg_transfn array_agg_finalfn 0 2281 0 _null_ )); /* text */ -DATA(insert ( 3538 string_agg_transfn string_agg_finalfn 0 2281 0 _null_ )); +DATA(insert ( 3538 n 0 string_agg_transfn string_agg_finalfn 0 2281 0 _null_ )); /* bytea */ -DATA(insert ( 3545 bytea_string_agg_transfn bytea_string_agg_finalfn 0 2281 0 _null_ )); +DATA(insert ( 3545 n 0 bytea_string_agg_transfn bytea_string_agg_finalfn 0 2281 0 _null_ )); /* json */ -DATA(insert ( 3175 json_agg_transfn json_agg_finalfn 0 2281 0 _null_ )); +DATA(insert ( 3175 n 0 json_agg_transfn json_agg_finalfn 0 2281 0 _null_ )); + +/* ordered-set and hypothetical-set aggregates */ +DATA(insert ( 3972 o 1 ordered_set_transition percentile_disc_final 0 2281 0 _null_ )); +DATA(insert ( 3974 o 1 ordered_set_transition percentile_cont_float8_final 0 2281 0 _null_ )); +DATA(insert ( 3976 o 1 ordered_set_transition percentile_cont_interval_final 0 2281 0 _null_ )); +DATA(insert ( 3978 o 1 ordered_set_transition percentile_disc_multi_final 0 2281 0 _null_ )); +DATA(insert ( 3980 o 1 ordered_set_transition percentile_cont_float8_multi_final 0 2281 0 _null_ )); +DATA(insert ( 3982 o 1 ordered_set_transition percentile_cont_interval_multi_final 0 2281 0 _null_ )); +DATA(insert ( 3984 o 0 ordered_set_transition mode_final 0 2281 0 _null_ )); +DATA(insert ( 3986 h 1 ordered_set_transition_multi rank_final 0 2281 0 _null_ )); +DATA(insert ( 3988 h 1 ordered_set_transition_multi percent_rank_final 0 2281 0 _null_ )); +DATA(insert ( 3990 h 1 ordered_set_transition_multi cume_dist_final 0 2281 0 _null_ )); +DATA(insert ( 3992 h 1 ordered_set_transition_multi dense_rank_final 0 2281 0 _null_ )); + /* * prototypes for functions in pg_aggregate.c */ extern Oid AggregateCreate(const char *aggName, Oid aggNamespace, + char aggKind, int numArgs, + int numDirectArgs, oidvector *parameterTypes, Datum allParameterTypes, Datum parameterModes, Datum parameterNames, List *parameterDefaults, + Oid variadicArgType, List *aggtransfnName, List *aggfinalfnName, List *aggsortopName, diff --git a/src/include/catalog/pg_operator.h b/src/include/catalog/pg_operator.h index 78efaa5f23e..a49cfdbdded 100644 --- a/src/include/catalog/pg_operator.h +++ b/src/include/catalog/pg_operator.h @@ -130,6 +130,7 @@ DATA(insert OID = 96 ( "=" PGNSP PGUID b t t 23 23 16 96 518 int4eq eqsel e DESCR("equal"); DATA(insert OID = 97 ( "<" PGNSP PGUID b f f 23 23 16 521 525 int4lt scalarltsel scalarltjoinsel )); DESCR("less than"); +#define Int4LessOperator 97 DATA(insert OID = 98 ( "=" PGNSP PGUID b t t 25 25 16 98 531 texteq eqsel eqjoinsel )); DESCR("equal"); #define TextEqualOperator 98 diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index 0117500a8a6..05d7ba54072 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -4756,10 +4756,65 @@ DESCR("SP-GiST support for quad tree over range"); DATA(insert OID = 3473 ( spg_range_quad_leaf_consistent PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "2281 2281" _null_ _null_ _null_ _null_ spg_range_quad_leaf_consistent _null_ _null_ _null_ )); DESCR("SP-GiST support for quad tree over range"); - /* event triggers */ DATA(insert OID = 3566 ( pg_event_trigger_dropped_objects PGNSP PGUID 12 10 100 0 0 f f f f t t s 0 0 2249 "" "{26,26,23,25,25,25,25}" "{o,o,o,o,o,o,o}" "{classid, objid, objsubid, object_type, schema_name, object_name, object_identity}" _null_ pg_event_trigger_dropped_objects _null_ _null_ _null_ )); DESCR("list objects dropped by the current command"); + +/* generic transition functions for ordered-set aggregates */ +DATA(insert OID = 3970 ( ordered_set_transition PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2281 "2281 2276" _null_ _null_ _null_ _null_ ordered_set_transition _null_ _null_ _null_ )); +DESCR("aggregate transition function"); +DATA(insert OID = 3971 ( ordered_set_transition_multi PGNSP PGUID 12 1 0 2276 0 f f f f f f i 2 0 2281 "2281 2276" "{2281,2276}" "{i,v}" _null_ _null_ ordered_set_transition_multi _null_ _null_ _null_ )); +DESCR("aggregate transition function"); + +/* inverse distribution aggregates (and their support functions) */ +DATA(insert OID = 3972 ( percentile_disc PGNSP PGUID 12 1 0 0 0 t f f f f f i 2 0 2283 "701 2283" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ )); +DESCR("discrete percentile"); +DATA(insert OID = 3973 ( percentile_disc_final PGNSP PGUID 12 1 0 0 0 f f f f f f i 3 0 2283 "2281 701 2283" _null_ _null_ _null_ _null_ percentile_disc_final _null_ _null_ _null_ )); +DESCR("aggregate final function"); +DATA(insert OID = 3974 ( percentile_cont PGNSP PGUID 12 1 0 0 0 t f f f f f i 2 0 701 "701 701" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ )); +DESCR("continuous distribution percentile"); +DATA(insert OID = 3975 ( percentile_cont_float8_final PGNSP PGUID 12 1 0 0 0 f f f f f f i 3 0 701 "2281 701 701" _null_ _null_ _null_ _null_ percentile_cont_float8_final _null_ _null_ _null_ )); +DESCR("aggregate final function"); +DATA(insert OID = 3976 ( percentile_cont PGNSP PGUID 12 1 0 0 0 t f f f f f i 2 0 1186 "701 1186" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ )); +DESCR("continuous distribution percentile"); +DATA(insert OID = 3977 ( percentile_cont_interval_final PGNSP PGUID 12 1 0 0 0 f f f f f f i 3 0 1186 "2281 701 1186" _null_ _null_ _null_ _null_ percentile_cont_interval_final _null_ _null_ _null_ )); +DESCR("aggregate final function"); +DATA(insert OID = 3978 ( percentile_disc PGNSP PGUID 12 1 0 0 0 t f f f f f i 2 0 2277 "1022 2283" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ )); +DESCR("multiple discrete percentiles"); +DATA(insert OID = 3979 ( percentile_disc_multi_final PGNSP PGUID 12 1 0 0 0 f f f f f f i 3 0 2277 "2281 1022 2283" _null_ _null_ _null_ _null_ percentile_disc_multi_final _null_ _null_ _null_ )); +DESCR("aggregate final function"); +DATA(insert OID = 3980 ( percentile_cont PGNSP PGUID 12 1 0 0 0 t f f f f f i 2 0 1022 "1022 701" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ )); +DESCR("multiple continuous percentiles"); +DATA(insert OID = 3981 ( percentile_cont_float8_multi_final PGNSP PGUID 12 1 0 0 0 f f f f f f i 3 0 1022 "2281 1022 701" _null_ _null_ _null_ _null_ percentile_cont_float8_multi_final _null_ _null_ _null_ )); +DESCR("aggregate final function"); +DATA(insert OID = 3982 ( percentile_cont PGNSP PGUID 12 1 0 0 0 t f f f f f i 2 0 1187 "1022 1186" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ )); +DESCR("multiple continuous percentiles"); +DATA(insert OID = 3983 ( percentile_cont_interval_multi_final PGNSP PGUID 12 1 0 0 0 f f f f f f i 3 0 1187 "2281 1022 1186" _null_ _null_ _null_ _null_ percentile_cont_interval_multi_final _null_ _null_ _null_ )); +DESCR("aggregate final function"); +DATA(insert OID = 3984 ( mode PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 2283 "2283" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ )); +DESCR("most common value"); +DATA(insert OID = 3985 ( mode_final PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2283 "2281 2283" _null_ _null_ _null_ _null_ mode_final _null_ _null_ _null_ )); +DESCR("aggregate final function"); + +/* hypothetical-set aggregates (and their support functions) */ +DATA(insert OID = 3986 ( rank PGNSP PGUID 12 1 0 2276 0 t f f f f f i 1 0 20 "2276" "{2276}" "{v}" _null_ _null_ aggregate_dummy _null_ _null_ _null_ )); +DESCR("rank of hypothetical row"); +DATA(insert OID = 3987 ( rank_final PGNSP PGUID 12 1 0 2276 0 f f f f f f i 2 0 20 "2281 2276" "{2281,2276}" "{i,v}" _null_ _null_ hypothetical_rank_final _null_ _null_ _null_ )); +DESCR("aggregate final function"); +DATA(insert OID = 3988 ( percent_rank PGNSP PGUID 12 1 0 2276 0 t f f f f f i 1 0 701 "2276" "{2276}" "{v}" _null_ _null_ aggregate_dummy _null_ _null_ _null_ )); +DESCR("fractional rank of hypothetical row"); +DATA(insert OID = 3989 ( percent_rank_final PGNSP PGUID 12 1 0 2276 0 f f f f f f i 2 0 701 "2281 2276" "{2281,2276}" "{i,v}" _null_ _null_ hypothetical_percent_rank_final _null_ _null_ _null_ )); +DESCR("aggregate final function"); +DATA(insert OID = 3990 ( cume_dist PGNSP PGUID 12 1 0 2276 0 t f f f f f i 1 0 701 "2276" "{2276}" "{v}" _null_ _null_ aggregate_dummy _null_ _null_ _null_ )); +DESCR("cumulative distribution of hypothetical row"); +DATA(insert OID = 3991 ( cume_dist_final PGNSP PGUID 12 1 0 2276 0 f f f f f f i 2 0 701 "2281 2276" "{2281,2276}" "{i,v}" _null_ _null_ hypothetical_cume_dist_final _null_ _null_ _null_ )); +DESCR("aggregate final function"); +DATA(insert OID = 3992 ( dense_rank PGNSP PGUID 12 1 0 2276 0 t f f f f f i 1 0 20 "2276" "{2276}" "{v}" _null_ _null_ aggregate_dummy _null_ _null_ _null_ )); +DESCR("rank of hypothetical row without gaps"); +DATA(insert OID = 3993 ( dense_rank_final PGNSP PGUID 12 1 0 2276 0 f f f f f f i 2 0 20 "2281 2276" "{2281,2276}" "{i,v}" _null_ _null_ hypothetical_dense_rank_final _null_ _null_ _null_ )); +DESCR("aggregate final function"); + + /* * Symbolic values for provolatile column: these indicate whether the result * of a function is dependent *only* on the values of its explicit arguments, diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h index f8ceb5da2eb..16817b68e77 100644 --- a/src/include/commands/defrem.h +++ b/src/include/commands/defrem.h @@ -63,6 +63,7 @@ extern void interpret_function_parameter_list(List *parameters, ArrayType **parameterModes, ArrayType **parameterNames, List **parameterDefaults, + Oid *variadicArgType, Oid *requiredResultType); /* commands/operatorcmds.c */ diff --git a/src/include/fmgr.h b/src/include/fmgr.h index 1f72e1bd48f..2b41746b56b 100644 --- a/src/include/fmgr.h +++ b/src/include/fmgr.h @@ -18,8 +18,12 @@ #ifndef FMGR_H #define FMGR_H -/* We don't want to include primnodes.h here, so make a stub reference */ +/* We don't want to include primnodes.h here, so make some stub references */ typedef struct Node *fmNodePtr; +typedef struct Aggref *fmAggrefPtr; + +/* Likewise, avoid including execnodes.h here */ +typedef struct ExprContext *fmExprContextPtr; /* Likewise, avoid including stringinfo.h here */ typedef struct StringInfoData *fmStringInfo; @@ -640,8 +644,8 @@ extern void **find_rendezvous_variable(const char *varName); /* * Support for aggregate functions * - * This is actually in executor/nodeAgg.c, but we declare it here since the - * whole point is for callers of it to not be overly friendly with nodeAgg. + * These are actually in executor/nodeAgg.c, but we declare them here since + * the whole point is for callers to not be overly friendly with nodeAgg. */ /* AggCheckCallContext can return one of the following codes, or 0: */ @@ -650,6 +654,9 @@ extern void **find_rendezvous_variable(const char *varName); extern int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext); +extern fmAggrefPtr AggGetAggref(FunctionCallInfo fcinfo); +extern fmExprContextPtr AggGetPerTupleEContext(FunctionCallInfo fcinfo); +extern fmExprContextPtr AggGetPerAggEContext(FunctionCallInfo fcinfo); /* * We allow plugin modules to hook function entry/exit. This is intended diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index 5a4034729cf..2a7b36e148f 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -141,7 +141,7 @@ typedef struct ExprContext /* Link to containing EState (NULL if a standalone ExprContext) */ struct EState *ecxt_estate; - /* Functions to call back when ExprContext is shut down */ + /* Functions to call back when ExprContext is shut down or rescanned */ ExprContext_CB *ecxt_callbacks; } ExprContext; @@ -587,8 +587,9 @@ typedef struct WholeRowVarExprState typedef struct AggrefExprState { ExprState xprstate; - List *args; /* states of argument expressions */ - ExprState *aggfilter; /* FILTER expression */ + List *aggdirectargs; /* states of direct-argument expressions */ + List *args; /* states of aggregated-argument expressions */ + ExprState *aggfilter; /* state of FILTER expression, if any */ int aggno; /* ID number for agg within its plan node */ } AggrefExprState; @@ -1704,6 +1705,7 @@ typedef struct AggState AggStatePerAgg peragg; /* per-Aggref information */ MemoryContext aggcontext; /* memory context for long-lived data */ ExprContext *tmpcontext; /* econtext for input expressions */ + AggStatePerAgg curperagg; /* identifies currently active aggregate */ bool agg_done; /* indicates completion of Agg scan */ /* these fields are used in AGG_PLAIN and AGG_SORTED modes: */ AggStatePerGroup pergroup; /* per-Aggref-per-group working state */ diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 6a5a8c5f2d7..e89d93034fb 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -281,7 +281,8 @@ typedef struct CollateClause /* * FuncCall - a function or aggregate invocation * - * agg_order (if not NIL) indicates we saw 'foo(... ORDER BY ...)'. + * agg_order (if not NIL) indicates we saw 'foo(... ORDER BY ...)', or if + * agg_within_group is true, it was 'foo(...) WITHIN GROUP (ORDER BY ...)'. * agg_star indicates we saw a 'foo(*)' construct, while agg_distinct * indicates we saw 'foo(DISTINCT ...)'. In any of these cases, the * construct *must* be an aggregate call. Otherwise, it might be either an @@ -298,6 +299,7 @@ typedef struct FuncCall List *args; /* the arguments (list of exprs) */ List *agg_order; /* ORDER BY (list of SortBy) */ Node *agg_filter; /* FILTER clause, if any */ + bool agg_within_group; /* ORDER BY appeared in WITHIN GROUP */ bool agg_star; /* argument was really '*' */ bool agg_distinct; /* arguments were labeled DISTINCT */ bool func_variadic; /* last argument was labeled VARIADIC */ diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h index 791853730b3..16144d45764 100644 --- a/src/include/nodes/primnodes.h +++ b/src/include/nodes/primnodes.h @@ -225,8 +225,9 @@ typedef struct Param /* * Aggref * - * The aggregate's args list is a targetlist, ie, a list of TargetEntry nodes - * (before Postgres 9.0 it was just bare expressions). The non-resjunk TLEs + * The aggregate's args list is a targetlist, ie, a list of TargetEntry nodes. + * + * For a normal (non-ordered-set) aggregate, the non-resjunk TargetEntries * represent the aggregate's regular arguments (if any) and resjunk TLEs can * be added at the end to represent ORDER BY expressions that are not also * arguments. As in a top-level Query, the TLEs can be marked with @@ -236,6 +237,12 @@ typedef struct Param * they are passed to the transition function. The grammar only allows a * simple "DISTINCT" specifier for the arguments, but we use the full * query-level representation to allow more code sharing. + * + * For an ordered-set aggregate, the args list represents the WITHIN GROUP + * (aggregated) arguments, all of which will be listed in the aggorder list. + * DISTINCT is not supported in this case, so aggdistinct will be NIL. + * The direct arguments appear in aggdirectargs (as a list of plain + * expressions, not TargetEntry nodes). */ typedef struct Aggref { @@ -244,12 +251,14 @@ typedef struct Aggref Oid aggtype; /* type Oid of result of the aggregate */ Oid aggcollid; /* OID of collation of result */ Oid inputcollid; /* OID of collation that function should use */ - List *args; /* arguments and sort expressions */ + List *aggdirectargs; /* direct arguments, if an ordered-set agg */ + List *args; /* aggregated arguments and sort expressions */ List *aggorder; /* ORDER BY (list of SortGroupClause) */ List *aggdistinct; /* DISTINCT (list of SortGroupClause) */ - Expr *aggfilter; /* FILTER expression */ + Expr *aggfilter; /* FILTER expression, if any */ bool aggstar; /* TRUE if argument list was really '*' */ bool aggvariadic; /* TRUE if VARIADIC was used in call */ + char aggkind; /* aggregate kind (see pg_aggregate.h) */ Index agglevelsup; /* > 0 if agg belongs to outer query */ int location; /* token location, or -1 if unknown */ } Aggref; @@ -265,7 +274,7 @@ typedef struct WindowFunc Oid wincollid; /* OID of collation of result */ Oid inputcollid; /* OID of collation that function should use */ List *args; /* arguments to the window function */ - Expr *aggfilter; /* FILTER expression */ + Expr *aggfilter; /* FILTER expression, if any */ Index winref; /* index of associated WindowClause */ bool winstar; /* TRUE if argument list was really '*' */ bool winagg; /* is function a simple aggregate? */ diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h index 6d7b5948cd9..a9219e0be95 100644 --- a/src/include/nodes/relation.h +++ b/src/include/nodes/relation.h @@ -47,15 +47,16 @@ typedef struct QualCost /* * Costing aggregate function execution requires these statistics about - * the aggregates to be executed by a given Agg node. Note that transCost - * includes the execution costs of the aggregates' input expressions. + * the aggregates to be executed by a given Agg node. Note that the costs + * include the execution costs of the aggregates' argument expressions as + * well as the aggregate functions themselves. */ typedef struct AggClauseCosts { int numAggs; /* total number of aggregate functions */ - int numOrderedAggs; /* number that use DISTINCT or ORDER BY */ + int numOrderedAggs; /* number w/ DISTINCT/ORDER BY/WITHIN GROUP */ QualCost transCost; /* total per-input-row execution costs */ - Cost finalCost; /* total costs of agg final functions */ + Cost finalCost; /* total per-aggregated-row costs */ Size transitionSpace; /* space for pass-by-ref transition data */ } AggClauseCosts; diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h index 8bd34d6e8f0..ab2715629c0 100644 --- a/src/include/parser/kwlist.h +++ b/src/include/parser/kwlist.h @@ -412,6 +412,7 @@ PG_KEYWORD("where", WHERE, RESERVED_KEYWORD) PG_KEYWORD("whitespace", WHITESPACE_P, UNRESERVED_KEYWORD) PG_KEYWORD("window", WINDOW, RESERVED_KEYWORD) PG_KEYWORD("with", WITH, RESERVED_KEYWORD) +PG_KEYWORD("within", WITHIN, UNRESERVED_KEYWORD) PG_KEYWORD("without", WITHOUT, UNRESERVED_KEYWORD) PG_KEYWORD("work", WORK, UNRESERVED_KEYWORD) PG_KEYWORD("wrapper", WRAPPER, UNRESERVED_KEYWORD) diff --git a/src/include/parser/parse_agg.h b/src/include/parser/parse_agg.h index b6d9dd37b04..487d5cc8894 100644 --- a/src/include/parser/parse_agg.h +++ b/src/include/parser/parse_agg.h @@ -23,8 +23,17 @@ extern void transformWindowFuncCall(ParseState *pstate, WindowFunc *wfunc, extern void parseCheckAggregates(ParseState *pstate, Query *qry); +extern int get_aggregate_argtypes(Aggref *aggref, Oid *inputTypes); + +extern Oid resolve_aggregate_transtype(Oid aggfuncid, + Oid aggtranstype, + Oid *inputTypes, + int numArguments); + extern void build_aggregate_fnexprs(Oid *agg_input_types, int agg_num_inputs, + int agg_num_direct_inputs, + bool agg_ordered_set, bool agg_variadic, Oid agg_state_type, Oid agg_result_type, diff --git a/src/include/parser/parse_clause.h b/src/include/parser/parse_clause.h index 9bdb03347ad..18f338d3404 100644 --- a/src/include/parser/parse_clause.h +++ b/src/include/parser/parse_clause.h @@ -42,6 +42,9 @@ extern List *transformDistinctClause(ParseState *pstate, extern List *transformDistinctOnClause(ParseState *pstate, List *distinctlist, List **targetlist, List *sortClause); +extern List *addTargetToSortList(ParseState *pstate, TargetEntry *tle, + List *sortlist, List *targetlist, SortBy *sortby, + bool resolveUnknown); extern Index assignSortGroupRef(TargetEntry *tle, List *tlist); extern bool targetIsInSortList(TargetEntry *tle, Oid sortop, List *sortList); diff --git a/src/include/parser/parse_func.h b/src/include/parser/parse_func.h index d33eef3482c..f28fd9974c3 100644 --- a/src/include/parser/parse_func.h +++ b/src/include/parser/parse_func.h @@ -43,9 +43,7 @@ typedef enum extern Node *ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, - List *agg_order, Expr *agg_filter, - bool agg_star, bool agg_distinct, bool func_variadic, - WindowDef *over, bool is_column, int location); + FuncCall *fn, int location); extern FuncDetailCode func_get_detail(List *funcname, List *fargs, List *fargnames, diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h index 1bfd145da50..4ad900ed2cf 100644 --- a/src/include/utils/builtins.h +++ b/src/include/utils/builtins.h @@ -515,6 +515,21 @@ extern Datum oidvectorgt(PG_FUNCTION_ARGS); extern oidvector *buildoidvector(const Oid *oids, int n); extern Oid oidparse(Node *node); +/* orderedsetaggs.c */ +extern Datum ordered_set_transition(PG_FUNCTION_ARGS); +extern Datum ordered_set_transition_multi(PG_FUNCTION_ARGS); +extern Datum percentile_disc_final(PG_FUNCTION_ARGS); +extern Datum percentile_cont_float8_final(PG_FUNCTION_ARGS); +extern Datum percentile_cont_interval_final(PG_FUNCTION_ARGS); +extern Datum percentile_disc_multi_final(PG_FUNCTION_ARGS); +extern Datum percentile_cont_float8_multi_final(PG_FUNCTION_ARGS); +extern Datum percentile_cont_interval_multi_final(PG_FUNCTION_ARGS); +extern Datum mode_final(PG_FUNCTION_ARGS); +extern Datum hypothetical_rank_final(PG_FUNCTION_ARGS); +extern Datum hypothetical_percent_rank_final(PG_FUNCTION_ARGS); +extern Datum hypothetical_cume_dist_final(PG_FUNCTION_ARGS); +extern Datum hypothetical_dense_rank_final(PG_FUNCTION_ARGS); + /* pseudotypes.c */ extern Datum cstring_in(PG_FUNCTION_ARGS); extern Datum cstring_out(PG_FUNCTION_ARGS); diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h index 49f459ad580..dfba74c47d3 100644 --- a/src/include/utils/lsyscache.h +++ b/src/include/utils/lsyscache.h @@ -90,6 +90,7 @@ extern Oid get_func_namespace(Oid funcid); extern Oid get_func_rettype(Oid funcid); extern int get_func_nargs(Oid funcid); extern Oid get_func_signature(Oid funcid, Oid **argtypes, int *nargs); +extern Oid get_func_variadictype(Oid funcid); extern bool get_func_retset(Oid funcid); extern bool func_strict(Oid funcid); extern char func_volatile(Oid funcid); diff --git a/src/include/utils/tuplesort.h b/src/include/utils/tuplesort.h index 25fa6de18e1..5f87254881e 100644 --- a/src/include/utils/tuplesort.h +++ b/src/include/utils/tuplesort.h @@ -99,6 +99,9 @@ extern IndexTuple tuplesort_getindextuple(Tuplesortstate *state, bool forward, extern bool tuplesort_getdatum(Tuplesortstate *state, bool forward, Datum *val, bool *isNull); +extern bool tuplesort_skiptuples(Tuplesortstate *state, int64 ntuples, + bool forward); + extern void tuplesort_end(Tuplesortstate *state); extern void tuplesort_get_stats(Tuplesortstate *state, |
