Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commite433bf5

Browse files
committed
If the inputs of a UNION/INTERSECT/EXCEPT construct all agree on the
typmod of a particular column, mark the output with that same typmod,not -1 as formerly. -1 is still used if there is any disagreement.Part of response to bug#513.
1 parent7a9ef7e commite433bf5

File tree

1 file changed

+92
-30
lines changed

1 file changed

+92
-30
lines changed

‎src/backend/optimizer/prep/prepunion.c

Lines changed: 92 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
*
1515
*
1616
* IDENTIFICATION
17-
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.68 2001/10/28 06:25:46 momjian Exp $
17+
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.69 2001/11/12 20:04:20 tgl Exp $
1818
*
1919
*-------------------------------------------------------------------------
2020
*/
@@ -63,6 +63,7 @@ static List *generate_setop_tlist(List *colTypes, int flag,
6363
boolhack_constants,
6464
List*input_tlist,
6565
List*refnames_tlist);
66+
staticvoidmerge_tlist_typmods(List*tlist,List*planlist);
6667
staticbooltlist_same_datatypes(List*tlist,List*colTypes,booljunkOK);
6768
staticNode*adjust_inherited_attrs_mutator(Node*node,
6869
adjust_inherited_attrs_context*context);
@@ -204,6 +205,7 @@ generate_union_plan(SetOperationStmt *op, Query *parse,
204205
List*refnames_tlist)
205206
{
206207
List*planlist;
208+
List*tlist;
207209
Plan*plan;
208210

209211
/*
@@ -218,29 +220,31 @@ generate_union_plan(SetOperationStmt *op, Query *parse,
218220
op,refnames_tlist));
219221

220222
/*
221-
*Append the child results together.
223+
*Generate tlist for Append plan node.
222224
*
223225
* The tlist for an Append plan isn't important as far as the Append is
224226
* concerned, but we must make it look real anyway for the benefit of
225227
* the next plan level up.
226228
*/
227-
plan= (Plan*)
228-
make_append(planlist,
229-
false,
230-
generate_setop_tlist(op->colTypes,-1, false,
229+
tlist=generate_setop_tlist(op->colTypes,-1, false,
231230
((Plan*)lfirst(planlist))->targetlist,
232-
refnames_tlist));
231+
refnames_tlist);
232+
merge_tlist_typmods(tlist,planlist);
233+
234+
/*
235+
* Append the child results together.
236+
*/
237+
plan= (Plan*)make_append(planlist, false,tlist);
233238

234239
/*
235240
* For UNION ALL, we just need the Append plan. For UNION, need to
236241
* add Sort and Unique nodes to produce unique output.
237242
*/
238243
if (!op->all)
239244
{
240-
List*tlist,
241-
*sortList;
245+
List*sortList;
242246

243-
tlist=new_unsorted_tlist(plan->targetlist);
247+
tlist=new_unsorted_tlist(tlist);
244248
sortList=addAllTargetsToSortList(NIL,tlist);
245249
plan=make_sortplan(parse,tlist,plan,sortList);
246250
plan= (Plan*)make_unique(tlist,plan,copyObject(sortList));
@@ -259,7 +263,8 @@ generate_nonunion_plan(SetOperationStmt *op, Query *parse,
259263
*rplan,
260264
*plan;
261265
List*tlist,
262-
*sortList;
266+
*sortList,
267+
*planlist;
263268
SetOpCmdcmd;
264269

265270
/* Recurse on children, ensuring their outputs are marked */
@@ -269,28 +274,32 @@ generate_nonunion_plan(SetOperationStmt *op, Query *parse,
269274
rplan=recurse_set_operations(op->rarg,parse,
270275
op->colTypes, false,1,
271276
refnames_tlist);
277+
planlist=makeList2(lplan,rplan);
272278

273279
/*
274-
*Append the child results together.
280+
*Generate tlist for Append plan node.
275281
*
276282
* The tlist for an Append plan isn't important as far as the Append is
277283
* concerned, but we must make it look real anyway for the benefit of
278284
* the next plan level up.In fact, it has to be real enough that the
279285
* flag column is shown as a variable not a constant, else setrefs.c
280286
* will get confused.
281287
*/
282-
plan= (Plan*)
283-
make_append(makeList2(lplan,rplan),
284-
false,
285-
generate_setop_tlist(op->colTypes,2, false,
286-
lplan->targetlist,
287-
refnames_tlist));
288+
tlist=generate_setop_tlist(op->colTypes,2, false,
289+
lplan->targetlist,
290+
refnames_tlist);
291+
merge_tlist_typmods(tlist,planlist);
292+
293+
/*
294+
* Append the child results together.
295+
*/
296+
plan= (Plan*)make_append(planlist, false,tlist);
288297

289298
/*
290299
* Sort the child results, then add a SetOp plan node to generate the
291300
* correct output.
292301
*/
293-
tlist=new_unsorted_tlist(plan->targetlist);
302+
tlist=new_unsorted_tlist(tlist);
294303
sortList=addAllTargetsToSortList(NIL,tlist);
295304
plan=make_sortplan(parse,tlist,plan,sortList);
296305
switch (op->op)
@@ -332,9 +341,11 @@ recurse_union_children(Node *setOp, Query *parse,
332341
{
333342
/* Same UNION, so fold children into parent's subplan list */
334343
returnnconc(recurse_union_children(op->larg,parse,
335-
top_union,refnames_tlist),
344+
top_union,
345+
refnames_tlist),
336346
recurse_union_children(op->rarg,parse,
337-
top_union,refnames_tlist));
347+
top_union,
348+
refnames_tlist));
338349
}
339350
}
340351

@@ -380,6 +391,7 @@ generate_setop_tlist(List *colTypes, int flag,
380391
OidcolType= (Oid)lfirsti(i);
381392
TargetEntry*inputtle= (TargetEntry*)lfirst(input_tlist);
382393
TargetEntry*reftle= (TargetEntry*)lfirst(refnames_tlist);
394+
int32colTypmod;
383395

384396
Assert(inputtle->resdom->resno==resno);
385397
Assert(reftle->resdom->resno==resno);
@@ -399,11 +411,6 @@ generate_setop_tlist(List *colTypes, int flag,
399411
* subquery-scan plans; we don't want phony constants appearing in
400412
* the output tlists of upper-level nodes!
401413
*/
402-
resdom=makeResdom((AttrNumber)resno++,
403-
colType,
404-
-1,
405-
pstrdup(reftle->resdom->resname),
406-
false);
407414
if (hack_constants&&inputtle->expr&&IsA(inputtle->expr,Const))
408415
expr=inputtle->expr;
409416
else
@@ -412,10 +419,24 @@ generate_setop_tlist(List *colTypes, int flag,
412419
inputtle->resdom->restype,
413420
inputtle->resdom->restypmod,
414421
0);
415-
expr=coerce_to_common_type(NULL,
416-
expr,
417-
colType,
418-
"UNION/INTERSECT/EXCEPT");
422+
if (inputtle->resdom->restype==colType)
423+
{
424+
/* no coercion needed, and believe the input typmod */
425+
colTypmod=inputtle->resdom->restypmod;
426+
}
427+
else
428+
{
429+
expr=coerce_to_common_type(NULL,
430+
expr,
431+
colType,
432+
"UNION/INTERSECT/EXCEPT");
433+
colTypmod=-1;
434+
}
435+
resdom=makeResdom((AttrNumber)resno++,
436+
colType,
437+
colTypmod,
438+
pstrdup(reftle->resdom->resname),
439+
false);
419440
tlist=lappend(tlist,makeTargetEntry(resdom,expr));
420441
input_tlist=lnext(input_tlist);
421442
refnames_tlist=lnext(refnames_tlist);
@@ -455,6 +476,47 @@ generate_setop_tlist(List *colTypes, int flag,
455476
returntlist;
456477
}
457478

479+
/*
480+
* Merge typmods of a list of set-operation subplans.
481+
*
482+
* If the inputs all agree on type and typmod of a particular column,
483+
* use that typmod; else use -1. We assume the result tlist has been
484+
* initialized with the types and typmods of the first input subplan.
485+
*/
486+
staticvoid
487+
merge_tlist_typmods(List*tlist,List*planlist)
488+
{
489+
List*planl;
490+
491+
foreach(planl,planlist)
492+
{
493+
Plan*subplan= (Plan*)lfirst(planl);
494+
List*subtlist=subplan->targetlist;
495+
List*restlist;
496+
497+
foreach(restlist,tlist)
498+
{
499+
TargetEntry*restle= (TargetEntry*)lfirst(restlist);
500+
TargetEntry*subtle;
501+
502+
if (restle->resdom->resjunk)
503+
continue;
504+
Assert(subtlist!=NIL);
505+
subtle= (TargetEntry*)lfirst(subtlist);
506+
while (subtle->resdom->resjunk)
507+
{
508+
subtlist=lnext(subtlist);
509+
Assert(subtlist!=NIL);
510+
subtle= (TargetEntry*)lfirst(subtlist);
511+
}
512+
if (restle->resdom->restype!=subtle->resdom->restype||
513+
restle->resdom->restypmod!=subtle->resdom->restypmod)
514+
restle->resdom->restypmod=-1;
515+
subtlist=lnext(subtlist);
516+
}
517+
}
518+
}
519+
458520
/*
459521
* Does tlist have same datatypes as requested colTypes?
460522
*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp