|
25 | 25 | static HTAB *fextra_ht = NULL; |
26 | 26 | static MemoryContext fextra_mcxt = NULL; |
27 | 27 |
|
28 | | -static void |
29 | | -init_fextra_stmt(plch_fextra *fextra, |
30 | | - int parentid, int *naturalid, int level, int cur_deep, |
31 | | - PLpgSQL_stmt *stmt); |
32 | | - |
33 | | -/* |
34 | | - * Iterate over all plpgsql statements in the list |
35 | | - */ |
36 | | -static void |
37 | | -init_fextra_stmts(plch_fextra *fextra, |
38 | | - int parentid, int *naturalid, int level, int cur_deep, |
39 | | - List *stmts) |
| 28 | +typedef struct |
40 | 29 | { |
41 | | - ListCell *lc; |
42 | | - |
43 | | - foreach(lc, stmts) |
44 | | - { |
45 | | - init_fextra_stmt(fextra, |
46 | | - parentid, naturalid, level, cur_deep, |
47 | | - (PLpgSQL_stmt *) lfirst(lc)); |
48 | | - } |
49 | | -} |
| 30 | + plch_fextra *fextra; |
| 31 | + int parentid; |
| 32 | + int *naturalid; |
| 33 | + int current_deep; /* starts from zero */ |
| 34 | +} fextra_init_context; |
50 | 35 |
|
51 | | -/* |
52 | | - * Iterate over statements tree, and set fextra fields |
53 | | - */ |
54 | 36 | static void |
55 | | -init_fextra_stmt(plch_fextra *fextra, |
56 | | - int parentid, int *naturalid, int level, int cur_deep, |
57 | | - PLpgSQL_stmt *stmt) |
| 37 | +init_fextra_stmt_walker(PLpgSQL_stmt *stmt, fextra_init_context *context) |
58 | 38 | { |
| 39 | + fextra_init_context loccontext; |
| 40 | + plch_fextra *fextra = context->fextra; |
59 | 41 | int stmtid = stmt->stmtid; |
60 | 42 |
|
61 | 43 | /* |
62 | 44 | * statement ids are starts by one. For simplicity don't |
63 | 45 | * change base to zero. |
64 | 46 | */ |
65 | | - fextra->parentids[stmtid] = parentid; |
66 | | - fextra->naturalids[stmtid] = ++(*naturalid); |
67 | | - fextra->levels[stmtid] = level++; |
| 47 | + fextra->parentids[stmtid] = context->parentid; |
| 48 | + fextra->naturalids[stmtid] = ++(*context->naturalid); |
| 49 | + fextra->levels[stmtid] = context->current_deep + 1; |
68 | 50 |
|
69 | 51 | fextra->natural_to_ids[fextra->naturalids[stmtid] - 1] = stmtid; |
70 | 52 |
|
71 | | - if (cur_deep > fextra->max_deep) |
72 | | - fextra->max_deep = cur_deep; |
| 53 | + if (context->current_deep > fextra->max_deep) |
| 54 | + fextra->max_deep = context->current_deep; |
73 | 55 |
|
74 | | - cur_deep++; |
| 56 | + loccontext.fextra = fextra; |
| 57 | + loccontext.parentid = stmtid; |
| 58 | + loccontext.naturalid = context->naturalid; |
| 59 | + loccontext.current_deep = context->current_deep + 1; |
75 | 60 |
|
76 | | - switch (stmt->cmd_type) |
77 | | - { |
78 | | - case PLPGSQL_STMT_BLOCK: |
79 | | - { |
80 | | - PLpgSQL_stmt_block *s = (PLpgSQL_stmt_block *) stmt; |
81 | | - |
82 | | - init_fextra_stmts(fextra, stmtid, naturalid, level, cur_deep, |
83 | | - s->body); |
84 | | - |
85 | | - if (s->exceptions) |
86 | | - { |
87 | | - ListCell *lc; |
88 | | - |
89 | | - foreach(lc, s->exceptions->exc_list) |
90 | | - { |
91 | | - init_fextra_stmts(fextra, stmtid, naturalid, level, cur_deep, |
92 | | - ((PLpgSQL_exception *) lfirst(lc))->action); |
93 | | - } |
94 | | - } |
95 | | - } |
96 | | - break; |
97 | | - |
98 | | - case PLPGSQL_STMT_IF: |
99 | | - { |
100 | | - PLpgSQL_stmt_if *s = (PLpgSQL_stmt_if *) stmt; |
101 | | - ListCell *lc; |
102 | | - |
103 | | - init_fextra_stmts(fextra, stmtid, naturalid, level, cur_deep, |
104 | | - s->then_body); |
105 | | - |
106 | | - foreach(lc, s->elsif_list) |
107 | | - { |
108 | | - init_fextra_stmts(fextra, stmtid, naturalid, level, cur_deep, |
109 | | - ((PLpgSQL_if_elsif *) lfirst(lc))->stmts); |
110 | | - } |
111 | | - |
112 | | - init_fextra_stmts(fextra, stmtid, naturalid, level, cur_deep, |
113 | | - s->else_body); |
114 | | - } |
115 | | - break; |
116 | | - |
117 | | - case PLPGSQL_STMT_CASE: |
118 | | - { |
119 | | - PLpgSQL_stmt_case *s = (PLpgSQL_stmt_case *) stmt; |
120 | | - ListCell *lc; |
121 | | - |
122 | | - foreach(lc, s->case_when_list) |
123 | | - { |
124 | | - init_fextra_stmts(fextra, stmtid, naturalid, level, cur_deep, |
125 | | - ((PLpgSQL_case_when *) lfirst(lc))->stmts); |
126 | | - } |
127 | | - |
128 | | - init_fextra_stmts(fextra, stmtid, naturalid, level, cur_deep, |
129 | | - s->else_stmts); |
130 | | - } |
131 | | - break; |
132 | | - |
133 | | - case PLPGSQL_STMT_LOOP: |
134 | | - init_fextra_stmts(fextra, stmtid, naturalid, level, cur_deep, |
135 | | - ((PLpgSQL_stmt_loop *) stmt)->body); |
136 | | - break; |
137 | | - |
138 | | - case PLPGSQL_STMT_FORI: |
139 | | - init_fextra_stmts(fextra, stmtid, naturalid, level, cur_deep, |
140 | | - ((PLpgSQL_stmt_fori *) stmt)->body); |
141 | | - break; |
142 | | - |
143 | | - case PLPGSQL_STMT_FORS: |
144 | | - init_fextra_stmts(fextra, stmtid, naturalid, level, cur_deep, |
145 | | - ((PLpgSQL_stmt_fors *) stmt)->body); |
146 | | - break; |
147 | | - |
148 | | - case PLPGSQL_STMT_FORC: |
149 | | - init_fextra_stmts(fextra, stmtid, naturalid, level, cur_deep, |
150 | | - ((PLpgSQL_stmt_forc *) stmt)->body); |
151 | | - break; |
152 | | - |
153 | | - case PLPGSQL_STMT_DYNFORS: |
154 | | - init_fextra_stmts(fextra, stmtid, naturalid, level, cur_deep, |
155 | | - ((PLpgSQL_stmt_dynfors *) stmt)->body); |
156 | | - break; |
157 | | - |
158 | | - case PLPGSQL_STMT_FOREACH_A: |
159 | | - init_fextra_stmts(fextra, stmtid, naturalid, level, cur_deep, |
160 | | - ((PLpgSQL_stmt_foreach_a *) stmt)->body); |
161 | | - break; |
162 | | - |
163 | | - case PLPGSQL_STMT_WHILE: |
164 | | - init_fextra_stmts(fextra, stmtid, naturalid, level, cur_deep, |
165 | | - ((PLpgSQL_stmt_while *) stmt)->body); |
166 | | - break; |
167 | | - |
168 | | - default: |
169 | | - /* all container statements are handled up */ |
170 | | - break; |
171 | | - } |
| 61 | + plch_statement_tree_walker(stmt, init_fextra_stmt_walker, NULL, &loccontext); |
172 | 62 | } |
173 | 63 |
|
174 | 64 | static void |
@@ -322,6 +212,7 @@ plch_get_fextra(PLpgSQL_function *func) |
322 | 212 | char *fn_name = NULL; |
323 | 213 | char *fn_namespacename = NULL; |
324 | 214 | int naturalid = 0; |
| 215 | + fextra_init_context context; |
325 | 216 |
|
326 | 217 | if (func->fn_oid) |
327 | 218 | { |
@@ -349,7 +240,13 @@ plch_get_fextra(PLpgSQL_function *func) |
349 | 240 | MemoryContextSwitchTo(oldcxt); |
350 | 241 |
|
351 | 242 | fextra->max_deep = 0; |
352 | | - init_fextra_stmt(fextra, 0, &naturalid, 1, 0, (PLpgSQL_stmt *) func->action); |
| 243 | + |
| 244 | + context.fextra = fextra; |
| 245 | + context.parentid = 0; |
| 246 | + context.current_deep = 0; |
| 247 | + context.naturalid = &naturalid; |
| 248 | + |
| 249 | + init_fextra_stmt_walker((PLpgSQL_stmt *) func->action, &context); |
353 | 250 |
|
354 | 251 | fextra->func = func; |
355 | 252 |
|
|
0 commit comments