KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > xquark > extractor > sybase > SybaseGenSqlVisitor


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.sybase;
24
25 import java.sql.Types JavaDoc;
26 import java.text.SimpleDateFormat JavaDoc;
27 import java.util.ArrayList JavaDoc;
28 import java.util.Iterator JavaDoc;
29 import java.util.List JavaDoc;
30
31 import org.xquark.extractor.algebra.*;
32 import org.xquark.extractor.common.Debug;
33 import org.xquark.extractor.common.MessageLibrary;
34 import org.xquark.extractor.common.SqlWrapperException;
35 import org.xquark.extractor.runtime.IDProvider;
36 import org.xquark.extractor.sql.*;
37 import org.xquark.extractor.sybase.sql.SqlCreateView;
38 import org.xquark.extractor.xfunctions.XfDate;
39 import org.xquark.extractor.xfunctions.XfDateTime;
40 import org.xquark.extractor.xfunctions.XfTime;
41 import org.xquark.jdbc.typing.DbType;
42 import org.xquark.schema.SchemaException;
43 import org.xquark.schema.datatypes.DateTime;
44 import org.xquark.schema.datatypes.PrimitiveType;
45
46 final public class SybaseGenSqlVisitor extends AbstractGenSqlVisitor {
47     private static final String JavaDoc RCSRevision = "$Revision: 1.15 $";
48     private static final String JavaDoc RCSName = "$Name: $";
49
50     private IDProvider _tmpTableIDProvider;
51
52     public SybaseGenSqlVisitor(IDProvider relIDProvider, IDProvider tmpTableIDProvider) {
53         super((SqlFactory) SybaseFactory.getInstance(), relIDProvider);
54         _tmpTableIDProvider = tmpTableIDProvider;
55     }
56
57     public void reinit() {
58         super.reinit();
59     }
60
61     public SqlExpression visit(BinOpArithmetic arg) {
62         //Trace.enter(this, "visit(BinOpArithmetic arg)");
63

64         SqlExpression retVal = null;
65
66         Expression aLOprnd = arg.getLeftOperand();
67         SqlExpression sLOprnd = aLOprnd.accept(this);
68
69         Expression aROprnd = arg.getRightOperand();
70         SqlExpression sROprnd = aROprnd.accept(this);
71
72         int oprtr = arg.getOperator();
73
74         if (MODULO_ARITHMETICS == oprtr) {
75             retVal = visitModulo(sLOprnd, (SqlTypeAtom) aLOprnd.getType(), sROprnd, (SqlTypeAtom) aROprnd.getType());
76         } else {
77             if (DIVIDE_ARITHMETICS == oprtr && aLOprnd.getType().isInteger() && aROprnd.getType().isInteger()) {
78                 /* Sybase will execute integer division while XQuery expect decimal result.
79                    So we cast left operand to decimal type before the division */

80                 sLOprnd = _factory.createConvert(sLOprnd, new DbType(Types.INTEGER), new DbType(Types.DECIMAL));
81             }
82             retVal = _factory.createBinOpArithmetic(oprtr, sLOprnd, sROprnd);
83         }
84
85         //Trace.exit(this, "visit(BinOpArithmetic arg)");
86
return retVal;
87     }
88
89     protected SqlExpression visitModulo(SqlExpression lOprnd, SqlTypeAtom lOprndType, SqlExpression rOprnd, SqlTypeAtom rOprndType) {
90         SqlBinOpArithmetic retVal = null;
91         if (lOprndType.isInteger() && rOprndType.isInteger()) {
92             retVal = _factory.createBinOpArithmetic(MODULO_ARITHMETICS, lOprnd, rOprnd);
93         } else {
94             /* sign(lOprnd) * ( abs(lOprnd)- floor(abs(lOprnd/rOprnd))*abs(rOprnd) */
95
96             SfSign signL = _factory.createSfSign(lOprnd);
97
98             SfAbs absL = _factory.createSfAbs(lOprnd);
99
100             SqlBinOpArithmetic LdivR = _factory.createBinOpArithmetic(DIVIDE_ARITHMETICS, lOprnd, rOprnd);
101             SfAbs absLdivR = _factory.createSfAbs(LdivR);
102             SfFloor floorAbs = _factory.createSfFloor(absLdivR);
103             SfAbs absR = _factory.createSfAbs(rOprnd);
104
105             SqlBinOpArithmetic floorMultiR = _factory.createBinOpArithmetic(MULTIPLY_ARITHMETICS, floorAbs, absR);
106
107             SqlBinOpArithmetic AbsMinusFloor = _factory.createBinOpArithmetic(MINUS_ARITHMETICS, absL, floorMultiR);
108
109             retVal = _factory.createBinOpArithmetic(MULTIPLY_ARITHMETICS, signL, AbsMinusFloor);
110         }
111         return retVal;
112     }
113
114     public SqlExpression visit(XfTime arg) throws SqlWrapperException {
115         //Trace.enter(this, "visit(XfTime arg)");
116
PrimitiveType pt = PrimitiveType.createType("time");
117         Expression arg0 = arg.getArgument(0);
118         String JavaDoc dateTimeString = ((LitString) arg0).getValue();
119         DateTime ts = null;
120         try {
121             ts = (DateTime) pt.convert(dateTimeString, false);
122         } catch (SchemaException ex) {
123             new SqlWrapperException(ex.getMessage(), ex);
124         }
125
126         SimpleDateFormat JavaDoc formatter = new SimpleDateFormat JavaDoc("hh:mm:ss.S");
127         dateTimeString = formatter.format(ts);
128
129         DbType arg0Type = (DbType) ((SqlTypeAtom) arg0.getType()).getType();
130
131         SqlExpression aArg = _factory.createLitString(dateTimeString);
132         SqlConvert retVal = _factory.createConvert(aArg, arg0Type, new DbType(Types.DATE));
133
134         //Trace.exit(this, "visit(XfTime arg)");
135
return retVal;
136     }
137
138     public SqlExpression visit(XfDate arg) throws SqlWrapperException {
139         //Trace.enter(this, "visit(XfDate arg)");
140
PrimitiveType pt = PrimitiveType.createType("date");
141         Expression arg0 = arg.getArgument(0);
142         String JavaDoc dateTimeString = ((LitString) arg0).getValue();
143
144         DateTime ts = null;
145         try {
146             ts = (DateTime) pt.convert(dateTimeString, false);
147         } catch (SchemaException ex) {
148             throw new SqlWrapperException(ex.getMessage(), ex);
149         }
150
151         SimpleDateFormat JavaDoc formatter = new SimpleDateFormat JavaDoc("yyyy.MM.dd");
152         dateTimeString = formatter.format(ts);
153
154         DbType arg0Type = (DbType) ((SqlTypeAtom) arg0.getType()).getType();
155
156         SqlExpression aArg = _factory.createLitString(dateTimeString);
157         SqlConvert retVal = _factory.createConvert(aArg, arg0Type, new DbType(Types.DATE));
158
159         //Trace.exit(this, "visit(XfDate arg)");
160
return retVal;
161     }
162
163     public SqlExpression visit(XfDateTime arg) throws SqlWrapperException {
164         //Trace.enter(this, "visit(XfDateTime arg)");
165
PrimitiveType pt = PrimitiveType.createType("dateTime");
166         Expression arg0 = arg.getArgument(0);
167         String JavaDoc dateTimeString = ((LitString) arg0).getValue();
168
169         DateTime ts = null;
170         try {
171             ts = (DateTime) pt.convert(dateTimeString, false);
172         } catch (SchemaException ex) {
173             new SqlWrapperException(ex.getMessage(), ex);
174         }
175
176         SimpleDateFormat JavaDoc formatter = new SimpleDateFormat JavaDoc("yyyy.MM.dd hh:mm:ss.S");
177         dateTimeString = formatter.format(ts);
178
179         DbType arg0Type = (DbType) ((SqlTypeAtom) arg0.getType()).getType();
180
181         SqlExpression aArg = _factory.createLitString(dateTimeString);
182         SqlConvert retVal = _factory.createConvert(aArg, arg0Type, new DbType(Types.TIMESTAMP));
183
184         //Trace.exit(this, "visit(XfDateTime arg)");
185
return retVal;
186     }
187
188     protected SqlSelect selectAddFromClause(SqlSelect select, DummyTable operand) {
189         //Trace.enter(this, "selectAddFromClause (SqlSelect select, DummyTable operand)");
190

191         //Trace.exit(this, "selectAddFromClause (SqlSelect select, DummyTable operand)");
192
return select;
193     }
194
195     public SqlExpression visit(SortSpecification arg) {
196         //Trace.enter(this, "visit(SortSpecification arg)");
197
SqlSortSpecification retVal = null;
198         Expression sortOperand = ((UnOpSort) arg.getFather()).getOperand();
199         if (sortOperand instanceof BinaryAlgebra && !(sortOperand instanceof BinOpOuterJoin)) {
200             Expression sortExpr = arg.getSortExpression();
201             SqlExpression sqlSortExpr = sortExpr.accept(this);
202             retVal = _factory.createSortSpecification(sqlSortExpr, arg.getSortDirection());
203         } else {
204             Expression sortExpr = arg.getSortExpression();
205             Expression underlyingExpr = null;
206             if (sortExpr instanceof AttributeExpression) {
207                 underlyingExpr = ((AttributeExpression) sortExpr).getUnderlyinExpr();
208                 if (underlyingExpr instanceof AttributeExpression) {
209                     sortExpr = underlyingExpr;
210                 }
211             }
212             SqlExpression sqlSortExpr = sortExpr.accept(this);
213
214             retVal = _factory.createSortSpecification(sqlSortExpr, arg.getSortDirection());
215         }
216         //Trace.exit(this, "visit(SortSpecification arg)");
217
return retVal;
218     }
219
220     public SqlExpression visit(ConstantTempTable arg) {
221         //Trace.enter(this, "visit(ConstantTempTable arg)");
222
SqlExpression retVal = null;
223
224         /* 1. create a temporay table */
225         String JavaDoc tableName = arg.getName();
226         SqlTable table = _factory.createTable("tempdb", null, tableName);
227         org.xquark.extractor.sybase.sql.SqlCreateTable createTable = new org.xquark.extractor.sybase.sql.SqlCreateTable();
228         createTable.setTableName(table);
229
230         List JavaDoc attrList = arg.getAttributes();
231         List JavaDoc attrDefList = new ArrayList JavaDoc();
232         Attribute attribute = null;
233         org.xquark.extractor.sybase.sql.SqlAttributeDefinition attrDef = null;
234         DbType pType = null;
235         for (int i = 0; i < attrList.size(); i++) {
236             attribute = (Attribute) attrList.get(i);
237             attrDef = new org.xquark.extractor.sybase.sql.SqlAttributeDefinition();
238
239             attrDef.setName(attribute.getName());
240             pType = (DbType) ((SqlTypeAtom) attribute.getType()).getType();
241             attrDef.setType(TypeMapper.mapType(pType));
242             if (0 == i) {
243                 attrDef.setPrimaryKey(true);
244             }
245             attrDefList.add(attrDef);
246         }
247         createTable.setAttrDefList(attrDefList);
248
249         SqlExpression currentStatement = createTable;
250         /* 2. Insert data to the new created table */
251         List JavaDoc tupleList = arg.getValues();
252         List JavaDoc tuple = null;
253         org.xquark.extractor.sybase.sql.SqlInsert insert = null;
254         org.xquark.extractor.sybase.sql.SqlValueList sqlValueList = null;
255         List JavaDoc valueList = null;
256         Expression aValue = null;
257         SqlExpression sValue = null;
258         for (int i = 0; i < tupleList.size(); i++) {
259             tuple = (List JavaDoc) tupleList.get(i);
260             /* create one INSERT statement. */
261             valueList = new ArrayList JavaDoc();
262             for (int j = 0; j < tuple.size(); j++) {
263                 aValue = (Expression) tuple.get(j);
264                 sValue = aValue.accept(this);
265                 valueList.add(sValue);
266             }
267             sqlValueList = new org.xquark.extractor.sybase.sql.SqlValueList(valueList);
268             insert = new org.xquark.extractor.sybase.sql.SqlInsert(table, sqlValueList);
269             insert.appendPrecedent(currentStatement);
270             currentStatement = insert;
271         }
272
273         retVal = currentStatement;
274         //Trace.exit(this, "visit(ConstantTempTable arg)");
275
return retVal;
276     }
277
278     /* Do nothing: desactivate the inherited rename relation creation for
279      * relation binary operations.
280      * @see org.xquark.extractor.sql.AbstractGenSqlVisitor#selectAddFromClause(org.xquark.extractor.sql.SqlSelect, org.xquark.extractor.algebra.BinaryAlgebra)
281      */

282     protected SqlSelect selectAddFromClause(SqlSelect select, BinaryAlgebra operand) {
283         //Trace.enter(this, "selectAddFromClause (SqlSelect select, BinAlgebra operand)", operand.toString());
284

285         Debug.nyi("SqlSelect selectAddFromClause (SqlSelect select, BinaryAlgebra operand)");
286
287         //Trace.exit(this, "selectAddFromClause (SqlSelect select, BinAlgebra operand)", operand.toString());
288
return select;
289     }
290
291     /* Do nothing: desactivate the inherited process.
292      * @see org.xquark.extractor.sql.AbstractGenSqlVisitor#selectAddFromClause(org.xquark.extractor.sql.SqlSelect, org.xquark.extractor.algebra.BinaryAlgebra)
293      */

294     public SqlSelect selectAddFromClause(SqlSelect select, BinOpOuterJoin arg) {
295         //Trace.enter(this, "selectAddFromClause (SqlSelect select, BinOpOuterJoin arg)", arg.pprint());
296

297         Debug.nyi("SqlSelect selectAddFromClause (SqlSelect select, BinaryAlgebra operand)");
298
299         //Trace.exit(this, "selectAddFromClause (SqlSelect select, BinOpOuterJoin arg)", arg.pprint());
300
return select;
301     }
302
303     protected SqlRenameRelation processPipedRelation(RenameRelation arg) {
304         SqlRenameRelation sRR = null;
305
306         String JavaDoc relationName = arg.getUniqueName();
307         Expression aRelation = arg.getOperand();
308         SqlExpression sRelation = null;
309         SqlSelect select = (SqlSelect) _nestStack.get(0); // only 1st select will remain...
310

311         if (aRelation instanceof ConstantTempTable) {
312             ConstantTempTable tempTable = (ConstantTempTable) aRelation;
313             SqlExpression sTempTable = tempTable.accept(this);
314             select.appendPrecedent(sTempTable);
315             sRelation = _factory.createTable("tempdb", null, tempTable.getName());
316             sRR = _factory.createRenameRelation(sRelation, relationName);
317         } else if (aRelation instanceof Table) {
318             Table table = (Table) aRelation;
319             sRelation = _factory.createTable(table.getCatalogName(), table.getSchemaName(), table.getName());
320             sRR = _factory.createRenameRelation(sRelation, relationName);
321
322         } else if (aRelation instanceof UnOpProject) {
323             sRelation = aRelation.accept(this);
324             String JavaDoc tempViewName = getTemporaryViewName();
325             SqlCreateView sCreateView = new SqlCreateView(tempViewName, sRelation);
326             select.appendPrecedent(sCreateView);
327             SqlTable tempView = _factory.createTable(tempViewName);
328             sRR = _factory.createRenameRelation(tempView, relationName);
329         } else if (aRelation instanceof UnaryAlgebra) {
330             //case : ,Restrict,Sort,Group,...
331
sRelation = aRelation.accept(this);
332             sRR = _factory.createRenameRelation(sRelation, relationName);
333         } else if (aRelation instanceof BinaryAlgebra) {
334             // case : UNION, DIFFERENCE, EXCEPT
335
sRelation = aRelation.accept(this);
336             sRR = _factory.createRenameRelation(sRelation, relationName);
337         } else
338             throw new SqlWrapperException(MessageLibrary.getMessage("INT_LOG_ERR"), null);
339
340         return sRR;
341     }
342
343     protected SqlSelect selectAddSelectClause(SqlSelect select, UnOpProject project) {
344         //Trace.enter(this, "selectAddSelectClause(SqlSelect select, UnOpProject project)", project);
345

346         List JavaDoc aExprList = project.getItemList();
347         ArrayList JavaDoc sExprList = new ArrayList JavaDoc();
348
349         if (null != aExprList) {
350             // Sybase does not like column aliases in some kind of subqueries
351
boolean removeAlias = _nestStack.size() > 1 && (project.getType().isAtom() || project.getFather() instanceof UnOpExists);
352
353             // translate item list in UnOpProject into SqlExpression
354
Iterator JavaDoc itr = aExprList.iterator();
355             while (itr.hasNext()) {
356
357                 Expression aExpr = (Expression) itr.next();
358
359                 if (removeAlias && aExpr instanceof RenameItem) {
360                     aExpr = ((RenameItem) aExpr).getOperand();
361                 }
362                 SqlExpression sExpr = aExpr.accept(this);
363                 sExprList.add(sExpr);
364             }
365             select.setSelectClause(project.getDistinct(), sExprList);
366         }
367
368         select = selectAddNextClause(select, project.getOperand());
369         //Trace.exit(this, "selectAddSelectClause(SqlSelect select, UnOpProject project)", project);
370
return select;
371     }
372
373     protected String JavaDoc getTemporaryViewName() {
374         return TMP_TABLE_PREFIX + _tmpTableIDProvider.getID();
375     }
376
377 }
378
Popular Tags