KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > xquark > extractor > algebra > GenAlgebraVisitor


1 /*
2  * This file belongs to the XQuark distribution.
3  * Copyright (C) 2003 Universite de Versailles Saint-Quentin.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307.
18  * You can also get it at http://www.gnu.org/licenses/lgpl.html
19  *
20  * For more information on this software, see http://www.xquark.org.
21  */

22
23 package org.xquark.extractor.algebra;
24
25 import java.sql.Types JavaDoc;
26 import java.util.*;
27
28 import org.xquark.extractor.common.*;
29 import org.xquark.extractor.metadata.MetaDataManager;
30 import org.xquark.extractor.runtime.IDProvider;
31 import org.xquark.extractor.xfunctions.*;
32 import org.xquark.jdbc.typing.DbType;
33 import org.xquark.schema.ComplexType;
34 import org.xquark.schema.ElementDeclaration;
35 import org.xquark.xpath.Axis;
36 import org.xquark.xpath.NodeKind;
37 import org.xquark.xquery.parser.*;
38 import org.xquark.xquery.parser.primitivefunctions.fnfunctions.*;
39 import org.xquark.xquery.parser.primitivefunctions.xsfunctions.*;
40 import org.xquark.xquery.parser.util.Constants;
41 import org.xquark.xquery.typing.*;
42
43 /**
44  * Builds the algebra tree from a database XQueryExpression (QDB).
45  */

