diff options
-rw-r--r-- | src/backend/catalog/pg_aggregate.c | 48 | ||||
-rw-r--r-- | src/backend/commands/aggregatecmds.c | 34 | ||||
-rw-r--r-- | src/backend/nodes/copyfuncs.c | 1 | ||||
-rw-r--r-- | src/backend/nodes/equalfuncs.c | 1 | ||||
-rw-r--r-- | src/backend/nodes/outfuncs.c | 1 | ||||
-rw-r--r-- | src/backend/nodes/readfuncs.c | 1 | ||||
-rw-r--r-- | src/backend/optimizer/plan/createplan.c | 2 | ||||
-rw-r--r-- | src/backend/parser/parse_agg.c | 2 | ||||
-rw-r--r-- | src/include/nodes/primnodes.h | 2 | ||||
-rw-r--r-- | src/test/regress/expected/create_aggregate_1.out | 73 | ||||
-rw-r--r-- | src/test/regress/expected/polymorphism_1.out | 129 |
11 files changed, 94 insertions, 200 deletions
diff --git a/src/backend/catalog/pg_aggregate.c b/src/backend/catalog/pg_aggregate.c index 6971dc168d..c5ad77cba2 100644 --- a/src/backend/catalog/pg_aggregate.c +++ b/src/backend/catalog/pg_aggregate.c @@ -67,7 +67,7 @@ AggregateCreate(const char *aggName, Form_pg_proc proc; Oid transfn; #ifdef PGXC - Oid collectfn; + Oid collectfn = InvalidOid; /* can be omitted */ #endif Oid finalfn = InvalidOid; /* can be omitted */ Oid sortop = InvalidOid; /* can be omitted */ @@ -91,8 +91,6 @@ AggregateCreate(const char *aggName, elog(ERROR, "aggregate must have a transition function"); #ifdef PGXC - if (!aggcollectfnName) - elog(ERROR, "aggregate must have a collection function"); if (aggTransType == INTERNALOID) ereport(ERROR, @@ -173,20 +171,23 @@ AggregateCreate(const char *aggName, ReleaseSysCache(tup); #ifdef PGXC - /* - * Collection function must be of two arguments, both of type aggTransType - * and return type is also aggTransType - */ - fnArgs[0] = aggTransType; - fnArgs[1] = aggTransType; - collectfn = lookup_agg_function(aggcollectfnName, 2, fnArgs, - &rettype); - if (rettype != aggTransType) - ereport(ERROR, - (errcode(ERRCODE_DATATYPE_MISMATCH), - errmsg("return type of collection function %s is not %s", - NameListToString(aggcollectfnName), - format_type_be(aggTransType)))); + if (aggcollectfnName) + { + /* + * Collection function must be of two arguments, both of type aggTransType + * and return type is also aggTransType + */ + fnArgs[0] = aggTransType; + fnArgs[1] = aggTransType; + collectfn = lookup_agg_function(aggcollectfnName, 2, fnArgs, + &rettype); + if (rettype != aggTransType) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("return type of collection function %s is not %s", + NameListToString(aggcollectfnName), + format_type_be(aggTransType)))); + } #endif /* handle finalfn, if supplied */ @@ -329,11 +330,14 @@ AggregateCreate(const char *aggName, recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); #ifdef PGXC - /* Depends on collection function */ - referenced.classId = ProcedureRelationId; - referenced.objectId = collectfn; - referenced.objectSubId = 0; - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + if (OidIsValid(collectfn)) + { + /* Depends on collection function */ + referenced.classId = ProcedureRelationId; + referenced.objectId = collectfn; + referenced.objectSubId = 0; + recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + } #endif /* Depends on final function, if any */ diff --git a/src/backend/commands/aggregatecmds.c b/src/backend/commands/aggregatecmds.c index 6b9f86ea0e..89201c2c1d 100644 --- a/src/backend/commands/aggregatecmds.c +++ b/src/backend/commands/aggregatecmds.c @@ -59,8 +59,6 @@ DefineAggregate(List *name, List *args, bool oldstyle, List *parameters) char *initval = NULL; #ifdef PGXC List *collectfuncName = NIL; - TypeName *collectType = NULL; - Oid collectTypeId; char *initcollect = NULL; #endif Oid *aggArgTypes; @@ -106,8 +104,6 @@ DefineAggregate(List *name, List *args, bool oldstyle, List *parameters) #ifdef PGXC else if (pg_strcasecmp(defel->defname, "cfunc") == 0) collectfuncName = defGetQualifiedName(defel); - else if (pg_strcasecmp(defel->defname, "ctype") == 0) - collectType = defGetTypeName(defel); else if (pg_strcasecmp(defel->defname, "initcollect") == 0) initcollect = defGetString(defel); #endif @@ -130,21 +126,6 @@ DefineAggregate(List *name, List *args, bool oldstyle, List *parameters) (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), errmsg("aggregate sfunc must be specified"))); -#ifdef PGXC - if (collectType == NULL) - ereport(ERROR, - (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - errmsg("aggregate ctype must be specified"))); - if (collectfuncName == NIL) - ereport(ERROR, - (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - errmsg("aggregate cfunc must be specified"))); - if (collectType != transType) - ereport(ERROR, - (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - errmsg("aggregate ctype should be same as aggregate stype"))); - -#endif /* * look up the aggregate's input datatype(s). */ @@ -221,21 +202,6 @@ DefineAggregate(List *name, List *args, bool oldstyle, List *parameters) format_type_be(transTypeId)))); } -#ifdef PGXC - collectTypeId = typenameTypeId(NULL, collectType, NULL); - if (get_typtype(collectTypeId) == TYPTYPE_PSEUDO && - !IsPolymorphicType(collectTypeId)) - { - if (collectTypeId == INTERNALOID && superuser()) - /* okay */ ; - else - ereport(ERROR, - (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - errmsg("aggregate transition data type cannot be %s", - format_type_be(collectTypeId)))); - } - -#endif /* * Most of the argument-checking is done inside of AggregateCreate */ diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 1a3b2057ca..363a548353 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -1137,6 +1137,7 @@ _copyAggref(Aggref *from) COPY_SCALAR_FIELD(aggtype); #ifdef PGXC COPY_SCALAR_FIELD(aggtrantype); + COPY_SCALAR_FIELD(agghas_collectfn); #endif /* PGXC */ COPY_NODE_FIELD(args); COPY_NODE_FIELD(aggorder); diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 01b0f51062..1f6ac2d27a 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -185,6 +185,7 @@ _equalAggref(Aggref *a, Aggref *b) COMPARE_SCALAR_FIELD(aggtype); #ifdef PGXC COMPARE_SCALAR_FIELD(aggtrantype); + COMPARE_SCALAR_FIELD(agghas_collectfn); #endif /* PGXC */ COMPARE_NODE_FIELD(args); COMPARE_NODE_FIELD(aggorder); diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index d9dd1b8def..bd10ba65e4 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -873,6 +873,7 @@ _outAggref(StringInfo str, Aggref *node) WRITE_OID_FIELD(aggtype); #ifdef PGXC WRITE_OID_FIELD(aggtrantype); + WRITE_BOOL_FIELD(agghas_collectfn); #endif /* PGXC */ WRITE_NODE_FIELD(args); WRITE_NODE_FIELD(aggorder); diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c index 6dccae989c..36e989b5bb 100644 --- a/src/backend/nodes/readfuncs.c +++ b/src/backend/nodes/readfuncs.c @@ -468,6 +468,7 @@ _readAggref(void) READ_OID_FIELD(aggtype); #ifdef PGXC READ_OID_FIELD(aggtrantype); + READ_BOOL_FIELD(agghas_collectfn); #endif /* PGXC */ READ_NODE_FIELD(args); READ_NODE_FIELD(aggorder); diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 19c8bd2c00..41c756b0e2 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -5481,7 +5481,7 @@ pgxc_process_grouping_targetlist(PlannerInfo *root, List **local_tlist) if (aggref->aggorder || aggref->aggdistinct || aggref->agglevelsup || - !aggref->has_collectfn || + !aggref->agghas_collectfn || IsPolymorphicType(aggref->aggtrantype)) { shippable_remote_tlist = false; diff --git a/src/backend/parser/parse_agg.c b/src/backend/parser/parse_agg.c index 4846b09b49..e8bb6bb041 100644 --- a/src/backend/parser/parse_agg.c +++ b/src/backend/parser/parse_agg.c @@ -204,7 +204,7 @@ transformAggregateCall(ParseState *pstate, Aggref *agg, agg->aggfnoid); aggform = (Form_pg_aggregate) GETSTRUCT(aggTuple); agg->aggtrantype = aggform->aggtranstype; - agg->has_collectfn = OidIsValid(aggform->aggcollectfn); + agg->agghas_collectfn = OidIsValid(aggform->aggcollectfn); if (IS_PGXC_DATANODE) agg->aggtype = agg->aggtrantype; diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h index d0b628211a..4e7a6d4ffd 100644 --- a/src/include/nodes/primnodes.h +++ b/src/include/nodes/primnodes.h @@ -230,7 +230,7 @@ typedef struct Aggref Oid aggtype; /* type Oid of result of the aggregate */ #ifdef PGXC Oid aggtrantype; /* type Oid of transition results */ - bool has_collectfn; /* is collection function available */ + bool agghas_collectfn; /* is collection function available */ #endif /* PGXC */ List *args; /* arguments and sort expressions */ List *aggorder; /* ORDER BY (list of SortGroupClause) */ diff --git a/src/test/regress/expected/create_aggregate_1.out b/src/test/regress/expected/create_aggregate_1.out deleted file mode 100644 index a1afc03d0a..0000000000 --- a/src/test/regress/expected/create_aggregate_1.out +++ /dev/null @@ -1,73 +0,0 @@ --- --- CREATE_AGGREGATE --- --- all functions CREATEd -CREATE AGGREGATE newavg ( - sfunc = int4_avg_accum, basetype = int4, stype = _int8, - finalfunc = int8_avg, - initcond1 = '{0,0}' -); -ERROR: aggregate ctype must be specified --- test comments -COMMENT ON AGGREGATE newavg_wrong (int4) IS 'an agg comment'; -ERROR: aggregate newavg_wrong(integer) does not exist -COMMENT ON AGGREGATE newavg (int4) IS 'an agg comment'; -ERROR: aggregate newavg(integer) does not exist -COMMENT ON AGGREGATE newavg (int4) IS NULL; -ERROR: aggregate newavg(integer) does not exist --- without finalfunc; test obsolete spellings 'sfunc1' etc -CREATE AGGREGATE newsum ( - sfunc1 = int4pl, basetype = int4, stype1 = int4, - initcond1 = '0' -); -ERROR: aggregate ctype must be specified --- zero-argument aggregate -CREATE AGGREGATE newcnt (*) ( - sfunc = int8inc, stype = int8, - initcond = '0' -); -ERROR: aggregate ctype must be specified --- old-style spelling of same -CREATE AGGREGATE oldcnt ( - sfunc = int8inc, basetype = 'ANY', stype = int8, - initcond = '0' -); -ERROR: aggregate ctype must be specified --- aggregate that only cares about null/nonnull input -CREATE AGGREGATE newcnt ("any") ( - sfunc = int8inc_any, stype = int8, - initcond = '0' -); -ERROR: aggregate ctype must be specified -COMMENT ON AGGREGATE nosuchagg (*) IS 'should fail'; -ERROR: aggregate nosuchagg(*) does not exist -COMMENT ON AGGREGATE newcnt (*) IS 'an agg(*) comment'; -ERROR: aggregate newcnt(*) does not exist -COMMENT ON AGGREGATE newcnt ("any") IS 'an agg(any) comment'; -ERROR: aggregate newcnt("any") does not exist --- multi-argument aggregate -create function sum3(int8,int8,int8) returns int8 as -'select $1 + $2 + $3' language sql strict immutable; -create aggregate sum2(int8,int8) ( - sfunc = sum3, stype = int8, - initcond = '0' -); -ERROR: aggregate ctype must be specified --- multi-argument aggregates sensitive to distinct/order, strict/nonstrict -create type aggtype as (a integer, b integer, c text); -create function aggf_trans(aggtype[],integer,integer,text) returns aggtype[] -as 'select array_append($1,ROW($2,$3,$4)::aggtype)' -language sql strict immutable; -create function aggfns_trans(aggtype[],integer,integer,text) returns aggtype[] -as 'select array_append($1,ROW($2,$3,$4)::aggtype)' -language sql immutable; -create aggregate aggfstr(integer,integer,text) ( - sfunc = aggf_trans, stype = aggtype[], - initcond = '{}' -); -ERROR: aggregate ctype must be specified -create aggregate aggfns(integer,integer,text) ( - sfunc = aggfns_trans, stype = aggtype[], - initcond = '{}' -); -ERROR: aggregate ctype must be specified diff --git a/src/test/regress/expected/polymorphism_1.out b/src/test/regress/expected/polymorphism_1.out index 008c399498..774f935dac 100644 --- a/src/test/regress/expected/polymorphism_1.out +++ b/src/test/regress/expected/polymorphism_1.out @@ -76,28 +76,28 @@ CREATE FUNCTION ffnp(int[]) returns int[] as -- should CREATE CREATE AGGREGATE myaggp01a(*) (SFUNC = stfnp, STYPE = int4[], FINALFUNC = ffp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified -- P N -- should ERROR: stfnp(anyarray) not matched by stfnp(int[]) CREATE AGGREGATE myaggp02a(*) (SFUNC = stfnp, STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: cannot determine transition data type +DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument. -- N P -- should CREATE CREATE AGGREGATE myaggp03a(*) (SFUNC = stfp, STYPE = int4[], FINALFUNC = ffp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified CREATE AGGREGATE myaggp03b(*) (SFUNC = stfp, STYPE = int4[], INITCOND = '{}'); -ERROR: aggregate ctype must be specified -- P P -- should ERROR: we have no way to resolve S CREATE AGGREGATE myaggp04a(*) (SFUNC = stfp, STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: cannot determine transition data type +DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument. CREATE AGGREGATE myaggp04b(*) (SFUNC = stfp, STYPE = anyarray, INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: cannot determine transition data type +DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument. -- Case2 (R = P) && ((B = P) || (B = N)) -- ------------------------------------- -- S tf1 B tf2 @@ -106,106 +106,103 @@ ERROR: aggregate ctype must be specified -- should CREATE CREATE AGGREGATE myaggp05a(BASETYPE = int, SFUNC = tfnp, STYPE = int[], FINALFUNC = ffp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified -- N N N P -- should CREATE CREATE AGGREGATE myaggp06a(BASETYPE = int, SFUNC = tf2p, STYPE = int[], FINALFUNC = ffp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified -- N N P N -- should ERROR: tfnp(int[], anyelement) not matched by tfnp(int[], int) CREATE AGGREGATE myaggp07a(BASETYPE = anyelement, SFUNC = tfnp, STYPE = int[], FINALFUNC = ffp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: function tfnp(integer[], anyelement) does not exist -- N N P P -- should CREATE CREATE AGGREGATE myaggp08a(BASETYPE = anyelement, SFUNC = tf2p, STYPE = int[], FINALFUNC = ffp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified -- N P N N -- should CREATE CREATE AGGREGATE myaggp09a(BASETYPE = int, SFUNC = tf1p, STYPE = int[], FINALFUNC = ffp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified CREATE AGGREGATE myaggp09b(BASETYPE = int, SFUNC = tf1p, STYPE = int[], INITCOND = '{}'); -ERROR: aggregate ctype must be specified -- N P N P -- should CREATE CREATE AGGREGATE myaggp10a(BASETYPE = int, SFUNC = tfp, STYPE = int[], FINALFUNC = ffp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified CREATE AGGREGATE myaggp10b(BASETYPE = int, SFUNC = tfp, STYPE = int[], INITCOND = '{}'); -ERROR: aggregate ctype must be specified -- N P P N -- should ERROR: tf1p(int[],anyelement) not matched by tf1p(anyarray,int) CREATE AGGREGATE myaggp11a(BASETYPE = anyelement, SFUNC = tf1p, STYPE = int[], FINALFUNC = ffp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: function tf1p(integer[], anyelement) does not exist CREATE AGGREGATE myaggp11b(BASETYPE = anyelement, SFUNC = tf1p, STYPE = int[], INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: function tf1p(integer[], anyelement) does not exist -- N P P P -- should ERROR: tfp(int[],anyelement) not matched by tfp(anyarray,anyelement) CREATE AGGREGATE myaggp12a(BASETYPE = anyelement, SFUNC = tfp, STYPE = int[], FINALFUNC = ffp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: function tfp(integer[], anyelement) does not exist CREATE AGGREGATE myaggp12b(BASETYPE = anyelement, SFUNC = tfp, STYPE = int[], INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: function tfp(integer[], anyelement) does not exist -- P N N N -- should ERROR: tfnp(anyarray, int) not matched by tfnp(int[],int) CREATE AGGREGATE myaggp13a(BASETYPE = int, SFUNC = tfnp, STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: cannot determine transition data type +DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument. -- P N N P -- should ERROR: tf2p(anyarray, int) not matched by tf2p(int[],anyelement) CREATE AGGREGATE myaggp14a(BASETYPE = int, SFUNC = tf2p, STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: cannot determine transition data type +DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument. -- P N P N -- should ERROR: tfnp(anyarray, anyelement) not matched by tfnp(int[],int) CREATE AGGREGATE myaggp15a(BASETYPE = anyelement, SFUNC = tfnp, STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: function tfnp(anyarray, anyelement) does not exist -- P N P P -- should ERROR: tf2p(anyarray, anyelement) not matched by tf2p(int[],anyelement) CREATE AGGREGATE myaggp16a(BASETYPE = anyelement, SFUNC = tf2p, STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: function tf2p(anyarray, anyelement) does not exist -- P P N N -- should ERROR: we have no way to resolve S CREATE AGGREGATE myaggp17a(BASETYPE = int, SFUNC = tf1p, STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: cannot determine transition data type +DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument. CREATE AGGREGATE myaggp17b(BASETYPE = int, SFUNC = tf1p, STYPE = anyarray, INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: cannot determine transition data type +DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument. -- P P N P -- should ERROR: tfp(anyarray, int) not matched by tfp(anyarray, anyelement) CREATE AGGREGATE myaggp18a(BASETYPE = int, SFUNC = tfp, STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: cannot determine transition data type +DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument. CREATE AGGREGATE myaggp18b(BASETYPE = int, SFUNC = tfp, STYPE = anyarray, INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: cannot determine transition data type +DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument. -- P P P N -- should ERROR: tf1p(anyarray, anyelement) not matched by tf1p(anyarray, int) CREATE AGGREGATE myaggp19a(BASETYPE = anyelement, SFUNC = tf1p, STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: function tf1p(anyarray, anyelement) does not exist CREATE AGGREGATE myaggp19b(BASETYPE = anyelement, SFUNC = tf1p, STYPE = anyarray, INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: function tf1p(anyarray, anyelement) does not exist -- P P P P -- should CREATE CREATE AGGREGATE myaggp20a(BASETYPE = anyelement, SFUNC = tfp, STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified CREATE AGGREGATE myaggp20b(BASETYPE = anyelement, SFUNC = tfp, STYPE = anyarray, INITCOND = '{}'); -ERROR: aggregate ctype must be specified -- Case3 (R = N) && (B = A) -- ------------------------ -- S tf1 @@ -214,28 +211,28 @@ ERROR: aggregate ctype must be specified -- should CREATE CREATE AGGREGATE myaggn01a(*) (SFUNC = stfnp, STYPE = int4[], FINALFUNC = ffnp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified CREATE AGGREGATE myaggn01b(*) (SFUNC = stfnp, STYPE = int4[], INITCOND = '{}'); -ERROR: aggregate ctype must be specified -- P N -- should ERROR: stfnp(anyarray) not matched by stfnp(int[]) CREATE AGGREGATE myaggn02a(*) (SFUNC = stfnp, STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: cannot determine transition data type +DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument. CREATE AGGREGATE myaggn02b(*) (SFUNC = stfnp, STYPE = anyarray, INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: cannot determine transition data type +DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument. -- N P -- should CREATE CREATE AGGREGATE myaggn03a(*) (SFUNC = stfp, STYPE = int4[], FINALFUNC = ffnp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified -- P P -- should ERROR: ffnp(anyarray) not matched by ffnp(int[]) CREATE AGGREGATE myaggn04a(*) (SFUNC = stfp, STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: cannot determine transition data type +DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument. -- Case4 (R = N) && ((B = P) || (B = N)) -- ------------------------------------- -- S tf1 B tf2 @@ -244,110 +241,107 @@ ERROR: aggregate ctype must be specified -- should CREATE CREATE AGGREGATE myaggn05a(BASETYPE = int, SFUNC = tfnp, STYPE = int[], FINALFUNC = ffnp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified CREATE AGGREGATE myaggn05b(BASETYPE = int, SFUNC = tfnp, STYPE = int[], INITCOND = '{}'); -ERROR: aggregate ctype must be specified -- N N N P -- should CREATE CREATE AGGREGATE myaggn06a(BASETYPE = int, SFUNC = tf2p, STYPE = int[], FINALFUNC = ffnp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified CREATE AGGREGATE myaggn06b(BASETYPE = int, SFUNC = tf2p, STYPE = int[], INITCOND = '{}'); -ERROR: aggregate ctype must be specified -- N N P N -- should ERROR: tfnp(int[], anyelement) not matched by tfnp(int[], int) CREATE AGGREGATE myaggn07a(BASETYPE = anyelement, SFUNC = tfnp, STYPE = int[], FINALFUNC = ffnp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: function tfnp(integer[], anyelement) does not exist CREATE AGGREGATE myaggn07b(BASETYPE = anyelement, SFUNC = tfnp, STYPE = int[], INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: function tfnp(integer[], anyelement) does not exist -- N N P P -- should CREATE CREATE AGGREGATE myaggn08a(BASETYPE = anyelement, SFUNC = tf2p, STYPE = int[], FINALFUNC = ffnp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified CREATE AGGREGATE myaggn08b(BASETYPE = anyelement, SFUNC = tf2p, STYPE = int[], INITCOND = '{}'); -ERROR: aggregate ctype must be specified -- N P N N -- should CREATE CREATE AGGREGATE myaggn09a(BASETYPE = int, SFUNC = tf1p, STYPE = int[], FINALFUNC = ffnp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified -- N P N P -- should CREATE CREATE AGGREGATE myaggn10a(BASETYPE = int, SFUNC = tfp, STYPE = int[], FINALFUNC = ffnp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified -- N P P N -- should ERROR: tf1p(int[],anyelement) not matched by tf1p(anyarray,int) CREATE AGGREGATE myaggn11a(BASETYPE = anyelement, SFUNC = tf1p, STYPE = int[], FINALFUNC = ffnp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: function tf1p(integer[], anyelement) does not exist -- N P P P -- should ERROR: tfp(int[],anyelement) not matched by tfp(anyarray,anyelement) CREATE AGGREGATE myaggn12a(BASETYPE = anyelement, SFUNC = tfp, STYPE = int[], FINALFUNC = ffnp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: function tfp(integer[], anyelement) does not exist -- P N N N -- should ERROR: tfnp(anyarray, int) not matched by tfnp(int[],int) CREATE AGGREGATE myaggn13a(BASETYPE = int, SFUNC = tfnp, STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: cannot determine transition data type +DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument. CREATE AGGREGATE myaggn13b(BASETYPE = int, SFUNC = tfnp, STYPE = anyarray, INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: cannot determine transition data type +DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument. -- P N N P -- should ERROR: tf2p(anyarray, int) not matched by tf2p(int[],anyelement) CREATE AGGREGATE myaggn14a(BASETYPE = int, SFUNC = tf2p, STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: cannot determine transition data type +DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument. CREATE AGGREGATE myaggn14b(BASETYPE = int, SFUNC = tf2p, STYPE = anyarray, INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: cannot determine transition data type +DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument. -- P N P N -- should ERROR: tfnp(anyarray, anyelement) not matched by tfnp(int[],int) CREATE AGGREGATE myaggn15a(BASETYPE = anyelement, SFUNC = tfnp, STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: function tfnp(anyarray, anyelement) does not exist CREATE AGGREGATE myaggn15b(BASETYPE = anyelement, SFUNC = tfnp, STYPE = anyarray, INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: function tfnp(anyarray, anyelement) does not exist -- P N P P -- should ERROR: tf2p(anyarray, anyelement) not matched by tf2p(int[],anyelement) CREATE AGGREGATE myaggn16a(BASETYPE = anyelement, SFUNC = tf2p, STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: function tf2p(anyarray, anyelement) does not exist CREATE AGGREGATE myaggn16b(BASETYPE = anyelement, SFUNC = tf2p, STYPE = anyarray, INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: function tf2p(anyarray, anyelement) does not exist -- P P N N -- should ERROR: ffnp(anyarray) not matched by ffnp(int[]) CREATE AGGREGATE myaggn17a(BASETYPE = int, SFUNC = tf1p, STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: cannot determine transition data type +DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument. -- P P N P -- should ERROR: tfp(anyarray, int) not matched by tfp(anyarray, anyelement) CREATE AGGREGATE myaggn18a(BASETYPE = int, SFUNC = tfp, STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: cannot determine transition data type +DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument. -- P P P N -- should ERROR: tf1p(anyarray, anyelement) not matched by tf1p(anyarray, int) CREATE AGGREGATE myaggn19a(BASETYPE = anyelement, SFUNC = tf1p, STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: function tf1p(anyarray, anyelement) does not exist -- P P P P -- should ERROR: ffnp(anyarray) not matched by ffnp(int[]) CREATE AGGREGATE myaggn20a(BASETYPE = anyelement, SFUNC = tfp, STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}'); -ERROR: aggregate ctype must be specified +ERROR: function ffnp(anyarray) does not exist -- multi-arg polymorphic CREATE AGGREGATE mysum2(anyelement,anyelement) (SFUNC = sum3, STYPE = anyelement, INITCOND = '0'); -ERROR: aggregate ctype must be specified -- create test data for polymorphic aggregates create temp table t(f1 int, f2 int[], f3 text); ERROR: PG-XC does not yet support temporary tables @@ -534,24 +528,23 @@ create aggregate build_group(anyelement, integer) ( SFUNC = add_group, STYPE = anyarray ); -ERROR: aggregate ctype must be specified select build_group(q1,3) from int8_tbl; -ERROR: function build_group(bigint, integer) does not exist -LINE 1: select build_group(q1,3) from int8_tbl; - ^ -HINT: No function matches the given name and argument types. You might need to add explicit type casts. + build_group +---------------------------- + {123,123,4567890123456789} +(1 row) + -- this should fail because stype isn't compatible with arg create aggregate build_group(int8, integer) ( SFUNC = add_group, STYPE = int2[] ); -ERROR: aggregate ctype must be specified +ERROR: function add_group(smallint[], bigint, integer) does not exist -- but we can make a non-poly agg from a poly sfunc if types are OK create aggregate build_group(int8, integer) ( SFUNC = add_group, STYPE = int8[] ); -ERROR: aggregate ctype must be specified -- check that we can apply functions taking ANYARRAY to pg_stats select distinct array_ndims(histogram_bounds) from pg_stats where histogram_bounds is not null; |