Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit ac653af

Browse files
committed
Merge branch 'REL_10_STABLE' into PGPRO10
2 parents eb01a27 + 8b89b7a commit ac653af

File tree

12 files changed

+362
-129
lines changed

12 files changed

+362
-129
lines changed

contrib/postgres_fdw/deparse.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ static void appendGroupByClause(List *tlist, deparse_expr_cxt *context);
178178
static void appendAggOrderBy(List *orderList, List *targetList,
179179
deparse_expr_cxt *context);
180180
static void appendFunctionName(Oid funcid, deparse_expr_cxt *context);
181-
static Node *deparseSortGroupClause(Index ref, List *tlist,
181+
static Node *deparseSortGroupClause(Index ref, List *tlist, bool force_colno,
182182
deparse_expr_cxt *context);
183183

184184
/*
@@ -2853,7 +2853,7 @@ appendAggOrderBy(List *orderList, List *targetList, deparse_expr_cxt *context)
28532853
first = false;
28542854

28552855
sortexpr = deparseSortGroupClause(srt->tleSortGroupRef, targetList,
2856-
context);
2856+
false, context);
28572857
sortcoltype = exprType(sortexpr);
28582858
/* See whether operator is default < or > for datatype */
28592859
typentry = lookup_type_cache(sortcoltype,
@@ -2960,7 +2960,7 @@ appendGroupByClause(List *tlist, deparse_expr_cxt *context)
29602960
appendStringInfoString(buf, ", ");
29612961
first = false;
29622962

2963-
deparseSortGroupClause(grp->tleSortGroupRef, tlist, context);
2963+
deparseSortGroupClause(grp->tleSortGroupRef, tlist, true, context);
29642964
}
29652965
}
29662966

@@ -3047,7 +3047,8 @@ appendFunctionName(Oid funcid, deparse_expr_cxt *context)
30473047
* need not find it again.
30483048
*/
30493049
static Node *
3050-
deparseSortGroupClause(Index ref, List *tlist, deparse_expr_cxt *context)
3050+
deparseSortGroupClause(Index ref, List *tlist, bool force_colno,
3051+
deparse_expr_cxt *context)
30513052
{
30523053
StringInfo buf = context->buf;
30533054
TargetEntry *tle;
@@ -3056,7 +3057,13 @@ deparseSortGroupClause(Index ref, List *tlist, deparse_expr_cxt *context)
30563057
tle = get_sortgroupref_tle(ref, tlist);
30573058
expr = tle->expr;
30583059

3059-
if (expr && IsA(expr, Const))
3060+
if (force_colno)
3061+
{
3062+
/* Use column-number form when requested by caller. */
3063+
Assert(!tle->resjunk);
3064+
appendStringInfo(buf, "%d", tle->resno);
3065+
}
3066+
else if (expr && IsA(expr, Const))
30603067
{
30613068
/*
30623069
* Force a typecast here so that we don't emit something like "GROUP

contrib/postgres_fdw/expected/postgres_fdw.out

Lines changed: 93 additions & 70 deletions
Large diffs are not rendered by default.

contrib/postgres_fdw/postgres_fdw.c

Lines changed: 39 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -4590,45 +4590,35 @@ static bool
45904590
foreign_grouping_ok(PlannerInfo *root, RelOptInfo *grouped_rel)
45914591
{
45924592
Query *query = root->parse;
4593-
PathTarget *grouping_target;
4593+
PathTarget *grouping_target = root->upper_targets[UPPERREL_GROUP_AGG];
45944594
PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) grouped_rel->fdw_private;
45954595
PgFdwRelationInfo *ofpinfo;
45964596
List *aggvars;
45974597
ListCell *lc;
45984598
int i;
45994599
List *tlist = NIL;
46004600

4601-
/* Grouping Sets are not pushable */
4601+
/* We currently don't support pushing Grouping Sets. */
46024602
if (query->groupingSets)
46034603
return false;
46044604

46054605
/* Get the fpinfo of the underlying scan relation. */
46064606
ofpinfo = (PgFdwRelationInfo *) fpinfo->outerrel->fdw_private;
46074607

46084608
/*
4609-
* If underneath input relation has any local conditions, those conditions
4609+
* If underlying scan relation has any local conditions, those conditions
46104610
* are required to be applied before performing aggregation. Hence the
46114611
* aggregate cannot be pushed down.
46124612
*/
46134613
if (ofpinfo->local_conds)
46144614
return false;
46154615

46164616
/*
4617-
* The targetlist expected from this node and the targetlist pushed down
4618-
* to the foreign server may be different. The latter requires
4619-
* sortgrouprefs to be set to push down GROUP BY clause, but should not
4620-
* have those arising from ORDER BY clause. These sortgrouprefs may be
4621-
* different from those in the plan's targetlist. Use a copy of path
4622-
* target to record the new sortgrouprefs.
4623-
*/
4624-
grouping_target = copy_pathtarget(root->upper_targets[UPPERREL_GROUP_AGG]);
4625-
4626-
/*
4627-
* Evaluate grouping targets and check whether they are safe to push down
4628-
* to the foreign side. All GROUP BY expressions will be part of the
4629-
* grouping target and thus there is no need to evaluate it separately.
4630-
* While doing so, add required expressions into target list which can
4631-
* then be used to pass to foreign server.
4617+
* Examine grouping expressions, as well as other expressions we'd need to
4618+
* compute, and check whether they are safe to push down to the foreign
4619+
* server. All GROUP BY expressions will be part of the grouping target
4620+
* and thus there is no need to search for them separately. Add grouping
4621+
* expressions into target list which will be passed to foreign server.
46324622
*/
46334623
i = 0;
46344624
foreach(lc, grouping_target->exprs)
@@ -4640,51 +4630,59 @@ foreign_grouping_ok(PlannerInfo *root, RelOptInfo *grouped_rel)
46404630
/* Check whether this expression is part of GROUP BY clause */
46414631
if (sgref && get_sortgroupref_clause_noerr(sgref, query->groupClause))
46424632
{
4633+
TargetEntry *tle;
4634+
46434635
/*
4644-
* If any of the GROUP BY expression is not shippable we can not
4636+
* If any GROUP BY expression is not shippable, then we cannot
46454637
* push down aggregation to the foreign server.
46464638
*/
46474639
if (!is_foreign_expr(root, grouped_rel, expr))
46484640
return false;
46494641

4650-
/* Pushable, add to tlist */
4651-
tlist = add_to_flat_tlist(tlist, list_make1(expr));
4642+
/*
4643+
* Pushable, so add to tlist. We need to create a TLE for this
4644+
* expression and apply the sortgroupref to it. We cannot use
4645+
* add_to_flat_tlist() here because that avoids making duplicate
4646+
* entries in the tlist. If there are duplicate entries with
4647+
* distinct sortgrouprefs, we have to duplicate that situation in
4648+
* the output tlist.
4649+
*/
4650+
tle = makeTargetEntry(expr, list_length(tlist) + 1, NULL, false);
4651+
tle->ressortgroupref = sgref;
4652+
tlist = lappend(tlist, tle);
46524653
}
46534654
else
46544655
{
4655-
/* Check entire expression whether it is pushable or not */
4656+
/*
4657+
* Non-grouping expression we need to compute. Is it shippable?
4658+
*/
46564659
if (is_foreign_expr(root, grouped_rel, expr))
46574660
{
4658-
/* Pushable, add to tlist */
4661+
/* Yes, so add to tlist as-is; OK to suppress duplicates */
46594662
tlist = add_to_flat_tlist(tlist, list_make1(expr));
46604663
}
46614664
else
46624665
{
4663-
/*
4664-
* If we have sortgroupref set, then it means that we have an
4665-
* ORDER BY entry pointing to this expression. Since we are
4666-
* not pushing ORDER BY with GROUP BY, clear it.
4667-
*/
4668-
if (sgref)
4669-
grouping_target->sortgrouprefs[i] = 0;
4670-
4671-
/* Not matched exactly, pull the var with aggregates then */
4666+
/* Not pushable as a whole; extract its Vars and aggregates */
46724667
aggvars = pull_var_clause((Node *) expr,
46734668
PVC_INCLUDE_AGGREGATES);
46744669

4670+
/*
4671+
* If any aggregate expression is not shippable, then we
4672+
* cannot push down aggregation to the foreign server.
4673+
*/
46754674
if (!is_foreign_expr(root, grouped_rel, (Expr *) aggvars))
46764675
return false;
46774676

46784677
/*
4679-
* Add aggregates, if any, into the targetlist. Plain var
4680-
* nodes should be either same as some GROUP BY expression or
4681-
* part of some GROUP BY expression. In later case, the query
4682-
* cannot refer plain var nodes without the surrounding
4683-
* expression. In both the cases, they are already part of
4678+
* Add aggregates, if any, into the targetlist. Plain Vars
4679+
* outside an aggregate can be ignored, because they should be
4680+
* either same as some GROUP BY column or part of some GROUP
4681+
* BY expression. In either case, they are already part of
46844682
* the targetlist and thus no need to add them again. In fact
4685-
* adding pulled plain var nodes in SELECT clause will cause
4686-
* an error on the foreign server if they are not same as some
4687-
* GROUP BY expression.
4683+
* including plain Vars in the tlist when they do not match a
4684+
* GROUP BY column would cause the foreign server to complain
4685+
* that the shipped query is invalid.
46884686
*/
46894687
foreach(l, aggvars)
46904688
{
@@ -4700,7 +4698,7 @@ foreign_grouping_ok(PlannerInfo *root, RelOptInfo *grouped_rel)
47004698
}
47014699

47024700
/*
4703-
* Classify the pushable and non-pushable having clauses and save them in
4701+
* Classify the pushable and non-pushable HAVING clauses and save them in
47044702
* remote_conds and local_conds of the grouped rel's fpinfo.
47054703
*/
47064704
if (root->hasHavingQual && query->havingQual)
@@ -4770,9 +4768,6 @@ foreign_grouping_ok(PlannerInfo *root, RelOptInfo *grouped_rel)
47704768
}
47714769
}
47724770

4773-
/* Transfer any sortgroupref data to the replacement tlist */
4774-
apply_pathtarget_labeling_to_tlist(tlist, grouping_target);
4775-
47764771
/* Store generated targetlist */
47774772
fpinfo->grouped_tlist = tlist;
47784773

contrib/postgres_fdw/sql/postgres_fdw.sql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,12 @@ explain (verbose, costs off)
636636
select count(c2) w, c2 x, 5 y, 7.0 z from ft1 group by 2, y, 9.0::int order by 2;
637637
select count(c2) w, c2 x, 5 y, 7.0 z from ft1 group by 2, y, 9.0::int order by 2;
638638

639+
-- GROUP BY clause referring to same column multiple times
640+
-- Also, ORDER BY contains an aggregate function
641+
explain (verbose, costs off)
642+
select c2, c2 from ft1 where c2 > 6 group by 1, 2 order by sum(c1);
643+
select c2, c2 from ft1 where c2 > 6 group by 1, 2 order by sum(c1);
644+
639645
-- Testing HAVING clause shippability
640646
explain (verbose, costs off)
641647
select c2, sum(c1) from ft2 group by c2 having avg(c1) < 500 and sum(c1) < 49800 order by c2;

src/backend/optimizer/prep/prepjointree.c

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,11 +1003,8 @@ pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte,
10031003

10041004
/*
10051005
* The subquery's targetlist items are now in the appropriate form to
1006-
* insert into the top query, but if we are under an outer join then
1007-
* non-nullable items and lateral references may have to be turned into
1008-
* PlaceHolderVars. If we are dealing with an appendrel member then
1009-
* anything that's not a simple Var has to be turned into a
1010-
* PlaceHolderVar. Set up required context data for pullup_replace_vars.
1006+
* insert into the top query, except that we may need to wrap them in
1007+
* PlaceHolderVars. Set up required context data for pullup_replace_vars.
10111008
*/
10121009
rvcontext.root = root;
10131010
rvcontext.targetlist = subquery->targetList;
@@ -1019,13 +1016,48 @@ pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte,
10191016
rvcontext.relids = NULL;
10201017
rvcontext.outer_hasSubLinks = &parse->hasSubLinks;
10211018
rvcontext.varno = varno;
1022-
rvcontext.need_phvs = (lowest_nulling_outer_join != NULL ||
1023-
containing_appendrel != NULL);
1024-
rvcontext.wrap_non_vars = (containing_appendrel != NULL);
1019+
/* these flags will be set below, if needed */
1020+
rvcontext.need_phvs = false;
1021+
rvcontext.wrap_non_vars = false;
10251022
/* initialize cache array with indexes 0 .. length(tlist) */
10261023
rvcontext.rv_cache = palloc0((list_length(subquery->targetList) + 1) *
10271024
sizeof(Node *));
10281025

1026+
/*
1027+
* If we are under an outer join then non-nullable items and lateral
1028+
* references may have to be turned into PlaceHolderVars.
1029+
*/
1030+
if (lowest_nulling_outer_join != NULL)
1031+
rvcontext.need_phvs = true;
1032+
1033+
/*
1034+
* If we are dealing with an appendrel member then anything that's not a
1035+
* simple Var has to be turned into a PlaceHolderVar. We force this to
1036+
* ensure that what we pull up doesn't get merged into a surrounding
1037+
* expression during later processing and then fail to match the
1038+
* expression actually available from the appendrel.
1039+
*/
1040+
if (containing_appendrel != NULL)
1041+
{
1042+
rvcontext.need_phvs = true;
1043+
rvcontext.wrap_non_vars = true;
1044+
}
1045+
1046+
/*
1047+
* If the parent query uses grouping sets, we need a PlaceHolderVar for
1048+
* anything that's not a simple Var. Again, this ensures that expressions
1049+
* retain their separate identity so that they will match grouping set
1050+
* columns when appropriate. (It'd be sufficient to wrap values used in
1051+
* grouping set columns, and do so only in non-aggregated portions of the
1052+
* tlist and havingQual, but that would require a lot of infrastructure
1053+
* that pullup_replace_vars hasn't currently got.)
1054+
*/
1055+
if (parse->groupingSets)
1056+
{
1057+
rvcontext.need_phvs = true;
1058+
rvcontext.wrap_non_vars = true;
1059+
}
1060+
10291061
/*
10301062
* Replace all of the top query's references to the subquery's outputs
10311063
* with copies of the adjusted subtlist items, being careful not to

src/backend/optimizer/prep/prepunion.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1681,15 +1681,15 @@ make_inh_translation_list(Relation oldrelation, Relation newrelation,
16811681
*/
16821682
if (old_attno < newnatts &&
16831683
(att = new_tupdesc->attrs[old_attno]) != NULL &&
1684-
!att->attisdropped && att->attinhcount != 0 &&
1684+
!att->attisdropped &&
16851685
strcmp(attname, NameStr(att->attname)) == 0)
16861686
new_attno = old_attno;
16871687
else
16881688
{
16891689
for (new_attno = 0; new_attno < newnatts; new_attno++)
16901690
{
16911691
att = new_tupdesc->attrs[new_attno];
1692-
if (!att->attisdropped && att->attinhcount != 0 &&
1692+
if (!att->attisdropped &&
16931693
strcmp(attname, NameStr(att->attname)) == 0)
16941694
break;
16951695
}

src/interfaces/ecpg/preproc/type.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,17 @@ ECPGdump_a_struct(FILE *o, const char *name, const char *ind_name, char *arrsize
609609
prefix, ind_prefix, arrsize, type->struct_sizeof,
610610
(ind_p != NULL) ? ind_type->struct_sizeof : NULL);
611611
if (ind_p != NULL && ind_p != &struct_no_indicator)
612+
{
612613
ind_p = ind_p->next;
614+
if (ind_p == NULL && p->next != NULL) {
615+
mmerror(PARSE_ERROR, ET_WARNING, "indicator struct \"%s\" has too few members", ind_name);
616+
ind_p = &struct_no_indicator;
617+
}
618+
}
619+
}
620+
621+
if (ind_type != NULL && ind_p != NULL && ind_p != &struct_no_indicator) {
622+
mmerror(PARSE_ERROR, ET_WARNING, "indicator struct \"%s\" has too many members", ind_name);
613623
}
614624

615625
free(pbuf);
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
Parsed test spec with 2 sessions
2+
3+
starting permutation: s1b s1delc1 s2sel s1c s2sel
4+
step s1b: BEGIN;
5+
step s1delc1: ALTER TABLE c1 NO INHERIT p;
6+
step s2sel: SELECT SUM(a) FROM p; <waiting ...>
7+
step s1c: COMMIT;
8+
step s2sel: <... completed>
9+
sum
10+
11+
11
12+
step s2sel: SELECT SUM(a) FROM p;
13+
sum
14+
15+
1
16+
17+
starting permutation: s1b s1delc1 s1addc2 s2sel s1c s2sel
18+
step s1b: BEGIN;
19+
step s1delc1: ALTER TABLE c1 NO INHERIT p;
20+
step s1addc2: ALTER TABLE c2 INHERIT p;
21+
step s2sel: SELECT SUM(a) FROM p; <waiting ...>
22+
step s1c: COMMIT;
23+
step s2sel: <... completed>
24+
sum
25+
26+
11
27+
step s2sel: SELECT SUM(a) FROM p;
28+
sum
29+
30+
101
31+
32+
starting permutation: s1b s1dropc1 s2sel s1c s2sel
33+
step s1b: BEGIN;
34+
step s1dropc1: DROP TABLE c1;
35+
step s2sel: SELECT SUM(a) FROM p; <waiting ...>
36+
step s1c: COMMIT;
37+
step s2sel: <... completed>
38+
sum
39+
40+
1
41+
step s2sel: SELECT SUM(a) FROM p;
42+
sum
43+
44+
1
45+
46+
starting permutation: s1b s1delc1 s1modc1a s2sel s1c s2sel
47+
step s1b: BEGIN;
48+
step s1delc1: ALTER TABLE c1 NO INHERIT p;
49+
step s1modc1a: ALTER TABLE c1 ALTER COLUMN a TYPE float;
50+
step s2sel: SELECT SUM(a) FROM p; <waiting ...>
51+
step s1c: COMMIT;
52+
step s2sel: <... completed>
53+
error in steps s1c s2sel: ERROR: attribute "a" of relation "c1" does not match parent's type
54+
step s2sel: SELECT SUM(a) FROM p;
55+
sum
56+
57+
1

src/test/isolation/isolation_schedule

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ test: multiple-cic
5959
test: alter-table-1
6060
test: alter-table-2
6161
test: alter-table-3
62+
test: alter-table-4
6263
test: create-trigger
6364
test: sequence-ddl
6465
test: async-notify

0 commit comments

Comments
 (0)