|
14 | 14 |
|
15 | 15 | #include "access/sysattr.h" |
16 | 16 | #include "catalog/pg_type.h" |
17 | | -#include "nodes/relation.h" |
18 | 17 | #include "nodes/nodeFuncs.h" |
| 18 | +#include "optimizer/planmain.h" |
19 | 19 | #include "utils/builtins.h" |
20 | 20 | #include "utils/rel.h" |
21 | 21 |
|
22 | 22 |
|
23 | 23 | #ifndef NATIVE_PARTITIONING_ROWMARKS |
24 | 24 |
|
25 | | -/* Special column name for rowmarks */ |
26 | | -#define TABLEOID_STR(subst) ( "pathman_tableoid" subst ) |
27 | | -#define TABLEOID_STR_BASE_LEN ( sizeof(TABLEOID_STR("")) - 1 ) |
28 | 25 |
|
29 | | - |
30 | | -static void lock_rows_visitor(Plan *plan, void *context); |
31 | | -static List *get_tableoids_list(List *tlist); |
32 | | - |
33 | | - |
34 | | -/* Final rowmark processing for partitioned tables */ |
35 | 26 | void |
36 | | -postprocess_lock_rows(List *rtable, Plan *plan) |
37 | | -{ |
38 | | - plan_tree_walker(plan, lock_rows_visitor, rtable); |
39 | | -} |
40 | | - |
41 | | -/* |
42 | | - * Add missing 'TABLEOID_STR%u' junk attributes for inherited partitions |
43 | | - * |
44 | | - * This is necessary since preprocess_targetlist() heavily |
45 | | - * depends on the 'inh' flag which we have to unset. |
46 | | - * |
47 | | - * postprocess_lock_rows() will later transform 'TABLEOID_STR:Oid' |
48 | | - * relnames into 'tableoid:rowmarkId'. |
49 | | - */ |
50 | | -void |
51 | | -rowmark_add_tableoids(Query *parse) |
52 | | -{ |
53 | | - ListCell *lc; |
54 | | - |
55 | | - /* Generate 'tableoid' for partitioned table rowmark */ |
56 | | - foreach (lc, parse->rowMarks) |
57 | | - { |
58 | | - RowMarkClause *rc = (RowMarkClause *) lfirst(lc); |
59 | | - Oid parent = getrelid(rc->rti, parse->rtable); |
60 | | - Var *var; |
61 | | - TargetEntry *tle; |
62 | | - char resname[64]; |
63 | | - |
64 | | - /* Check that table is partitioned */ |
65 | | - if (!get_pathman_relation_info(parent)) |
66 | | - continue; |
67 | | - |
68 | | - var = makeVar(rc->rti, |
69 | | - TableOidAttributeNumber, |
70 | | - OIDOID, |
71 | | - -1, |
72 | | - InvalidOid, |
73 | | - 0); |
74 | | - |
75 | | - /* Use parent's Oid as TABLEOID_STR's key (%u) */ |
76 | | - snprintf(resname, sizeof(resname), TABLEOID_STR("%u"), parent); |
77 | | - |
78 | | - tle = makeTargetEntry((Expr *) var, |
79 | | - list_length(parse->targetList) + 1, |
80 | | - pstrdup(resname), |
81 | | - true); |
82 | | - |
83 | | - /* There's no problem here since new attribute is junk */ |
84 | | - parse->targetList = lappend(parse->targetList, tle); |
85 | | - } |
86 | | -} |
87 | | - |
88 | | -/* |
89 | | - * Extract target entries with resnames beginning with TABLEOID_STR |
90 | | - * and var->varoattno == TableOidAttributeNumber |
91 | | - */ |
92 | | -static List * |
93 | | -get_tableoids_list(List *tlist) |
| 27 | +append_tle_for_rowmark(PlannerInfo *root, PlanRowMark *rc) |
94 | 28 | { |
95 | | - List *result = NIL; |
96 | | - ListCell *lc; |
97 | | - |
98 | | - foreach (lc, tlist) |
99 | | - { |
100 | | - TargetEntry *te = (TargetEntry *) lfirst(lc); |
101 | | - Var *var = (Var *) te->expr; |
102 | | - |
103 | | - if (!IsA(var, Var)) |
104 | | - continue; |
105 | | - |
106 | | - /* Check that column name begins with TABLEOID_STR & it's tableoid */ |
107 | | - if (var->varoattno == TableOidAttributeNumber && |
108 | | - (te->resname && strlen(te->resname) > TABLEOID_STR_BASE_LEN) && |
109 | | - 0 == strncmp(te->resname, TABLEOID_STR(""), TABLEOID_STR_BASE_LEN)) |
110 | | - { |
111 | | - result = lappend(result, te); |
112 | | - } |
113 | | - } |
114 | | - |
115 | | - return result; |
116 | | -} |
117 | | - |
118 | | -/* |
119 | | - * Find 'TABLEOID_STR%u' attributes that were manually |
120 | | - * created for partitioned tables and replace Oids |
121 | | - * (used for '%u') with expected rc->rowmarkIds |
122 | | - */ |
123 | | -static void |
124 | | -lock_rows_visitor(Plan *plan, void *context) |
125 | | -{ |
126 | | - List *rtable = (List *) context; |
127 | | - LockRows *lock_rows = (LockRows *) plan; |
128 | | - Plan *lock_child = outerPlan(plan); |
129 | | - List *tableoids; |
130 | | - ListCell *lc; |
131 | | - |
132 | | - if (!IsA(lock_rows, LockRows)) |
133 | | - return; |
134 | | - |
135 | | - Assert(rtable && IsA(rtable, List) && lock_child); |
136 | | - |
137 | | - /* Select tableoid attributes that must be renamed */ |
138 | | - tableoids = get_tableoids_list(lock_child->targetlist); |
139 | | - if (!tableoids) |
140 | | - return; /* this LockRows has nothing to do with partitioned table */ |
141 | | - |
142 | | - foreach (lc, lock_rows->rowMarks) |
143 | | - { |
144 | | - PlanRowMark *rc = (PlanRowMark *) lfirst(lc); |
145 | | - Oid parent_oid = getrelid(rc->rti, rtable); |
146 | | - ListCell *mark_lc; |
147 | | - List *finished_tes = NIL; /* postprocessed target entries */ |
148 | | - |
149 | | - foreach (mark_lc, tableoids) |
150 | | - { |
151 | | - TargetEntry *te = (TargetEntry *) lfirst(mark_lc); |
152 | | - const char *cur_oid_str = &(te->resname[TABLEOID_STR_BASE_LEN]); |
153 | | - Datum cur_oid_datum; |
154 | | - |
155 | | - cur_oid_datum = DirectFunctionCall1(oidin, CStringGetDatum(cur_oid_str)); |
| 29 | + Var *var; |
| 30 | + char resname[32]; |
| 31 | + TargetEntry *tle; |
156 | 32 |
|
157 | | - if (DatumGetObjectId(cur_oid_datum) == parent_oid) |
158 | | - { |
159 | | - char resname[64]; |
| 33 | + var = makeVar(rc->rti, |
| 34 | + TableOidAttributeNumber, |
| 35 | + OIDOID, |
| 36 | + -1, |
| 37 | + InvalidOid, |
| 38 | + 0); |
160 | 39 |
|
161 | | - /* Replace 'TABLEOID_STR:Oid' with 'tableoid:rowmarkId' */ |
162 | | - snprintf(resname, sizeof(resname), "tableoid%u", rc->rowmarkId); |
163 | | - te->resname = pstrdup(resname); |
| 40 | + snprintf(resname, sizeof(resname), "tableoid%u", rc->rowmarkId); |
164 | 41 |
|
165 | | - finished_tes = lappend(finished_tes, te); |
166 | | - } |
167 | | - } |
| 42 | + tle = makeTargetEntry((Expr *) var, |
| 43 | + list_length(root->processed_tlist) + 1, |
| 44 | + pstrdup(resname), |
| 45 | + true); |
168 | 46 |
|
169 | | - /* Remove target entries that have been processed in this step */ |
170 | | - foreach (mark_lc, finished_tes) |
171 | | - tableoids = list_delete_ptr(tableoids, lfirst(mark_lc)); |
| 47 | + root->processed_tlist = lappend(root->processed_tlist, tle); |
172 | 48 |
|
173 | | - if (list_length(tableoids) == 0) |
174 | | - break; /* nothing to do */ |
175 | | - } |
| 49 | + add_vars_to_targetlist(root, list_make1(var), bms_make_singleton(0), true); |
176 | 50 | } |
177 | 51 |
|
178 | 52 | #endif /* NATIVE_PARTITIONING_ROWMARKS */ |
0 commit comments