KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > xquark > extractor > sql > AbstractGenSqlVisitor


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.sql;
24
25 import java.sql.Types JavaDoc;
26 import java.util.*;
27
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30 import org.xquark.extractor.algebra.*;
31 import org.xquark.extractor.common.Debug;
32 import org.xquark.extractor.common.MessageLibrary;
33 import org.xquark.extractor.common.SqlWrapperException;
34 import org.xquark.extractor.metadata.MetaDataManager;
35 import org.xquark.extractor.runtime.IDProvider;
36 import org.xquark.extractor.xfunctions.*;
37 import org.xquark.jdbc.typing.DbType;
38
39 public class AbstractGenSqlVisitor extends DefaultGenSqlVisitor implements Constants
40 {
41     private static final String JavaDoc RCSRevision = "$Revision: 1.18 $";
42     private static final String JavaDoc RCSName = "$Name: $";
43     
44     private static Log log = LogFactory.getLog(AbstractGenSqlVisitor.class);
45
46     public static final String JavaDoc TMP_TABLE_PREFIX = "XTMP";
47
48     protected SqlFactory _factory = null;
49
50     protected MetaDataManager _metadataManager= null;
51     protected IDProvider _relIDProvider = null;
52
53     // QUESTION: what's the use of this. peek() is never used and stack is only used by Sybase
54
// to know if there are nested selects... A counter would be enough eventually ?
55
protected Stack _nestStack = new Stack();
56
57     protected AbstractGenSqlVisitor(SqlFactory aSqlFactory, IDProvider relIDProvider)
58     {
59         setSqlFactory(aSqlFactory);
60         _relIDProvider = relIDProvider;
61     }
62
63     /**
64      * Sets the value of the _sqlFactory property.
65      * @param aSqlFactory the new value of the _sqlFactory property
66      */

67     public void setSqlFactory(SqlFactory aSqlFactory)
68     {
69        Debug.assertTrue(null != aSqlFactory,"null != aSqlFactory");
70         _factory = aSqlFactory;
71     }
72
73     public void setMetadataManager(MetaDataManager metadataManager) {
74         _metadataManager = metadataManager;
75     }
76
77     public void reinit ()
78     {
79         _nestStack.clear();
80     }
81
82     public SqlExpression visit(Expression arg)
83     {
84         throw new SqlWrapperException(MessageLibrary.getMessage("T_N_SUP_EXPR",arg.pprint()),null);
85     }
86
87     public SqlExpression visit(AttributeExpression arg)
88     {
89         String JavaDoc tableInstanceName = null;
90         RenameRelation rr = arg.getTableInstance();
91         if (rr != null)
92             tableInstanceName = rr.getUniqueName();
93
94         return _factory.createAttributeExpression (tableInstanceName, arg.getName());
95     }
96
97     public SqlExpression visit(BinOpArithmetic arg)
98     {
99         return _factory.createBinOpArithmetic(arg.getOperator(),
100                 arg.getLeftOperand().accept(this),
101                 arg.getRightOperand().accept(this)
102                 );
103     }
104
105     public SqlExpression visit(BinOpBoolean arg)
106     {
107         return _factory.createBinOpBoolean(arg.getOperator(),
108                 arg.getLeftOperand().accept(this),
109                 arg.getRightOperand().accept(this)
110                 );
111     }
112
113     public SqlExpression visit(BinOpCompare arg)
114     {
115         SqlExpression retVal = null;
116         Expression aLOprnd = arg.getLeftOperand();
117         Expression aROprnd = arg.getRightOperand();
118
119         if (aLOprnd.getType().isString() && aROprnd.getType().isString()) {
120             retVal = visitCompareString(arg);
121         }
122         else {
123             SqlExpression sLOprnd = aLOprnd.accept(this);
124             SqlExpression sROprnd = aROprnd.accept(this);
125             int oprtr = arg.getOperator();
126             retVal = _factory.createBinOpCompare(oprtr,sLOprnd,sROprnd);
127         }
128
129         return retVal;
130     }
131
132     protected SqlExpression visitCompareString(BinOpCompare arg)
133     {
134         SqlExpression retVal = null;
135
136         Expression aLOprnd = arg.getLeftOperand();
137         SqlExpression sLOprnd = aLOprnd.accept(this);
138
139         Expression aROprnd = arg.getRightOperand();
140         SqlExpression sROprnd = aROprnd.accept(this);
141
142         int oprtr = arg.getOperator();
143         DbType leftType = ((SqlTypeAtom)aLOprnd.getType()).getType();
144         DbType rightType = ((SqlTypeAtom)aROprnd.getType()).getType();
145         boolean leftIsChar = leftType.getPrimitiveTypeCode() == java.sql.Types.CHAR;
146         boolean rightIsChar = rightType.getPrimitiveTypeCode() == java.sql.Types.CHAR;
147
148         if (leftIsChar || rightIsChar) {
149             /* when one operand is of CHAR (including string constant), suffix
150              space should be considered. that is why the size of the column is added */

151             
152             SqlExpression comp = null;
153             SqlExpression eq = null;
154             SqlExpression lenLOprnd = null;
155             SqlExpression lenROprnd = null;
156             SqlExpression lenL_lenR = null;
157             SqlExpression and = null;
158             SqlExpression or = null;
159             
160             if (leftIsChar)
161                 lenLOprnd = _factory.createLitInteger(new Integer JavaDoc((int)leftType.getLength()));
162             else
163                 lenLOprnd = _factory.createSfStringLength(sLOprnd);
164
165             if (rightIsChar)
166                 lenROprnd = _factory.createLitInteger(new Integer JavaDoc((int)rightType.getLength()));
167             else
168                 lenROprnd = _factory.createSfStringLength(sROprnd);
169
170             lenL_lenR = _factory.createBinOpCompare(oprtr,lenLOprnd,lenROprnd);
171             
172             // TODO: if two operands are char or litString, the length can either
173
// make the length or the whole predicate useless (according the
174
// fact that length are different or not)
175

176             switch (oprtr) {
177                 case LT_COMPOP:
178                     /* lOprnd < rOprnd ==> lOprnd< rOprnd or ( lOprnd = rOprnd and length(lOprnd) < length(rOprnd) ) */
179                 case GT_COMPOP:
180                     /* lOprnd > rOprnd ==> lOprnd > rOprnd or ( lOprnd = rOprnd and length(lOprnd) > length(rOprnd) ) */
181                     comp = _factory.createBinOpCompare(oprtr,sLOprnd,sROprnd);
182                     eq = _factory.createBinOpCompare(EQ_COMPOP,sLOprnd,sROprnd);
183                     and = _factory.createBinOpBoolean(AND,eq,lenL_lenR);
184                     or = _factory.createBinOpBoolean(OR, comp, and);
185                     retVal = or;
186                     break;
187                 case GEQ_COMPOP:
188                 case LEQ_COMPOP:
189                     retVal = _factory.createBinOpCompare(oprtr,sLOprnd,sROprnd);
190                     break;
191                 case NEQ_COMPOP:
192                     /* lOprnd != rOprnd ==> lOprnd != rOprnd or length(lOprnd) != length(rOprnd) */
193                     SqlExpression neq = _factory.createBinOpCompare(oprtr,sLOprnd,sROprnd);
194                     or = _factory.createBinOpBoolean(OR,neq,lenL_lenR);
195                     retVal = or;
196                     break;
197                 case EQ_COMPOP:
198                     /* lOprnd = rOprnd ==> lOprnd = rOprnd and length(lOprnd) = length(rOprnd) ) */
199                     eq = _factory.createBinOpCompare(oprtr,sLOprnd,sROprnd);
200                     and = _factory.createBinOpBoolean(AND,eq,lenL_lenR);
201                     retVal = and;
202                     break;
203                 default:
204                     throw new SqlWrapperException(MessageLibrary.getMessage("T_N_SUP_OPTR",COMPOPSSTRINGS[oprtr]));
205             }
206         }
207         else // Perform a simple comparison for VARCHARs
208
retVal = _factory.createBinOpCompare(oprtr,sLOprnd,sROprnd);
209
210         return retVal;
211     }
212
213     public SqlExpression visit(BinOpCompareAny arg)
214     {
215         return _factory.createBinOpCompareAny(arg.getOperator(),
216                 arg.getLeftOperand().accept(this),
217                 arg.getRightOperand().accept(this)
218                 );
219     }
220
221     public SqlExpression visit(BinOpDifference arg)
222     {
223         throw new SqlWrapperException(MessageLibrary.getMessage("T_N_SUP_EXPR",arg),null);
224
225     }
226
227     public SqlExpression visit(BinOpIntersect arg)
228     {
229         throw new SqlWrapperException(MessageLibrary.getMessage("T_N_SUP_EXPR",arg),null);
230     }
231
232     public SqlExpression visit(BinOpMerge arg)
233     {
234         return _factory.createBinOpUnion (UNION_ALL,
235                 arg.getLeftOperand().accept(this),
236                 arg.getRightOperand().accept(this)
237                 );
238     }
239
240
241     public SqlExpression visit(BinOpUnion arg)
242     {
243         return _factory.createBinOpUnion(UNION,
244                 arg.getLeftOperand().accept(this),
245                 arg.getRightOperand().accept(this)
246                 );
247     }
248
249     public SqlExpression visit(UnOpExists arg)
250     {
251         return _factory.createUnOpExists(arg.getOperand().accept(this), arg.getNot());
252     }
253
254     public SqlExpression visit(UnOpIsNull arg) throws SqlWrapperException
255     {
256         return _factory.createUnOpIsNull(arg.getOperand().accept(this), arg.getNot());
257     }
258
259     public SqlExpression visit(ExternalVariable arg) throws SqlWrapperException {
260         return _factory.createPlaceHolder(arg);
261     }
262
263     public SqlExpression visit(FunAggregate arg)
264     {
265         return _factory.createFunAggregate(
266                 arg.getOperator(),
267                 arg.getOperand().accept(this),
268                 arg.getDistinct()
269                 );
270     }
271
272
273     public SqlExpression visit(IfThenElse arg)
274     {
275         return _factory.createIfThenElse(
276                 arg.getIf().accept(this),
277                 arg.getThen().accept(this),
278                 arg.getElse().accept(this)
279                 );
280     }
281
282     // NOTE: we suppose no join would be heading an algebra tree.
283
public SqlExpression visit(Join arg)
284     {
285         List relations = arg.getOperands();
286         if (null == relations) {
287             throw new SqlWrapperException(MessageLibrary.getMessage("INT_LOG_ERR"),null);
288         }
289
290         Expression aRelation;
291         int len = relations.size();
292         
293         /* add join predicate to WHERE clause */
294         List aPredicateList = arg.getPredicateList();
295         if (null != aPredicateList) {
296             Iterator iter = aPredicateList.iterator();
297             SqlSelect select = (SqlSelect) _nestStack.peek();
298             while (iter.hasNext()) {
299                 Expression aPredicate = (Expression)iter.next();
300                 SqlExpression sPredicate = aPredicate.accept(this);
301                 SqlExpression newWhereClause = whereClauseAddPredicate(select.getWhereClause(), sPredicate);
302                 select.setWhereClause(newWhereClause);
303             }
304         }
305         else {
306             if (log.isDebugEnabled())
307                 log.warn("join operation without predicate");
308         }
309
310         /* Create join clause */
311         SqlJoin sJoin = _factory.createJoin();
312
313         for (int i = 0; i < len; i++) {
314             /* generate FROM clause for SELECT */
315             aRelation = (Expression) relations.get(i);
316             // ADD 06/07/2003
317
if (aRelation instanceof UnOpSort)
318                 aRelation = ((UnOpSort)aRelation).getOperand();
319             if (aRelation instanceof UnOpRestrict)
320                 aRelation = ((UnOpRestrict)aRelation).getOperand();
321             // end ADD
322

323             selectAddFromClause(sJoin, (RenameRelation)aRelation);
324         }
325         
326         return sJoin;
327     }
328
329     public SqlExpression visit(LitBoolean arg)
330     {
331         return _factory.createLitBoolean (arg.getValue());
332     }
333
334     public SqlExpression visit(LitDate arg)
335     {
336         return _factory.createLitDate (arg.getValue());
337     }
338
339
340     public SqlExpression visit(LitDecimal arg)
341     {
342         return _factory.createLitDecimal(arg.getValue());
343     }
344
345     public SqlExpression visit(LitDouble arg)
346     {
347         return _factory.createLitDouble (arg.getValue());
348     }
349
350     public SqlExpression visit(LitFloat arg)
351     {
352         return _factory.createLitFloat (arg.getValue());
353     }
354
355     public SqlExpression visit(LitInteger arg)
356     {
357         return _factory.createLitInteger (arg.getValue());
358     }
359
360     public SqlExpression visit(LitList arg) {
361         SqlLitList retVal = null;
362         List sExprList = new ArrayList(arg.getLitList().size());
363         SqlExpression sExpr = null;
364         for (int i = 0; i < arg.getLitList().size(); i++) {
365             sExpr = ((Expression)arg.getLitList().get(i)).accept(this);
366             sExprList.add(sExpr);
367         }
368
369         retVal = _factory.createLitList(sExprList);
370         return retVal;
371     }
372
373     public SqlExpression visit(LitNull arg)
374     {
375         return _factory.createLitNull();
376     }
377
378     public SqlExpression visit(LitString arg)
379     {
380         return _factory.createLitString (arg.getValue());
381     }
382
383     public SqlExpression visit(RenameItem arg)
384     {
385         SqlRenameItem retVal = null;
386         SqlExpression sExpr = arg.getOperand().accept(this);
387         String JavaDoc name = arg.getName();
388         retVal = _factory.createRenameItem (sExpr,name);
389
390         return retVal;
391     }
392
393     public SqlExpression visit(RenameRelation arg)
394     {
395         SqlRenameRelation retVal = null;
396         SqlExpression sExpr = arg.getOperand().accept(this);
397         String JavaDoc name = arg.getUniqueName();
398         retVal = _factory.createRenameRelation (sExpr,name);
399
400         return retVal;
401     }
402
403     public SqlExpression visit(SortSpecification arg)
404     {
405         Expression sortExpr = arg.getSortExpression();
406         SqlExpression sqlSortExpr = sortExpr.accept(this);
407
408         return _factory.createSortSpecification(sqlSortExpr,arg.getSortDirection());
409     }
410
411
412     public SqlExpression visit(Table arg)
413     {
414         return _factory.createTable(arg.getCatalogName(), arg.getSchemaName(), arg.getName());
415     }
416
417     public SqlExpression visit(ConstantTempTable arg)
418     {
419         SqlExpression retVal = null;
420         List values = arg.getValues();
421         Debug.assertTrue(null != values && !values.isEmpty(), " TempTable is empty");
422
423         SqlSelect select = null;
424         List tuple = null;
425         List selectList = null;
426         Expression aAttr = null;
427         SqlExpression sAttr = null;
428         String JavaDoc attrName = null;
429
430         for (int i = 0; i < values.size(); i++) {
431             select = _factory.createSelect(arg);
432
433             tuple = (List)values.get(i);
434             selectList = new ArrayList();
435             for (int j = 0; j < tuple.size(); j++) {
436                 aAttr = (Expression)tuple.get(j);
437                 sAttr = aAttr.accept(this);
438                 if (0 ==i) {
439                     attrName = ((Attribute)arg.getAttributes().get(j)).getName();
440                     sAttr = _factory.createRenameItem(sAttr, attrName);
441                 }
442                 selectList.add(sAttr);
443             }
444
445             select.setSelectList(selectList);
446             DummyTable dummyTable = new DummyTable();
447             selectAddNextClause(select, dummyTable);
448
449             if (null == retVal) {
450                 /* this select is the first select */
451                 retVal = select;
452             }
453             else {
454                 retVal = _factory.createBinOpUnion(Constants.UNION_ALL, retVal, select);
455             }
456         }
457
458         return retVal;
459     }
460
461     public SqlExpression visit(TempTable arg)
462     {
463         SqlExpression retVal = null;
464         
465         // TODO: create a select into (create table ... as) statement
466

467         return retVal;
468     }
469     
470     public SqlExpression visit(TempValue arg)
471     {
472         return arg.getValue() == null ? arg.getOperand().accept(this) : arg.getValue().accept(this);
473     }
474
475     public SqlExpression visit(UnOpAggregate arg)
476     {
477         SqlSelect retVal = _factory.createSelect(arg);
478         _nestStack.push(retVal);
479         retVal = selectAddSelectClause(retVal,arg);
480         _nestStack.pop();
481
482         return retVal;
483     }
484
485 // public SqlExpression visit(UnOpGroup arg)
486
// {
487
// Trace.enter(this,"visit(UnOpGroup arg)");
488
//
489
// SqlSelect retVal = _factory.createSelect();
490
// retVal = selectAddGroupbyClause(retVal,arg);
491
//
492
// Trace.exit(this,"visit(UnOpGroup arg)");
493
// return retVal;
494
// }
495

496     public SqlExpression visit(UnOpMinus arg)
497     {
498         return _factory.createUnOpMinus(arg.getOperand().accept(this));
499     }
500
501     public SqlExpression visit(UnOpNot arg)
502     {
503         return _factory.createUnOpNot(arg.getOperand().accept(this));
504     }
505
506     public SqlExpression visit(UnOpProject arg)
507     {
508         SqlSelect retVal = _factory.createSelect(arg);
509         _nestStack.push(retVal);
510         retVal = selectAddSelectClause(retVal,arg);
511         _nestStack.pop();
512
513         return retVal;
514     }
515
516     public SqlExpression visit(UnOpRestrict arg)
517     {
518         SqlSelect retVal = _factory.createSelect(arg);
519         _nestStack.push(retVal);
520         if (arg.isPostResult())
521             retVal = selectAddHavingClause(retVal, arg);
522         else
523             retVal = selectAddWhereClause(retVal, arg);
524         _nestStack.pop();
525
526         return retVal;
527     }
528
529     public SqlExpression visit(UnOpSort arg)
530     {
531         SqlSelect retVal = _factory.createSelect(arg);
532         _nestStack.push(retVal);
533         selectAddSortClause(retVal,arg);
534         _nestStack.pop();
535
536         return retVal;
537     }
538
539     /**
540      * Main switch for select statement building.
541      * @param select
542      * @param operand
543      * @return
544      */

545     protected SqlSelect selectAddNextClause(SqlSelect select, Expression operand)
546     {
547         if (operand instanceof UnOpProject) {
548             if (select.getSelectDistinct() == false && null == select.getSelectList())
549                 return selectAddSelectClause(select,(UnOpProject)operand);
550             else
551                 return selectAddFromClause(select, new RenameRelation(operand, _relIDProvider));
552             /* NOTE:
553              * Some DBMS (like SQL Server) do not support select in from without
554              * relation alias. Doing it during algebra generation would prevent
555              * current RemoveProjectVisitor to collapse correctly piped projections.
556              */

557             
558         }
559         if (operand instanceof UnOpRestrict) {
560             UnOpRestrict restrict = (UnOpRestrict) operand;
561             if (restrict.isPostResult())
562                 return selectAddHavingClause(select, (UnOpRestrict) operand);
563             else
564                 return selectAddWhereClause(select, (UnOpRestrict) operand);
565         }
566         // TODO: Create a visitor to avoid these ugly "instanceof"
567
if (operand instanceof UnOpAggregate) return selectAddSelectClause(select,(UnOpAggregate)operand);
568         if (operand instanceof UnOpGroup) return selectAddGroupbyClause(select,(UnOpGroup)operand);
569         if (operand instanceof UnOpSort) return selectAddSortClause(select,(UnOpSort)operand);
570         if (operand instanceof Join) return selectAddFromClause(select,(Join)operand);
571         if (operand instanceof Table) return selectAddFromClause(select,(Table)operand);
572         if (operand instanceof DummyTable) return selectAddFromClause(select,(DummyTable)operand);
573         if (operand instanceof BinOpOuterJoin) return selectAddFromClause(select,(BinOpOuterJoin)operand);
574         if (operand instanceof BinaryAlgebra) return selectAddFromClause(select,(BinaryAlgebra)operand);
575         if (operand instanceof RenameRelation) return selectAddFromClause(select,(RenameRelation)operand);
576
577         Debug.assertTrue(false,"NYI!"+operand);
578         return null;
579     }
580
581     protected SqlSelect selectAddSortClause(SqlSelect select, UnOpSort sort)
582     {
583         List aSortList = sort.getSortSpecificationList();
584         if (null!=aSortList && null == select.getOrderbyClause()) {
585             List sSortList = new ArrayList();
586             Iterator iter = aSortList.iterator();
587             while (iter.hasNext()) {
588                 SortSpecification aSortSpecification = (SortSpecification)iter.next();
589                 SqlSortSpecification sSortSpecification = (SqlSortSpecification)aSortSpecification.accept(this);
590                 sSortList.add(sSortSpecification);
591             }
592             select.setOrderbyClause(sSortList);
593         }
594         select = selectAddNextClause(select,sort.getOperand());
595         return select;
596     }
597
598
599     /**
600      * Sets the attributes of the select clause and calls the method to add the
601      * from clause corresponding to the operand.
602      * @param select
603      * @param project
604      * @return
605      */

606     protected SqlSelect selectAddSelectClause(SqlSelect select, UnOpProject project)
607     {
608         List aExprList = project.getItemList();
609         ArrayList sExprList = new ArrayList();
610
611         if (null != aExprList)
612         {
613             // translate item list in UnOpProject into SqlExpression
614
Iterator itr = aExprList.iterator () ;
615             while ( itr.hasNext())
616             {
617                 SqlExpression sExpr = ((Expression)itr.next()).accept (this);
618                 sExprList.add(sExpr) ;
619             }
620             select.setSelectClause ( project.getDistinct(),sExprList);
621         }
622
623         select = selectAddNextClause(select,project.getOperand());
624         return select;
625     }
626
627
628     protected SqlJoin selectAddFromClause(SqlJoin join, RenameRelation arg)
629     {
630         join.addOperand(processPipedRelation(arg));
631         return join;
632     }
633     
634     protected SqlSelect selectAddFromClause(SqlSelect select, RenameRelation arg)
635     {
636         select.addFromClause(processPipedRelation(arg));
637         return select;
638     }
639
640     protected SqlRenameRelation processPipedRelation(RenameRelation arg)
641     {
642         SqlRenameRelation sRR = _factory.createRenameRelation (
643                 arg.getOperand().accept(this), arg.getUniqueName());
644
645         return sRR;
646     }
647
648
649     protected SqlSelect selectAddFromClause (SqlSelect select, Join join)
650     {
651         /* Add it to the select from clause */
652         select.addFromClause(join.accept(this));
653         return select;
654     }
655
656     // TODO: this default implementation is for Oracle (7 because outer joins are
657
// used). Move if mysql and progress use the same standard syntax ?
658
protected SqlSelect selectAddFromClause (SqlSelect select, BinOpOuterJoin arg)
659     {
660         Expression [] relations = {arg.getLeftOperand(), arg.getRightOperand()};
661
662         RenameRelation aRR;
663         Expression aRelation;
664         SqlExpression sRelation;
665         SqlRenameRelation sInnerTable = null;
666
667         for (int i = 0; i < relations.length; i++) {
668             /* generate FROM clause for SELECT */
669             aRelation = relations[i];
670             if (aRelation instanceof RenameRelation) {
671                 aRR = (RenameRelation)aRelation;
672                 aRelation = aRR.getOperand();
673                 
674                 // NOTE: a list of if (instanceof) used to check algebra integrity have
675
// been removed because these tests make visitor automatic type switch worthless...
676
sRelation = aRelation.accept(this);
677                 SqlRenameRelation sRR = _factory.createRenameRelation (sRelation, aRR.getUniqueName());
678                 select.addFromClause(sRR);
679                 
680                 if (LEFT_OUTER_JOIN == arg.getJoinType() && i == 1){
681                     sInnerTable = sRR;
682                 }
683                 else if (RIGHT_OUTER_JOIN == arg.getJoinType() && i == 0){
684                     sInnerTable = sRR;
685                 }
686             }
687             else {
688                 selectAddNextClause(select ,aRelation);
689             }
690         }
691
692         /* add join predicate to WHERE clause */
693         List aPredicateList = arg.getPredicateList();
694         if (null != aPredicateList)
695         {
696             Iterator iter = aPredicateList.iterator();
697             while (iter.hasNext()) {
698                 Expression aPredicate = (Expression)iter.next();
699                 SqlExpression sPredicate = aPredicate.accept(this);
700                 sPredicate = new SqlOuterJoinPredicate(sPredicate ,sInnerTable);
701                 SqlExpression newWhereClause = whereClauseAddPredicate(select.getWhereClause(), sPredicate);
702                 select.setWhereClause(newWhereClause);
703             }
704         }
705         else
706         {
707             if (log.isDebugEnabled())
708                 log.warn("outer join operation without predicate");
709         }
710
711         return select;
712     }
713
714
715     protected SqlSelect selectAddWhereClause (SqlSelect select, UnOpRestrict restrict)
716     {
717         List aPredicates = restrict.getPredicateList();
718         SqlExpression sPredicate ;
719
720         if ( null != aPredicates ) {
721             Iterator iter = aPredicates.iterator();
722             while (iter.hasNext()) {
723                 Expression aPredicate = (Expression)iter.next();
724                 sPredicate = aPredicate.accept(this) ;
725                 SqlExpression newWhereClause = whereClauseAddPredicate(select.getWhereClause(), sPredicate);
726                 select.setWhereClause(newWhereClause);
727             }
728         }
729
730         select = selectAddNextClause(select, restrict.getOperand());
731         return select;
732     }
733
734     protected SqlSelect selectAddHavingClause (SqlSelect select, UnOpRestrict restrict)
735     {
736         List aPredicates = restrict.getPredicateList();
737         SqlExpression sPredicate ;
738
739         if ( null != aPredicates ) {
740             Iterator iter = aPredicates.iterator();
741             while (iter.hasNext()) {
742                 Expression aPredicate = (Expression)iter.next();
743                 sPredicate = aPredicate.accept(this) ;
744                 SqlExpression newWhereClause = whereClauseAddPredicate(select.getHavingClause(), sPredicate);
745                 select.setHavingClause(newWhereClause);
746             }
747         }
748
749         select = selectAddNextClause(select, restrict.getOperand());
750         return select;
751     }
752
753     public SqlSelect selectAddGroupbyClause (SqlSelect select, UnOpGroup group)
754     {
755         List aExprList = group.getGroupExpressionList();
756         ArrayList sExprList = new ArrayList();
757         if (null != aExprList)
758         {
759             // translate group expression list in UnOpGroup into SqlExpression
760
Iterator itr = aExprList.iterator () ;
761             while ( itr.hasNext())
762             {
763                 SqlExpression sExpr = ((Expression)itr.next()).accept (this);
764                 sExprList.add(sExpr) ;
765             }
766             select.setGroupbyClause (sExprList);
767             select = selectAddNextClause(select,group.getOperand());
768         }
769
770         return select;
771     }
772
773     protected SqlSelect selectAddFromClause (SqlSelect select, Table operand)
774     {
775         SqlTable newFrom = _factory.createTable (operand.getCatalogName(), operand.getSchemaName(), operand.getName());
776         select.addFromClause(newFrom);
777         return select;
778     }
779
780     protected SqlSelect selectAddFromClause (SqlSelect select, DummyTable operand)
781     {
782         return select;
783     }
784
785     protected SqlSelect selectAddFromClause (SqlSelect select, BinaryAlgebra operand)
786     {
787         SqlExpression sRelation = operand.accept(this);
788         SqlRenameRelation sRR = _factory.createRenameRelation ( sRelation,null);
789
790         select.addFromClause(sRR);
791         return select;
792     }
793
794     public SqlExpression visit(AfTrim arg) throws SqlWrapperException
795     {
796         return _factory.createSfTrim(((Expression)arg.getArgument(0)).accept(this));
797     }
798
799     public SqlExpression visit(XfCast arg) throws SqlWrapperException
800     {
801         Expression expr = (Expression)arg.getExpression();
802         SqlExpression sqlExpr = expr.accept(this);
803         DbType type0= ((SqlTypeAtom)expr.getType()).getType();
804         DbType type1= (DbType)arg.getTargetType();
805         SqlExpression retVal = _factory.createConvert(sqlExpr, (DbType)type0, type1);
806         return retVal;
807     }
808
809     public SqlExpression visit(AfCast arg) throws SqlWrapperException
810     {
811         SqlExpression retVal = null;
812         Expression expr = (Expression)arg.getExpression();
813
814         DbType type0= ((SqlTypeAtom)expr.getType()).getType();
815         DbType type1= arg.getTargetType();
816
817         String JavaDoc name = expr.getName();
818         if (null != name){
819             if (expr instanceof RenameItem) {
820                 expr = ((RenameItem)expr).getOperand();;
821             }
822             SqlExpression sqlExpr = expr.accept(this);
823             retVal = _factory.createConvert(sqlExpr, (DbType)type0, type1);
824             retVal = _factory.createRenameItem(retVal,name);
825         }
826         else {
827             SqlExpression sqlExpr = expr.accept(this);
828             retVal = _factory.createConvert(sqlExpr, (DbType)type0, type1);
829         }
830
831         return retVal;
832     }
833
834     public SqlExpression visit(XfAbs arg) throws SqlWrapperException
835     {
836         return _factory.createSfAbs(((Expression)arg.getArgument(0)).accept(this));
837     }
838
839     public SqlExpression visit(XfCeiling arg) throws SqlWrapperException
840     {
841         return _factory.createSfCeiling(((Expression)arg.getArgument(0)).accept(this));
842     }
843
844     public SqlExpression visit(XfConcat arg)
845     {
846         SfConcat retVal = _factory.createSfConcat();
847
848         List sqlArguments = new ArrayList();
849
850         List algArguments = arg.getArguments();
851         Iterator iter = algArguments.iterator();
852         while (iter.hasNext()) {
853               Expression item = (Expression)iter.next();
854               sqlArguments.add(item.accept(this));
855         }
856
857         retVal.setArguments (sqlArguments);
858         return retVal;
859     }
860
861
862     public SqlExpression visit(XfContains arg) throws SqlWrapperException
863     {
864         Debug.assertTrue(2 == arg.getArgumentNumber(),"2 == arg.getArgumentNumber()");
865         SqlBinOpLike retVal = _factory.createBinOpLike();
866
867         Expression aArg0 = (Expression)arg.getArgument(0);
868         SqlExpression sArg0 = aArg0.accept(this);
869
870         Expression aArg1 = (Expression)arg.getArgument(1);
871         SqlExpression sArg1 = aArg1.accept(this);
872
873         retVal.setLeftOperand(sArg0);
874
875         SfConcat pattern = _factory.createSfConcat();
876         pattern.setArgument(0, _factory.createLitString("%"));
877         pattern.setArgument(1,sArg1);
878         pattern.setArgument(2, _factory.createLitString("%"));
879
880         retVal.setRightOperand(pattern);
881
882         return retVal;
883     }
884
885     public SqlExpression visit(XfCurrentDateTime arg) throws SqlWrapperException
886     {
887         return _factory.createSfCurrentDateTime();
888     }
889
890     public SqlExpression visit(XfDate arg) throws SqlWrapperException
891     {
892         Expression arg0 = (Expression)arg.getArgument(0);
893         DbType arg0Type = (DbType)((SqlTypeAtom)arg0.getType()).getType();
894
895         SqlExpression aArg = arg0.accept(this);
896         return _factory.createConvert(aArg, arg0Type, new DbType(Types.DATE));
897     }
898
899     public SqlExpression visit(XfDateTime arg) throws SqlWrapperException
900     {
901         Expression arg0 = (Expression)arg.getArgument(0);
902         DbType arg0Type = (DbType)((SqlTypeAtom)arg0.getType()).getType();
903
904         SqlExpression aArg = arg0.accept(this);
905         return _factory.createConvert(aArg, arg0Type, new DbType(Types.TIMESTAMP));
906     }
907
908     public SqlExpression visit(XfEndsWith arg) throws SqlWrapperException
909     {
910         Debug.assertTrue(2 == arg.getArgumentNumber(),"2 == arg.getArgumentNumber()");
911         SqlBinOpLike retVal = _factory.createBinOpLike();
912
913         Expression aArg0 = ((Expression)arg.getArgument(0));
914         SqlExpression sArg0 = aArg0.accept(this);
915
916         Expression aArg1 = (Expression)arg.getArgument(1);
917         SqlExpression sArg1 = aArg1.accept(this);
918
919         retVal.setLeftOperand(sArg0);
920
921         SfConcat pattern = _factory.createSfConcat();
922         pattern.setArgument(0, _factory.createLitString("%"));
923         pattern.setArgument(1,sArg1);
924
925         retVal.setRightOperand(pattern);
926
927         return retVal;
928     }
929
930
931     public SqlExpression visit(XfFloor arg) throws SqlWrapperException
932     {
933         return _factory.createSfFloor(((Expression)arg.getArgument(0)).accept(this));
934     }
935
936
937     public SqlExpression visit(XfLowerCase arg) throws SqlWrapperException
938     {
939         Debug.assertTrue(1 == arg.getArgumentNumber(),"1 == arg.getArgumentNumber()");
940         SfLowerCase retVal = _factory.createSfLowerCase();
941
942         Expression aArg = ((Expression)arg.getArgument(0));
943         SqlExpression sArg = aArg.accept(this);
944         retVal.setArgument(0,sArg);
945
946         return retVal;
947     }
948
949
950     public SqlExpression visit(XfRound arg) throws SqlWrapperException
951     {
952         Expression arg0 = (Expression)arg.getArgument(0);
953         SqlExpression retVal = _factory.createBinOpArithmetic(PLUS_ARITHMETICS,
954             arg0.accept(this), _factory.createLitFloat(new Float JavaDoc(0.5)));
955         _factory.createSfFloor(retVal);
956         return retVal;
957     }
958
959
960     public SqlExpression visit(XfStartsWith arg) throws SqlWrapperException
961     {
962         Debug.assertTrue(2 == arg.getArgumentNumber(),"2 == arg.getArgumentNumber()");
963         SqlBinOpLike retVal = _factory.createBinOpLike();
964
965         Expression aArg0 = ((Expression)arg.getArgument(0));
966         SqlExpression sArg0 = aArg0.accept(this);
967
968         Expression aArg1 = (Expression)arg.getArgument(1);
969         SqlExpression sArg1 = aArg1.accept(this);
970
971         retVal.setLeftOperand(sArg0);
972
973         SfConcat pattern = _factory.createSfConcat();
974         pattern.setArgument(0,sArg1);
975         pattern.setArgument(1, _factory.createLitString("%"));
976
977         retVal.setRightOperand(pattern);
978
979         return retVal;
980     }
981
982
983     public SqlExpression visit(XfStringLength arg) throws SqlWrapperException
984     {
985         Debug.assertTrue(1 == arg.getArgumentNumber(),"1 == arg.getArgumentNumber()");
986         SfStringLength retVal = _factory.createSfStringLength();
987
988         Expression aArg = ((Expression)arg.getArgument(0));
989         SqlExpression sArg = aArg.accept(this);
990         retVal.setArgument(0,sArg);
991
992         return retVal;
993     }
994
995
996     public SqlExpression visit(XfSubString arg) throws SqlWrapperException
997     {
998         SfSubString retVal = _factory.createSfSubString();
999
1000        Expression aArg = ((Expression)arg.getArgument(0));
1001        SqlExpression sArg = aArg.accept(this);
1002        retVal.setArgument(0,sArg);
1003
1004        aArg = (Expression)arg.getArgument(1);
1005        sArg = aArg.accept(this);
1006        retVal.setArgument(1,sArg);
1007
1008        if (2 < arg.getArgumentNumber()) {
1009            aArg = (Expression)arg.getArgument(2);
1010            sArg = aArg.accept(this);
1011            retVal.setArgument(2,sArg);
1012        }
1013
1014        return retVal;
1015    }
1016
1017    public SqlExpression visit(XfTime arg) throws SqlWrapperException
1018    {
1019        Expression arg0 = (Expression)arg.getArgument(0);
1020        DbType arg0Type = (DbType)((SqlTypeAtom)arg0.getType()).getType();
1021
1022        SqlExpression aArg = arg0.accept(this);
1023        SqlConvert retVal = _factory.createConvert(aArg, arg0Type, new DbType(Types.TIME));
1024
1025        return retVal;
1026    }
1027
1028    public SqlExpression visit(XfUpperCase arg) throws SqlWrapperException
1029    {
1030        Debug.assertTrue(1 == arg.getArgumentNumber(),"1 == arg.getArgumentNumber()");
1031        SfUpperCase retVal = _factory.createSfUpperCase();
1032
1033        Expression aArg = ((Expression)arg.getArgument(0));
1034        SqlExpression sArg = aArg.accept(this);
1035        retVal.setArgument(0,sArg);
1036
1037        return retVal;
1038    }
1039
1040    protected SqlExpression whereClauseAddPredicate(SqlExpression whereClause, SqlExpression predicate)
1041    {
1042        return whereClause == null ? predicate : _factory.createBinOpBoolean(AND, whereClause, predicate);
1043    }
1044
1045
1046    public org.xquark.extractor.sql.SqlExpression visit(BinOpOuterJoin arg)
1047    {
1048        SqlSelect retVal = _factory.createSelect(arg);
1049        _nestStack.push(retVal);
1050        selectAddFromClause(retVal,arg);
1051        _nestStack.pop();
1052    
1053        return retVal;
1054    }
1055}
1056
Popular Tags