Merge lp:~zorba-coders/zorba/no-copy into lp:zorba
- no-copy
- Merge into trunk
Proposed by
Markos Zaharioudakis
Status: | Merged |
---|---|
Approved by: | Markos Zaharioudakis |
Approved revision: | 11077 |
Merged at revision: | 11084 |
Proposed branch: | lp:~zorba-coders/zorba/no-copy |
Merge into: | lp:zorba |
Diff against target: |
633 lines (+411/-39) 8 files modified
src/compiler/expression/expr_base.cpp (+24/-0) src/compiler/expression/expr_base.h (+13/-4) src/compiler/rewriter/rules/nodeid_rules.cpp (+336/-26) src/compiler/rewriter/rules/ruleset.h (+3/-9) test/rbkt/ExpQueryResults/zorba/no-copy/test4.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/no-copy/test5.xml.res (+1/-0) test/rbkt/Queries/zorba/no-copy/test4.xq (+17/-0) test/rbkt/Queries/zorba/no-copy/test5.xq (+16/-0) |
To merge this branch: | bzr merge lp:~zorba-coders/zorba/no-copy |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Markos Zaharioudakis | Approve | ||
Review via email: mp+127604@code.launchpad.net |
Commit message
1. Put back markForSerializ
2. path expr is unsafe if it contains any KindTest with type check and the construction mode i strip
3. copying is unsafe only if ns_inherit and ns_preserve
Description of the change
1. Put back markForSerializ
2. path expr is unsafe if it contains any KindTest with type check and the construction mode i strip
3. copying is unsafe only if ns_inherit and ns_preserve
To post a comment you must log in.
lp:~zorba-coders/zorba/no-copy
updated
- 11077. By Markos Zaharioudakis
-
put back markForSerializ
ation() + path expr is unsafe if it contains any KindTest with type and the construction mode i strip + copying is unsafe only if ns_inherit and ns_preserve
Revision history for this message
Markos Zaharioudakis (markos-za) : | # |
review:
Approve
Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote : | # |
Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue job no-copy-
All tests succeeded!
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'src/compiler/expression/expr_base.cpp' | |||
2 | --- src/compiler/expression/expr_base.cpp 2012-10-02 11:57:15 +0000 | |||
3 | +++ src/compiler/expression/expr_base.cpp 2012-10-02 22:52:19 +0000 | |||
4 | @@ -541,6 +541,30 @@ | |||
5 | 541 | /******************************************************************************* | 541 | /******************************************************************************* |
6 | 542 | 542 | ||
7 | 543 | ********************************************************************************/ | 543 | ********************************************************************************/ |
8 | 544 | BoolAnnotationValue expr::getInUnsafeContext() const | ||
9 | 545 | { | ||
10 | 546 | return (BoolAnnotationValue) | ||
11 | 547 | ((theFlags1 & IN_UNSAFE_CONTEXT_MASK) >> IN_UNSAFE_CONTEXT); | ||
12 | 548 | } | ||
13 | 549 | |||
14 | 550 | |||
15 | 551 | void expr::setInUnsafeContext(BoolAnnotationValue v) | ||
16 | 552 | { | ||
17 | 553 | theFlags1 &= ~IN_UNSAFE_CONTEXT_MASK; | ||
18 | 554 | theFlags1 |= (v << IN_UNSAFE_CONTEXT); | ||
19 | 555 | } | ||
20 | 556 | |||
21 | 557 | |||
22 | 558 | bool expr::inUnsafeContext() const | ||
23 | 559 | { | ||
24 | 560 | BoolAnnotationValue v = getInUnsafeContext(); | ||
25 | 561 | return (v == ANNOTATION_TRUE || v == ANNOTATION_TRUE_FIXED); | ||
26 | 562 | } | ||
27 | 563 | |||
28 | 564 | |||
29 | 565 | /******************************************************************************* | ||
30 | 566 | |||
31 | 567 | ********************************************************************************/ | ||
32 | 544 | BoolAnnotationValue expr::getContainsPragma() const | 568 | BoolAnnotationValue expr::getContainsPragma() const |
33 | 545 | { | 569 | { |
34 | 546 | return (BoolAnnotationValue) | 570 | return (BoolAnnotationValue) |
35 | 547 | 571 | ||
36 | === modified file 'src/compiler/expression/expr_base.h' | |||
37 | --- src/compiler/expression/expr_base.h 2012-10-02 11:57:15 +0000 | |||
38 | +++ src/compiler/expression/expr_base.h 2012-10-02 22:52:19 +0000 | |||
39 | @@ -147,8 +147,9 @@ | |||
40 | 147 | UNFOLDABLE = 10, | 147 | UNFOLDABLE = 10, |
41 | 148 | CONTAINS_RECURSIVE_CALL = 12, | 148 | CONTAINS_RECURSIVE_CALL = 12, |
42 | 149 | PROPAGATES_INPUT_NODES = 14, | 149 | PROPAGATES_INPUT_NODES = 14, |
45 | 150 | MUST_COPY_NODES = 16, | 150 | IN_UNSAFE_CONTEXT = 16, |
46 | 151 | CONTAINS_PRAGMA = 18 | 151 | MUST_COPY_NODES = 18, |
47 | 152 | CONTAINS_PRAGMA = 20 | ||
48 | 152 | } Annotationkey; | 153 | } Annotationkey; |
49 | 153 | 154 | ||
50 | 154 | typedef enum | 155 | typedef enum |
51 | @@ -161,8 +162,9 @@ | |||
52 | 161 | UNFOLDABLE_MASK = 0xC00, | 162 | UNFOLDABLE_MASK = 0xC00, |
53 | 162 | CONTAINS_RECURSIVE_CALL_MASK = 0x3000, | 163 | CONTAINS_RECURSIVE_CALL_MASK = 0x3000, |
54 | 163 | PROPAGATES_INPUT_NODES_MASK = 0xC000, | 164 | PROPAGATES_INPUT_NODES_MASK = 0xC000, |
57 | 164 | MUST_COPY_NODES_MASK = 0x30000, | 165 | IN_UNSAFE_CONTEXT_MASK = 0x30000, |
58 | 165 | CONTAINS_PRAGMA_MASK = 0xC0000 | 166 | MUST_COPY_NODES_MASK = 0xC0000, |
59 | 167 | CONTAINS_PRAGMA_MASK = 0x300000 | ||
60 | 166 | } AnnotationMask; | 168 | } AnnotationMask; |
61 | 167 | 169 | ||
62 | 168 | 170 | ||
63 | @@ -313,6 +315,13 @@ | |||
64 | 313 | 315 | ||
65 | 314 | void setMustCopyNodes(BoolAnnotationValue v); | 316 | void setMustCopyNodes(BoolAnnotationValue v); |
66 | 315 | 317 | ||
67 | 318 | // Annotation : inUnsafeContext | ||
68 | 319 | BoolAnnotationValue getInUnsafeContext() const; | ||
69 | 320 | |||
70 | 321 | void setInUnsafeContext(BoolAnnotationValue v); | ||
71 | 322 | |||
72 | 323 | bool inUnsafeContext() const; | ||
73 | 324 | |||
74 | 316 | // Annotation : containsPragma | 325 | // Annotation : containsPragma |
75 | 317 | BoolAnnotationValue getContainsPragma() const; | 326 | BoolAnnotationValue getContainsPragma() const; |
76 | 318 | 327 | ||
77 | 319 | 328 | ||
78 | === modified file 'src/compiler/rewriter/rules/nodeid_rules.cpp' | |||
79 | --- src/compiler/rewriter/rules/nodeid_rules.cpp 2012-10-02 11:57:15 +0000 | |||
80 | +++ src/compiler/rewriter/rules/nodeid_rules.cpp 2012-10-02 22:52:19 +0000 | |||
81 | @@ -600,11 +600,11 @@ | |||
82 | 600 | // inherited from the referencing tree if N had been copied into that | 600 | // inherited from the referencing tree if N had been copied into that |
83 | 601 | // tree. (On the other hand it is ok if the query result contains nodes | 601 | // tree. (On the other hand it is ok if the query result contains nodes |
84 | 602 | // which are not shared but have shared descendants). To handle this, | 602 | // which are not shared but have shared descendants). To handle this, |
86 | 603 | // we set theIsInUnsafeContext so that any exprs that (a) extract nodes | 603 | // we call markInUnsafeContext() so that any exprs that (a) extract nodes |
87 | 604 | // out of input nodes and (b) may propagate the extracted nodes to the | 604 | // out of input nodes and (b) may propagate the extracted nodes to the |
88 | 605 | // query result will be considered as unsafe and thus require that | 605 | // query result will be considered as unsafe and thus require that |
89 | 606 | // their input trees are standalone. | 606 | // their input trees are standalone. |
91 | 607 | theIsInUnsafeContext = true; | 607 | markInUnsafeContext(node); |
92 | 608 | } | 608 | } |
93 | 609 | } | 609 | } |
94 | 610 | else | 610 | else |
95 | @@ -652,25 +652,11 @@ | |||
96 | 652 | expr* node, | 652 | expr* node, |
97 | 653 | UDFCallChain& udfCaller) | 653 | UDFCallChain& udfCaller) |
98 | 654 | { | 654 | { |
99 | 655 | TypeManager* tm = node->get_type_manager(); | ||
100 | 656 | RootTypeManager& rtm = GENV_TYPESYSTEM; | ||
101 | 657 | |||
102 | 658 | bool savedIsInUnsafeContext = theIsInUnsafeContext; | ||
103 | 659 | |||
104 | 660 | if (theIsInUnsafeContext) | ||
105 | 661 | { | ||
106 | 662 | xqtref_t retType = node->get_return_type(); | ||
107 | 663 | |||
108 | 664 | if (TypeOps::is_subtype(tm, *retType, *rtm.ANY_ATOMIC_TYPE_STAR)) | ||
109 | 665 | theIsInUnsafeContext = false; | ||
110 | 666 | } | ||
111 | 667 | |||
112 | 668 | switch (node->get_expr_kind()) | 655 | switch (node->get_expr_kind()) |
113 | 669 | { | 656 | { |
114 | 670 | case const_expr_kind: | 657 | case const_expr_kind: |
115 | 671 | case var_expr_kind: | 658 | case var_expr_kind: |
116 | 672 | { | 659 | { |
117 | 673 | theIsInUnsafeContext = savedIsInUnsafeContext; | ||
118 | 674 | return; | 660 | return; |
119 | 675 | } | 661 | } |
120 | 676 | 662 | ||
121 | @@ -692,7 +678,8 @@ | |||
122 | 692 | 678 | ||
123 | 693 | static_context* sctx = e->get_sctx(); | 679 | static_context* sctx = e->get_sctx(); |
124 | 694 | 680 | ||
126 | 695 | if (sctx->preserve_mode() != StaticContextConsts::no_preserve_ns) | 681 | if (sctx->preserve_mode() == StaticContextConsts::preserve_ns && |
127 | 682 | sctx->inherit_mode() == StaticContextConsts::inherit_ns) | ||
128 | 696 | { | 683 | { |
129 | 697 | csize numPairs = e->num_pairs(); | 684 | csize numPairs = e->num_pairs(); |
130 | 698 | for (csize i = 0; i < numPairs; ++i) | 685 | for (csize i = 0; i < numPairs; ++i) |
131 | @@ -717,7 +704,8 @@ | |||
132 | 717 | 704 | ||
133 | 718 | static_context* sctx = e->get_sctx(); | 705 | static_context* sctx = e->get_sctx(); |
134 | 719 | 706 | ||
136 | 720 | if (sctx->preserve_mode() != StaticContextConsts::no_preserve_ns) | 707 | if (sctx->preserve_mode() == StaticContextConsts::preserve_ns && |
137 | 708 | sctx->inherit_mode() == StaticContextConsts::inherit_ns) | ||
138 | 721 | { | 709 | { |
139 | 722 | std::vector<expr*> sources; | 710 | std::vector<expr*> sources; |
140 | 723 | theSourceFinder->findNodeSources(e->get_expr(), &udfCaller, sources); | 711 | theSourceFinder->findNodeSources(e->get_expr(), &udfCaller, sources); |
141 | @@ -732,7 +720,7 @@ | |||
142 | 732 | { | 720 | { |
143 | 733 | relpath_expr* e = static_cast<relpath_expr *>(node); | 721 | relpath_expr* e = static_cast<relpath_expr *>(node); |
144 | 734 | 722 | ||
146 | 735 | if (theIsInUnsafeContext) | 723 | if (e->inUnsafeContext()) |
147 | 736 | { | 724 | { |
148 | 737 | std::vector<expr*> sources; | 725 | std::vector<expr*> sources; |
149 | 738 | theSourceFinder->findNodeSources((*e)[0], &udfCaller, sources); | 726 | theSourceFinder->findNodeSources((*e)[0], &udfCaller, sources); |
150 | @@ -750,6 +738,7 @@ | |||
151 | 750 | 738 | ||
152 | 751 | if (axisKind != axis_kind_child && | 739 | if (axisKind != axis_kind_child && |
153 | 752 | axisKind != axis_kind_descendant && | 740 | axisKind != axis_kind_descendant && |
154 | 741 | axisKind != axis_kind_descendant_or_self && | ||
155 | 753 | axisKind != axis_kind_self && | 742 | axisKind != axis_kind_self && |
156 | 754 | axisKind != axis_kind_attribute) | 743 | axisKind != axis_kind_attribute) |
157 | 755 | { | 744 | { |
158 | @@ -758,12 +747,24 @@ | |||
159 | 758 | markSources(sources); | 747 | markSources(sources); |
160 | 759 | break; | 748 | break; |
161 | 760 | } | 749 | } |
162 | 750 | else | ||
163 | 751 | { | ||
164 | 752 | match_expr* matchExpr = axisExpr->getTest(); | ||
165 | 753 | |||
166 | 754 | if (matchExpr->getTypeName() != NULL && | ||
167 | 755 | node->get_sctx()->construction_mode() == StaticContextConsts::cons_strip) | ||
168 | 756 | { | ||
169 | 757 | std::vector<expr*> sources; | ||
170 | 758 | theSourceFinder->findNodeSources((*e)[0], &udfCaller, sources); | ||
171 | 759 | markSources(sources); | ||
172 | 760 | break; | ||
173 | 761 | } | ||
174 | 762 | } | ||
175 | 761 | } | 763 | } |
176 | 762 | } | 764 | } |
177 | 763 | 765 | ||
178 | 764 | applyInternal(rCtx, (*e)[0], udfCaller); | 766 | applyInternal(rCtx, (*e)[0], udfCaller); |
179 | 765 | 767 | ||
180 | 766 | theIsInUnsafeContext = savedIsInUnsafeContext; | ||
181 | 767 | return; | 768 | return; |
182 | 768 | } | 769 | } |
183 | 769 | 770 | ||
184 | @@ -846,7 +847,9 @@ | |||
185 | 846 | { | 847 | { |
186 | 847 | if (node->get_sctx()->construction_mode() == StaticContextConsts::cons_strip) | 848 | if (node->get_sctx()->construction_mode() == StaticContextConsts::cons_strip) |
187 | 848 | { | 849 | { |
189 | 849 | theIsInUnsafeContext = true; | 850 | cast_or_castable_base_expr* e = static_cast<cast_or_castable_base_expr*>(node); |
190 | 851 | |||
191 | 852 | markInUnsafeContext(e->get_input()); | ||
192 | 850 | } | 853 | } |
193 | 851 | 854 | ||
194 | 852 | break; | 855 | break; |
195 | @@ -895,7 +898,8 @@ | |||
196 | 895 | 898 | ||
197 | 896 | static_context* sctx = e->get_sctx(); | 899 | static_context* sctx = e->get_sctx(); |
198 | 897 | 900 | ||
200 | 898 | if (sctx->preserve_mode() != StaticContextConsts::no_preserve_ns) | 901 | if (sctx->preserve_mode() == StaticContextConsts::preserve_ns && |
201 | 902 | sctx->inherit_mode() == StaticContextConsts::inherit_ns) | ||
202 | 899 | { | 903 | { |
203 | 900 | std::vector<copy_clause*>::const_iterator ite = e->begin(); | 904 | std::vector<copy_clause*>::const_iterator ite = e->begin(); |
204 | 901 | std::vector<copy_clause*>::const_iterator end = e->end(); | 905 | std::vector<copy_clause*>::const_iterator end = e->end(); |
205 | @@ -1028,7 +1032,6 @@ | |||
206 | 1028 | 1032 | ||
207 | 1029 | applyInternal(rCtx, udf->getBody(), dummyUdfCaller); | 1033 | applyInternal(rCtx, udf->getBody(), dummyUdfCaller); |
208 | 1030 | 1034 | ||
209 | 1031 | theIsInUnsafeContext = savedIsInUnsafeContext; | ||
210 | 1032 | return; | 1035 | return; |
211 | 1033 | } | 1036 | } |
212 | 1034 | 1037 | ||
213 | @@ -1049,9 +1052,6 @@ | |||
214 | 1049 | iter.next(); | 1052 | iter.next(); |
215 | 1050 | } | 1053 | } |
216 | 1051 | 1054 | ||
217 | 1052 | |||
218 | 1053 | theIsInUnsafeContext = savedIsInUnsafeContext; | ||
219 | 1054 | |||
220 | 1055 | return; | 1055 | return; |
221 | 1056 | } | 1056 | } |
222 | 1057 | 1057 | ||
223 | @@ -1090,5 +1090,315 @@ | |||
224 | 1090 | } | 1090 | } |
225 | 1091 | 1091 | ||
226 | 1092 | 1092 | ||
227 | 1093 | /******************************************************************************* | ||
228 | 1094 | This method is called when an expr E1 satisfies a condition that may make a | ||
229 | 1095 | sub-expr E2 of E1 be unsafe, even though E2 by itself is safe. | ||
230 | 1096 | |||
231 | 1097 | This method marks as being in "unsafe context" any expr that may produce | ||
232 | 1098 | nodes which may be propagated into the result of E1. | ||
233 | 1099 | ********************************************************************************/ | ||
234 | 1100 | void MarkNodeCopyProps::markInUnsafeContext(expr* node) | ||
235 | 1101 | { | ||
236 | 1102 | TypeManager* tm = node->get_type_manager(); | ||
237 | 1103 | RootTypeManager& rtm = GENV_TYPESYSTEM; | ||
238 | 1104 | |||
239 | 1105 | xqtref_t retType = node->get_return_type(); | ||
240 | 1106 | |||
241 | 1107 | if (TypeOps::is_subtype(tm, *retType, *rtm.ANY_ATOMIC_TYPE_STAR)) | ||
242 | 1108 | return; | ||
243 | 1109 | |||
244 | 1110 | switch (node->get_expr_kind()) | ||
245 | 1111 | { | ||
246 | 1112 | case const_expr_kind: | ||
247 | 1113 | { | ||
248 | 1114 | return; | ||
249 | 1115 | } | ||
250 | 1116 | case var_expr_kind: | ||
251 | 1117 | { | ||
252 | 1118 | var_expr* e = static_cast<var_expr*>(node); | ||
253 | 1119 | |||
254 | 1120 | switch (e->get_kind()) | ||
255 | 1121 | { | ||
256 | 1122 | case var_expr::for_var: | ||
257 | 1123 | case var_expr::let_var: | ||
258 | 1124 | case var_expr::win_var: | ||
259 | 1125 | case var_expr::wincond_out_var: | ||
260 | 1126 | case var_expr::wincond_in_var: | ||
261 | 1127 | case var_expr::non_groupby_var: | ||
262 | 1128 | { | ||
263 | 1129 | if (!e->inUnsafeContext()) | ||
264 | 1130 | { | ||
265 | 1131 | e->setInUnsafeContext(ANNOTATION_TRUE); | ||
266 | 1132 | markInUnsafeContext(e->get_domain_expr()); | ||
267 | 1133 | } | ||
268 | 1134 | return; | ||
269 | 1135 | } | ||
270 | 1136 | |||
271 | 1137 | case var_expr::copy_var: | ||
272 | 1138 | case var_expr::catch_var: | ||
273 | 1139 | { | ||
274 | 1140 | e->setInUnsafeContext(ANNOTATION_TRUE); | ||
275 | 1141 | return; | ||
276 | 1142 | } | ||
277 | 1143 | |||
278 | 1144 | case var_expr::arg_var: | ||
279 | 1145 | { | ||
280 | 1146 | e->setInUnsafeContext(ANNOTATION_TRUE); | ||
281 | 1147 | return; | ||
282 | 1148 | } | ||
283 | 1149 | |||
284 | 1150 | case var_expr::prolog_var: | ||
285 | 1151 | case var_expr::local_var: | ||
286 | 1152 | { | ||
287 | 1153 | if (!e->inUnsafeContext()) | ||
288 | 1154 | { | ||
289 | 1155 | e->setInUnsafeContext(ANNOTATION_TRUE); | ||
290 | 1156 | |||
291 | 1157 | std::vector<expr*>::const_iterator ite = e->setExprsBegin(); | ||
292 | 1158 | std::vector<expr*>::const_iterator end = e->setExprsEnd(); | ||
293 | 1159 | |||
294 | 1160 | for (; ite != end; ++ite) | ||
295 | 1161 | { | ||
296 | 1162 | expr* setExpr = *ite; | ||
297 | 1163 | |||
298 | 1164 | if (setExpr->get_expr_kind() == var_decl_expr_kind) | ||
299 | 1165 | { | ||
300 | 1166 | markInUnsafeContext(static_cast<var_decl_expr*>(setExpr)->get_init_expr()); | ||
301 | 1167 | } | ||
302 | 1168 | else | ||
303 | 1169 | { | ||
304 | 1170 | assert(setExpr->get_expr_kind() == var_set_expr_kind); | ||
305 | 1171 | |||
306 | 1172 | markInUnsafeContext(static_cast<var_set_expr*>(setExpr)->get_expr()); | ||
307 | 1173 | } | ||
308 | 1174 | } | ||
309 | 1175 | } | ||
310 | 1176 | return; | ||
311 | 1177 | } | ||
312 | 1178 | |||
313 | 1179 | case var_expr::groupby_var: | ||
314 | 1180 | case var_expr::wincond_in_pos_var: | ||
315 | 1181 | case var_expr::wincond_out_pos_var: | ||
316 | 1182 | case var_expr::pos_var: | ||
317 | 1183 | case var_expr::score_var: | ||
318 | 1184 | case var_expr::count_var: | ||
319 | 1185 | default: | ||
320 | 1186 | { | ||
321 | 1187 | ZORBA_ASSERT(false); | ||
322 | 1188 | return; | ||
323 | 1189 | } | ||
324 | 1190 | } | ||
325 | 1191 | } | ||
326 | 1192 | |||
327 | 1193 | case doc_expr_kind: | ||
328 | 1194 | case elem_expr_kind: | ||
329 | 1195 | case attr_expr_kind: | ||
330 | 1196 | case text_expr_kind: | ||
331 | 1197 | case pi_expr_kind: | ||
332 | 1198 | { | ||
333 | 1199 | break; | ||
334 | 1200 | } | ||
335 | 1201 | |||
336 | 1202 | #ifdef ZORBA_WITH_JSON | ||
337 | 1203 | case json_object_expr_kind: | ||
338 | 1204 | case json_direct_object_expr_kind: | ||
339 | 1205 | case json_array_expr_kind: | ||
340 | 1206 | { | ||
341 | 1207 | break; | ||
342 | 1208 | } | ||
343 | 1209 | #endif | ||
344 | 1210 | |||
345 | 1211 | case relpath_expr_kind: | ||
346 | 1212 | { | ||
347 | 1213 | relpath_expr* e = static_cast<relpath_expr *>(node); | ||
348 | 1214 | e->setInUnsafeContext(ANNOTATION_TRUE); | ||
349 | 1215 | markInUnsafeContext((*e)[0]); | ||
350 | 1216 | return; | ||
351 | 1217 | } | ||
352 | 1218 | |||
353 | 1219 | case gflwor_expr_kind: | ||
354 | 1220 | case flwor_expr_kind: | ||
355 | 1221 | { | ||
356 | 1222 | flwor_expr* e = static_cast<flwor_expr *>(node); | ||
357 | 1223 | e->setInUnsafeContext(ANNOTATION_TRUE); | ||
358 | 1224 | markInUnsafeContext(e->get_return_expr()); | ||
359 | 1225 | return; | ||
360 | 1226 | } | ||
361 | 1227 | |||
362 | 1228 | case if_expr_kind: | ||
363 | 1229 | case trycatch_expr_kind: | ||
364 | 1230 | { | ||
365 | 1231 | break; | ||
366 | 1232 | } | ||
367 | 1233 | |||
368 | 1234 | case fo_expr_kind: | ||
369 | 1235 | { | ||
370 | 1236 | fo_expr* e = static_cast<fo_expr *>(node); | ||
371 | 1237 | function* f = e->get_func(); | ||
372 | 1238 | |||
373 | 1239 | e->setInUnsafeContext(ANNOTATION_TRUE); | ||
374 | 1240 | |||
375 | 1241 | if (f->isUdf() && static_cast<user_function*>(f)->getBody() != NULL) | ||
376 | 1242 | { | ||
377 | 1243 | user_function* udf = static_cast<user_function*>(f); | ||
378 | 1244 | expr* body = udf->getBody(); | ||
379 | 1245 | |||
380 | 1246 | if (!body->inUnsafeContext()) | ||
381 | 1247 | { | ||
382 | 1248 | markInUnsafeContext(body); | ||
383 | 1249 | } | ||
384 | 1250 | |||
385 | 1251 | std::vector<var_expr*>::const_iterator ite = udf->getArgVars().begin(); | ||
386 | 1252 | std::vector<var_expr*>::const_iterator end = udf->getArgVars().end(); | ||
387 | 1253 | for (; ite != end; ++ite) | ||
388 | 1254 | { | ||
389 | 1255 | expr* argVar = (*ite); | ||
390 | 1256 | if (argVar->inUnsafeContext()) | ||
391 | 1257 | { | ||
392 | 1258 | expr* argExpr = e->get_arg(ite - udf->getArgVars().begin()); | ||
393 | 1259 | markInUnsafeContext(argExpr); | ||
394 | 1260 | } | ||
395 | 1261 | } | ||
396 | 1262 | } // f->isUdf() | ||
397 | 1263 | else | ||
398 | 1264 | { | ||
399 | 1265 | csize numArgs = e->num_args(); | ||
400 | 1266 | for (csize i = 0; i < numArgs; ++i) | ||
401 | 1267 | { | ||
402 | 1268 | if (f->propagatesInputNodes(e, i)) | ||
403 | 1269 | { | ||
404 | 1270 | markInUnsafeContext(e->get_arg(i)); | ||
405 | 1271 | } | ||
406 | 1272 | } | ||
407 | 1273 | } | ||
408 | 1274 | |||
409 | 1275 | return; | ||
410 | 1276 | } | ||
411 | 1277 | |||
412 | 1278 | case treat_expr_kind: | ||
413 | 1279 | case order_expr_kind: | ||
414 | 1280 | case wrapper_expr_kind: | ||
415 | 1281 | case function_trace_expr_kind: | ||
416 | 1282 | case extension_expr_kind: | ||
417 | 1283 | { | ||
418 | 1284 | break; | ||
419 | 1285 | } | ||
420 | 1286 | |||
421 | 1287 | case validate_expr_kind: | ||
422 | 1288 | { | ||
423 | 1289 | node->setInUnsafeContext(ANNOTATION_TRUE); | ||
424 | 1290 | return; | ||
425 | 1291 | } | ||
426 | 1292 | |||
427 | 1293 | case transform_expr_kind: | ||
428 | 1294 | { | ||
429 | 1295 | transform_expr* e = static_cast<transform_expr *>(node); | ||
430 | 1296 | e->setInUnsafeContext(ANNOTATION_TRUE); | ||
431 | 1297 | markInUnsafeContext(e->getReturnExpr()); | ||
432 | 1298 | return; | ||
433 | 1299 | } | ||
434 | 1300 | |||
435 | 1301 | case block_expr_kind: | ||
436 | 1302 | { | ||
437 | 1303 | block_expr* e = static_cast<block_expr *>(node); | ||
438 | 1304 | e->setInUnsafeContext(ANNOTATION_TRUE); | ||
439 | 1305 | expr* lastChild = (*e)[e->size()-1]; | ||
440 | 1306 | markInUnsafeContext(lastChild); | ||
441 | 1307 | return; | ||
442 | 1308 | } | ||
443 | 1309 | |||
444 | 1310 | case var_decl_expr_kind: | ||
445 | 1311 | case var_set_expr_kind: | ||
446 | 1312 | { | ||
447 | 1313 | return; | ||
448 | 1314 | } | ||
449 | 1315 | |||
450 | 1316 | case apply_expr_kind: | ||
451 | 1317 | { | ||
452 | 1318 | break; | ||
453 | 1319 | } | ||
454 | 1320 | |||
455 | 1321 | case exit_catcher_expr_kind: | ||
456 | 1322 | { | ||
457 | 1323 | exit_catcher_expr* e = static_cast<exit_catcher_expr*>(node); | ||
458 | 1324 | |||
459 | 1325 | std::vector<expr*>::const_iterator ite = e->exitExprsBegin(); | ||
460 | 1326 | std::vector<expr*>::const_iterator end = e->exitExprsEnd(); | ||
461 | 1327 | |||
462 | 1328 | for (; ite != end; ++ite) | ||
463 | 1329 | { | ||
464 | 1330 | exit_expr* ex = static_cast<exit_expr*>(*ite); | ||
465 | 1331 | |||
466 | 1332 | markInUnsafeContext(ex->get_expr()); | ||
467 | 1333 | } | ||
468 | 1334 | |||
469 | 1335 | break; | ||
470 | 1336 | } | ||
471 | 1337 | |||
472 | 1338 | |||
473 | 1339 | case eval_expr_kind: | ||
474 | 1340 | { | ||
475 | 1341 | break; | ||
476 | 1342 | } | ||
477 | 1343 | |||
478 | 1344 | case debugger_expr_kind: | ||
479 | 1345 | { | ||
480 | 1346 | break; // ???? | ||
481 | 1347 | } | ||
482 | 1348 | |||
483 | 1349 | case dynamic_function_invocation_expr_kind: | ||
484 | 1350 | { | ||
485 | 1351 | break; | ||
486 | 1352 | } | ||
487 | 1353 | |||
488 | 1354 | case function_item_expr_kind: | ||
489 | 1355 | { | ||
490 | 1356 | function_item_expr* e = static_cast<function_item_expr*>(node); | ||
491 | 1357 | |||
492 | 1358 | user_function* udf = static_cast<user_function*>(e->get_function()); | ||
493 | 1359 | |||
494 | 1360 | markInUnsafeContext(udf->getBody()); | ||
495 | 1361 | |||
496 | 1362 | return; | ||
497 | 1363 | } | ||
498 | 1364 | |||
499 | 1365 | case promote_expr_kind: | ||
500 | 1366 | case castable_expr_kind: | ||
501 | 1367 | case cast_expr_kind: | ||
502 | 1368 | case instanceof_expr_kind: | ||
503 | 1369 | case name_cast_expr_kind: | ||
504 | 1370 | case axis_step_expr_kind: | ||
505 | 1371 | case match_expr_kind: | ||
506 | 1372 | case delete_expr_kind: | ||
507 | 1373 | case rename_expr_kind: | ||
508 | 1374 | case insert_expr_kind: | ||
509 | 1375 | case replace_expr_kind: | ||
510 | 1376 | case while_expr_kind: | ||
511 | 1377 | case flowctl_expr_kind: | ||
512 | 1378 | case exit_expr_kind: | ||
513 | 1379 | #ifndef ZORBA_NO_FULL_TEXT | ||
514 | 1380 | case ft_expr_kind: | ||
515 | 1381 | #endif | ||
516 | 1382 | default: | ||
517 | 1383 | ZORBA_ASSERT(false); | ||
518 | 1384 | } | ||
519 | 1385 | |||
520 | 1386 | node->setInUnsafeContext(ANNOTATION_TRUE); | ||
521 | 1387 | |||
522 | 1388 | ExprIterator iter(node); | ||
523 | 1389 | while(!iter.done()) | ||
524 | 1390 | { | ||
525 | 1391 | expr* child = (**iter); | ||
526 | 1392 | if (child != NULL) | ||
527 | 1393 | { | ||
528 | 1394 | markInUnsafeContext(child); | ||
529 | 1395 | } | ||
530 | 1396 | iter.next(); | ||
531 | 1397 | } | ||
532 | 1398 | |||
533 | 1399 | return; | ||
534 | 1400 | } | ||
535 | 1401 | |||
536 | 1402 | |||
537 | 1093 | } | 1403 | } |
538 | 1094 | /* vim:set et sw=2 ts=2: */ | 1404 | /* vim:set et sw=2 ts=2: */ |
539 | 1095 | 1405 | ||
540 | === modified file 'src/compiler/rewriter/rules/ruleset.h' | |||
541 | --- src/compiler/rewriter/rules/ruleset.h 2012-10-02 11:57:15 +0000 | |||
542 | +++ src/compiler/rewriter/rules/ruleset.h 2012-10-02 22:52:19 +0000 | |||
543 | @@ -125,11 +125,6 @@ | |||
544 | 125 | 125 | ||
545 | 126 | /******************************************************************************* | 126 | /******************************************************************************* |
546 | 127 | 127 | ||
547 | 128 | theIsInUnsafeContext: | ||
548 | 129 | --------------------- | ||
549 | 130 | If true, it indicates that an expr E1 satisfies a condition that makes a | ||
550 | 131 | sub-expr E2 of E1 be unsafe, even though E2 by itself is safe. | ||
551 | 132 | |||
552 | 133 | ********************************************************************************/ | 128 | ********************************************************************************/ |
553 | 134 | class MarkNodeCopyProps : public RewriteRule | 129 | class MarkNodeCopyProps : public RewriteRule |
554 | 135 | { | 130 | { |
555 | @@ -140,13 +135,10 @@ | |||
556 | 140 | 135 | ||
557 | 141 | UdfCalls theProcessedUDFCalls; | 136 | UdfCalls theProcessedUDFCalls; |
558 | 142 | 137 | ||
559 | 143 | bool theIsInUnsafeContext; | ||
560 | 144 | |||
561 | 145 | public: | 138 | public: |
562 | 146 | MarkNodeCopyProps() | 139 | MarkNodeCopyProps() |
563 | 147 | : | 140 | : |
566 | 148 | RewriteRule(RewriteRule::MarkNodeCopyProps, "MarkNodeCopyProps"), | 141 | RewriteRule(RewriteRule::MarkNodeCopyProps, "MarkNodeCopyProps") |
565 | 149 | theIsInUnsafeContext(false) | ||
567 | 150 | { | 142 | { |
568 | 151 | } | 143 | } |
569 | 152 | 144 | ||
570 | @@ -156,6 +148,8 @@ | |||
571 | 156 | void applyInternal(RewriterContext& rCtx, expr* node, UDFCallChain& udfCaller); | 148 | void applyInternal(RewriterContext& rCtx, expr* node, UDFCallChain& udfCaller); |
572 | 157 | 149 | ||
573 | 158 | void markSources(const std::vector<expr*>& sources); | 150 | void markSources(const std::vector<expr*>& sources); |
574 | 151 | |||
575 | 152 | void markInUnsafeContext(expr* node); | ||
576 | 159 | }; | 153 | }; |
577 | 160 | 154 | ||
578 | 161 | 155 | ||
579 | 162 | 156 | ||
580 | === added file 'test/rbkt/ExpQueryResults/zorba/no-copy/test4.xml.res' | |||
581 | --- test/rbkt/ExpQueryResults/zorba/no-copy/test4.xml.res 1970-01-01 00:00:00 +0000 | |||
582 | +++ test/rbkt/ExpQueryResults/zorba/no-copy/test4.xml.res 2012-10-02 22:52:19 +0000 | |||
583 | @@ -0,0 +1,1 @@ | |||
584 | 1 | <s:name xmlns:s="http://www.zorba-xquery.org/simple">foo</s:name> | ||
585 | 0 | 2 | ||
586 | === added file 'test/rbkt/ExpQueryResults/zorba/no-copy/test5.xml.res' | |||
587 | --- test/rbkt/ExpQueryResults/zorba/no-copy/test5.xml.res 1970-01-01 00:00:00 +0000 | |||
588 | +++ test/rbkt/ExpQueryResults/zorba/no-copy/test5.xml.res 2012-10-02 22:52:19 +0000 | |||
589 | @@ -0,0 +1,1 @@ | |||
590 | 1 | <s:name xmlns:s="http://www.zorba-xquery.org/simple">foo</s:name> true | ||
591 | 0 | 2 | ||
592 | === added file 'test/rbkt/Queries/zorba/no-copy/test4.xq' | |||
593 | --- test/rbkt/Queries/zorba/no-copy/test4.xq 1970-01-01 00:00:00 +0000 | |||
594 | +++ test/rbkt/Queries/zorba/no-copy/test4.xq 2012-10-02 22:52:19 +0000 | |||
595 | @@ -0,0 +1,17 @@ | |||
596 | 1 | |||
597 | 2 | declare namespace opt = "http://www.zorba-xquery.com/options/optimizer"; | ||
598 | 3 | |||
599 | 4 | declare construction strip; | ||
600 | 5 | |||
601 | 6 | declare copy-namespaces preserve, no-inherit; | ||
602 | 7 | |||
603 | 8 | |||
604 | 9 | import schema namespace s="http://www.zorba-xquery.org/simple" at "simple.xsd"; | ||
605 | 10 | |||
606 | 11 | declare option opt:enable "for-serialization-only"; | ||
607 | 12 | |||
608 | 13 | declare variable $doc := <s:person><s:name>foo</s:name><s:age>25</s:age></s:person>; | ||
609 | 14 | |||
610 | 15 | let $vdoc := validate { $doc } | ||
611 | 16 | let $copy := <root>{$vdoc/s:name}</root> | ||
612 | 17 | return $copy/child::element(*, xs:untyped) | ||
613 | 0 | 18 | ||
614 | === added file 'test/rbkt/Queries/zorba/no-copy/test5.xq' | |||
615 | --- test/rbkt/Queries/zorba/no-copy/test5.xq 1970-01-01 00:00:00 +0000 | |||
616 | +++ test/rbkt/Queries/zorba/no-copy/test5.xq 2012-10-02 22:52:19 +0000 | |||
617 | @@ -0,0 +1,16 @@ | |||
618 | 1 | declare namespace opt = "http://www.zorba-xquery.com/options/optimizer"; | ||
619 | 2 | |||
620 | 3 | declare construction strip; | ||
621 | 4 | |||
622 | 5 | declare copy-namespaces preserve, no-inherit; | ||
623 | 6 | |||
624 | 7 | import schema namespace s="http://www.zorba-xquery.org/simple" at "simple.xsd"; | ||
625 | 8 | |||
626 | 9 | declare option opt:enable "for-serialization-only"; | ||
627 | 10 | |||
628 | 11 | declare variable $doc := <s:person><s:name>foo</s:name><s:age>25</s:age></s:person>; | ||
629 | 12 | |||
630 | 13 | let $vdoc := validate { $doc } | ||
631 | 14 | let $copy := <root>{$vdoc/s:name}</root> | ||
632 | 15 | let $copyname := $copy/s:name | ||
633 | 16 | return ($copyname, " ", $copyname instance of element(*, xs:string)) |
Validation queue starting for merge proposal. zorbatest. lambda. nu:8080/ remotequeue/ no-copy- 2012-10- 02T22-59- 53.733Z/ log.html
Log at: http://