|
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