46 public final class GenAlgebraVisitor extends DefaultParserVisitor implements Constants {
47     private static final String JavaDoc RCSRevision = "$Revision: 1.52 $";
48     private static final String JavaDoc RCSName = "$Name: $";
49
50     /* the "return value" of each visit function is pushed in this stack */
51     private Stack _returnStack = new Stack();
52
53     /* stores the context for related Path Expression and sortby */
54     private Stack _typeContextStack = new Stack();
55
56     /* temporary sqlType builder for guiding generation */ // TODO: check if basing on query flags is not enough
57
private TypeInterpreter _typeInterpreter;
58     private AlgebraTypeVisitor _typeVistor = new AlgebraTypeVisitor();
59     private MetaDataManager _mdm;
60
61     /* variable table that stores the translation of the variables */
62     private VariableTable _variableTable = null;
63
64     // NOTE: Attributes here, are "columns" in the relational terminology
65
/* Locally used here for predicate exploration in FLWOR translation */
66     private BuildReferredAttributes _brav = new BuildReferredAttributes();
67
68     /* Locally used in FLWOR translation */
69     private AddKeys _akv = new AddKeys();
70
71     /* the final algebra tree generated by a visite */
72     private Expression _algebraTree = null;
73
74     /** This object maintains a correpondence between path waited by reconstruction
75      * and attributes of the top relation.
76      */

77     private Mapper _mapper = null;
78
79     /** if there is a SortedOuterUnion in the query ,
80      * this list contains all the arguments of the SortedOuterUnion.
81      * This help adding keys for these arguments
82      */

83     private List _flwrsInSortedOuterUnion = new ArrayList();
84
85     static final String JavaDoc NUMBER_COLUMN_PREFIX = "SqlWrapperNumber_";
86
87     /* counters for generate unique name */
88     protected IDProvider _attIDProvider = null;
89     protected IDProvider _relIDProvider = null;
90
91     /* a flag to treat view in nested xquery */ // QUESTION : not used ? Only stored from AddKeyVisitors and published
92
private boolean _heavyEliminationNeeded = false;
93
94     public GenAlgebraVisitor(TypeInterpreter ti, MetaDataManager mdm, IDProvider attIDProvider, IDProvider relIDProvider) {
95         setTypeInterpreter(ti);
96         setMetaDataManager(mdm);
97         _attIDProvider = attIDProvider;
98         _relIDProvider = relIDProvider;
99     }
100
101     public void setTypeInterpreter(TypeInterpreter ti) {
102         _typeInterpreter = ti;
103     }
104
105     public void setMetaDataManager(MetaDataManager mdm) {
106         _mdm = mdm;
107     }
108
109     public boolean isHeavyEliminationNeeded() {
110         return _heavyEliminationNeeded;
111     }
112
113     public void noticSortedOuterUnion(List argumentsOfSortedOuterUnion) {
114         XQueryExpression xExpr = null;
115         Variable var = null;
116         FLWRExpression flwr = null;
117         for (int i = 0; i < argumentsOfSortedOuterUnion.size(); i++) {
118             xExpr = (XQueryExpression) argumentsOfSortedOuterUnion.get(i);
119             if (xExpr instanceof Variable) { // TODO: Check if a variable can be produced by front-end
120
_flwrsInSortedOuterUnion.add(((Variable) xExpr).getExpression());
121             } else if (xExpr instanceof FLWRExpression) {
122                 _flwrsInSortedOuterUnion.add(xExpr);
123             } else {
124                 Debug.assertTrue(false, "Internal logic error.");
125             }
126         }
127     }
128
129     public void reinit() {
130         _returnStack.clear();
131         _typeContextStack.clear();
132         _variableTable = null;
133         _flwrsInSortedOuterUnion.clear();
134         _heavyEliminationNeeded = false;
135     }
136
137     public Expression getAlgebraTree() {
138         //Trace.enter(this, "getAlgebraTree()");
139

140         Expression retVal = (Expression) _returnStack.peek();
141         //Trace.exit(this, "getAlgebraTree()");
142
return retVal;
143     }
144
145     public void visit(BinOpANDExpression arg) throws XQueryException {
146         Expression retVal = null;
147
148         XQueryExpression xLOprnd, xROprnd;
149         Expression lOprnd, rOprnd;
150         SqlType lType, rType;
151
152         // check the signature
153
xLOprnd = arg.getLeftOperand();
154         xROprnd = arg.getRightOperand();
155
156         lType = _typeInterpreter.interprete(xLOprnd.getQType());
157         rType = _typeInterpreter.interprete(xROprnd.getQType());
158         if (!lType.isBoolean() || !rType.isBoolean()) {
159             throw new NotSupport(MessageLibrary.getMessage("T_N_SUP_SIG", arg), null);
160         }
161
162         if (xLOprnd instanceof ValueBoolean) {
163             boolean lValue = ((ValueBoolean) xLOprnd).getBooleanValue();
164             if (xROprnd instanceof ValueBoolean) {
165
166                 /* both left Operand and right operand are boolean constants
167                  * so the return value is a boolean constant
168                  */

169                 boolean rValue = ((ValueBoolean) xROprnd).getBooleanValue();
170                 retVal = new LitBoolean(lValue && rValue);
171                 _returnStack.push(retVal); // a return value
172
} else {
173
174                 /* left Operand is boolean constant but right operand is not */
175                 if (lValue) {
176                     xROprnd.accept(this); // a return value
177
retVal = (Expression) _returnStack.peek();
178                 } else {
179                     retVal = new LitBoolean(false);
180                     _returnStack.push(retVal); // a return value
181
}
182             }
183         } else {
184             if (xROprnd instanceof ValueBoolean) {
185
186                 /* left Operand is not boolean constant but right operand is. */
187                 boolean rValue = ((ValueBoolean) xROprnd).getBooleanValue();
188                 if (rValue) {
189                     xLOprnd.accept(this); // a return value
190
retVal = (Expression) _returnStack.peek();
191                 } else {
192                     retVal = new LitBoolean(false);
193                     _returnStack.push(retVal); // a return value
194
}
195             } else {
196
197                 /* neither left Operand nor right operand are boolean constants */
198                 xLOprnd.accept(this);
199                 lOprnd = (Expression) _returnStack.pop();
200                 xROprnd.accept(this);
201                 rOprnd = (Expression) _returnStack.pop();
202
203                 retVal = new BinOpBoolean(Constants.AND, lOprnd, rOprnd);
204                 _returnStack.push(retVal); // a return value
205
}
206         }
207
208         retVal.setOrginalXExpr(arg);
209     }
210
211     public void visit(BinOpORExpression arg) throws XQueryException {
212         Expression retVal = null;
213
214         XQueryExpression xLOprnd, xROprnd;
215         Expression lOprnd, rOprnd;
216         SqlType lType, rType;
217
218         // check the signature
219
xLOprnd = arg.getLeftOperand();
220         xROprnd = arg.getRightOperand();
221         lType = _typeInterpreter.interprete(xLOprnd.getQType());
222         rType = _typeInterpreter.interprete(xROprnd.getQType());
223         if (!lType.isBoolean() || !rType.isBoolean()) {
224             throw new NotSupport(MessageLibrary.getMessage("T_N_SUP_SIG", arg), null);
225         }
226
227         if (xLOprnd instanceof ValueBoolean) {
228             boolean lValue = ((ValueBoolean) xLOprnd).getBooleanValue();
229             if (xROprnd instanceof ValueBoolean) {
230
231                 /* both left Operand and right operand are boolean constants
232                  * so the return value is a boolean constant
233                  */

234                 boolean rValue = ((ValueBoolean) xROprnd).getBooleanValue();
235                 retVal = new LitBoolean(lValue || rValue);
236                 _returnStack.push(retVal); // a return value
237
} else {
238
239                 /* left Operand is boolean constant but right operand is not */
240                 if (lValue) {
241                     retVal = new LitBoolean(true);
242                     _returnStack.push(retVal); // a return value
243
} else {
244                     xROprnd.accept(this); // a return value
245
retVal = (Expression) _returnStack.peek();
246                 }
247             }
248         } else {
249             if (xROprnd instanceof ValueBoolean) {
250
251                 /* left Operand is not boolean constant but right operand is. */
252                 boolean rValue = ((ValueBoolean) xROprnd).getBooleanValue();
253                 if (rValue) {
254                     retVal = new LitBoolean(true);
255                     _returnStack.push(retVal); // a return value
256
} else {
257                     xLOprnd.accept(this); // a return value
258
retVal = (Expression) _returnStack.peek();
259                 }
260             } else {
261
262                 /* neither left Operand nor right operand are boolean constants */
263                 xLOprnd.accept(this);
264                 lOprnd = (Expression) _returnStack.pop();
265                 xROprnd.accept(this);
266                 rOprnd = (Expression) _returnStack.pop();
267
268                 retVal = new BinOpBoolean(OR, lOprnd, rOprnd);
269                 _returnStack.push(retVal); // a return value
270
}
271         }
272
273         retVal.setOrginalXExpr(arg);
274     }
275
276     public void visit(CastTreatExpression arg) throws XQueryException {
277         throw new SqlWrapperException(MessageLibrary.getMessage("T_N_SUP_OPTR", arg), null);
278     }
279
280     public void visit(FLWRExpression arg) throws XQueryException {
281         /* create a new VariableTable for the new scope*/
282         VariableTable newVT = new VariableTable();
283         newVT.setDefautVariableTable(_variableTable);
284         _variableTable = newVT;
285
286         Expression retVal = null;
287         Mapper mapper = new Mapper(); // TODO: check the generation of mapper is correct (2nd Qdb of UCR11 is strange...)
288
// at least items generated for key could be mapped on already present ?
289

290         /* generate algebra for FOR,LET clause */
291         List variables = arg.getVariables();
292         Iterator iter = variables.iterator();
293         Variable variable;
294         int bindingType;
295
296         List tableInstanceList = new ArrayList();
297         List bindingTypeList = new ArrayList();
298
299         List pseudoIdPathList = new ArrayList();
300
301         /* for the case of a artificial for clause */
302         String JavaDoc pseudoIdPath = null;
303         List idOrder = new ArrayList();
304         VarMappingInfo varInfo;
305
306         List predicateListAddedByForBinding = new ArrayList();
307         while (iter.hasNext()) {
308             variable = ((Variable) iter.next());
309             bindingType = variable.getBindingType();
310             switch (bindingType) {
311                 case LET_BINDINGTYPE :
312                     visitLetBinding(variable);
313                     break;
314                 case FOR_BINDINGTYPE :
315                     varInfo = visitForBinding(variable);
316                     if (null != varInfo) {
317                         tableInstanceList.add(varInfo.relation);
318                         idOrder.add(varInfo);
319                     } else {
320                         visit(variable);
321                         Expression atomicExpr = (Expression) _returnStack.pop();
322
323                         if (!(atomicExpr instanceof Literal))
324                             predicateListAddedByForBinding.add(new UnOpIsNull(atomicExpr, true));
325
326                         if (variable.getExpression() instanceof ValueInteger) {
327                             pseudoIdPath = "$" + variable.getVarName().getName();
328                             idOrder.add(pseudoIdPath);
329                             pseudoIdPathList.add(pseudoIdPath);
330                         }
331                     }
332                     break;
333                 default :
334                     throw new InternalErrorException(MessageLibrary.getMessage("IE_INV_XEXPR", variable.toString()), null);
335             }
336         }
337
338         /* translate predicate in XQuery into Expression list */
339         List aPredicates = new ArrayList();
340         aPredicates.addAll(predicateListAddedByForBinding);
341         XQueryExpression whereClause = arg.getWhereClause();
342         if (null != whereClause) {
343             List xPredicates = new ArrayList();
344             xPredicates = decomposePredicate(whereClause, xPredicates);
345             iter = xPredicates.iterator();
346             XQueryExpression xPredicate;
347             Expression aPredicate;
348             while (iter.hasNext()) {
349                 xPredicate = (XQueryExpression) iter.next();
350                 xPredicate.accept(this);
351                 aPredicate = (Expression) _returnStack.pop();
352                 aPredicate.accept(_brav);
353                 aPredicates.add(aPredicate);
354             }
355         }
356
357         if (1 == tableInstanceList.size())
358             retVal = new UnOpRestrict((Expression) tableInstanceList.get(0), aPredicates);
359         else if (1 < tableInstanceList.size())
360             retVal = new Join(tableInstanceList, aPredicates);
361
362         /* generate algebra for RETURN clause */
363         XQueryExpression returnClause = arg.getReturnClause();
364         List subPathList = null;
365         XQueryExpression subPath = null;
366
367         List selectList = new ArrayList();
368         Variable xExpr;
369         Expression aExpr;
370
371         if (returnClause instanceof XQueryExpressionSequence) {
372             /* normal case */
373             List xExprs = ((XQueryExpressionSequence) returnClause).getSubExpressions();
374
375             Debug.assertTrue(null != xExprs, "null != xExprs");
376             SqlType xExprSqlType;
377
378             for (int j = 0; j < xExprs.size(); j++) {
379                 xExpr = (Variable) xExprs.get(j);
380                 subPathList = xExpr.getUniqueSubPathList();
381                 if (null != subPathList && !subPathList.isEmpty()) {
382                     for (int i = 0; i < subPathList.size(); i++) {
383                         subPath = (XQueryExpression) subPathList.get(i);
384                         // NOTE: Front-end may generate let that have to be ignored
385
// (these lets may be useful for other backends that do
386
// not want to expand variable for perf reasons)
387
if (!subPath.getQType().isMultiple()) {
388                             subPath.accept(this);
389                             aExpr = (Expression) _returnStack.pop();
390                             selectList.add(aExpr);
391                         }
392                     }
393                 }
394                 // TODO: the following branch is to be removed ? Used "for $x in 1" ?
395
else if (xExpr instanceof Variable && ((Variable) xExpr).getExpression() instanceof ValueInteger) {
396                     xExpr.accept(this);
397                     aExpr = (Expression) _returnStack.pop();
398                     selectList.add(aExpr);
399                 }
400             }
401         } else { // for variable by example
402
returnClause.accept(this);
403             aExpr = (Expression) _returnStack.pop();
404             selectList.add(aExpr);
405         }
406
407         if (null == retVal) /* nothing is producted by JoinBuilder*/ {
408             /* check SortedOuterUnion */
409             boolean isSortedOuterUnion = false;
410
411             // the way for detecting the existance of SOU is simplified
412
XQueryExpression tmpExpr = returnClause;
413             if (returnClause instanceof XQueryExpressionSequence && ((XQueryExpressionSequence) returnClause).getSubExpressions().size() == 1)
414                 tmpExpr = (XQueryExpression) ((XQueryExpressionSequence) returnClause).getSubExpressions().get(0);
415             else if (tmpExpr instanceof Variable)
416                 tmpExpr = ((Variable) tmpExpr).getExpression();
417             else if (tmpExpr instanceof InternalFunctionCall)
418                 isSortedOuterUnion = true;
419
420             if (isSortedOuterUnion) {
421                 /* sorted-outer-union */
422                 retVal = (Expression) selectList.get(0);
423             } else {
424                 /* case : a special case where this is not For Clause in the query
425                  * and return clause contains several values
426                  */

427
428                 if (!aPredicates.isEmpty()) {
429                     /* generate UnOpRestrict for aPredicates whick was not treaded by joinbuilder */
430                     retVal = new UnOpRestrict(new DummyTable(), aPredicates);
431                     retVal = new UnOpProject(retVal, selectList, false, _attIDProvider);
432                 } else
433                     retVal = new UnOpProject(new DummyTable(), selectList, false, _attIDProvider);
434
435                 /* second pass of making map , for catch the AttributesExpressions which
436                  * are genreated from TupleExpressions
437                  */

438                 mapper.createMap(((UnOpProject) retVal).getItemList());
439
440                 /* add pseudoId(s) to the result */
441                 if (pseudoIdPathList.size() > 0) {
442                     for (int i = 0; i < pseudoIdPathList.size(); i++) {
443                         pseudoIdPath = (String JavaDoc) pseudoIdPathList.get(i);
444                         MapItem pseudoId = mapper.map(pseudoIdPath);
445                         //Debug.assertTrue(null!= pseudoId, "null!= pseudoId");
446
if (pseudoId != null)
447                             mapper.addIdentifier(pseudoIdPath, pseudoId.getRelatedExpression());
448                     }
449                 }
450
451                 retVal.setMapper(mapper);
452             }
453         } else {
454             /* first pass of making map , for catch the TupleExpressions that
455              * disappear after adding generation of selectList to UnOp project
456              */

457             List tupleExpressionList = new ArrayList();
458             for (int i = 0; i < selectList.size(); i++) {
459                 Expression selectItem = (Expression) selectList.get(i);
460                 if (selectItem instanceof TupleExpression) {
461                     tupleExpressionList.add(selectItem);
462                 }
463             }
464             if (0 < tupleExpressionList.size()) {
465                 mapper.createMap(tupleExpressionList);
466             }
467
468             retVal = new UnOpProject(retVal, selectList, false, _attIDProvider);
469
470             /* second pass of making map , for catch the AttributesExpressions which
471              * are generated from TupleExpressions
472              */

473             mapper.createMap(((UnOpProject) retVal).getItemList());
474
475             if (_flwrsInSortedOuterUnion.contains(arg)) {
476                 /* add key(s) to the result */
477                 List keyItemList = new ArrayList();
478
479                 /*add key(s) to all table instances*/
480                 List allKeys = new ArrayList();
481
482                 String JavaDoc pathForkey = null;
483                 for (int i = 0; i < idOrder.size(); i++) {
484                     Object JavaDoc obj = idOrder.get(i);
485                     if (obj instanceof VarMappingInfo) {
486                         VarMappingInfo item = (VarMappingInfo) obj;
487                         pathForkey = "key/$" + item.varName;
488                         _akv.reinit();
489                         item.relation.accept(_akv);
490                         allKeys = _akv.getKeys();
491
492                         /* added for support view in nested xquery */
493                         if (_akv.isHeavyEliminationNeeded())
494                             _heavyEliminationNeeded = true;
495                         /* end of -- added for support view in nested xquery */
496
497                         Debug.assertTrue(0 < allKeys.size(), "0 < allKeys.size()");
498
499                         for (int j = 0; j < allKeys.size(); j++) {
500                             Expression keyAttribute = (Expression) allKeys.get(j);
501                             // TODO verify if the keyAttribute is already in the retVal*/
502
keyAttribute = ((UnOpProject) retVal).addItem(keyAttribute);
503                             allKeys.set(j, keyAttribute);
504                         }
505                         mapper.addIdentifier(pathForkey, allKeys);
506                     } else { // String
507
/* generate a pseudoId*/
508                         pseudoIdPath = (String JavaDoc) obj;
509                         MapItem pseudoId = mapper.map(pseudoIdPath);
510                         Debug.assertTrue(null != pseudoId, "null!= pseudoId");
511                         mapper.addIdentifier(pseudoIdPath, pseudoId.getRelatedExpression());
512                     }
513
514                 }
515             }
516             retVal.setMapper(mapper);
517         }
518
519         /* translate sortby clause */
520         List xOrderbySpecList = arg.getOrderBy();
521         if (null != xOrderbySpecList && (!xOrderbySpecList.isEmpty())) {
522
523             List aSortSpecList = new ArrayList();
524             XQueryExpression xOrderbyExpr = null;
525             SortSpecification aSortSpec = null;
526             Expression projectItem = null;
527             AttributeExpression aSortExpr = null;
528             int order = 0;
529             String JavaDoc strOrderbytExpr = null;
530
531             PlaceHolder placeHolder = null;
532             Object JavaDoc obj = null;
533             MapItem sortItemMap = null;
534             for (int i = 0; i < xOrderbySpecList.size(); i++) {
535                 obj = xOrderbySpecList.get(i);
536
537                 if (obj instanceof PlaceHolder) {
538                     List sortSpecList = generateSortSpecList((PlaceHolder) obj, mapper);
539                     aSortSpecList.addAll(sortSpecList);
540                 } else {
541                     xOrderbyExpr = (XQueryExpression) obj;
542
543                     if (xOrderbyExpr.getOrder(0) == Constants.PLACE_ORDER) {
544                         xOrderbyExpr.accept(this);
545                         Expression relation = (Expression) _returnStack.pop();
546                         if (relation instanceof TupleExpression) {
547                             relation = ((TupleExpression) relation).getTableInstance();
548                         }
549                         if (relation instanceof RenameRelation) {
550                             RenameRelation item = (RenameRelation) relation;
551                             _akv.reinit();
552                             item.accept(_akv);
553                             List allKeys = _akv.getKeys();
554                             for (int j = 0; j < allKeys.size(); j++) {
555                                 Expression key = (Expression) allKeys.get(j);
556                                 aSortSpecList.add(new SortSpecification(key, ASCENDING_ORDER));
557                             }
558                         }
559                     } else {
560                         /* find out corresponding AttributeExpression */
561                         strOrderbytExpr = xOrderbyExpr.getStringValue();
562
563                         sortItemMap = mapper.map(strOrderbytExpr);
564                         if (null == sortItemMap) {
565                             int index = strOrderbytExpr.indexOf("/child::text()");
566                             if (-1 == index) {
567                                 strOrderbytExpr += "/child::text()";
568                             } else {
569                                 strOrderbytExpr = strOrderbytExpr.substring(0, index);
570                             }
571                             sortItemMap = mapper.map(strOrderbytExpr);
572                         }
573
574                         if (null == sortItemMap) {
575                             if (!xOrderbyExpr.getQType().isMultiple()) {
576                                 xOrderbyExpr.accept(this);
577                                 aExpr = (Expression) _returnStack.pop();
578                                 if (aExpr instanceof AttributeExpression) {
579                                     aSortExpr = (AttributeExpression) aExpr;
580                                 }
581                             }
582                         } else {
583                             projectItem = sortItemMap.getRelatedExpression();
584                             aSortExpr = new AttributeExpression(projectItem instanceof AttributeExpression ? ((AttributeExpression) projectItem).getTableInstance() : null, projectItem.getName());
585                             aSortExpr.setOrginalXExpr(xOrderbyExpr);
586                             aSortExpr.setUnderlyingExpr(projectItem);
587                         }
588
589                         Debug.assertTrue(null != aSortExpr, "failed in finding order by expression in return clause");
590
591                         order = xOrderbyExpr.getOrder(0);
592                         if (order == -1)
593                             order = 0;
594                         aSortSpec = new SortSpecification(aSortExpr, order);
595                         aSortSpecList.add(aSortSpec);
596                     }
597                 }
598             }
599             /* added for sybase*/
600             removeDuplicatedExpr(aSortSpecList);
601             retVal = new UnOpSort(retVal, aSortSpecList);
602             /* the following line is added so that the RemoveProjectReplaceVisitor can reach the UnOpSort*/
603              ((UnOpProject) ((UnOpSort) retVal).getOperand()).setAssociatedSort((UnOpSort) retVal);
604             retVal.setMapper(mapper);
605         }
606
607         retVal.setOrginalXExpr(arg);
608
609         /* remove the VariableTable from VariableTable chaine*/
610         _variableTable = _variableTable.getDefautVariableTable();
611
612         _returnStack.push(retVal);
613     }
614
615     private List generateSortSpecList(PlaceHolder placeHolder, Mapper mapper) {
616         List varNameList = new ArrayList();
617         List varList = placeHolder.getList();
618         Variable var = null;
619         for (int i = 0; i < varList.size(); i++) {
620             var = (Variable) varList.get(i);
621             varNameList.add(var.toString());
622         }
623         return generateSortSpecList(varNameList, mapper);
624     }
625
626     private List generateSortSpecList(List varNameList, Mapper mapper) {
627         List retVal = new ArrayList();
628         List idMapItemList = mapper.getIdentifierList();
629         MapItem mapItem = null;
630         MapItem childMapItem = null;
631         Expression sortExpr = null;
632         String JavaDoc varName = null;
633         if (idMapItemList != null) {
634             for (int i = 0; i < idMapItemList.size(); i++) {
635                 mapItem = (MapItem) idMapItemList.get(i);
636                 varName = mapItem.getPath().substring(4);
637                 if (varNameList.contains(varName)) {
638                     /*mapItem is of current level */
639                     if (mapItem.isLeafPath()) {
640                         sortExpr = mapItem.getRelatedExpression();
641                         retVal.add(createSortSpecification(sortExpr, ASCENDING_ORDER));
642                     } else {
643                         List children = mapItem.getChildren();
644                         for (int j = 0; j < children.size(); j++) {
645                             childMapItem = (MapItem) mapper.map((String JavaDoc) children.get(j));
646                             sortExpr = childMapItem.getRelatedExpression();
647                             retVal.add(createSortSpecification(sortExpr, ASCENDING_ORDER));
648                         }
649                     }
650                 }
651             }
652         }
653
654         return retVal;
655     }
656
657     static public void removeDuplicatedExpr(List sortSpecList) {
658         List exprList = new ArrayList();
659
660         SortSpecification sortSpec = null;
661         AttributeExpression expr = null;
662
663         for (int i = 0; i < sortSpecList.size(); i++) {
664             sortSpec = (SortSpecification) sortSpecList.get(i);
665             exprList.add(sortSpec.getSortExpression());
666         }
667
668         boolean duplicated = false;
669         for (int i = exprList.size() - 1; i > -1; i--) {
670             expr = (AttributeExpression) exprList.get(i);
671             for (int j = 0; j < i; j++) {
672                 duplicated = UnOpProject.isIdentical((AttributeExpression) exprList.get(j), expr);
673                 if (duplicated) {
674                     sortSpecList.remove(i);
675                     break;
676                 }
677             }
678         }
679     }
680
681     private SortSpecification createSortSpecification(Expression expr, int order) {
682         String JavaDoc attrName = expr.getName();
683         Debug.assertTrue(null != attrName, "null != attrName");
684
685         AttributeExpression sortExpr = new AttributeExpression(expr instanceof AttributeExpression ? ((AttributeExpression) expr).getTableInstance() : null, expr.getName());
686         sortExpr.setUnderlyingExpr(expr);
687
688         return new SortSpecification(sortExpr, order);
689     }
690
691     public void visit(InternalFunctionCall arg) throws XQueryException {
692         String JavaDoc functionName;
693         functionName = arg.getFuncName().getLocalName();
694         if (functionName.equalsIgnoreCase("SOU")) {
695             visitSortedOuterUnion(arg);
696         } else
697             throw new InternalErrorException(MessageLibrary.getMessage("IE_INV_XEXPR", arg), null);
698     }
699
700     public void visitSortedOuterUnion(InternalFunctionCall arg) throws XQueryException {
701         Expression retVal = null;
702         List args = arg.getArguments();
703         List aExprs = new ArrayList();
704         List sortSpecListList = new ArrayList();
705
706         /* pick out UnOpprojects and UnOpSorts*/
707         Mapper mapper = null;
708         UnOpProject project = null;
709         for (int i = 0; i < args.size(); i++) {
710             ((XQueryExpression) args.get(i)).accept(this);
711             Expression aExpr = (Expression) _returnStack.pop();
712             if (aExpr instanceof UnOpProject) {
713                 aExprs.add(aExpr);
714                 sortSpecListList.add(null);
715             } else if (aExpr instanceof UnOpSort) {
716                 UnOpSort sort = (UnOpSort) aExpr;
717                 sortSpecListList.add(sort.getSortSpecificationList());
718                 project = (UnOpProject) sort.getOperand();
719                 // mapper = project.getMapper();
720
// mapper.addSortItemList(sort.getSortSpecificationList());
721
aExprs.add(project);
722             } else {
723                 Debug.assertTrue(false, "Internal error.");
724             }
725         }
726
727         /* build a globle mapper */
728         mapper = ((Expression) aExprs.get(0)).getMapper();
729
730         try {
731             mapper = (Mapper) mapper.clone();
732         } catch (CloneNotSupportedException JavaDoc e) {
733             throw new XQueryException(e.getMessage());
734         }
735
736         int sqlWrapperPartBitMap = 1;
737         mapper.setPart(sqlWrapperPartBitMap);
738         for (int i = 1; i < aExprs.size(); i++) {
739             Mapper tmpMapper = ((Expression) aExprs.get(i)).getMapper();
740             sqlWrapperPartBitMap = sqlWrapperPartBitMap << 1;
741             tmpMapper.setPart(sqlWrapperPartBitMap);
742             mapper.merge(tmpMapper);
743         }
744
745         Numbering num = new Numbering(mapper.getIdentifierList(), args.size());
746         num.number();
747         mapper.setNumbering(num);
748
749         List mapItemList = mapper.getMapItemList();
750         for (int i = 0; i < mapItemList.size(); i++) {
751             MapItem mapItem = (MapItem) mapItemList.get(i);
752             if (mapItem.isLeafPath()) {
753                 Expression relatedExpr = mapItem.getRelatedExpression();
754                 relatedExpr.accept(_typeVistor);
755             }
756         }
757
758         /* rebuild select list of each participating relation */
759         sqlWrapperPartBitMap = 1;
760         RenameItem partAttr = null;
761         RenameItem numberAttr = null;
762         int numbers[];
763         int number;
764         List sortSpecList = null;
765         SortSpecification sortSpec = null;
766         AttributeExpression sortExpr = null;
767         XQueryExpression sortXExpr = null;
768         Expression projectItem = null;
769         for (int i = 0; i < aExprs.size(); i++) {
770             // Debug.assertTrue(aExprs.get(i) instanceof UnOpProject,"aExprs.get(i) instanceof UnOpProject");
771
project = (UnOpProject) aExprs.get(i);
772
773             reBuildSelectList(project, ((Expression) aExprs.get(i)).getMapper(), mapper, 0 == i);
774             if (0 == i) {
775                 rebuildSortSpecListList(mapper, sortSpecListList);
776             }
777
778             project.setMapper(mapper);
779
780             LitInteger part = new LitInteger(sqlWrapperPartBitMap);
781             partAttr = new RenameItem(part, "SQLWrapper_Part");
782             project.addItem(partAttr);
783
784             numbers = num.getNumbersForQuery(i + 1);
785             for (int j = 1; j < numbers.length; j++) {
786                 number = numbers[j];
787                 numberAttr = new RenameItem(new LitInteger(number), NUMBER_COLUMN_PREFIX + Integer.toString(j));
788                 project.addItem(numberAttr);
789             }
790
791             sqlWrapperPartBitMap = sqlWrapperPartBitMap << 1;
792         }
793         MapItem sqlWrapperPart = new MapItem(partAttr.getName(), null, partAttr.getName(), null);
794
795         mapper.setPartAttribute(partAttr);
796
797         retVal = new BinOpMerge((Expression) aExprs.get(0), (Expression) aExprs.get(1));
798         for (int i = 2; i < aExprs.size(); i++) {
799             retVal = new BinOpMerge(retVal, (Expression) aExprs.get(i));
800         }
801         retVal.setMapper(mapper);
802
803         /* generate UnOpSort */
804         num._mapper = mapper;
805
806         num.setSortSpecListList(sortSpecListList);
807         sortSpecList = num.getSortList();
808         retVal = new UnOpSort(retVal, sortSpecList);
809
810         retVal.setMapper(mapper);
811         _returnStack.push(retVal);
812     }
813
814     private List rebuildSortSpecListList(Mapper mapper, List sortSpecListList) {
815         SortSpecification sortSpec = null;
816         AttributeExpression sortExpr = null;
817         XQueryExpression xExpr = null;
818         List sortSpecList = null;
819
820         List mapItemList = new ArrayList();
821         MapItem mapItem = null;
822         String JavaDoc attrName = null;
823
824         for (int i = 0; i < sortSpecListList.size(); i++) {
825             sortSpecList = (List) sortSpecListList.get(i);
826             if (null == sortSpecList) {
827                 continue;
828             }
829             for (int j = sortSpecList.size() - 1; j >= 0; j--) {
830                 sortSpec = (SortSpecification) sortSpecList.get(j);
831                 sortExpr = (AttributeExpression) sortSpec.getSortExpression();
832                 mapItem = findMapItem(mapper, sortExpr);
833                 Debug.assertTrue(null != mapItem && mapItem.isLeafPath(), "null !=mapItem && mapItem.isLeafPath()");
834                 if (mapItemList.contains(mapItem)) {
835                     /* */
836                     sortSpecList.remove(j);
837                 } else {
838                     mapItemList.add(mapItem);
839                     attrName = mapItem.getItemName();
840                     sortExpr.setAttribute(attrName);
841                 }
842             }
843         }
844         return sortSpecListList;
845     }
846
847     private MapItem findMapItem(Mapper mapper, Expression expr) {
848         MapItem retVal = null;
849
850         String JavaDoc strXExpr = expr.getOrginalXExpr().toString();
851
852         retVal = mapper.map(strXExpr);
853         if (null == retVal) {
854             int index = strXExpr.indexOf("/child::text()");
855             if (-1 == index) {
856                 strXExpr += "/child::text()";
857             } else {
858                 strXExpr = strXExpr.substring(0, index);
859             }
860             retVal = mapper.map(strXExpr);
861         }
862         return retVal;
863     }
864
865     protected String JavaDoc insertNullItem(UnOpProject project, int index, MapItem mapItem) {
866         Expression nullItem = new LitNull();
867         SqlTypeAtom itemType = (SqlTypeAtom) mapItem.getRelatedExpression().getType();
868         DbType primitiveType = (DbType) itemType.getType();
869         nullItem = new AfCast(nullItem, primitiveType);
870
871         nullItem = new RenameItem(nullItem, mapItem.getItemName());
872         Expression newExpr = project.insertItem(index, nullItem);
873
874         return newExpr.getName();
875     }
876
877     protected void reBuildSelectList(UnOpProject project, Mapper local, Mapper global, boolean updateMap) {
878         List globalItems = global.getMapItemList();
879         List localItems = local.getMapItemList();
880         List selectItems = project.getItemList();
881
882         int iG = 0; /* a pointer to globalItems */
883         int leafPathCounter = 0; /* count the number of leaf path */
884         int iS = 0; /* a pointer to selectlItems */
885
886         MapItem localItem;
887         MapItem globalItem;
888         int j = 0;
889         for (iG = 0; iG < globalItems.size(); iG++) {
890             globalItem = (MapItem) globalItems.get(iG);
891             if (globalItem.isLeafPath()) {
892                 leafPathCounter++;
893                 if (null == local.map(globalItem.getPath())) {
894                     String JavaDoc newName = insertNullItem(project, leafPathCounter - 1, globalItem);
895                     if (updateMap) {
896                         globalItem.setItemName(newName);
897                     }
898                 }
899             }
900         }
901     }
902
903     public void visit(ListOpArithExpression arg) throws XQueryException {
904         Expression retVal = null;
905
906         /**2.5.1 Arithmetic operators
907          * Syntax
908          * AdditiveExpr ::= Expr ("+" | "-") Expr
909          * MultiplicativeExpr ::= Expr ("*" | "div" | "mod") Expr
910          * UnaryExpr ::= ("-" | "+") Expr
911          *
912          * XQuery provides the usual arithmetic operators for addition, subtraction,
913          * multiplication, division, and modulus, in the usual binary and unary forms
914          * and with the usual meanings.
915          *
916          * When both operands of an arithmetic operator are numeric, the result is
917          * straightforward. When one or more operands is a node, the content of the
918          * node is extracted by an implicit call to the data function and converted
919          * to a number before the operation is performed; if this conversion is not
920          * possible, an error results. When one operand is a number and the other
921          * is a sequence of numbers, the result of the operator is a sequence that
922          * is created by applying the operator pairwise to the numeric operand and
923          * each individual member of the sequence operand, preserving the original
924          * order.
925          */

926
927         XQueryExpression xLOprnd = arg.getLeftOperand();
928         XQueryExpression xROprnd = arg.getRightOperand();
929         int xOprtr = arg.getOperator();
930         SqlType lType = _typeInterpreter.interprete(xLOprnd.getQType());
931         SqlType rType = _typeInterpreter.interprete(xROprnd.getQType());
932
933         xLOprnd.accept(this);
934         Expression aLOprnd = (Expression) _returnStack.pop();
935
936         xROprnd.accept(this);
937         Expression aROprnd = (Expression) _returnStack.pop();
938
939         /* verify operand types*/
940         if (!lType.isNumeric() || !rType.isNumeric()) {
941             throw new InternalErrorException(MessageLibrary.getMessage("IE_INV_SIG", arg), null);
942         }
943
944         /* translate */
945         if (lType.isAtom() && rType.isAtom()) {
946             /* signature 1 Numeric_Atom <op> Numeric_Atom */
947             retVal = new BinOpArithmetic(xOprtr, aLOprnd, aROprnd);
948         } else {
949             throw new InternalErrorException(MessageLibrary.getMessage("IE_INV_SIG", arg), null);
950         }
951
952         retVal.setOrginalXExpr(arg);
953         _returnStack.push(retVal);
954     }
955
956     protected void VisitColumeArithmeticOperatorAtom(Expression relation, int operator, Expression leftOperand, Expression rightOperand) {
957         /* find out the underlying UnOpProject node */
958         Expression cursor = relation;
959         while (!(cursor instanceof UnOpProject)) {
960             /** @todo binary algebra and join is to treated */
961             cursor = ((UnaryAlgebra) cursor).getOperand();
962         }
963         if (!(cursor instanceof UnOpProject)) {
964             //Trace.exit(this, "VisitColumeArithmeticOperatorAtom");
965
throw new SqlWrapperException(MessageLibrary.getMessage("INT_LOG_ERR"), null);
966         }
967         UnOpProject project = (UnOpProject) cursor;
968
969         /* push the operation into the UnOpProject node */
970         project.arithmeticOperation(operator, leftOperand, rightOperand);
971     }
972
973     public void visit(ListOpCompExpression arg) throws XQueryException {
974         Expression retVal = null;
975
976         int xOprtr = arg.getOperator();
977         // add LARS 06/04/04 to support valuecomp
978
// TODO better!!!
979
if (xOprtr > 5)
980             xOprtr = xOprtr - 6;
981
982         XQueryExpression lXOprnd = arg.getLeftOperand();
983
984         SqlType lOprndType = _typeInterpreter.interprete(lXOprnd.getQType());
985         lXOprnd.accept(this);
986         Expression lOprnd = (Expression) _returnStack.pop();
987
988         XQueryExpression rXOprnd = arg.getRightOperand();
989
990         SqlType rOprndType = _typeInterpreter.interprete(rXOprnd.getQType());
991         rXOprnd.accept(this);
992         Expression rOprnd = (Expression) _returnStack.pop();
993
994         if (lOprndType.isAtom()) {
995             if (rOprndType.isAtom()) {
996                 /* signature : compare ( atomic , atomic ) : boolean */
997                 retVal = new BinOpCompare(xOprtr, lOprnd, rOprnd);
998             } else if (rOprndType.isColumn()) {
999                 /* signature : compare ( atomic , column ) : boolean */
1000                rOprnd = removeUselessSort(rOprnd);
1001                retVal = new BinOpCompareAny(xOprtr, lOprnd, rOprnd);
1002            } else if (rOprndType.isTuple()) {
1003                /* signature : compare ( atomic, tuple ) : boolean */
1004                Debug.assertTrue(false, "NYI!");
1005            } else
1006                throw new InternalErrorException(MessageLibrary.getMessage("IE_INV_SIG", arg), null);
1007        } else if (rOprndType.isAtom()) {
1008            if (lOprndType.isColumn()) {
1009                /* signature : compare ( column , atomic ) : boolean */
1010                lOprnd = removeUselessSort(lOprnd);
1011                retVal = new BinOpCompareAny(inverseCompareOperator(xOprtr), rOprnd, lOprnd);
1012            } else if (lOprndType.isTuple()) {
1013                /* signature : compare ( tuple , atomic ) : boolean */
1014                Debug.assertTrue(false, "NYI!");
1015            } else
1016                throw new InternalErrorException(MessageLibrary.getMessage("IE_INV_SIG", arg), null);
1017        } else if (lOprndType.isColumn() && rOprndType.isColumn()) {
1018            /* signature : compare ( column , column ) : boolean */
1019            retVal = visitColumnCompareColumn(xOprtr, lOprnd, rOprnd);
1020        } else
1021            throw new InternalErrorException(MessageLibrary.getMessage("IE_INV_SIG", arg), null);
1022
1023        retVal.setOrginalXExpr(arg);
1024        _returnStack.push(retVal);
1025    }
1026
1027    protected Expression visitColumnCompareColumn(int operator, Expression leftOperand, Expression rightOperand) {
1028        /* make out AttributeExpression for leftOperand */
1029        Expression column = (Expression) ((Relation) leftOperand).nameTest("*").get(0);
1030        String JavaDoc attrName = column.getName();
1031        AttributeExpression leftAttribute = new AttributeExpression(null, attrName);
1032        leftAttribute.setUnderlyingExpr(column);
1033
1034        column = (Expression) ((Relation) rightOperand).nameTest("*").get(0);
1035        attrName = column.getName();
1036        AttributeExpression rightAttribute = new AttributeExpression(null, attrName);
1037        rightAttribute.setUnderlyingExpr(column);
1038
1039        /* translation for =,!= */
1040        // TODO implement more performent translation for >,>=,<,<= */
1041
Join join = new Join();
1042
1043        RenameRelation left = new RenameRelation(leftOperand, "left");
1044        join.addOperand(left);
1045        RenameRelation right = new RenameRelation(rightOperand, "right");
1046        join.addOperand(right);
1047
1048        leftAttribute.setTableInstance(left);
1049        rightAttribute.setTableInstance(right);
1050        BinOpCompare predicate = new BinOpCompare(operator, leftAttribute, rightAttribute);
1051        join.addPredicate(predicate);
1052
1053        return new UnOpExists(join);
1054    }
1055
1056    protected int inverseCompareOperator(int comparisonOperator) {
1057        int retVal = -1;
1058        switch (comparisonOperator) {
1059            case LT_COMPOP :
1060                retVal = GT_COMPOP;
1061                break;
1062            case GT_COMPOP :
1063                retVal = LT_COMPOP;
1064                break;
1065            case GEQ_COMPOP :
1066                retVal = LEQ_COMPOP;
1067                break;
1068            case LEQ_COMPOP :
1069                retVal = GEQ_COMPOP;
1070                break;
1071            case EQ_COMPOP :
1072                retVal = EQ_COMPOP;
1073                break;
1074            case NEQ_COMPOP :
1075                retVal = NEQ_COMPOP;
1076            default :
1077
1078                break;
1079        }
1080
1081        return retVal;
1082    }
1083
1084    public void visit(ListOpEXCEPTExpression arg) throws XQueryException {
1085        throw new SqlWrapperException(MessageLibrary.getMessage("T_N_SUP_EXPR", arg + " : " + arg.getClass()), null);
1086    }
1087
1088    public void visit(ListOpINTERSECTExpression arg) throws XQueryException {
1089        throw new SqlWrapperException(MessageLibrary.getMessage("T_N_SUP_EXPR", arg + " : " + arg.getClass()), null);
1090    }
1091
1092    public void visit(ListOpUNIONExpression arg) throws XQueryException {
1093        throw new SqlWrapperException(MessageLibrary.getMessage("T_N_SUP_EXPR", arg + " : " + arg.getClass()), null);
1094    }
1095
1096    public void visit(LocatedExpression arg) throws XQueryException {
1097        /** treat ablolute locatedExpression
1098         * ablolute locatedExpression
1099         */

1100        List steps = arg.getSteps();
1101
1102        int numSteps = steps.size();
1103        Step step = (Step) steps.get(numSteps - 1);
1104        step.setQType(arg.getQType());
1105
1106        Expression prefixAlgebraExpr = null;
1107        /* the algebra translation of a prefix path expression */
1108        QType prefixQType = null;
1109
1110        /* for inner LocatedExpression , convert the context to prefixQType and prefixAlgebraExpr */
1111        if (arg.getContext()) {
1112            /* case : in predicate of LocatedExpression or in Sort expression , there are often
1113            * LocatedExpressions that base on a context
1114            * eg. offered_by/data()
1115            * Collection("SQLWrapper1:items")/items[offered_by/text() = $U/userid]
1116            */

1117            Context context = (Context) _typeContextStack.peek();
1118
1119            /* make out prefixAlgebraExpr */
1120            prefixQType = context.qType;
1121            SqlType xExprType = _typeInterpreter.interprete(prefixQType);
1122
1123            /* find out underlying table instance */
1124            Set tableInstanceSet = ((Relation) context.aExpr).providedTableInstances();
1125            Object JavaDoc[] tableInstances = tableInstanceSet.toArray();
1126            Debug.assertTrue(1 == tableInstances.length, "1 == tableInstances.length");
1127            // RenameRelation tableInstance = (RenameRelation)tableInstances[0];
1128
RenameRelation tableInstance;
1129            if (tableInstances[0] instanceof RenameRelation)
1130                tableInstance = (RenameRelation) tableInstances[0];
1131            else
1132                tableInstance = null;
1133
1134            if (xExprType.isColumn()) {
1135                // case 1_2 For $I In Collection("SqlWrapper1:items")/items/description [ ]
1136
List attributes = ((Relation) context.aExpr).nameTest("*");
1137                Debug.assertTrue(1 == attributes.size(), "1== attributes.size()");
1138                Expression attribute = (Expression) attributes.get(0);
1139
1140                prefixAlgebraExpr = new AttributeExpression(tableInstance, attribute.getName());
1141                ((AttributeExpression) prefixAlgebraExpr).setUnderlyingExpr(attribute);
1142
1143            } else if (xExprType.isRelation()) {
1144                // case 1_1 For $I In Collection("SqlWrapper1:items")/items[]
1145
prefixAlgebraExpr = new AttributeExpression(tableInstance, "*");
1146            }
1147            /* make out prefixQType */
1148            // prefixQType = ((QTypeCollection) prefixQType).getCollectionType();
1149
}
1150
1151        _returnStack.push(prefixAlgebraExpr);
1152        Iterator iter = steps.iterator();
1153        int axis;
1154
1155        while (iter.hasNext()) {
1156            step = (Step) iter.next();
1157            prefixAlgebraExpr = (Expression) _returnStack.pop();
1158            axis = step.getAxis();
1159            switch (axis) {
1160                case Axis.CHILD :
1161                case Axis.NONE :
1162                    visit(step, prefixQType, prefixAlgebraExpr);
1163                    break;
1164                case Axis.SELF :
1165                    XQueryExpression stepXExpr = step.getExpression();
1166                    if (stepXExpr instanceof NodeTest && NodeKind.NODE == ((NodeTest) stepXExpr).getKind()) {
1167                        Expression retVal = prefixAlgebraExpr;
1168                        retVal.setOrginalXExpr(step);
1169                        _returnStack.push(retVal);
1170                        break;
1171                    }
1172                default :
1173                    throw new SqlWrapperException(MessageLibrary.getMessage("T_N_SUP_EXPR", step), null);
1174            }
1175            prefixQType = step.getQType();
1176        }
1177
1178        ((Expression) _returnStack.peek()).setOrginalXExpr(arg);
1179    }
1180
1181    public void visit(QName arg) throws XQueryException {
1182        /* this fonction should only be called when a QName acts as a implicte LocatedExpression
1183        * eg. offered_by, name
1184        * (FOR $U IN Collection("SQLWrapper1:users")/users
1185        * FOR $I IN Collection("SQLWrapper1:items")/items[offered_by = $U/userid]
1186        * RETURN <tag> {$U/name ,$I/itemno , $B/itemno} <tag> ) SORT BY name
1187        */

1188        Context context = (Context) _typeContextStack.peek();
1189        Expression retVal = null;
1190
1191        SqlType conType = null == context.qType ? null : _typeInterpreter.interprete(context.qType);
1192        // conType : SqlType of context
1193
Debug.assertTrue(null != conType, "null!=conType");
1194
1195        if (conType.isRelation()) {
1196
1197            /* case A, eg. Collection("SQLWrapper1:items")/items[offered_by = "U03"] */
1198
1199            /* find out underlying table instance */
1200            Set tableInstanceSet = ((Relation) context.aExpr).providedTableInstances();
1201            Object JavaDoc[] tableInstances = tableInstanceSet.toArray();
1202
1203            Debug.assertTrue(1 == tableInstances.length, "1 == tableInstances.length");
1204            // RenameRelation tableInstance = (RenameRelation)tableInstances[0];
1205
RenameRelation tableInstance;
1206            if (tableInstances[0] instanceof RenameRelation)
1207                tableInstance = (RenameRelation) tableInstances[0];
1208            else
1209                tableInstance = null;
1210
1211            String JavaDoc attrName = arg.getLocalName();
1212            if (attrName.equals("*"))
1213                throw new NotSupport("WildCard(*) in localName is not supported", null);
1214
1215            /* find out underlying expression. */
1216            List underlyingExprs = ((Relation) context.aExpr).nameTest(attrName);
1217            Debug.assertTrue(1 == underlyingExprs.size(), "1==underlyingExprs.size()");
1218            Expression underlyingExpr = (Expression) underlyingExprs.get(0);
1219            AttributeExpression attrExpr = new AttributeExpression(tableInstance, underlyingExpr.getName());
1220            attrExpr.setUnderlyingExpr(underlyingExpr);
1221
1222            retVal = attrExpr;
1223        } else {
1224            throw new SqlWrapperException(MessageLibrary.getMessage("T_N_SUP_EXPR", arg + " : " + arg.getClass()), null);
1225        }
1226
1227        retVal.setOrginalXExpr(arg);
1228        _returnStack.push(retVal);
1229    }
1230
1231    public void visit(QuantifiedExpression arg) throws XQueryException {
1232        /* create a new VariableTable for the new scope*/
1233        VariableTable newVT = new VariableTable();
1234        newVT.setDefautVariableTable(_variableTable);
1235        _variableTable = newVT;
1236        Expression retVal = null;
1237
1238        /* generate algebra for FOR,LET clause */
1239        List variables = arg.getVariables();
1240        Iterator iter = variables.iterator();
1241
1242        List tableInstanceList = new ArrayList();
1243        List bindingTypeList = new ArrayList();
1244        List pseudoIdPathList = new ArrayList();
1245
1246        /* for the case of a artificial for clause */
1247        String JavaDoc pseudoIdPath = null;
1248        List predicateListAddedByForBinding = null;
1249
1250        while (iter.hasNext()) {
1251            Variable variable = ((Variable) iter.next());
1252            VarMappingInfo varInfo = visitForBinding(variable);
1253            if (varInfo != null) {
1254                tableInstanceList.add(varInfo.relation);
1255            } else {
1256                visit(variable);
1257                Expression atomicExpr = (Expression) _returnStack.pop();
1258                if (!(atomicExpr instanceof Literal)) {
1259                    if (predicateListAddedByForBinding == null)
1260                        predicateListAddedByForBinding = new ArrayList();
1261                    predicateListAddedByForBinding.add(new UnOpIsNull(atomicExpr, true));
1262                }
1263                // dit que je n'aurai plus de for $v in 1 , 2002-03-07 // SR 06/08/03 c'est faux cf UCR11
1264
if (variable.getExpression() instanceof ValueInteger) {
1265                    pseudoIdPath = "$" + variable.getVarName().getName();
1266                    pseudoIdPathList.add(pseudoIdPath);
1267                }
1268            }
1269        }
1270
1271        XQueryExpression xPredicate = arg.getConstraintExpresson();
1272        xPredicate.accept(this);
1273        Expression aPredicate = (Expression) _returnStack.pop();
1274        if (Constants.EVERY_QUANTIFIER == arg.getKind())
1275            aPredicate = new UnOpNot(aPredicate);
1276
1277        if (1 == tableInstanceList.size()) {
1278            retVal = new UnOpRestrict((Expression) tableInstanceList.get(0), aPredicate);
1279            if (Constants.SOME_QUANTIFIER == arg.getKind()) {
1280                retVal = new UnOpExists(retVal, false);
1281            } else // Constants.EVERY_QUANTIFIER == arg.getKind())
1282
retVal = new UnOpExists(retVal, true);
1283        } else if (1 < tableInstanceList.size()) {
1284            ArrayList aPredicates = new ArrayList(1);
1285            aPredicates.add(aPredicate);
1286            retVal = new Join(tableInstanceList, aPredicates);
1287
1288            Value val = new ValueInteger("1", null);
1289            val.accept(this);
1290            //((Variable)variables.get(0)).accept(this);
1291
Expression aExpr = (Expression) _returnStack.pop();
1292            ArrayList selectList = new ArrayList(1);
1293            selectList.add(aExpr);
1294
1295            retVal = new UnOpProject(retVal, selectList, false, _attIDProvider);
1296            Mapper mapper = new Mapper();
1297            mapper.createMap(((UnOpProject) retVal).getItemList());
1298            retVal.setMapper(mapper);
1299
1300            if (Constants.SOME_QUANTIFIER == arg.getKind())
1301                retVal = new UnOpExists(retVal, false);
1302            else // Constants.EVERY_QUANTIFIER == arg.getKind())
1303
retVal = new UnOpExists(retVal, true);
1304
1305            //remove the VariableTable from VariableTable chaine
1306
_variableTable = _variableTable.getDefautVariableTable();
1307        }
1308
1309        retVal.setOrginalXExpr(arg);
1310        _returnStack.push(retVal);
1311    }
1312
1313    public void visit(SortedExpression arg) throws XQueryException {
1314        Expression retVal = null;
1315
1316        /* check type */
1317        XQueryExpression xOprnd = arg.getExpression();
1318        SqlType oprndType = _typeInterpreter.interprete(xOprnd.getQType());
1319        if (!oprndType.isRelation() && !oprndType.isColumn()) {
1320            throw new SqlWrapperException(MessageLibrary.getMessage("T_N_SUP_EXPR", arg + " : " + arg.getClass()), null);
1321        }
1322
1323        xOprnd.accept(this);
1324        retVal = (Expression) _returnStack.pop();
1325
1326        Context context = new Context();
1327        context.xExpr = xOprnd;
1328        context.aExpr = retVal;
1329        context.qType = xOprnd.getQType();
1330        _typeContextStack.push(context);
1331
1332        ArrayList aSortSpecList = new ArrayList();
1333        XQueryExpression xSortSpec;
1334
1335        Expression aSortExpr;
1336        int aDirection;
1337        SortSpecification aSortSpec;
1338
1339        Iterator iter = arg.getSortClauses().iterator();
1340        while (iter.hasNext()) {
1341            xSortSpec = (XQueryExpression) iter.next();
1342            xSortSpec.accept(this);
1343
1344            aSortExpr = (Expression) _returnStack.pop();
1345            // OLIVIER - W3C WD 16 August 2002
1346
//aDirection = xSortSpec.getOrder();
1347
aDirection = xSortSpec.getOrder(0);
1348
1349            aSortSpec = new SortSpecification(aSortExpr, aDirection);
1350            aSortSpecList.add(aSortSpec);
1351        }
1352        retVal = new UnOpSort(retVal, aSortSpecList);
1353
1354        _typeContextStack.pop();
1355
1356        retVal.setOrginalXExpr(arg);
1357        _returnStack.push(retVal);
1358    }
1359
1360    public void visit(Step arg) throws XQueryException {
1361        Debug.assertTrue(false, "Function \"visit(Step arg)\" should not be called.");
1362    }
1363
1364    protected void visit(Step arg, QType prefixQType, Expression prefixAlgebraExpr) throws XQueryException {
1365        Expression retVal = null;
1366        Expression algebraExpr;
1367        XQueryExpression stepXExpr = arg.getExpression();
1368        // the XQueryExpression contained in the Step
1369

1370        SqlType pType = null == prefixQType ? null : _typeInterpreter.interprete(prefixQType);
1371        // pType : SqlType of prefix path
1372
SqlType tType = _typeInterpreter.interprete(arg.getQType());
1373        // tType : SqlType of this step
1374

1375        if (null == prefixQType && null == prefixAlgebraExpr) {
1376            /* case 0 eg. Collection("SQLWrapper1:items") */
1377            /* case 0 eg. $I */
1378            arg.getExpression().accept(this);
1379
1380            retVal = (Expression) _returnStack.pop();
1381        } else if (prefixAlgebraExpr instanceof PseudoExpression) {
1382            if (!(stepXExpr instanceof QName)) {
1383                throw new SqlWrapperException(MessageLibrary.getMessage("T_N_SUP_EXPR", arg), null);
1384            }
1385
1386            String JavaDoc tableName = ((QName) stepXExpr).getLocalName();
1387            CollectionName colName = ((PseudoExpression) prefixAlgebraExpr).getCollectionName();
1388            colName.setTable(tableName);
1389
1390            List tableList = _mdm.findTables(colName);
1391
1392            org.xquark.extractor.metadata.Table mTable = null;
1393
1394            if (null != tableList && 1 == tableList.size()) {
1395                mTable = (org.xquark.extractor.metadata.Table) tableList.get(0);
1396            } else if (null == tableList || 1 > tableList.size()) {
1397                throw new SqlWrapperException(MessageLibrary.getMessage("IE_TAB_NOT_FND", arg));
1398            } else { /* tableList.size() > 1 */
1399                throw new SqlWrapperException(MessageLibrary.getMessage("E_AMBG", arg));
1400            }
1401            retVal = new Table(mTable);
1402            retVal = new RenameRelation(retVal, _relIDProvider);
1403        } else if (pType.isRelation() && tType.isRelation()) {
1404            Debug.assertTrue(stepXExpr instanceof QName, "stepXExpr instanceof QName");
1405
1406            String JavaDoc localName = ((QName) stepXExpr).getLocalName();
1407            if (localName.equals("*")) {
1408                throw new NotSupport("WildCard(*) in localName is not supported", null);
1409            }
1410
1411            int prefixTypeItemNumber = ((SqlTypeStructure) pType).getAttributes().size();
1412            int thisTypeItemNumber = ((SqlTypeStructure) tType).getAttributes().size();
1413            if (prefixTypeItemNumber == thisTypeItemNumber) {
1414                /* case 1_a eg. Collection("SQLWrapper1:items")/items[iteno>"1002"][end_date>"01/05/2000"] */
1415                /* there is nothing to do for the NameTest (items) */
1416                retVal = prefixAlgebraExpr;
1417            } else {
1418                /* case 1_b eg.
1419                 * Let $J = ( FOR $U IN Collection("SQLWrapper1:users")/users
1420                 * for $I IN Collection("SQLWrapper1:items")/items[offered_by = $U/userid]
1421                 * FOR $B IN Collection("SQLWrapper1:bids") /bids
1422                 * RETURN <tag> {$U/name ,$I/itemno , $B/itemno} <tag>
1423                 * )
1424                 * FOR $R IN $J/itemno[...] // !!: $J/itemno
1425                 * RETURN ( $R )
1426                 * In "$J/itemno" , the type of $J and $J/itemno are both relation ,
1427                 * but we can distinguish this case with case 1_a by the the number
1428                 * of attributes in the relation.
1429                 */

1430                Debug.assertTrue(stepXExpr instanceof QName, "stepXExpr instanceof QName");
1431
1432                String JavaDoc name = ((QName) stepXExpr).getLocalName();
1433                if (name.equals("*")) {
1434                    throw new NotSupport("WildCard(*) in localName is not supported", null);
1435                }
1436
1437                List attrList = ((Relation) prefixAlgebraExpr).nameTest(name);
1438                Debug.assertTrue(attrList.size() > 1, "attrList.size()>1");
1439
1440                List selectList = new ArrayList();
1441                Iterator iter = attrList.iterator();
1442                AttributeExpression attr;
1443                while (iter.hasNext()) {
1444                    Object JavaDoc item = iter.next();
1445                    attr = new AttributeExpression(new RenameRelation(prefixAlgebraExpr, _relIDProvider), ((Expression) item).getName());
1446                    selectList.add(attr);
1447                }
1448                retVal = new UnOpProject(prefixAlgebraExpr, selectList, false, _attIDProvider);
1449            }
1450        } else if (pType.isRelation() && tType.isColumn()) {
1451            // case 2 eg. Collection("SQLWrapper1:items")/items[iteno>"1002"][end_date>"01/05/2000"]/description
1452

1453            Debug.assertTrue(stepXExpr instanceof QName, "stepXExpr instanceof QName");
1454            String JavaDoc attrName = ((QName) stepXExpr).getLocalName();
1455            if (attrName.equals("*")) {
1456                throw new NotSupport("WildCard(*) in localName is not supported", null);
1457            }
1458
1459            if (!(prefixAlgebraExpr instanceof UnOpProject)) {
1460
1461                /*find out underlying table instance */
1462                Set tableInstanceSet = ((Relation) prefixAlgebraExpr).providedTableInstances();
1463                Object JavaDoc[] tableInstances = tableInstanceSet.toArray();
1464                Debug.assertTrue(1 == tableInstances.length, "1 == tableInstances.length");
1465                // RenameRelation tableInstance = (RenameRelation)tableInstances[0];
1466
RenameRelation tableInstance;
1467                if (tableInstances[0] instanceof RenameRelation) {
1468                    tableInstance = (RenameRelation) tableInstances[0];
1469                } else {
1470                    tableInstance = null;
1471                }
1472
1473                /* create AttributeExpression*/
1474                List underlyingExprs = ((Relation) prefixAlgebraExpr).nameTest(attrName);
1475                Debug.assertTrue(1 == underlyingExprs.size(), "1==underlyingExprs.size()");
1476                Expression underlyingExpr = (Expression) underlyingExprs.get(0);
1477                AttributeExpression attrExpr = new AttributeExpression(tableInstance, underlyingExpr.getName());
1478                attrExpr.setUnderlyingExpr(underlyingExpr);
1479
1480                retVal = new UnOpProject(prefixAlgebraExpr, _attIDProvider);
1481                ((UnOpProject) retVal).addItem(attrExpr);
1482            } else {
1483                /* find out the selected expression. */
1484                List itemList = ((Relation) prefixAlgebraExpr).nameTest(attrName);
1485                Debug.assertTrue(1 == itemList.size(), "1==itemList.size()");
1486                Expression item = (Expression) itemList.get(0);
1487                /* replace old UnOpPreject*/
1488                retVal = new UnOpProject(((UnOpProject) prefixAlgebraExpr).getOperand(), item, _attIDProvider);
1489            }
1490        } else if (pType.isColumn()) {
1491            // case 3 eg. Collection("SQLWrapper1:items")/items/description/text()
1492

1493            Debug.assertTrue((stepXExpr instanceof NodeTest), "(stepXExpr instanceof NodeType)");
1494            NodeTest nodeType = (NodeTest) stepXExpr;
1495            Debug.assertTrue((nodeType.getKind() == NodeKind.TEXT), "nodeType.getKind() == NodeKind.TEXT");
1496
1497            if (prefixAlgebraExpr instanceof UnOpProject) {
1498                UnOpProject project = (UnOpProject) prefixAlgebraExpr;
1499                Expression item = (Expression) project.getItemList().get(0);
1500                DbType string = new DbType(java.sql.Types.VARCHAR);
1501                item = new XfCast(item, string);
1502                project.setItem(0, item);
1503            } else {
1504                Debug.assertTrue(prefixAlgebraExpr instanceof Table, "prefixAlgebraExpr instanceof Table");
1505                Debug.nyi("table with only one column");
1506            }
1507            retVal = prefixAlgebraExpr;
1508        } else if (pType.isTuple()) {
1509            /* case A, eg. $I/itemno ;$I/description
1510             * FOR $I IN Collection("SQLWrapper1:items")/items[offered_by = $U/userid]
1511             * RETURN <tag> {$I/itemno , $I/description } <tag>
1512             */

1513
1514            /* find out tableInstance*/
1515            RenameRelation ti = null;
1516
1517            if (prefixAlgebraExpr instanceof TupleExpression) {
1518                ti = ((TupleExpression) prefixAlgebraExpr).getTableInstance();
1519            } else if (prefixAlgebraExpr instanceof AttributeExpression) {
1520                ti = ((AttributeExpression) prefixAlgebraExpr).getTableInstance();
1521            } else {
1522                throw new SqlWrapperException("internal logic error", null);
1523            }
1524
1525            /* find items (in the tuple) whoes name is QName */
1526            Debug.assertTrue(stepXExpr instanceof QName, "stepXExpr instanceof QName");
1527            QName qName = (QName) stepXExpr;
1528            String JavaDoc name = qName.getLocalName();
1529            if (name.equals("*")) {
1530                throw new NotSupport("WildCard(*) in localName is not supported", null);
1531            }
1532
1533            /* find out underlying expression */
1534            List attributes = ti.nameTest(name);
1535            Debug.assertTrue(1 <= attributes.size(), "1<=attributes.size()");
1536            /** @todo the case where there are multiplue expressions in "attributes" */
1537            Expression underlyingExpr = (Expression) attributes.get(0);
1538            AttributeExpression attrExpr = new AttributeExpression(ti, underlyingExpr.getName());
1539            attrExpr.setUnderlyingExpr(underlyingExpr);
1540            retVal = attrExpr;
1541        } else if (pType.isAtom()) {
1542
1543            // this branch will be called by relative LocatedExpression
1544
// (predicate or sort sepcification)
1545
if (stepXExpr instanceof NodeTest) {
1546                int kind = ((NodeTest) stepXExpr).getKind();
1547                if (kind == NodeKind.TEXT) {
1548                    DbType dbString = new DbType(java.sql.Types.VARCHAR);
1549                    retVal = new XfCast(prefixAlgebraExpr, dbString);
1550                } else {
1551                    throw new SqlWrapperException("Invalid node type in Located Expression :" + arg);
1552                }
1553            } else {
1554                throw new SqlWrapperException("Invalid step in Located Expression :" + arg);
1555            }
1556        } else {
1557            throw new SqlWrapperException(MessageLibrary.getMessage("G_INT_LOG_ERR", "Type Analysis Error"), null);
1558        }
1559
1560        retVal.setOrginalXExpr(arg);
1561        _returnStack.push(retVal);
1562
1563        // There must not be predicates left in the located expression
1564
// NOTE: the code processing it, is available in CVS history
1565
Debug.assertTrue(arg.getPredicates() == null, "XQuery frontend should not produce predicates in located expression.");
1566    }
1567
1568    public void visit(UnOpMinusExpression arg) throws XQueryException {
1569        Expression retVal = null;
1570
1571        XQueryExpression xExpr = arg.getExpression();
1572        xExpr.accept(this);
1573        Expression aOprnd = (Expression) _returnStack.pop();
1574
1575        boolean minus = arg.getMinus();
1576
1577        if (minus) {
1578            retVal = new UnOpMinus(aOprnd);
1579        } else {
1580            retVal = aOprnd;
1581        }
1582
1583        retVal.setOrginalXExpr(arg);
1584        _returnStack.push(retVal);
1585    }
1586
1587    public void visit(ValueBoolean arg) throws XQueryException {
1588        LitBoolean retVal = new LitBoolean(arg.getBooleanValue());
1589        retVal.setOrginalXExpr(arg);
1590        _returnStack.push(retVal);
1591    }
1592
1593    public void visit(ValueDecimal arg) throws XQueryException {
1594        LitDecimal retVal = new LitDecimal(arg.getDecimalValue());
1595        retVal.setOrginalXExpr(arg);
1596        _returnStack.push(retVal);
1597    }
1598
1599    public void visit(ValueDouble arg) throws XQueryException {
1600        LitDouble retVal = new LitDouble(arg.getDoubleValue());
1601        retVal.setOrginalXExpr(arg);
1602        _returnStack.push(retVal);
1603    }
1604
1605    public void visit(ValueFloat arg) throws XQueryException {
1606        LitFloat retVal = new LitFloat(arg.getFloatValue());
1607        retVal.setOrginalXExpr(arg);
1608        _returnStack.push(retVal);
1609    }
1610
1611    public void visit(ValueInteger arg) throws XQueryException {
1612        LitInteger retVal = new LitInteger(arg.getIntValue());
1613        retVal.setOrginalXExpr(arg);
1614        _returnStack.push(retVal);
1615    }
1616
1617    public void visit(ValueString arg) throws XQueryException {
1618        LitString retVal = new LitString(arg.getStringValue());
1619        retVal.setOrginalXExpr(arg);
1620        _returnStack.push(retVal);
1621    }
1622
1623    public void visit(ValueText arg) throws XQueryException {
1624        throw new SqlWrapperException(MessageLibrary.getMessage("T_N_SUP_EXPR", arg + " : " + arg.getClass()), null);
1625    }
1626
1627    public void visit(Variable arg) throws XQueryException {
1628        Expression translation = (Expression) _variableTable.get(arg.getName());
1629        if (translation != null) {
1630            try {
1631                _returnStack.push(translation.clone());
1632            } catch (CloneNotSupportedException JavaDoc e) {
1633                throw new XQueryException(e.getMessage());
1634            }
1635        } else
1636            throw new SqlWrapperException("Variable " + arg.toString() + " is not defined.");
1637    }
1638
1639    public void visit(org.xquark.xquery.parser.ExternalVariable arg) throws XQueryException {
1640        QName varQName = ((Variable) arg.getObjectValue()).getVarName();
1641        _returnStack.push(new ExternalVariable(varQName.getNameSpace(), varQName.getLocalName(), arg.getQType().getSimpleType()));
1642    }
1643
1644    protected void visitLetBinding(Variable arg) throws XQueryException {
1645        XQueryExpression xExpr = arg.getExpression();
1646        xExpr.accept(this);
1647
1648        Expression retVal = (Expression) _returnStack.pop();
1649        retVal.setOrginalXExpr(arg);
1650        _variableTable.put(arg.getName(), retVal);
1651    };
1652
1653    protected VarMappingInfo visitForBinding(Variable arg) throws XQueryException {
1654        XQueryExpression varXExpr = arg.getExpression();
1655        SqlType xExprType = _typeInterpreter.interprete(varXExpr.getQType());
1656        VarMappingInfo retVal = null;
1657
1658        if ((varXExpr instanceof InternalFunctionCall) && ((InternalFunctionCall) varXExpr).getFuncName().getLocalName().equalsIgnoreCase("SOU")) {
1659            visitLetBinding(arg);
1660        } else if (null == xExprType) {
1661            throw new NotSupport(MessageLibrary.getMessage("T_N_SUP_EXPR", varXExpr.toString()));
1662        } else if (xExprType.isColumn() || xExprType.isRelation()) {
1663            // case 1_1 For $I In Collection("SqlWrapper1:items")/items
1664
// case 1_2 For $I In Collection("SqlWrapper1:items")/items/description
1665
Expression tmpExpr = null;
1666
1667            varXExpr.accept(this);
1668            Expression relation = (Expression) _returnStack.pop();
1669
1670            String JavaDoc varName = arg.getName();
1671            if (relation instanceof RenameRelation)
1672                retVal = new VarMappingInfo(varName, (RenameRelation) relation);
1673            else
1674                retVal = new VarMappingInfo(varName, new RenameRelation(relation, _relIDProvider));
1675
1676            Expression varTrans = null;
1677            if (xExprType.isColumn()) {
1678                // case 1_2 For $I In Collection("SqlWrapper1:items")/items/description
1679
List attributes = ((Relation) relation).nameTest("*");
1680                Debug.assertTrue(1 == attributes.size(), "1== attributes.size()");
1681
1682                Expression attribute = (Expression) attributes.get(0);
1683                varTrans = new AttributeExpression(retVal.relation, attribute.getName());
1684                ((AttributeExpression) varTrans).setUnderlyingExpr(attribute);
1685                varTrans.setOrginalXExpr(arg);
1686            } else if (xExprType.isRelation()) {
1687                varTrans = createTupleExpression(arg, retVal.relation);
1688            }
1689            _variableTable.put(varName, varTrans);
1690        } else
1691            visitLetBinding(arg);
1692
1693        return retVal;
1694    }
1695
1696    protected TupleExpression createTupleExpression(Variable arg, RenameRelation relation) throws XQueryException {
1697        // case 1_1 For $I In Collection("SqlWrapper1:items")/items
1698

1699        SqlTypeStructure stVar = (SqlTypeStructure) _typeInterpreter.interprete(arg.getQType());
1700
1701        List elementNameList = ((SqlTypeStructure) stVar).getNames();
1702        boolean varBindedOnSeq = false;
1703        if (null == elementNameList.get(0)) {
1704            /* Variable arg is binded to a squence */
1705            relation.accept(_typeVistor);
1706            elementNameList = ((SqlTypeStructure) relation.getType()).getNames();
1707            varBindedOnSeq = true;
1708        }
1709
1710        String JavaDoc elementName;
1711
1712        List attrExprs = new ArrayList(); // Attributes in the tuple (varTrans)
1713
Expression attrExpr;
1714
1715        List attrExprsFromNameTest = null; //
1716
Expression exprFromNameTest = null;
1717
1718        Iterator iter = elementNameList.iterator();
1719
1720        XQueryExpression xVirtualExpr = null;
1721        while (iter.hasNext()) {
1722            elementName = (String JavaDoc) iter.next();
1723
1724            attrExprsFromNameTest = ((Relation) relation).nameTest(elementName);
1725            Debug.assertTrue(1 == attrExprsFromNameTest.size(), "1== attributes.size()");
1726            exprFromNameTest = (Expression) attrExprsFromNameTest.get(0);
1727
1728            attrExpr = new AttributeExpression(relation, exprFromNameTest.getName());
1729            ((AttributeExpression) attrExpr).setUnderlyingExpr(exprFromNameTest);
1730
1731            if (!varBindedOnSeq) {
1732                xVirtualExpr = makeVirtualLocatedeExpression(arg, elementName);
1733            }
1734
1735            attrExpr.setOrginalXExpr(xVirtualExpr);
1736            attrExprs.add(attrExpr);
1737        }
1738
1739        return new TupleExpression(relation, attrExprs, arg);
1740    }
1741
1742    private LocatedExpression makeVirtualLocatedeExpression(Variable variable, String JavaDoc elementName) {
1743        try {
1744            /* create a located expression */
1745            ArrayList steps = new ArrayList();
1746            Step step = null;
1747
1748            step = new Step(false, Axis.NONE, variable, null, null);
1749            steps.add(step);
1750
1751            step = new Step(true, Axis.CHILD, new QName(elementName, null), null, null);
1752            steps.add(step);
1753
1754            LocatedExpression retVal = new LocatedExpression(steps, null);
1755
1756            /* find out the QType of this retVal */
1757            QType varQtype = variable.getQType();
1758            if (varQtype instanceof QTypeElement) {
1759                /* find out the sub element whoes name == elementName */
1760                ComplexType varType = (ComplexType) varQtype.getType();
1761                QName varQName = (QName) varQtype.getName();
1762                ElementDeclaration elementDeclaration = varType.getElementDeclaration(varQName.getNameSpace(), elementName);
1763                if (null == elementDeclaration) {
1764                    elementDeclaration = varType.getElementDeclaration(null, elementName);
1765                }
1766
1767                /* create a QTypeElement */
1768                QTypeElement qType = null;
1769                if (null != elementDeclaration) {
1770
1771                    qType = new QTypeElement(new QName(elementDeclaration.getNamespace(), null, elementName, null, null), elementDeclaration, elementDeclaration.getType());
1772                }
1773
1774                Debug.assertTrue(null != qType, "null != qType");
1775                retVal.setQType(qType);
1776            } else if (varQtype instanceof QTypeSequence) {
1777                List qteList = ((QTypeSequence) varQtype).getList();
1778                QTypeElement qType = null;
1779                for (int i = 0; i < qteList.size(); i++) {
1780                    QTypeElement item = (QTypeElement) qteList.get(i);
1781                    if (((QName) item.getName()).getLocalName().equals(elementName)) {
1782                        qType = item;
1783                        break;
1784                    }
1785                }
1786                Debug.assertTrue(null != qType, "null != qType");
1787                retVal.setQType(qType);
1788            }
1789
1790            return retVal;
1791        } catch (XQueryException ex) {
1792            throw new SqlWrapperException(MessageLibrary.getMessage("G_INT_LOG_ERR", "make virtual located expression failed"), ex);
1793        }
1794    }
1795
1796    public void visit(XQueryExpression arg) throws XQueryException {
1797        throw new NotSupport(MessageLibrary.getMessage("T_N_SUP_EXPR", arg.toString() + " : " + arg.getClass()), null);
1798    }
1799
1800    public void visit(XQueryExpressionSequence arg) throws XQueryException {
1801        Expression retVal = null;
1802        List xExprs = arg.getSubExpressions();
1803
1804        /* create structure for the virtual table */
1805        QType qtElementOfCollection = arg.getQType();
1806
1807        // CHANGE LARS 03/05/04 delete obsolete code
1808
if (qtElementOfCollection instanceof QTypeAtom) {
1809            retVal = createLitList(arg);
1810        } else {
1811            throw new XQueryException(MessageLibrary.getMessage("T_N_SUP_EXPR", arg), null);
1812        }
1813        retVal.setOrginalXExpr(arg);
1814        _returnStack.push(retVal);
1815    }
1816
1817    // CHANGE LARS 03/05/04 delete obsolete code
1818

1819    protected LitList createLitList(XQueryExpressionSequence arg) throws XQueryException {
1820        QTypeAtom qta = (QTypeAtom) arg.getQType();
1821
1822        /* add values to retVal */
1823        XQueryExpression xExpr = null;
1824        Expression aExpr = null;
1825        List xExprList = arg.getSubExpressions();
1826        List aExprList = new ArrayList(xExprList.size());
1827
1828        for (int i = 0; i < xExprList.size(); i++) {
1829            xExpr = (Value) xExprList.get(i);
1830            xExpr.accept(this);
1831            aExpr = (Expression) _returnStack.pop();
1832            aExprList.add(aExpr);
1833        }
1834
1835        return new LitList(aExprList);
1836    }
1837
1838    public void visit(FunctionABS arg) throws XQueryException {
1839        Expression retVal = null;
1840        arg.getArgument(0).accept(this);
1841        retVal = (Expression) _returnStack.pop();
1842        retVal = new XfAbs(retVal);
1843        retVal.setOrginalXExpr(arg);
1844        _returnStack.push(retVal);
1845    }
1846
1847    public void visit(FunctionCEILING arg) throws XQueryException {
1848        Expression retVal = null;
1849        arg.getArgument(0).accept(this);
1850        retVal = (Expression) _returnStack.pop();
1851        retVal = new XfCeiling(retVal);
1852        retVal.setOrginalXExpr(arg);
1853        _returnStack.push(retVal);
1854    }
1855
1856    public void visit(FunctionFLOOR arg) throws XQueryException {
1857        Expression retVal = null;
1858        arg.getArgument(0).accept(this);
1859        retVal = (Expression) _returnStack.pop();
1860        retVal = new XfFloor(retVal);
1861        retVal.setOrginalXExpr(arg);
1862        _returnStack.push(retVal);
1863    }
1864
1865    public void visit(FunctionROUND arg) throws XQueryException {
1866        Expression retVal = null;
1867        arg.getArgument(0).accept(this);
1868        retVal = (Expression) _returnStack.pop();
1869        retVal = new XfRound(retVal);
1870        retVal.setOrginalXExpr(arg);
1871        _returnStack.push(retVal);
1872    }
1873
1874    public void visit(FunctionAVG arg) throws XQueryException {
1875        _returnStack.push(visitAggregationFunction(arg, AVG));
1876    }
1877
1878    public void visit(FunctionCOLLECTION arg) throws XQueryException {
1879        Expression retVal = null;
1880        CollectionName colName = new CollectionName(arg.getSourceName(), arg.getCollectionName());
1881
1882        if (null != colName.getTable() && !colName.tableIsWildCard()) {
1883            /* table name is designated, we should be able to find one and only one table in meta-data */
1884
1885            /* case : collection("Extractor:use-case.items") or collection("Extractor:items")
1886             * or collection("Extractor:use-case.items") */

1887            List tableList = _mdm.findTables(colName);
1888            org.xquark.extractor.metadata.Table mTable = null;
1889
1890            if (null != tableList && 1 == tableList.size()) {
1891                mTable = (org.xquark.extractor.metadata.Table) tableList.get(0);
1892            } else if (null == tableList || 1 > tableList.size()) {
1893                throw new SqlWrapperException(MessageLibrary.getMessage("IE_TAB_NOT_FND", arg));
1894            } else { /* tableList.size() > 1 */
1895                throw new SqlWrapperException(MessageLibrary.getMessage("E_AMBG", arg));
1896            }
1897            retVal = new Table(mTable);
1898            retVal = new RenameRelation(retVal, _relIDProvider);
1899        } else {
1900            PseudoExpression ps = new PseudoExpression();
1901            ps.setCollectionName(colName);
1902            retVal = ps;
1903        }
1904
1905        retVal.setOrginalXExpr(arg);
1906        _returnStack.push(retVal);
1907    }
1908
1909    public void visit(FunctionCONCAT arg) throws XQueryException {
1910        Expression retVal = null;
1911
1912        List xArgumentList = arg.getArguments();
1913        int argNumber = xArgumentList.size();
1914
1915        XQueryExpression xArgument = null;
1916        Expression aArgument = null;
1917
1918        if (0 == argNumber) {
1919            retVal = new LitString("");
1920        } else if (1 == argNumber) {
1921            xArgument = (XQueryExpression) xArgumentList.get(0);
1922            xArgument.accept(this);
1923            retVal = (Expression) _returnStack.pop();
1924        } else {
1925            retVal = new XfConcat();
1926            for (int i = 0; i < xArgumentList.size(); i++) {
1927                xArgument = (XQueryExpression) xArgumentList.get(i);
1928                xArgument.accept(this);
1929                aArgument = (Expression) _returnStack.pop();
1930                ((XfConcat) retVal).setArgument(i, aArgument);
1931            }
1932        }
1933
1934        retVal.setOrginalXExpr(arg);
1935        _returnStack.push(retVal);
1936    }
1937
1938    public void visit(FunctionCONTAINS arg) throws XQueryException {
1939        arg.getArgument(0).accept(this);
1940        Expression arg0 = (Expression) _returnStack.pop();
1941
1942        arg.getArgument(1).accept(this);
1943        Expression arg1 = (Expression) _returnStack.pop();
1944
1945        XfContains retVal = new XfContains();
1946        retVal.setArgument(0, arg0);
1947        retVal.setArgument(1, arg1);
1948
1949        retVal.setOrginalXExpr(arg);
1950        _returnStack.push(retVal);
1951    }
1952
1953    public void visit(FunctionCURRENT_DATETIME arg) throws XQueryException {
1954        XfCurrentDateTime retVal = new XfCurrentDateTime();
1955        retVal.setOrginalXExpr(arg);
1956        _returnStack.push(retVal);
1957    }
1958
1959    public void visit(FunctionCOUNT arg) throws XQueryException {
1960        _returnStack.push(visitAggregationFunction(arg, COUNT));
1961    }
1962
1963    public void visit(FunctionDATA arg) throws XQueryException {
1964        Expression retVal = null;
1965
1966        XQueryExpression xArg = arg.getArgument(0);
1967        xArg.accept(this);
1968        retVal = (Expression) _returnStack.pop();
1969        retVal.setOrginalXExpr(arg);
1970
1971        _returnStack.push(retVal);
1972    }
1973
1974    public void visit(FunctionEXISTS arg) throws XQueryException {
1975        Debug.assertTrue(1 == arg.getArguments().size(), "1 == arg.getArguments().size()");
1976
1977        Expression retVal = null;
1978        XQueryExpression xArg = (XQueryExpression) arg.getArgument(0);
1979
1980        xArg.accept(this);
1981        Expression aArg = (Expression) _returnStack.pop();
1982
1983        aArg = removeUselessSort(aArg);
1984
1985        QType xArgQtype = xArg.getQType();
1986        SqlType xArgSqlType = _typeInterpreter.interprete(xArgQtype);
1987
1988        if (xArgSqlType.isRelation() || xArgSqlType.isColumn()) {
1989            retVal = new UnOpExists(aArg, false); /* exists (aArg)*/
1990        } else if (xArgSqlType.isAtom()) {
1991            retVal = new UnOpIsNull(aArg, true); /* aArg IS NOT NULL */
1992        } else if (xArgSqlType.isTuple()) {
1993            TupleExpression tuple = (TupleExpression) aArg;
1994            List itemList = tuple.getItemList();
1995            Expression item = null;
1996            UnOpIsNull isNull = null;
1997
1998            for (int i = 0; i < itemList.size(); i++) {
1999                item = (Expression) itemList.get(i);
2000                isNull = new UnOpIsNull(item, true);
2001                if (null != retVal) {
2002                    retVal = new BinOpBoolean(OR, retVal, isNull);
2003                } else {
2004                    retVal = isNull;
2005                }
2006            }
2007        }
2008
2009        retVal.setOrginalXExpr(arg);
2010        _returnStack.push(retVal);
2011    }
2012
2013    public void visit(FunctionEMPTY arg) throws XQueryException {
2014        Debug.assertTrue(1 == arg.getArguments().size(), "1 == arg.getArguments().size()");
2015
2016        Expression retVal = null;
2017        XQueryExpression xArg = (XQueryExpression) arg.getArgument(0);
2018
2019        xArg.accept(this);
2020        Expression aArg = (Expression) _returnStack.pop();
2021
2022        aArg = removeUselessSort(aArg);
2023
2024        QType xArgQtype = xArg.getQType();
2025        SqlType xArgSqlType = _typeInterpreter.interprete(xArgQtype);
2026
2027        if (xArgSqlType.isRelation() || xArgSqlType.isColumn()) {
2028            retVal = new UnOpExists(aArg, true); /* not exists (aArg)*/
2029        } else if (xArgSqlType.isAtom()) {
2030            retVal = new UnOpIsNull(aArg, false); /* aArg IS NULL */
2031        } else if (xArgSqlType.isTuple()) {
2032            TupleExpression tuple = (TupleExpression) aArg;
2033            List itemList = tuple.getItemList();
2034            Expression item = null;
2035            UnOpIsNull isNull = null;
2036
2037            for (int i = 0; i < itemList.size(); i++) {
2038                item = (Expression) itemList.get(i);
2039                isNull = new UnOpIsNull(item);
2040                if (null != retVal) {
2041                    retVal = new BinOpBoolean(AND, retVal, isNull);
2042                } else {
2043                    retVal = isNull;
2044                }
2045            }
2046        }
2047
2048        retVal.setOrginalXExpr(arg);
2049        _returnStack.push(retVal);
2050    }
2051
2052    public void visit(FunctionDATE arg) throws XQueryException {
2053        XfDate retVal = new XfDate();
2054
2055        XQueryExpression xDate = (XQueryExpression) arg.getArgument(0);
2056        xDate.accept(this);
2057        Expression aArg = (Expression) _returnStack.pop();
2058        retVal.setArgument(0, aArg);
2059
2060        retVal.setOrginalXExpr(arg);
2061        _returnStack.push(retVal);
2062    }
2063
2064    public void visit(FunctionDATETIME arg) throws XQueryException {
2065        XfDateTime retVal = new XfDateTime();
2066
2067        XQueryExpression xDate = (XQueryExpression) arg.getArgument(0);
2068        xDate.accept(this);
2069        Expression aArg = (Expression) _returnStack.pop();
2070        retVal.setArgument(0, aArg);
2071
2072        retVal.setOrginalXExpr(arg);
2073        _returnStack.push(retVal);
2074    }
2075
2076    public void visit(FunctionDISTINCT_VALUES arg) throws XQueryException {
2077        Expression retVal = null;
2078
2079        /* check type */
2080        XQueryExpression xOprnd = arg.getArgument(0);
2081        SqlType oprndType = _typeInterpreter.interprete(xOprnd.getQType());
2082
2083        xOprnd.accept(this);
2084        retVal = (Expression) _returnStack.pop();
2085
2086        if (oprndType.isRelation() || oprndType.isColumn()) {
2087
2088            if (retVal instanceof UnOpProject) {
2089                ((UnOpProject) retVal).setDistinct(true);
2090            } else if (retVal instanceof Table || retVal instanceof RenameRelation || retVal instanceof UnOpRestrict) {
2091                Set tis = ((Relation) retVal).providedTableInstances();
2092                Debug.assertTrue(1 == tis.size(), "1 ==tis.size())");
2093                RenameRelation ti = (RenameRelation) tis.iterator().next();
2094                List attrExprs = new ArrayList();
2095                // Attributes in the tuple (varTrans)
2096
Expression attrExpr;
2097
2098                List attrExprsFromNameTest = ((Relation) retVal).nameTest("*");
2099                //
2100
Expression exprFromNameTest = null;
2101                String JavaDoc name = null;
2102
2103                for (int i = 0; i < attrExprsFromNameTest.size(); i++) {
2104                    exprFromNameTest = (Expression) attrExprsFromNameTest.get(i);
2105                    name = exprFromNameTest.getName();
2106                    attrExpr = new AttributeExpression(ti, name);
2107                    ((AttributeExpression) attrExpr).setUnderlyingExpr(exprFromNameTest);
2108
2109                    attrExprs.add(attrExpr);
2110                }
2111                retVal = new UnOpProject(retVal, _attIDProvider);
2112                ((UnOpProject) retVal).addItemList(attrExprs);
2113                ((UnOpProject) retVal).setDistinct(true);
2114            } else if (retVal instanceof UnOpSort) {
2115                retVal = ((UnOpSort) retVal).getOperand();
2116                ((UnOpProject) retVal).setDistinct(true);
2117            } else {
2118                // TODO: implementation for distinct_values */
2119
Debug.nyi("cas imprevu");
2120            }
2121        } else if (oprndType.isAtom()) {
2122        } else if (oprndType.isTuple() && (xOprnd.getQType() instanceof QTypeElement)) {
2123        } else {
2124            throw new SqlWrapperException(MessageLibrary.getMessage("T_N_SUP_EXPR", arg + " : " + arg.getClass()), null);
2125        }
2126
2127        retVal.setOrginalXExpr(arg);
2128        _returnStack.push(retVal);
2129    }
2130
2131    public void visit(FunctionENDS_WITH arg) throws XQueryException {
2132        arg.getArgument(0).accept(this);
2133        Expression arg0 = (Expression) _returnStack.pop();
2134
2135        arg.getArgument(1).accept(this);
2136        Expression arg1 = (Expression) _returnStack.pop();
2137
2138        XfEndsWith retVal = new XfEndsWith();
2139        retVal.setArgument(0, arg0);
2140        retVal.setArgument(1, arg1);
2141
2142        _returnStack.push(retVal);
2143    }
2144
2145    public void visit(FunctionLOWER_CASE arg) throws XQueryException {
2146        arg.getArgument(0).accept(this);
2147        Expression arg0 = (Expression) _returnStack.pop();
2148
2149        XfLowerCase retVal = new XfLowerCase();
2150        retVal.setArgument(0, arg0);
2151
2152        retVal.setOrginalXExpr(arg);
2153        _returnStack.push(retVal);
2154    }
2155
2156    public void visit(FunctionMAX arg) throws XQueryException {
2157        _returnStack.push(visitAggregationFunction(arg, MAX));
2158    }
2159
2160    protected Expression visitAggregationFunction(PrimitiveFunctionCall arg, int oprtr) throws XQueryException {
2161        Expression retVal = null;
2162
2163        XQueryExpression xOprd = arg.getArgument(0);
2164        SqlType argType = _typeInterpreter.interprete(xOprd.getQType());
2165
2166        xOprd.accept(this);
2167        Expression relation = (Expression) _returnStack.pop();
2168
2169        /* NOTE:
2170         * Removes Sorts in aggregates we don't know how to process at now.
2171         * Sorts might be necessary when XPath expressions like $x[1 to N] will be
2172         * supported. Indeed, ordering may change result of functions like SUM.
2173         */

2174        relation = removeUselessSort(relation);
2175
2176        if (argType.isColumn() || argType.isRelation()) {
2177
2178            /* create UnOpAggregate */
2179            AttributeExpression expr;
2180            Expression tmpExpr = null;
2181            if (argType.isColumn()) {
2182                tmpExpr = (Expression) ((Relation) relation).nameTest("*").get(0);
2183                expr = new AttributeExpression(null, tmpExpr.getName());
2184                expr.setUnderlyingExpr(tmpExpr);
2185            } else { /* argType.isRelation(). This is only possible for count(*) */
2186                Object JavaDoc[] vti = ((Relation) relation).providedTableInstances().toArray();
2187                Debug.assertTrue(vti.length == 1, "vti.length == 1");
2188                if (vti[0] instanceof RenameRelation) {
2189                    expr = new AttributeExpression((RenameRelation) vti[0], "*");
2190                } else {
2191                    relation = new RenameRelation(relation, _relIDProvider);
2192                    expr = new AttributeExpression((RenameRelation) relation, "*");
2193                }
2194            }
2195
2196            FunAggregate aggregationFunction = new FunAggregate(oprtr, expr, false);
2197            aggregationFunction.setOrginalXExpr(arg);
2198            retVal = new UnOpAggregate(_attIDProvider);
2199
2200            ((UnOpAggregate) retVal).setOperand(relation);
2201            ((UnOpAggregate) retVal).insertItemWithoutRename(0, aggregationFunction);
2202
2203            Mapper mapper = new Mapper();
2204            mapper.createMap(((UnOpAggregate) retVal).getItemList());
2205            retVal.setMapper(mapper);
2206
2207            retVal.setOrginalXExpr(arg);
2208        } else if (argType.isAtom()) {
2209            switch (oprtr) {
2210                case AVG :
2211                case MAX :
2212                case MIN :
2213                case SUM :
2214                    retVal = relation;
2215                    retVal.setOrginalXExpr(arg);
2216                    break;
2217                case COUNT :
2218                    retVal = new UnOpIsNull(relation);
2219                    retVal = new IfThenElse(retVal, new LitInteger(0), new LitInteger(1));
2220                    break;
2221                default :
2222                    Debug.assertTrue(false, "invalid aggregation function ( " + arg + ").");
2223            }
2224        } else if (argType.isTuple()) {
2225            /** @todo */
2226            throw new NotSupport(MessageLibrary.getMessage("T_N_SUP_SIG", arg), null);
2227        } else {
2228            throw new NotSupport(MessageLibrary.getMessage("T_N_SUP_SIG", arg), null);
2229        }
2230
2231        retVal.setOrginalXExpr(arg);
2232        return retVal;
2233    }
2234
2235    /**
2236     * Removes Sorts in aggregates or set functions.
2237     * @param relation
2238     * @return
2239     */

2240    private Expression removeUselessSort(Expression relation) {
2241        if (relation instanceof UnOpSort) {
2242            XQueryExpression xqExpr = relation.getOrginalXExpr();
2243            relation = ((UnOpSort) relation).getOperand();
2244            relation.setOrginalXExpr(xqExpr);
2245        }
2246        return relation;
2247    }
2248
2249    public void visit(FunctionMIN arg) throws XQueryException {
2250        _returnStack.push(visitAggregationFunction(arg, MIN));
2251    }
2252
2253    public void visit(FunctionNOT arg) throws XQueryException {
2254        XQueryExpression xOprnd;
2255        Expression aOprnd;
2256        SqlType type;
2257
2258        // check the signature
2259
xOprnd = arg.getArgument(0);
2260        type = _typeInterpreter.interprete(xOprnd.getQType());
2261        if (!type.isBoolean()) {
2262            throw new NotSupport(MessageLibrary.getMessage("T_N_SUP_SIG", "NOT"), null);
2263        }
2264
2265        xOprnd.accept(this);
2266        aOprnd = (Expression) _returnStack.pop();
2267
2268        UnOpNot retVal = new UnOpNot(aOprnd);
2269
2270        retVal.setOrginalXExpr(arg);
2271        _returnStack.push(retVal);
2272    }
2273
2274    public void visit(FunctionNUMBER arg) throws XQueryException {
2275        Debug.assertTrue(1 == arg.getArguments().size(), "1 == arg.getArguments().size()");
2276
2277        Expression retVal = null;
2278        XQueryExpression xArg = arg.getArgument(0);
2279
2280        SqlTypeAtom sqlType = (SqlTypeAtom) _typeInterpreter.interprete(xArg.getQType());
2281        xArg.accept(this);
2282        retVal = (Expression) _returnStack.pop();
2283
2284        if (sqlType.isString()) {
2285            retVal = new XfCast(retVal, new DbType(java.sql.Types.DOUBLE));
2286        } else if (sqlType.isNumeric()) {
2287            /* return retVal */
2288        } else {
2289            throw new InternalErrorException("IE_INV_XEXPR" + arg);
2290        }
2291
2292        retVal.setOrginalXExpr(arg);
2293        _returnStack.push(retVal);
2294    }
2295
2296    public void visit(FunctionDECIMAL arg) throws XQueryException {
2297        Debug.assertTrue(1 == arg.getArguments().size(), "1 == arg.getArguments().size()");
2298
2299        Expression retVal = null;
2300        XQueryExpression xArg = arg.getArgument(0);
2301
2302        SqlTypeAtom sqlType = (SqlTypeAtom) _typeInterpreter.interprete(xArg.getQType());
2303        xArg.accept(this);
2304        retVal = (Expression) _returnStack.pop();
2305
2306        if (sqlType.isString()) {
2307            retVal = new XfCast(retVal, new DbType(java.sql.Types.DECIMAL));
2308        } else if (!sqlType.isNumeric())
2309            throw new InternalErrorException("IE_INV_XEXPR" + arg);
2310
2311        retVal.setOrginalXExpr(arg);
2312        _returnStack.push(retVal);
2313    }
2314
2315    public void visit(FunctionDOUBLE arg) throws XQueryException {
2316        Debug.assertTrue(1 == arg.getArguments().size(), "1 == arg.getArguments().size()");
2317
2318        Expression retVal = null;
2319
2320        XQueryExpression xArg = arg.getArgument(0);
2321
2322        SqlTypeAtom sqlType = (SqlTypeAtom) _typeInterpreter.interprete(xArg.getQType());
2323        xArg.accept(this);
2324        retVal = (Expression) _returnStack.pop();
2325
2326        if (sqlType.isString()) {
2327            retVal = new XfCast(retVal, new DbType(java.sql.Types.DOUBLE));
2328        } else if (!sqlType.isNumeric())
2329            throw new InternalErrorException("IE_INV_XEXPR" + arg);
2330
2331        retVal.setOrginalXExpr(arg);
2332        _returnStack.push(retVal);
2333    }
2334
2335    public void visit(FunctionINTEGER arg) throws XQueryException {
2336        Debug.assertTrue(1 == arg.getArguments().size(), "1 == arg.getArguments().size()");
2337
2338        Expression retVal = null;
2339        XQueryExpression xArg = arg.getArgument(0);
2340
2341        SqlTypeAtom sqlType = (SqlTypeAtom) _typeInterpreter.interprete(xArg.getQType());
2342        xArg.accept(this);
2343        retVal = (Expression) _returnStack.pop();
2344
2345        if (sqlType.isString()) {
2346            retVal = new XfCast(retVal, new DbType(java.sql.Types.INTEGER));
2347        } else if (!sqlType.isNumeric())
2348            throw new InternalErrorException("IE_INV_XEXPR" + arg);
2349
2350        retVal.setOrginalXExpr(arg);
2351        _returnStack.push(retVal);
2352    }
2353
2354    public void visit(FunctionFLOAT arg) throws XQueryException {
2355        Debug.assertTrue(1 == arg.getArguments().size(), "1 == arg.getArguments().size()");
2356
2357        Expression retVal = null;
2358        XQueryExpression xArg = arg.getArgument(0);
2359
2360        SqlTypeAtom sqlType = (SqlTypeAtom) _typeInterpreter.interprete(xArg.getQType());
2361        xArg.accept(this);
2362        retVal = (Expression) _returnStack.pop();
2363
2364        if (sqlType.isString()) {
2365            retVal = new XfCast(retVal, new DbType(java.sql.Types.FLOAT));
2366        } else if (!sqlType.isNumeric())
2367            throw new InternalErrorException("IE_INV_XEXPR" + arg);
2368
2369        retVal.setOrginalXExpr(arg);
2370        _returnStack.push(retVal);
2371    }
2372
2373    public void visit(FunctionSTARTS_WITH arg) throws XQueryException {
2374        arg.getArgument(0).accept(this);
2375        Expression arg0 = (Expression) _returnStack.pop();
2376
2377        arg.getArgument(1).accept(this);
2378        Expression arg1 = (Expression) _returnStack.pop();
2379
2380        XfStartsWith retVal = new XfStartsWith();
2381        retVal.setArgument(0, arg0);
2382        retVal.setArgument(1, arg1);
2383
2384        retVal.setOrginalXExpr(arg);
2385        _returnStack.push(retVal);
2386    }
2387
2388    public void visit(FunctionSTRING arg) throws XQueryException {
2389        Expression retVal = null;
2390
2391        arg.getArgument(0).accept(this);
2392        retVal = (Expression) _returnStack.pop();
2393        retVal = new XfCast(retVal, new DbType(Types.VARCHAR));
2394        retVal.setOrginalXExpr(arg);
2395
2396        _returnStack.push(retVal);
2397    }
2398
2399    public void visit(FunctionSTRING_LENGTH arg) throws XQueryException {
2400        arg.getArgument(0).accept(this);
2401        Expression arg0 = (Expression) _returnStack.pop();
2402
2403        XfStringLength retVal = new XfStringLength();
2404        retVal.setArgument(0, arg0);
2405
2406        retVal.setOrginalXExpr(arg);
2407        _returnStack.push(retVal);
2408    }
2409
2410    public void visit(FunctionSUBSTRING arg) throws XQueryException {
2411        XfSubString retVal = new XfSubString();
2412        arg.getArgument(0).accept(this);
2413        Expression aArg = (Expression) _returnStack.pop();
2414        retVal.setArgument(0, aArg);
2415
2416        arg.getArgument(1).accept(this);
2417        aArg = (Expression) _returnStack.pop();
2418        retVal.setArgument(1, aArg);
2419
2420        if (2 < arg.getArguments().size()) {
2421            arg.getArgument(2).accept(this);
2422            aArg = (Expression) _returnStack.pop();
2423            retVal.setArgument(2, aArg);
2424        }
2425
2426        retVal.setOrginalXExpr(arg);
2427        _returnStack.push(retVal);
2428    }
2429
2430    public void visit(FunctionUPPER_CASE arg) throws XQueryException {
2431        arg.getArgument(0).accept(this);
2432        Expression arg0 = (Expression) _returnStack.pop();
2433
2434        XfUpperCase retVal = new XfUpperCase();
2435        retVal.setArgument(0, arg0);
2436
2437        retVal.setOrginalXExpr(arg);
2438        _returnStack.push(retVal);
2439    }
2440
2441    public void visit(FunctionSUM arg) throws XQueryException {
2442        _returnStack.push(visitAggregationFunction(arg, SUM));
2443    }
2444
2445    public void visit(FunctionTIME arg) throws XQueryException {
2446        XfTime retVal = new XfTime();
2447
2448        XQueryExpression xTime = (XQueryExpression) arg.getArgument(0);
2449        xTime.accept(this);
2450        Expression aArg = (Expression) _returnStack.pop();
2451        retVal.setArgument(0, aArg);
2452
2453        retVal.setOrginalXExpr(arg);
2454        _returnStack.push(retVal);
2455    }
2456
2457    public void visit(FunctionTRUE arg) throws XQueryException {
2458        _returnStack.push(new LitBoolean(true));
2459    }
2460
2461    public void visit(FunctionFALSE arg) throws XQueryException {
2462        _returnStack.push(new LitBoolean(false));
2463    }
2464
2465    protected List decomposePredicate(XQueryExpression predicate, List predicateList) {
2466        if (null == predicateList)
2467            predicateList = new ArrayList();
2468
2469        XQueryExpression xP1 = predicate;
2470        BinOpANDExpression and;
2471
2472        if (xP1 instanceof BinOpANDExpression) {
2473            and = (BinOpANDExpression) xP1;
2474            decomposePredicate(and.getLeftOperand(), predicateList);
2475            decomposePredicate(and.getRightOperand(), predicateList);
2476        } else
2477            predicateList.add(predicate);
2478
2479        return predicateList;
2480    }
2481
2482    protected class Context {
2483        private static final String JavaDoc RCSRevision = "$Revision: 1.52 $";
2484        private static final String JavaDoc RCSName = "$Name: $";
2485
2486        public XQueryExpression xExpr = null;
2487        public QType qType = null;
2488        public Expression aExpr = null;
2489        Context() {
2490        }
2491    }
2492
2493    private class VarMappingInfo {
2494        public String JavaDoc varName = null;
2495        public RenameRelation relation = null;
2496        public VarMappingInfo(String JavaDoc varName, RenameRelation relation) {
2497            this.varName = varName;
2498            this.relation = relation;
2499        }
2500    }
2501}
2502
Popular Tags