PostgreSQL Source Code: src/backend/optimizer/util/appendinfo.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
16
29
30
31typedef struct
32{
37
44
45
46
47
48
49
52 Index parentRTindex, Index childRTindex)
53{
55
62
63 return appinfo;
64}
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79static void
83{
89 int oldnatts = old_tupdesc->natts;
90 int newnatts = new_tupdesc->natts;
91 int old_attno;
92 int new_attno = 0;
93
94
96 appinfo->parent_colnos = pcolnos =
98
99 for (old_attno = 0; old_attno < oldnatts; old_attno++)
100 {
103 Oid atttypid;
105 Oid attcollation;
106
108 if (att->attisdropped)
109 {
110
112 continue;
113 }
115 atttypid = att->atttypid;
116 atttypmod = att->atttypmod;
117 attcollation = att->attcollation;
118
119
120
121
122
123 if (oldrelation == newrelation)
124 {
127 atttypid,
128 atttypmod,
129 attcollation,
130 0));
131 pcolnos[old_attno] = old_attno + 1;
132 continue;
133 }
134
135
136
137
138
139
140
141
142
143
144 if (new_attno >= newnatts ||
145 (att = TupleDescAttr(new_tupdesc, new_attno))->attisdropped ||
147 {
149
152 elog(ERROR, "could not find inherited attribute \"%s\" of relation \"%s\"",
155 Assert(new_attno >= 0 && new_attno < newnatts);
157
159 }
160
161
162 if (atttypid != att->atttypid || atttypmod != att->atttypmod)
164 (errcode(ERRCODE_INVALID_COLUMN_DEFINITION),
165 errmsg("attribute \"%s\" of relation \"%s\" does not match parent's type",
167 if (attcollation != att->attcollation)
169 (errcode(ERRCODE_INVALID_COLUMN_DEFINITION),
170 errmsg("attribute \"%s\" of relation \"%s\" does not match parent's collation",
172
175 atttypid,
176 atttypmod,
177 attcollation,
178 0));
179 pcolnos[new_attno] = old_attno + 1;
180 new_attno++;
181 }
182
184}
185
186
187
188
189
190
191
192
193
194
195
196
197
198
202{
204
208
209
210 Assert(nappinfos >= 1 && appinfos != NULL);
211
212
214
216}
217
221{
223 int nappinfos = context->nappinfos;
224 int cnt;
225
226 if (node == NULL)
227 return NULL;
229 {
232
234 return (Node *) var;
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265 for (cnt = 0; cnt < nappinfos; cnt++)
266 {
268 {
269 appinfo = appinfos[cnt];
270 break;
271 }
272 }
273
274 if (appinfo)
275 {
277
278 var->varnosyn = 0;
279 var->varattnosyn = 0;
281 {
282 Node *newnode;
283
285 elog(ERROR, "attribute %d of relation \"%s\" does not exist",
289 if (newnode == NULL)
290 elog(ERROR, "attribute %d of relation \"%s\" does not exist",
293 {
295 ((Var *) newnode)->varnullingrels = var->varnullingrels;
296 }
297 else
298 {
300 elog(ERROR, "failed to apply returningtype to a non-Var");
301 if (var->varnullingrels != NULL)
302 elog(ERROR, "failed to apply nullingrels to a non-Var");
303 }
304 return newnode;
305 }
307 {
308
309
310
311
312
313
315 {
318 {
320
325
327 return (Node *) r;
328 }
329 }
330 else
331 {
332
333
334
335
336
337
338
339
340
341
342
344 List *fields;
346
351 rowexpr->args = fields;
352 rowexpr->row_typeid = var->vartype;
354 rowexpr->colnames = copyObject(rte->eref->colnames);
356
358 elog(ERROR, "failed to apply returningtype to a non-Var");
359 if (var->varnullingrels != NULL)
360 elog(ERROR, "failed to apply nullingrels to a non-Var");
361
362 return (Node *) rowexpr;
363 }
364 }
365
366 }
368 {
369
370
371
372
373
374
375
376
378 Index leaf_relid = 0;
379
380 for (cnt = 0; cnt < nappinfos; cnt++)
381 {
383 leaf_result_relids))
384 {
385 if (leaf_relid)
386 elog(ERROR, "cannot translate to multiple leaf relids");
388 }
389 }
390
391 if (leaf_relid)
392 {
395
397 {
398
400
401 var->varno = leaf_relid;
402
403 Assert(var->varnullingrels == NULL);
404
405 var->varnosyn = 0;
406 var->varattnosyn = 0;
407 }
408 else
409 {
410
411
412
413
415 var->vartypmod,
416 var->varcollid);
417 }
418 }
419 }
420 return (Node *) var;
421 }
423 {
425
426 for (cnt = 0; cnt < nappinfos; cnt++)
427 {
429
431 {
433 break;
434 }
435 }
436 return (Node *) cexpr;
437 }
439 {
440
442
445 context);
446
448 {
450 nappinfos, appinfos);
451
452 }
453 return (Node *) phv;
454 }
455
460
461
462
463
464
465
467 {
470
471
472 memcpy(newinfo, oldinfo, sizeof(RestrictInfo));
473
474
477
478
479 newinfo->orclause = (Expr *)
481
482
498
499
500
501
502
503
504
505 newinfo->eval_cost.startup = -1;
506 newinfo->norm_selec = -1;
507 newinfo->outer_selec = -1;
508 newinfo->left_em = NULL;
509 newinfo->right_em = NULL;
510 newinfo->scansel_cache = NIL;
511 newinfo->left_bucketsize = -1;
512 newinfo->right_bucketsize = -1;
513 newinfo->left_mcvfreq = -1;
514 newinfo->right_mcvfreq = -1;
515
516 return (Node *) newinfo;
517 }
518
519
520
521
523 {
526
529 context);
530
533 context);
534
536
539 context);
540
541 return (Node *) newinfo;
542 }
543
544
545
546
548 {
551
552
553 memcpy(newtarget, oldtarget, sizeof(PathTarget));
554
557 context);
558
559 if (oldtarget->sortgrouprefs)
560 {
562
563 newtarget->sortgrouprefs = (Index *) palloc(nbytes);
564 memcpy(newtarget->sortgrouprefs, oldtarget->sortgrouprefs, nbytes);
565 }
566
567 return (Node *) newtarget;
568 }
569
570
571
572
573
576
579
581}
582
583
584
585
586
587
588
589
590
595{
597 int nappinfos;
598
599
600 if (childrel->parent != parentrel)
601 {
602 if (childrel->parent)
604 childrel->parent,
605 parentrel);
606 else
607 elog(ERROR, "childrel is not a child of parentrel");
608 }
609
610
612
614
616
617 return node;
618}
619
620
621
622
623
626{
628 int cnt;
629
630 for (cnt = 0; cnt < nappinfos; cnt++)
631 {
633
634
636 {
637
638 if (!result)
640
643 }
644 }
645
646
647 if (result)
648 return result;
649
650
651 return relids;
652}
653
654
655
656
657
662{
664 int nappinfos;
665
666
667
668
669
671 return relids;
672
673
674 if (childrel->parent != parentrel)
675 {
676 if (childrel->parent)
678 childrel->parent,
679 parentrel);
680 else
681 elog(ERROR, "childrel is not a child of parentrel");
682 }
683
684
686
688
690
691 return relids;
692}
693
694
695
696
697
700{
703
704
706
707
708 foreach(lc, attnums)
709 {
711 Var *childvar;
712
713
714 if (parentattno <= 0 ||
716 elog(ERROR, "attribute %d of relation \"%s\" does not exist",
719 if (childvar == NULL || (childvar, Var))
720 elog(ERROR, "attribute %d of relation \"%s\" does not exist",
722
724 }
725 return result;
726}
727
728
729
730
731
734 Index child_relid, Index top_parent_relid)
735{
737
738 if (!appinfo)
739 elog(ERROR, "child rel %d not found in append_rel_array", child_relid);
740
741
742 if (appinfo->parent_relid != top_parent_relid)
745 top_parent_relid);
746
747
749}
750
751
752
753
754
755
756
757
758
759
760void
762 List **processed_tlist, List **update_colnos)
763{
764
766 if (relid == root->parse->resultRelation)
767 {
768
769
770
771
772 *processed_tlist = copyObject(root->processed_tlist);
773 if (update_colnos)
775 }
776 else
777 {
779 *processed_tlist = (List *)
781 (Node *) root->processed_tlist,
784 if (update_colnos)
785 *update_colnos =
787 relid,
788 root->parse->resultRelation);
789 }
790}
791
792
793
794
795
796
797
798
799
800
801
802
805{
807 int cnt = 0;
808 int i;
809
810
812
813 i = -1;
815 {
817
818 if (!appinfo)
819 {
820
822 continue;
823
824 elog(ERROR, "child rel %d not found in append_rel_array", i);
825 }
826
827 appinfos[cnt++] = appinfo;
828 }
829 *nappinfos = cnt;
830 return appinfos;
831}
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858void
860 Index rtindex, const char *rowid_name)
861{
863 Var *rowid_var;
866
867
871 Assert(orig_var->varnullingrels == NULL);
872
873
874
875
876
877
878 if (rtindex == root->parse->resultRelation)
879 {
883 true);
884 root->processed_tlist = lappend(root->processed_tlist, tle);
885 return;
886 }
887
888
889
890
891
893 Assert(root->append_rel_array[rtindex] != NULL);
894
895
896
897
898
899
901
903
904
905 foreach(lc, root->row_identity_vars)
906 {
908 if (strcmp(rowid_name, ridinfo->rowidname) != 0)
909 continue;
911 {
912
914 return;
915 }
916 else
917 {
918
919 elog(ERROR, "conflicting uses of row-identity name \"%s\"",
920 rowid_name);
921 }
922 }
923
924
927
932
933 root->row_identity_vars = lappend(root->row_identity_vars, ridinfo);
934
935
937
938
942 true);
943 root->processed_tlist = lappend(root->processed_tlist, tle);
944}
945
946
947
948
949
950
951
952
953void
957{
958 CmdType commandType = root->parse->commandType;
959 char relkind = target_relation->rd_rel->relkind;
960 Var *var;
961
963
964 if (relkind == RELKIND_RELATION ||
965 relkind == RELKIND_MATVIEW ||
966 relkind == RELKIND_PARTITIONED_TABLE)
967 {
968
969
970
971
974 TIDOID,
975 -1,
977 0);
979 }
980 else if (relkind == RELKIND_FOREIGN_TABLE)
981 {
982
983
984
986
988
991 target_rte, target_relation);
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1007 (target_relation->trigdesc &&
1010 {
1013 RECORDOID,
1014 -1,
1016 0);
1018 }
1019 }
1020}
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034void
1036{
1038 int result_relation = parse->resultRelation;
1042
1043
1044
1045
1048 {
1050 return;
1051 }
1052 target_rte = rt_fetch(result_relation, parse->rtable);
1053 if (!target_rte->inh)
1054 {
1056 return;
1057 }
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072 if (root->row_identity_vars == NIL)
1073 {
1075
1078 target_rte, target_relation);
1081
1082 return;
1083 }
1084
1085
1086
1087
1088
1089
1090
1091
1093
1094 foreach(lc, root->processed_tlist)
1095 {
1098
1100 {
1103
1104 }
1105 }
1106}
void distribute_row_identity_vars(PlannerInfo *root)
void get_translated_update_targetlist(PlannerInfo *root, Index relid, List **processed_tlist, List **update_colnos)
AppendRelInfo ** find_appinfos_by_relids(PlannerInfo *root, Relids relids, int *nappinfos)
static void make_inh_translation_list(Relation oldrelation, Relation newrelation, Index newvarno, AppendRelInfo *appinfo)
Node * adjust_appendrel_attrs(PlannerInfo *root, Node *node, int nappinfos, AppendRelInfo **appinfos)
Relids adjust_child_relids_multilevel(PlannerInfo *root, Relids relids, RelOptInfo *childrel, RelOptInfo *parentrel)
List * adjust_inherited_attnums_multilevel(PlannerInfo *root, List *attnums, Index child_relid, Index top_parent_relid)
Node * adjust_appendrel_attrs_multilevel(PlannerInfo *root, Node *node, RelOptInfo *childrel, RelOptInfo *parentrel)
void add_row_identity_columns(PlannerInfo *root, Index rtindex, RangeTblEntry *target_rte, Relation target_relation)
static Node * adjust_appendrel_attrs_mutator(Node *node, adjust_appendrel_attrs_context *context)
AppendRelInfo * make_append_rel_info(Relation parentrel, Relation childrel, Index parentRTindex, Index childRTindex)
Relids adjust_child_relids(Relids relids, int nappinfos, AppendRelInfo **appinfos)
void add_row_identity_var(PlannerInfo *root, Var *orig_var, Index rtindex, const char *rowid_name)
List * adjust_inherited_attnums(List *attnums, AppendRelInfo *context)
#define InvalidAttrNumber
Bitmapset * bms_make_singleton(int x)
int bms_next_member(const Bitmapset *a, int prevbit)
Bitmapset * bms_del_member(Bitmapset *a, int x)
int bms_num_members(const Bitmapset *a)
bool bms_is_member(int x, const Bitmapset *a)
Bitmapset * bms_add_member(Bitmapset *a, int x)
bool bms_overlap(const Bitmapset *a, const Bitmapset *b)
Bitmapset * bms_copy(const Bitmapset *a)
#define OidIsValid(objectId)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
bool equal(const void *a, const void *b)
#define palloc_array(type, count)
FdwRoutine * GetFdwRoutineForRelation(Relation relation, bool makecopy)
Assert(PointerIsAligned(start, uint64))
#define HeapTupleIsValid(tuple)
static void * GETSTRUCT(const HeapTupleData *tuple)
void build_base_rel_tlists(PlannerInfo *root, List *final_tlist)
if(TABLE==NULL||TABLE_index==NULL)
List * lappend(List *list, void *datum)
List * lappend_int(List *list, int datum)
char * get_rel_name(Oid relid)
int32 get_typavgwidth(Oid typid, int32 typmod)
Var * makeVar(int varno, AttrNumber varattno, Oid vartype, int32 vartypmod, Oid varcollid, Index varlevelsup)
Const * makeNullConst(Oid consttype, int32 consttypmod, Oid constcollid)
TargetEntry * makeTargetEntry(Expr *expr, AttrNumber resno, char *resname, bool resjunk)
char * pstrdup(const char *in)
void pfree(void *pointer)
void * palloc0(Size size)
Oid exprType(const Node *expr)
int32 exprTypmod(const Node *expr)
#define expression_tree_mutator(n, m, c)
#define IsA(nodeptr, _type_)
#define rt_fetch(rangetable_index, rangetable)
FormData_pg_attribute * Form_pg_attribute
static int list_length(const List *l)
static void * list_nth(const List *list, int n)
static struct subre * parse(struct vars *v, int stopper, int type, struct state *init, struct state *final)
#define RelationGetRelid(relation)
#define RelationGetDescr(relation)
#define RelationGetRelationName(relation)
RelOptInfo * find_base_rel(PlannerInfo *root, int relid)
RelOptInfo * find_base_rel_ignore_join(PlannerInfo *root, int relid)
AddForeignUpdateTargets_function AddForeignUpdateTargets
Relids leaf_result_relids
struct PathTarget * agg_input
struct PathTarget * target
struct PathTarget * reltarget
bool trig_delete_before_row
bool trig_delete_after_row
VarReturningType varreturningtype
AppendRelInfo ** appinfos
#define SelfItemPointerAttributeNumber
void ReleaseSysCache(HeapTuple tuple)
HeapTuple SearchSysCacheAttName(Oid relid, const char *attname)
void table_close(Relation relation, LOCKMODE lockmode)
Relation table_open(Oid relationId, LOCKMODE lockmode)
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)