From 37a795a60b4f4b1def11c615525ec5e0e9449e05 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Thu, 26 Oct 2017 13:47:45 -0400 Subject: Support domains over composite types. This is the last major omission in our domains feature: you can now make a domain over anything that's not a pseudotype. The major complication from an implementation standpoint is that places that might be creating tuples of a domain type now need to be prepared to apply domain_check(). It seems better that unprepared code fail with an error like " is not composite" than that it silently fail to apply domain constraints. Therefore, relevant infrastructure like get_func_result_type() and lookup_rowtype_tupdesc() has been adjusted to treat domain-over-composite as a distinct case that unprepared code won't recognize, rather than just transparently treating it the same as plain composite. This isn't a 100% solution to the possibility of overlooked domain checks, but it catches most places. In passing, improve typcache.c's support for domains (it can now cache the identity of a domain's base type), and rewrite the argument handling logic in jsonfuncs.c's populate_record[set]_worker to reduce duplicative per-call lookups. I believe this is code-complete so far as the core and contrib code go. The PLs need varying amounts of work, which will be tackled in followup patches. Discussion: https://postgr.es/m/4206.1499798337@sss.pgh.pa.us --- src/backend/parser/parse_func.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/backend/parser/parse_func.c') diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c index 2f2f2c7fb0..fc0d6bc2f2 100644 --- a/src/backend/parser/parse_func.c +++ b/src/backend/parser/parse_func.c @@ -1819,18 +1819,19 @@ ParseComplexProjection(ParseState *pstate, char *funcname, Node *first_arg, } /* - * Else do it the hard way with get_expr_result_type(). + * Else do it the hard way with get_expr_result_tupdesc(). * * If it's a Var of type RECORD, we have to work even harder: we have to - * find what the Var refers to, and pass that to get_expr_result_type. + * find what the Var refers to, and pass that to get_expr_result_tupdesc. * That task is handled by expandRecordVariable(). */ if (IsA(first_arg, Var) && ((Var *) first_arg)->vartype == RECORDOID) tupdesc = expandRecordVariable(pstate, (Var *) first_arg, 0); - else if (get_expr_result_type(first_arg, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) + else + tupdesc = get_expr_result_tupdesc(first_arg, true); + if (!tupdesc) return NULL; /* unresolvable RECORD type */ - Assert(tupdesc); for (i = 0; i < tupdesc->natts; i++) { -- cgit v1.2.1