1 /*
2  * Copyright 2006-2008 The FLWOR Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include "stdafx.h"
17 
18 #include "compiler/expression/update_exprs.h"
19 #include "compiler/expression/var_expr.h"
20 #include "compiler/expression/expr_visitor.h"
21 
22 #include "compiler/api/compilercb.h"
23 
24 #include "diagnostics/assert.h"
25 #include "diagnostics/xquery_diagnostics.h"
26 
27 namespace zorba
28 {
29 
30 
31 DEF_EXPR_ACCEPT (insert_expr)
DEF_EXPR_ACCEPT(delete_expr)32 DEF_EXPR_ACCEPT (delete_expr)
33 DEF_EXPR_ACCEPT (rename_expr)
34 DEF_EXPR_ACCEPT (replace_expr)
35 DEF_EXPR_ACCEPT (transform_expr)
36 
37 
38 /*******************************************************************************
39 
40 ********************************************************************************/
41 update_expr_base::update_expr_base(
42     CompilerCB* ccb,
43     static_context* sctx,
44     const QueryLoc& loc,
45     expr_kind_t kind,
46     expr* targetExpr,
47     expr* sourceExpr)
48   :
49   expr(ccb, sctx, loc, kind),
50   theTargetExpr(targetExpr),
51   theSourceExpr(sourceExpr)
52 {
53   compute_scripting_kind();
54 }
55 
56 
compute_scripting_kind()57 void update_expr_base::compute_scripting_kind()
58 {
59   theScriptingKind = UPDATING_EXPR;
60 
61   checkSimpleExpr(theTargetExpr);
62 
63   if (theSourceExpr)
64     checkSimpleExpr(theSourceExpr);
65 }
66 
67 
68 /*******************************************************************************
69 
70 ********************************************************************************/
insert_expr(CompilerCB * ccb,static_context * sctx,const QueryLoc & loc,store::UpdateConsts::InsertType aType,expr * sourceExpr,expr * targetExpr)71 insert_expr::insert_expr(
72     CompilerCB* ccb,
73     static_context* sctx,
74     const QueryLoc& loc,
75     store::UpdateConsts::InsertType aType,
76     expr* sourceExpr,
77     expr* targetExpr)
78   :
79   update_expr_base(ccb, sctx, loc, insert_expr_kind, targetExpr, sourceExpr),
80   theType(aType)
81 {
82 }
83 
84 
cloneImpl(substitution_t & subst) const85 expr* insert_expr::cloneImpl(substitution_t& subst) const
86 {
87   return theCCB->theEM->create_insert_expr(theSctx,
88                          get_loc(),
89                          getType(),
90                          getSourceExpr()->clone(subst),
91                          getTargetExpr()->clone(subst));
92 }
93 
94 
95 /*******************************************************************************
96 
97 ********************************************************************************/
delete_expr(CompilerCB * ccb,static_context * sctx,const QueryLoc & loc,expr * targetExpr)98 delete_expr::delete_expr(
99     CompilerCB* ccb,
100     static_context* sctx,
101     const QueryLoc& loc,
102     expr* targetExpr)
103   :
104   update_expr_base(ccb, sctx, loc, delete_expr_kind, targetExpr, NULL)
105 {
106 }
107 
108 
cloneImpl(substitution_t & subst) const109 expr* delete_expr::cloneImpl(substitution_t& subst) const
110 {
111   return theCCB->theEM->create_delete_expr(theSctx, get_loc(), getTargetExpr()->clone(subst));
112 }
113 
114 
115 /*******************************************************************************
116 
117 ********************************************************************************/
replace_expr(CompilerCB * ccb,static_context * sctx,const QueryLoc & loc,store::UpdateConsts::ReplaceType aType,expr * targetExpr,expr * replaceExpr)118 replace_expr::replace_expr(
119     CompilerCB* ccb,
120     static_context* sctx,
121     const QueryLoc& loc,
122     store::UpdateConsts::ReplaceType aType,
123     expr* targetExpr,
124     expr* replaceExpr)
125   :
126   update_expr_base(ccb, sctx, loc, replace_expr_kind, targetExpr, replaceExpr),
127   theType(aType)
128 {
129 }
130 
131 
cloneImpl(substitution_t & subst) const132 expr* replace_expr::cloneImpl(substitution_t& subst) const
133 {
134   return theCCB->theEM->create_replace_expr(theSctx,
135                           get_loc(),
136                           getType(),
137                           getTargetExpr()->clone(subst),
138                           getReplaceExpr()->clone(subst));
139 }
140 
141 
142 /*******************************************************************************
143 
144 ********************************************************************************/
rename_expr(CompilerCB * ccb,static_context * sctx,const QueryLoc & loc,expr * targetExpr,expr * nameExpr)145 rename_expr::rename_expr(
146     CompilerCB* ccb,
147     static_context* sctx,
148     const QueryLoc& loc,
149     expr* targetExpr,
150     expr* nameExpr)
151   :
152   update_expr_base(ccb, sctx, loc, rename_expr_kind, targetExpr, nameExpr)
153 {
154 }
155 
156 
cloneImpl(substitution_t & subst) const157 expr* rename_expr::cloneImpl(substitution_t& subst) const
158 {
159   return theCCB->theEM->create_rename_expr(theSctx,
160                          get_loc(),
161                          getTargetExpr()->clone(subst),
162                          getNameExpr()->clone(subst));
163 }
164 
165 
166 /*******************************************************************************
167 
168 ********************************************************************************/
copy_clause(CompilerCB * ccb,var_expr * aVar,expr * aExpr)169 copy_clause::copy_clause(CompilerCB* ccb, var_expr* aVar, expr* aExpr)
170   :
171   theVar(aVar),
172   theExpr(aExpr),
173   theCCB(ccb)
174 {
175   theVar->set_copy_clause(this);
176 }
177 
178 
~copy_clause()179 copy_clause::~copy_clause()
180 {
181   if (theVar)
182     theVar->set_copy_clause(NULL);
183 }
184 
185 
clone(expr::substitution_t & subst) const186 copy_clause* copy_clause::clone(expr::substitution_t& subst) const
187 {
188   ZORBA_ASSERT(theVar && theExpr);
189 
190   expr* domainCopy = theExpr->clone(subst);
191 
192   var_expr* varCopy = theExpr->get_ccb()->theEM->create_var_expr(*theVar);
193 
194   subst[theVar] = varCopy;
195 
196   return theCCB->theEM->create_copy_clause(varCopy, domainCopy);
197 }
198 
199 
transform_expr(CompilerCB * ccb,static_context * sctx,const QueryLoc & loc)200 transform_expr::transform_expr(
201     CompilerCB* ccb,
202     static_context* sctx,
203     const QueryLoc& loc)
204   :
205   expr(ccb, sctx, loc, transform_expr_kind)
206 {
207   theScriptingKind = SIMPLE_EXPR;
208 }
209 
210 
setModifyExpr(expr * e)211 void transform_expr::setModifyExpr(expr* e)
212 {
213   theModifyExpr = e;
214 
215   if (! theModifyExpr->is_updating_or_vacuous())
216   {
217     throw XQUERY_EXCEPTION(err::XUST0002,
218                            ERROR_PARAMS(ZED(XUST0002_Transform)),
219                            ERROR_LOC(theModifyExpr->get_loc()));
220   }
221 }
222 
223 
setReturnExpr(expr * e)224 void transform_expr::setReturnExpr(expr* e)
225 {
226   theReturnExpr = e;
227 
228   checkNonUpdating(theReturnExpr);
229 
230   theScriptingKind = theReturnExpr->get_scripting_detail();
231 
232   theScriptingKind &= ~VACUOUS_EXPR;
233 }
234 
235 
add_back(copy_clause * c)236 void transform_expr::add_back(copy_clause* c)
237 {
238   theCopyClauses.push_back(c);
239 
240   checkNonUpdating(c->getExpr());
241 }
242 
243 
compute_scripting_kind()244 void transform_expr::compute_scripting_kind()
245 {
246   ZORBA_ASSERT(false);
247 }
248 
249 
cloneImpl(substitution_t & subst) const250 expr* transform_expr::cloneImpl(substitution_t& subst) const
251 {
252   ZORBA_ASSERT(theModifyExpr && theReturnExpr);
253 
254   transform_expr* cloneExpr =
255     theCCB->theEM->create_transform_expr(theSctx, get_loc());
256 
257   for (std::vector<copy_clause*>::const_iterator lIter = theCopyClauses.begin();
258        lIter != theCopyClauses.end();
259        ++lIter)
260   {
261     cloneExpr->add_back((*lIter)->clone(subst));
262   }
263 
264   cloneExpr->setModifyExpr(theModifyExpr->clone(subst));
265   cloneExpr->setReturnExpr(theReturnExpr->clone(subst));
266 
267   return cloneExpr;
268 }
269 
270 
271 } /* namespace zorba */
272 /* vim:set et sw=2 ts=2: */
273