Source Code Cross Referenced for SelectStatement.java in  » Rule-Engine » Mandarax » org » mandarax » jdbc » server » sql » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Rule Engine » Mandarax » org.mandarax.jdbc.server.sql 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright (C) 1999-2004 <a href="mailto:mandarax@jbdietrich.com">Jens Dietrich</a>
003:         *
004:         * This library is free software; you can redistribute it and/or
005:         * modify it under the terms of the GNU Lesser General Public
006:         * License as published by the Free Software Foundation; either
007:         * version 2 of the License, or (at your option) any later version.
008:         *
009:         * This library is distributed in the hope that it will be useful,
010:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
011:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
012:         * Lesser General Public License for more details.
013:         *
014:         * You should have received a copy of the GNU Lesser General Public
015:         * License along with this library; if not, write to the Free Software
016:         * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
017:         */
018:
019:        package org.mandarax.jdbc.server.sql;
020:
021:        import java.sql.Types;
022:        import java.util.*;
023:        import org.mandarax.jdbc.*;
024:        import org.mandarax.jdbc.server.*;
025:        import org.mandarax.kernel.*;
026:        import org.mandarax.util.CachedResultSet;
027:        import org.mandarax.util.StringUtils;
028:        import org.mandarax.util.resultsetfilters.AggregationFunction;
029:        import org.mandarax.util.resultsetfilters.GroupByFilter;
030:        import org.mandarax.util.resultsetfilters.OrderByFilter;
031:        import org.mandarax.util.resultsetfilters.WhereFilter;
032:
033:        /**
034:         * Represents the SQL SELECT statement.
035:         * @author <A HREF="mailto:mandarax@jbdietrich.com">Jens Dietrich</A>
036:         * @version 3.3.2 <29 December 2004>
037:         * @since 3.0
038:         */
039:
040:        public class SelectStatement extends SQLObject {
041:            private SelectClause selectClause = null;
042:            private WhereClause whereClause = null;
043:            private FromClause fromClause = null;
044:            private OrderByClause orderByClause = null;
045:            private List hostVariables = null;
046:            private KnowledgeBase kb = null;
047:            private GroupByClause groupByClause = null;
048:            private HavingClause havingClause = null;
049:            private boolean distinct = false;
050:            private boolean normalized = false;
051:            private Map variablesByName = null;
052:
053:            // cached properties needed in order to build the mandarax query
054:            // this is the predicate in the original query
055:            private Predicate predicate = null;
056:            // this is the predicate in the final result set. filters, in particular 
057:            // GROUP BY may result in a different predicate !
058:            private Predicate resultsetPredicate = null;
059:            private Object[] termTemplates = null; // terms plus host variables - to be reused (when building terms for the mandarax query)!
060:
061:            private static LogicFactory lfactory = LogicFactory
062:                    .getDefaultFactory();
063:
064:            // class used to represent result sets generated by SELECT COUNT(*) statements
065:            private static String varName = "COUNT(*)";
066:            private static List queryVars = new ArrayList(1);
067:            private static VariableTerm queryVar = lfactory.createVariableTerm(
068:                    varName, Integer.class);
069:
070:            class CountAllResultSet extends CachedResultSet {
071:                CountAllResultSet(int count) {
072:                    super ();
073:                    synchronized (queryVars) {
074:                        if (queryVars.size() == 0)
075:                            queryVars.add(queryVar);
076:                    }
077:                    this .results = new ArrayList(1);
078:                    results.add(new Result(queryVar, lfactory
079:                            .createConstantTerm(new Integer(count))));
080:                }
081:
082:                public List getQueryVariables() throws InferenceException {
083:                    return queryVars;
084:                }
085:            }
086:
087:            /**
088:             * Constructor.
089:             */
090:            public SelectStatement() {
091:                super ();
092:            }
093:
094:            /**
095:             * Constructor. 
096:             * @param tableName a table name
097:             */
098:            public SelectStatement(String tableName) {
099:                super ();
100:                this .setTableName(tableName);
101:            }
102:
103:            /**
104:             * Constructor.
105:             * @param tableName a table name
106:             * @param columns - comma separated column names or a *
107:             */
108:            public SelectStatement(String tableName, String columns) {
109:                super ();
110:                this .setTableName(tableName);
111:                if (columns.trim().equals("*"))
112:                    this .setSelect2Star();
113:                else {
114:                    SelectClauseColumnList colList = new SelectClauseColumnList();
115:                    setSelectClause(colList);
116:                    for (StringTokenizer tokenizer = new StringTokenizer(
117:                            columns, ","); tokenizer.hasMoreTokens();) {
118:                        String token = tokenizer.nextToken();
119:                        ColumnName colName = new ColumnName(token);
120:                        colList.add(colName);
121:                        colName.setOwner(colList);
122:                    }
123:                }
124:            }
125:
126:            /**
127:             * Constructor.
128:             * @param tableName a table name
129:             * @param columns - an array of column names
130:             */
131:            public SelectStatement(String tableName, String[] columns) {
132:                super ();
133:                this .setTableName(tableName);
134:                this .setSelectColumnList(columns);
135:            }
136:
137:            /**
138:             * Compares objects. 
139:             * @param obj another object.
140:             * @return a boolean
141:             */
142:            public boolean sameAs(Object obj) {
143:                if (obj != null && obj instanceof  SelectStatement) {
144:                    SelectStatement s = (SelectStatement) obj;
145:                    boolean result = true;
146:                    result = result
147:                            && (this .selectClause == null ? s.selectClause == null
148:                                    : selectClause.sameAs(s.selectClause));
149:                    result = result
150:                            && (this .whereClause == null ? s.whereClause == null
151:                                    : whereClause.sameAs(s.whereClause));
152:                    result = result
153:                            && (this .fromClause == null ? s.fromClause == null
154:                                    : fromClause.sameAs(s.fromClause));
155:                    result = result
156:                            && (this .orderByClause == null ? s.orderByClause == null
157:                                    : orderByClause.sameAs(s.orderByClause));
158:                    result = result
159:                            && (this .groupByClause == null ? s.groupByClause == null
160:                                    : groupByClause.sameAs(s.groupByClause));
161:                    result = result
162:                            && (this .havingClause == null ? s.havingClause == null
163:                                    : havingClause.sameAs(s.havingClause));
164:                    return result;
165:                }
166:                return false;
167:            }
168:
169:            /**
170:             * Set the table name.
171:             * @param tableName the table name
172:             */
173:            public void setTableName(String tableName) {
174:                int pos = tableName.lastIndexOf('.');
175:                String table = null;
176:                if (pos == -1)
177:                    table = tableName;
178:                else {
179:                    // scoped table name. not really supported, but generic tools like to use it
180:                    // so we add minimal support
181:                    // TODO this should be done by the parser
182:                    table = tableName.substring(pos + 1);
183:                    String schemaName = tableName.substring(0, pos);
184:                    if (!DatabaseMetaDataImpl.DEFAULT_SCHEMA.equals(schemaName)) {
185:                        throw new IllegalArgumentException(
186:                                "This is an unknown schema " + schemaName);
187:                    }
188:
189:                }
190:                FromClause from = new FromClauseOneTable(table);
191:                setFromClause(from);
192:                from.setOwner(this );
193:            }
194:
195:            /**
196:             * Set the select clause to a star.
197:             */
198:            public void setSelect2Star() {
199:                setSelectClause(new SelectClauseStar());
200:            }
201:
202:            /**
203:             * Set a column list.
204:             * @param cols an array of column names
205:             */
206:            public void setSelectColumnList(String[] cols) {
207:                SelectClauseColumnList colList = new SelectClauseColumnList();
208:                for (int i = 0; i < cols.length; i++) {
209:                    ColumnName colName = new ColumnName(cols[i]);
210:                    colList.add(colName);
211:                    colName.setOwner(colList);
212:                }
213:                setSelectClause(colList);
214:            }
215:
216:            /** Getter for property fromClause.
217:             * @return Value of property fromClause.
218:             *
219:             */
220:            public org.mandarax.jdbc.server.sql.FromClause getFromClause() {
221:                return fromClause;
222:            }
223:
224:            /** Setter for property fromClause.
225:             * @param fromClause New value of property fromClause.
226:             *
227:             */
228:            public void setFromClause(
229:                    org.mandarax.jdbc.server.sql.FromClause fromClause) {
230:                this .fromClause = fromClause;
231:                fromClause.setOwner(this );
232:
233:            }
234:
235:            /** Getter for property selectClause.
236:             * @return Value of property selectClause.
237:             *
238:             */
239:            public org.mandarax.jdbc.server.sql.SelectClause getSelectClause() {
240:                return selectClause;
241:            }
242:
243:            /** Setter for property selectClause.
244:             * @param selectClause New value of property selectClause.
245:             *
246:             */
247:            public void setSelectClause(
248:                    org.mandarax.jdbc.server.sql.SelectClause selectClause) {
249:                this .selectClause = selectClause;
250:                selectClause.setOwner(this );
251:            }
252:
253:            /** Getter for property whereClause.
254:             * @return Value of property whereClause.
255:             *
256:             */
257:            public org.mandarax.jdbc.server.sql.WhereClause getWhereClause() {
258:                return whereClause;
259:            }
260:
261:            /**
262:             * Prepare the statement, i.e. gather the host variables.
263:             */
264:            public synchronized void prepare() {
265:                if (hostVariables == null) {
266:                    hostVariables = new ArrayList();
267:                    if (whereClause != null)
268:                        whereClause.prepare(hostVariables);
269:                }
270:            }
271:
272:            /**
273:             * Get the host variables.
274:             * @return a list of host variables.
275:             */
276:            private List getHostVariables() {
277:                prepare();
278:                return hostVariables;
279:            }
280:
281:            /**
282:             * Get a host variable.
283:             * @param index an index
284:             * @return a host variable.
285:             */
286:            private HostVariable getHostVariable(int index) {
287:                List vars = getHostVariables();
288:                if (index < 1)
289:                    throw new IllegalArgumentException(
290:                            "No host variable found - index must be > 0 !");
291:                if (index > vars.size())
292:                    throw new IllegalArgumentException(
293:                            "No host variable found - index must be < "
294:                                    + vars.size());
295:                return (HostVariable) vars.get(index - 1);
296:            }
297:
298:            /**
299:             * Bind a host variable.
300:             * @param value a value
301:             * @param index a slot index (starting with 1)
302:             * @exception illegal argument exception
303:             */
304:            public void bind(int index, Object value) {
305:                getHostVariable(index).bind(value);
306:            }
307:
308:            /**
309:             * Reset a host variable.
310:             * @param index a slot index (starting with 1)
311:             * @exception illegal argument exception
312:             */
313:            public void reset(int index) {
314:                getHostVariable(index).reset();
315:            }
316:
317:            /**
318:             * Indicates whether a host variable has been bound.
319:             * @param index a slot index (starting with 1)
320:             * @return a boolean
321:             * @exception illegal argument exception
322:             */
323:            public boolean isBound(int index) {
324:                return getHostVariable(index).isBound();
325:            }
326:
327:            /**
328:             * Check whether all host variables are bound - throw an exception if not.
329:             */
330:            public void checkBindings() throws JDBCException {
331:                List vars = getHostVariables();
332:                for (int i = 0; i < vars.size(); i++) {
333:                    if (!((HostVariable) vars.get(i)).isBound())
334:                        throw new JDBCException(
335:                                "Unbound host variable in prepared statement found at position "
336:                                        + (i + 1));
337:                }
338:            }
339:
340:            /**
341:             * Resets all host variables.
342:             */
343:            public void resetAll() {
344:                List vars = getHostVariables();
345:                for (int i = 0; i < vars.size(); i++) {
346:                    ((HostVariable) vars.get(i)).reset();
347:                }
348:            }
349:
350:            /**
351:             * Indicates whether this statement has host variables.
352:             */
353:            public boolean hasHostVariables() {
354:                return getHostVariables().size() > 0;
355:            }
356:
357:            /**
358:             * Sets the whereClause.
359:             * @param whereClause The whereClause to set
360:             */
361:            public void setWhereClause(WhereClause whereClause) {
362:                this .whereClause = whereClause;
363:                whereClause.setOwner(this );
364:            }
365:
366:            /**
367:             * Normalize the statement. I.e. remove redundant nestings,
368:             * set types fro context, etc
369:             * @param typesByColumn associations between column names and (SQL) types
370:             */
371:            public void normalize(Map typesByColumn) {
372:                fromClause.normalize(typesByColumn);
373:                selectClause.normalize(typesByColumn);
374:                if (whereClause != null)
375:                    whereClause.normalize(typesByColumn);
376:                normalized = true;
377:            }
378:
379:            /**
380:             * Get the knowledge base.
381:             * @return a knowledge base
382:             */
383:            public KnowledgeBase getKB() {
384:                return kb;
385:            }
386:
387:            /**
388:             * Sets the kb.
389:             * @param kb The knowledge base to set
390:             */
391:            public void setKB(KnowledgeBase kb) {
392:                this .kb = kb;
393:            }
394:
395:            /**
396:             * Build a mandarax query.
397:             * @return a mandarax query.
398:             */
399:            public Query asMandaraxQuery() throws JDBCException {
400:
401:                boolean debugOn = LOG_JDBC.isDebugEnabled();
402:                if (debugOn)
403:                    LOG_JDBC
404:                            .debug("Converting SQL statement into Mandarax query: "
405:                                    + this );
406:
407:                if (kb == null)
408:                    throw new JDBCException(
409:                            "The knowledge base must be set to build a mandarax query from a SelectStatement");
410:                String tableName = ((FromClauseOneTable) getFromClause())
411:                        .getTableName();
412:                // find predicate
413:                if (predicate == null)
414:                    predicate = JDBC2KBUtils.getPredicate(kb, tableName);
415:                if (predicate == null)
416:                    throw new JDBCException(
417:                            "No predicate found for table name " + tableName
418:                                    + " in kb " + kb);
419:
420:                // normalize the statement
421:                if (!normalized) {
422:                    // prepare col name - type associations
423:                    Class[] struct = predicate.getStructure();
424:                    String[] names = predicate.getSlotNames();
425:                    Map typesByColumn = new HashMap(struct.length);
426:                    for (int i = 0; i < struct.length; i++)
427:                        typesByColumn.put(names[i], new Integer(JDBCUtils
428:                                .getTypeMapping(struct[i])));
429:                    normalize(typesByColumn);
430:                }
431:
432:                // prepare terms using equal conditions
433:                if (termTemplates == null)
434:                    prepareMandaraxQueryTerms();
435:
436:                // bind host variables
437:                Term[] terms = new Term[termTemplates.length];
438:                for (int i = 0; i < terms.length; i++) {
439:                    if (termTemplates[i] instanceof  HostVariable) {
440:                        HostVariable hVar = (HostVariable) termTemplates[i];
441:                        if (!hVar.isBound()) {
442:                            // throw new JDBCException("Unbound host variable encountered - cannot build mandarax query");
443:                            // use variable
444:                            terms[i] = lfactory.createVariableTerm("@" + i,
445:                                    predicate.getStructure()[i]);
446:                        } else {
447:                            terms[i] = lfactory.createConstantTerm(hVar
448:                                    .getValue(), predicate.getStructure()[i]);
449:                        }
450:                    } else {
451:                        terms[i] = (Term) termTemplates[i];
452:                    }
453:                }
454:                if (debugOn) {
455:                    LOG_JDBC.debug("Query predicate is: " + predicate);
456:                    LOG_JDBC.debug("Query terms are: "
457:                            + StringUtils.toString(terms));
458:                }
459:
460:                // finally build the query
461:                return lfactory.createQuery(lfactory.createFact(predicate,
462:                        terms), "");
463:            }
464:
465:            /**
466:             * Get the name->variable mappings.
467:             * @param rs a result set
468:             * @return a map containing name -> variable associations
469:             */
470:            private Map getVariablesByName(ResultSet rs)
471:                    throws InferenceException {
472:                if (variablesByName == null)
473:                    variablesByName = new IdentityHashMap();
474:                Map mappings = (Map) variablesByName.get(rs);
475:                if (mappings == null) {
476:                    mappings = new HashMap();
477:                    variablesByName.put(rs, mappings);
478:                    for (Iterator iter = rs.getQueryVariables().iterator(); iter
479:                            .hasNext();) {
480:                        VariableTerm var = (VariableTerm) iter.next();
481:                        mappings.put(var.getName(), var);
482:                    }
483:                }
484:                return mappings;
485:            }
486:
487:            /**
488:             * Apply the conditions build from the WHERE clause using a mandarax result set filter.
489:             * Note that some conditions are used directly in the mandarax query (to bind variables)
490:             * and do not occur as conditions here. This method should be called after the mandarax query has been built.
491:             * @param rs the result set to be filtered
492:             * @param debugOn whether debug is switched on
493:             * @return a condition that can be used to build a filter
494:             */
495:            private ResultSet applyWhereCondition(ResultSet rs, boolean debugOn)
496:                    throws InferenceException {
497:                if (whereClause == null || whereClause.isEmpty()) {
498:                    if (debugOn)
499:                        LOG_JDBC
500:                                .debug("No where clause found, skip where filter");
501:                    return rs;
502:                }
503:                whereClause.setVariablesByName(this .getVariablesByName(rs));
504:                if (debugOn)
505:                    LOG_JDBC.debug("Applying where filter");
506:                // apply conditions		
507:                return new WhereFilter(rs, whereClause);
508:            }
509:
510:            /**
511:             * Apply the count all condition in statements without GROUP BY clause.
512:             * @param rs the result set to be filtered
513:             * @param debugOn whether debug is switched on
514:             * @return a condition that can be used to build a filter
515:             */
516:            private ResultSet applyCountAllCondition(ResultSet rs,
517:                    boolean debugOn) throws InferenceException {
518:                if (groupByClause == null) {
519:                    if (selectClause instanceof  SelectClauseColumnList) {
520:                        List cols = ((SelectClauseColumnList) selectClause)
521:                                .getColumns();
522:                        if (cols.size() == 1
523:                                && cols.get(0) instanceof  ComplexTerm1) {
524:                            ComplexTerm1 ct1 = (ComplexTerm1) cols.get(0);
525:                            if (ct1.getFunction() == Functions.COUNT) {
526:                                // count result set
527:                                if (debugOn)
528:                                    LOG_JDBC
529:                                            .debug("Counting results in result set to support COUNT(*) query - this can be expensive!");
530:                                rs.last();
531:                                int rowCount = rs.getCursorPosition() + 1;
532:                                // build result set
533:                                return new CountAllResultSet(rowCount);
534:                            }
535:                        }
536:                    }
537:                }
538:                return rs;
539:            }
540:
541:            /**
542:             * Apply the conditions build from the HAVING clause using a mandarax result set filter.
543:             * @param rs the result set to be filtered
544:             * @param debugOn whether debug is switched on
545:             * @return a condition that can be used to build a filter
546:             */
547:            private ResultSet applyHavingCondition(ResultSet rs, boolean debugOn)
548:                    throws InferenceException {
549:                if (havingClause == null || havingClause.isEmpty()) {
550:                    if (debugOn)
551:                        LOG_JDBC
552:                                .debug("No having clause found, skip having filter");
553:                    return rs;
554:                }
555:                havingClause.setVariablesByName(this .getVariablesByName(rs));
556:                if (debugOn)
557:                    LOG_JDBC.debug("Applying having filter");
558:                // apply conditions		
559:                return new WhereFilter(rs, havingClause);
560:            }
561:
562:            /**
563:             * Apply clauses in the select filters (WHERE, ORDER BY) as filters.
564:             * @param rs the result set
565:             * @return the filtered result set
566:             */
567:            public ResultSet applyFilters(ResultSet rs)
568:                    throws InferenceException {
569:                ResultSet filteredRS = rs;
570:                boolean debugOn = LOG_JDBC.isDebugEnabled();
571:                // check whether predicate has to be transformed
572:                setResultSetPredicate(rs, debugOn);
573:
574:                // filters
575:                filteredRS = applyWhereCondition(filteredRS, debugOn);
576:                filteredRS = applyCountAllCondition(filteredRS, debugOn);
577:                filteredRS = applyGroupByCondition(filteredRS, debugOn);
578:                filteredRS = applyHavingCondition(filteredRS, debugOn);
579:                filteredRS = applyOrderByCondition(filteredRS, debugOn);
580:                return filteredRS;
581:            }
582:
583:            /**
584:             * Build a new predicate for the result set. 
585:             * In general, the result set has a structure that differs from the original
586:             * due to functions, a subset of columns used, count(*) expression etc. <br>
587:             * In case this statement contains a group by clause, this is done in the 
588:             * applyGroupByCondition method.
589:             * @param rs a result set
590:             * @param debugOn whether debug is switched on
591:             * @throws InferenceException
592:             */
593:            private void setResultSetPredicate(ResultSet rs, boolean debugOn)
594:                    throws InferenceException {
595:                if (groupByClause == null
596:                        && (selectClause instanceof  SelectClauseColumnList)) {
597:                    if (debugOn)
598:                        LOG_JDBC.debug("Transforming predicate for result set");
599:                    List colList = ((SelectClauseColumnList) selectClause)
600:                            .getColumns();
601:                    String name = predicate.getName() + " (transf.)";
602:                    if (debugOn)
603:                        LOG_JDBC.debug("Predicate name in result set  will be "
604:                                + name);
605:                    Class[] structure = new Class[colList.size()];
606:                    String[] slotNames = new String[colList.size()];
607:                    String[] origSlotNames = predicate.getSlotNames();
608:                    for (int i = 0; i < structure.length; i++) {
609:                        ColumnTerm col = (ColumnTerm) colList.get(i);
610:                        if (col instanceof  ColumnName) {
611:                            String colName = ((ColumnName) col).getName();
612:                            // look up index
613:                            int j = 0;
614:                            while (j < origSlotNames.length
615:                                    && structure[i] == null) {
616:                                if (colName.equals(origSlotNames[j])) {
617:                                    structure[i] = predicate.getStructure()[j];
618:                                    slotNames[i] = origSlotNames[j];
619:                                }
620:                                j = j + 1;
621:                            }
622:                            if (structure[i] == null)
623:                                throw new InferenceException(
624:                                        "Unknown column (slot) " + colName
625:                                                + " in predicate " + name);
626:                        } else if (col instanceof  ComplexTerm1
627:                                && ((ComplexTerm1) col).getFunction() == Functions.COUNT) {
628:                            slotNames[i] = "COUNT(*)";
629:                            structure[i] = Integer.class;
630:                        }
631:                        // TODO generalize this and add support for functions such as || (concatenation), 
632:                        // UPPER etc (in the next version)
633:                    }
634:                    resultsetPredicate = new SimplePredicate(name, structure);
635:                    resultsetPredicate.setSlotNames(slotNames);
636:                }
637:            }
638:
639:            /**
640:             * Apply the conditions build from the WHERE clause using a mandarax result set filter.
641:             * @param rs the result set to be filtered
642:             * @param debugOn whether debug is switched on
643:             * @return the filtered result set
644:             */
645:            private ResultSet applyOrderByCondition(ResultSet rs,
646:                    boolean debugOn) throws InferenceException {
647:                if (orderByClause == null || orderByClause.isEmpty()) {
648:                    if (debugOn)
649:                        LOG_JDBC
650:                                .debug("No order by clause found, skip order by filter");
651:                    return rs;
652:                }
653:                orderByClause.setVariablesByName(this .getVariablesByName(rs));
654:                if (debugOn)
655:                    LOG_JDBC.debug("Applying order by filter");
656:                // apply conditions		
657:                return new OrderByFilter(rs, orderByClause.getConditions());
658:            }
659:
660:            /**
661:             * Apply the conditions build from the GROUP BY clause using a mandarax result set filter.
662:             * @param rs the result set to be filtered
663:             * @param debugOn whether debug is switched on
664:             * @return the filtered result set
665:             */
666:            private ResultSet applyGroupByCondition(ResultSet rs,
667:                    boolean debugOn) throws InferenceException {
668:                if (groupByClause == null || groupByClause.isEmpty()) {
669:                    if (debugOn)
670:                        LOG_JDBC
671:                                .debug("No group by clause found, skip group by filter");
672:                    return rs;
673:                }
674:                groupByClause.setVariablesByName(this .getVariablesByName(rs));
675:                // apply conditions		
676:                AggregationFunction[] aggregationFunctions = groupByClause
677:                        .getAggregationFunctions();
678:                VariableTerm[] groupByTerms = groupByClause
679:                        .getAggregationTerms();
680:                VariableTerm[] selectedColumnNames = groupByClause
681:                        .getSelectedAggregationTerms();
682:                // build result set predicate
683:                Class[] structure = new Class[selectedColumnNames.length
684:                        + aggregationFunctions.length];
685:                String[] slotNames = new String[selectedColumnNames.length
686:                        + aggregationFunctions.length];
687:                for (int i = 0; i < selectedColumnNames.length; i++) {
688:                    structure[i] = selectedColumnNames[i].getType();
689:                    slotNames[i] = selectedColumnNames[i].getName();
690:                }
691:                for (int i = 0; i < aggregationFunctions.length; i++) {
692:                    structure[i + groupByTerms.length] = aggregationFunctions[i]
693:                            .getResultType();
694:                    slotNames[i + groupByTerms.length] = aggregationFunctions[i]
695:                            .getVariableInResult().getName();
696:                }
697:                if (debugOn) {
698:                    LOG_JDBC.debug("Applying group by filter");
699:                    LOG_JDBC.debug("Building new GROUP BY variable names: "
700:                            + StringUtils.toString(slotNames));
701:                    LOG_JDBC.debug("Building new GROUP BY variable terms: "
702:                            + StringUtils.toString(structure));
703:                }
704:                String name = predicate.getName() + " (aggr.)";
705:                if (debugOn)
706:                    LOG_JDBC
707:                            .debug("Predicate name in GROUP BY result set  will be "
708:                                    + name);
709:                resultsetPredicate = new SimplePredicate(name, structure);
710:                resultsetPredicate.setSlotNames(slotNames);
711:
712:                return new GroupByFilter(rs, aggregationFunctions, groupByTerms);
713:            }
714:
715:            /**
716:             * Prepare the terms for the sql query. I.e., prepare the array termTemplates containing terms as well as 
717:             * host variables (which will be turned into terms later). Terms means terms in the mandarax sense.
718:             */
719:            private void prepareMandaraxQueryTerms() {
720:                Class[] structure = predicate.getStructure();
721:                termTemplates = new Object[structure.length];
722:                List equalConditions = whereClause == null ? new ArrayList()
723:                        : whereClause.extractEqualConditions();
724:                SimpleCondition cond = null;
725:                ColumnTerm ct1, ct2 = null;
726:                for (int i = 0; i < termTemplates.length; i++) {
727:                    // replace only if null - might already be initialized through a col1=col2 condition
728:                    // warning: "col1=col2 and col2='value'" not yet handled !
729:                    String colName = JDBC2KBUtils.getSlotName(predicate, i);
730:                    if (termTemplates[i] == null) {
731:                        for (int j = 0; j < equalConditions.size(); j++) {
732:                            cond = (SimpleCondition) equalConditions.get(j);
733:                            if (cond.isCondition4Column(colName)) {
734:                                ct1 = cond.getColumnTerm(0);
735:                                ct2 = cond.getColumnTerm(1);
736:                                if (ct1 instanceof  Value
737:                                        && ct2 instanceof  ColumnName) {
738:                                    termTemplates[i] = lfactory
739:                                            .createConstantTerm(((Value) ct1)
740:                                                    .getConvertedValue(),
741:                                                    structure[i]);
742:                                } else if (ct2 instanceof  Value
743:                                        && ct1 instanceof  ColumnName) {
744:                                    termTemplates[i] = lfactory
745:                                            .createConstantTerm(((Value) ct2)
746:                                                    .getConvertedValue(),
747:                                                    structure[i]);
748:                                } else if (ct1 instanceof  HostVariable
749:                                        && ct2 instanceof  ColumnName) {
750:                                    termTemplates[i] = ct1;
751:                                } else if (ct2 instanceof  HostVariable
752:                                        && ct1 instanceof  ColumnName) {
753:                                    termTemplates[i] = ct2;
754:                                } else if (ct1 instanceof  ColumnName
755:                                        && ct2 instanceof  ColumnName) {
756:                                    String colName1 = ((ColumnName) ct1)
757:                                            .getName();
758:                                    String colName2 = ((ColumnName) ct2)
759:                                            .getName();
760:                                    if (colName.equals(colName1)) {
761:                                        VariableTerm var = lfactory
762:                                                .createVariableTerm(colName,
763:                                                        structure[i]);
764:                                        termTemplates[i] = var;
765:                                        termTemplates[JDBC2KBUtils
766:                                                .getSlotNumber(predicate,
767:                                                        colName2)] = var;
768:                                    }
769:                                }
770:                            }
771:                        }
772:                    }
773:                    if (termTemplates[i] == null) {
774:                        // if still null then this is a variable term
775:                        termTemplates[i] = lfactory.createVariableTerm(
776:                                JDBC2KBUtils.getSlotName(predicate, i),
777:                                structure[i]);
778:                    }
779:                }
780:            }
781:
782:            /**
783:             * @return boolean
784:             */
785:            public boolean isDistinct() {
786:                return distinct;
787:            }
788:
789:            /**
790:             * Sets the distinct.
791:             * @param distinct The distinct to set
792:             */
793:            public void setDistinct(boolean distinct) {
794:                this .distinct = distinct;
795:            }
796:
797:            /**
798:             * Returns the ORDER BY clause.
799:             * @return the ORDER BY clause
800:             */
801:            public OrderByClause getOrderByClause() {
802:                return orderByClause;
803:            }
804:
805:            /**
806:             * Sets the ORDER BY clause.
807:             * @param orderByClause The ORDER BY clause to set
808:             */
809:            public void setOrderByClause(OrderByClause orderByClause) {
810:                this .orderByClause = orderByClause;
811:                orderByClause.setOwner(this );
812:            }
813:
814:            /**
815:             * Returns the GROUP BY clause.
816:             * @return the GROUP BY clause
817:             */
818:            public GroupByClause getGroupByClause() {
819:                return groupByClause;
820:            }
821:
822:            /**
823:             * Sets the GROUP BY clause.
824:             * @param groupByClause the GROUP BY clause
825:             */
826:            public void setGroupByClause(GroupByClause groupByClause) {
827:                this .groupByClause = groupByClause;
828:                groupByClause.setOwner(this );
829:            }
830:
831:            /**
832:             * Returns the HAVING clause.
833:             * @return the HAVING clause to set
834:             */
835:            public HavingClause getHavingClause() {
836:                return havingClause;
837:            }
838:
839:            /**
840:             * Sets the HAVING clause.
841:             * @param havingClause the HAVING clause to set
842:             */
843:            public void setHavingClause(HavingClause havingClause) {
844:                this .havingClause = havingClause;
845:                havingClause.setOwner(this );
846:            }
847:
848:            /**
849:             * Get the predicate in the final result set.
850:             * @return a predicate
851:             */
852:            public Predicate getResultSetPredicate() {
853:                if (this .resultsetPredicate != null)
854:                    return resultsetPredicate;
855:                else
856:                    return predicate;
857:            }
858:
859:            /**
860:             * Get a list of column terms from the SELECT statement.
861:             * @return a list of column terms 
862:             */
863:            List getColumns() throws InferenceException {
864:                if (selectClause instanceof  SelectClauseColumnList) {
865:                    return ((SelectClauseColumnList) selectClause).getColumns();
866:                }
867:                LOG_JDBC
868:                        .debug("Cannot list columns in statement, return empty list");
869:                return new ArrayList();
870:            }
871:
872:            /**
873:             * Get a list of column names from the SELECT statement.
874:             * @return a list of column names  
875:             */
876:            List getColumnNames() throws InferenceException {
877:                List columns = getColumns();
878:                List columnNames = new ArrayList(columns.size());
879:                for (int i = 0; i < columns.size(); i++) {
880:                    if (columns.get(i) instanceof  ColumnName)
881:                        columnNames.add(columns.get(i));
882:                }
883:                return columnNames;
884:            }
885:
886:            /**
887:             * Print the object on a buffer in order to display the parsed SQL.
888:             * @param out a string bufer to print on
889:             */
890:            public void print(StringBuffer out) {
891:                out.append("SELECT ");
892:                if (isDistinct())
893:                    out.append(" DISTINCT ");
894:                selectClause.print(out);
895:                out.append(" FROM ");
896:                fromClause.print(out);
897:                if (whereClause != null) {
898:                    out.append(" WHERE ");
899:                    whereClause.print(out);
900:                }
901:                if (groupByClause != null) {
902:                    out.append(" GROUP BY ");
903:                    groupByClause.print(out);
904:                }
905:                if (havingClause != null) {
906:                    out.append(" HAVING ");
907:                    havingClause.print(out);
908:                }
909:                if (orderByClause != null) {
910:                    out.append(" ORDER BY ");
911:                    orderByClause.print(out);
912:                }
913:
914:            }
915:
916:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.