Source Code Cross Referenced for TableExpressionFromSet.java in  » Database-DBMS » mckoi » com » mckoi » database » interpret » 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 » Database DBMS » mckoi » com.mckoi.database.interpret 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /**
002:         * com.mckoi.database.interpret.TableExpressionFromSet  01 Nov 2001
003:         *
004:         * Mckoi SQL Database ( http://www.mckoi.com/database )
005:         * Copyright (C) 2000, 2001, 2002  Diehl and Associates, Inc.
006:         *
007:         * This program is free software; you can redistribute it and/or
008:         * modify it under the terms of the GNU General Public License
009:         * Version 2 as published by the Free Software Foundation.
010:         *
011:         * This program is distributed in the hope that it will be useful,
012:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014:         * GNU General Public License Version 2 for more details.
015:         *
016:         * You should have received a copy of the GNU General Public License
017:         * Version 2 along with this program; if not, write to the Free Software
018:         * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
019:         *
020:         * Change Log:
021:         * 
022:         * 
023:         */package com.mckoi.database.interpret;
024:
025:        import com.mckoi.database.Variable;
026:        import com.mckoi.database.TableName;
027:        import com.mckoi.database.Expression;
028:        import com.mckoi.database.DatabaseSystem;
029:        import com.mckoi.database.DatabaseException;
030:        import com.mckoi.database.StatementException;
031:        import com.mckoi.database.ExpressionPreparer;
032:        import com.mckoi.database.CorrelatedVariable;
033:        import com.mckoi.database.DatabaseConnection;
034:        import java.util.ArrayList;
035:
036:        /**
037:         * A set of tables and function references that make up the resources made
038:         * available by a table expression.  When a SelectQueriable is prepared this
039:         * object is created and is used to dereference names to sources.  It also
040:         * has the ability to chain to another TableExpressionFromSet and resolve
041:         * references over a complex sub-query hierarchy.
042:         *
043:         * @author Tobias Downer
044:         */
045:
046:        class TableExpressionFromSet {
047:
048:            /**
049:             * The list of table resources in this set.
050:             * (FromTableInterface).
051:             */
052:            private ArrayList table_resources;
053:
054:            /**
055:             * The list of function expression resources.  For example, one table
056:             * expression may expose a function as 'SELECT (a + b) AS c, ....' in which
057:             * case we have a virtual assignment of c = (a + b) in this set.
058:             */
059:            private ArrayList function_resources;
060:
061:            /**
062:             * The list of Variable references in this set that are exposed to the
063:             * outside, including function aliases.  For example,
064:             *   SELECT a, b, c, (a + 1) d FROM ABCTable
065:             * Would be exposing variables 'a', 'b', 'c' and 'd'.
066:             */
067:            private ArrayList exposed_variables;
068:
069:            /**
070:             * Set to true if this should do case insensitive resolutions.
071:             */
072:            private boolean case_insensitive = false;
073:
074:            /**
075:             * The parent TableExpressionFromSet if one exists.  This is used for
076:             * chaining a set of table sets together.  When chained the
077:             * 'globalResolveVariable' method can be used to resolve a reference in the
078:             * chain.
079:             */
080:            private TableExpressionFromSet parent;
081:
082:            /**
083:             * Constructs the object.
084:             */
085:            public TableExpressionFromSet(DatabaseConnection connection) {
086:                table_resources = new ArrayList();
087:                function_resources = new ArrayList();
088:                exposed_variables = new ArrayList();
089:                // Is the database case insensitive?
090:                this .case_insensitive = connection.isInCaseInsensitiveMode();
091:            }
092:
093:            /**
094:             * Sets the parent of this expression.  parent can be set to null.
095:             */
096:            public void setParent(TableExpressionFromSet parent) {
097:                this .parent = parent;
098:            }
099:
100:            /**
101:             * Returns the parent of this set.  If it has no parent it returns null.
102:             */
103:            public TableExpressionFromSet getParent() {
104:                return parent;
105:            }
106:
107:            /**
108:             * Toggle the case sensitivity flag.
109:             */
110:            public void setCaseInsensitive(boolean status) {
111:                case_insensitive = status;
112:            }
113:
114:            boolean stringCompare(String str1, String str2) {
115:                if (!case_insensitive) {
116:                    return str1.equals(str2);
117:                }
118:                return str1.equalsIgnoreCase(str2);
119:            }
120:
121:            /**
122:             * Adds a table resource to the set.
123:             */
124:            public void addTable(FromTableInterface table_resource) {
125:                table_resources.add(table_resource);
126:            }
127:
128:            /**
129:             * Adds a function resource to the set.  Note that is possible for there to
130:             * be references in the 'expression' that do not reference resources in this
131:             * set.  For example, a correlated reference.
132:             */
133:            public void addFunctionRef(String name, Expression expression) {
134:                //    System.out.println("addFunctionRef: " + name + ", " + expression);
135:                function_resources.add(name);
136:                function_resources.add(expression);
137:            }
138:
139:            /**
140:             * Adds a variable in this from set that is exposed to the outside.  This
141:             * list should contain all references from the SELECT ... part of the
142:             * query.  For example, SELECT a, b, (a + 1) d exposes variables
143:             * a, b and d.
144:             */
145:            public void exposeVariable(Variable v) {
146:                //    System.out.println("exposeVariable: " + v);
147:                //    new Error().printStackTrace();
148:                exposed_variables.add(v);
149:            }
150:
151:            /**
152:             * Exposes all the columns from the given FromTableInterface.
153:             */
154:            public void exposeAllColumnsFromSource(FromTableInterface table) {
155:                Variable[] v = table.allColumns();
156:                for (int p = 0; p < v.length; ++p) {
157:                    exposeVariable(v[p]);
158:                }
159:            }
160:
161:            /**
162:             * Exposes all the columns in all the child tables.
163:             */
164:            public void exposeAllColumns() {
165:                for (int i = 0; i < setCount(); ++i) {
166:                    exposeAllColumnsFromSource(getTable(i));
167:                }
168:            }
169:
170:            /**
171:             * Exposes all the columns from the given table name.
172:             */
173:            public void exposeAllColumnsFromSource(TableName tn) {
174:                FromTableInterface table_interface = findTable(tn.getSchema(),
175:                        tn.getName());
176:                if (table_interface == null) {
177:                    throw new StatementException("Table name found: " + tn);
178:                }
179:                exposeAllColumnsFromSource(table_interface);
180:            }
181:
182:            /**
183:             * Returns a Variable[] array for each variable that is exposed in this
184:             * from set.  This is a list of fully qualified variables that are
185:             * referencable from the final result of the table expression.
186:             */
187:            public Variable[] generateResolvedVariableList() {
188:                int sz = exposed_variables.size();
189:                Variable[] list = new Variable[sz];
190:                for (int i = 0; i < sz; ++i) {
191:                    list[i] = new Variable((Variable) exposed_variables.get(i));
192:                }
193:                return list;
194:            }
195:
196:            /**
197:             * Returns the first FromTableInterface object that matches the given schema,
198:             * table reference.  Returns null if no objects with the given schema/name
199:             * reference match.
200:             */
201:            FromTableInterface findTable(String schema, String name) {
202:                for (int p = 0; p < setCount(); ++p) {
203:                    FromTableInterface table = getTable(p);
204:                    if (table.matchesReference(null, schema, name)) {
205:                        return table;
206:                    }
207:                }
208:                return null;
209:            }
210:
211:            /**
212:             * Returns the number of FromTableInterface objects in this set.
213:             */
214:            int setCount() {
215:                return table_resources.size();
216:            }
217:
218:            /**
219:             * Returns the FromTableInterface object at the given index position in this
220:             * set.
221:             */
222:            FromTableInterface getTable(int i) {
223:                return (FromTableInterface) table_resources.get(i);
224:            }
225:
226:            /**
227:             * Dereferences a fully qualified reference that is within this set.  For
228:             * example, SELECT ( a + b ) AS z given 'z' would return the expression
229:             * (a + b).
230:             * <p>
231:             * Returns null if unable to dereference assignment because it does not
232:             * exist.
233:             */
234:            Expression dereferenceAssignment(Variable v) {
235:                TableName tname = v.getTableName();
236:                String var_name = v.getName();
237:                // We are guarenteed not to match with a function if the table name part
238:                // of a Variable is present.
239:                if (tname != null) {
240:                    return null;
241:                }
242:
243:                // Search for the function with this name
244:                Expression last_found = null;
245:                int matches_found = 0;
246:                for (int i = 0; i < function_resources.size(); i += 2) {
247:                    String fun_name = (String) function_resources.get(i);
248:                    if (stringCompare(fun_name, var_name)) {
249:                        if (matches_found > 0) {
250:                            throw new StatementException(
251:                                    "Ambiguous reference '" + v + "'");
252:                        }
253:                        last_found = (Expression) function_resources.get(i + 1);
254:                        ++matches_found;
255:                    }
256:                }
257:
258:                return last_found;
259:            }
260:
261:            /**
262:             * Resolves the given Variable object to an assignment if it's possible to do
263:             * so within the context of this set.  If the variable can not be
264:             * unambiguously resolved to a function or aliased column, a
265:             * StatementException is thrown.  If the variable isn't assigned to any
266:             * function or aliased column, 'null' is returned.
267:             */
268:            private Variable resolveAssignmentReference(Variable v) {
269:                TableName tname = v.getTableName();
270:                String var_name = v.getName();
271:                // We are guarenteed not to match with a function if the table name part
272:                // of a Variable is present.
273:                if (tname != null) {
274:                    return null;
275:                }
276:
277:                // Search for the function with this name
278:                Variable last_found = null;
279:                int matches_found = 0;
280:                for (int i = 0; i < function_resources.size(); i += 2) {
281:                    String fun_name = (String) function_resources.get(i);
282:                    if (stringCompare(fun_name, var_name)) {
283:                        if (matches_found > 0) {
284:                            throw new StatementException(
285:                                    "Ambiguous reference '" + v + "'");
286:                        }
287:                        last_found = new Variable(fun_name);
288:                        ++matches_found;
289:                    }
290:                }
291:
292:                return last_found;
293:            }
294:
295:            /**
296:             * Resolves the given Variable against the table columns in this from set.
297:             * If the variable does not resolve to anything 'null' is returned.  If the
298:             * variable is ambiguous, a StatementException is thrown.
299:             * <p>
300:             * Note that the given variable does not have to be fully qualified but the
301:             * returned expressions are fully qualified.
302:             */
303:            Variable resolveTableColumnReference(Variable v) {
304:                TableName tname = v.getTableName();
305:                String sch_name = null;
306:                String tab_name = null;
307:                String col_name = v.getName();
308:                if (tname != null) {
309:                    sch_name = tname.getSchema();
310:                    tab_name = tname.getName();
311:                }
312:
313:                // Find matches in our list of tables sources,
314:                Variable matched_var = null;
315:
316:                for (int i = 0; i < table_resources.size(); ++i) {
317:                    FromTableInterface table = (FromTableInterface) table_resources
318:                            .get(i);
319:                    int rcc = table.resolveColumnCount(null, sch_name,
320:                            tab_name, col_name);
321:                    if (rcc == 0) {
322:                        // do nothing if no matches
323:                    } else if (rcc == 1 && matched_var == null) {
324:                        // If 1 match and matched_var = null
325:                        matched_var = table.resolveColumn(null, sch_name,
326:                                tab_name, col_name);
327:                    } else { // if (rcc >= 1 and matched_var != null)
328:                        System.out.println(matched_var);
329:                        System.out.println(rcc);
330:                        throw new StatementException("Ambiguous reference '"
331:                                + v + "'");
332:                    }
333:                }
334:
335:                return matched_var;
336:            }
337:
338:            /**
339:             * Resolves the given Variable object to a fully resolved Variable
340:             * within the context of this table expression.  If the variable does not
341:             * resolve to anything 'null' is returned.  If the variable is ambiguous, a
342:             * StatementException is thrown.
343:             * <p>
344:             * If the variable name references a table column, an expression with a
345:             * single Variable element is returned.  If the variable name references a
346:             * function, an expression of the function is returned.
347:             * <p>
348:             * Note that the given variable does not have to be fully qualified but the
349:             * returned expressions are fully qualified.
350:             */
351:            Variable resolveReference(Variable v) {
352:                // Try and resolve against alias names first,
353:                ArrayList list = new ArrayList();
354:
355:                //    Expression exp = dereferenceAssignment(v);
356:                //    // If this is an alias like 'a AS b' then add 'a' to the list instead of
357:                //    // adding 'b'.  This allows us to handle a number of ambiguous conditions.
358:                //    if (exp != null) {
359:                //      Variable v2 = exp.getVariable();
360:                //      if (v2 != null) {
361:                //        list.add(resolveTableColumnReference(v2));
362:                //      }
363:                //      else {
364:                //        list.add(resolveAssignmentReference(v));
365:                //      }
366:                //    }
367:
368:                Variable function_var = resolveAssignmentReference(v);
369:                if (function_var != null) {
370:                    list.add(function_var);
371:                }
372:
373:                Variable tc_var = resolveTableColumnReference(v);
374:                if (tc_var != null) {
375:                    list.add(tc_var);
376:                }
377:
378:                //    TableName tname = v.getTableName();
379:                //    String sch_name = null;
380:                //    String tab_name = null;
381:                //    String col_name = v.getName();
382:                //    if (tname != null) {
383:                //      sch_name = tname.getSchema();
384:                //      tab_name = tname.getName();
385:                //    }
386:                //
387:                //    // Find matches in our list of tables sources,
388:                //    for (int i = 0; i < table_resources.size(); ++i) {
389:                //      FromTableInterface table = (FromTableInterface) table_resources.get(i);
390:                //      int rcc = table.resolveColumnCount(null, sch_name, tab_name, col_name);
391:                //      if (rcc == 1) {
392:                //        Variable matched =
393:                //                      table.resolveColumn(null, sch_name, tab_name, col_name);
394:                //        list.add(matched);
395:                //      }
396:                //      else if (rcc > 1) {
397:                //        throw new StatementException("Ambiguous reference '" + v + "'");
398:                //      }
399:                //    }
400:
401:                // Return the variable if we found one unambiguously.
402:                int list_size = list.size();
403:                if (list_size == 0) {
404:                    return null;
405:                } else if (list_size == 1) {
406:                    return (Variable) list.get(0);
407:                } else {
408:                    //      // Check if the variables are the same?
409:                    //      Variable cv = (Variable) list.get(0);
410:                    //      for (int i = 1; i < list.size(); ++i) {
411:                    //        if (!cv.equals(list.get(i))) {
412:                    throw new StatementException("Ambiguous reference '" + v
413:                            + "'");
414:                    //        }
415:                    //      }
416:                    //      // If they are all the same return the variable.
417:                    //      return v;
418:                }
419:
420:            }
421:
422:            /**
423:             * Resolves the given Variable reference within the chained list of
424:             * TableExpressionFromSet objects to a CorrelatedVariable.  If the reference
425:             * is not found in this set the method recurses to the parent set.  The first
426:             * unambiguous reference is returned.
427:             * <p>
428:             * If resolution is ambiguous within a set, a StatementException is thrown.
429:             * <p>
430:             * Returns null if the reference could not be resolved.
431:             */
432:            CorrelatedVariable globalResolveReference(int level, Variable v) {
433:                Variable nv = resolveReference(v);
434:                if (nv == null && getParent() != null) {
435:                    // If we need to descend to the parent, increment the level.
436:                    return getParent().globalResolveReference(level + 1, v);
437:                } else if (nv != null) {
438:                    return new CorrelatedVariable(nv, level);
439:                }
440:                return null;
441:            }
442:
443:            /**
444:             * Attempts to qualify the given Variable object to a value found either
445:             * in this from set, or a value in the parent from set.  A variable that
446:             * is qualified by the parent is called a correlated variable.  Any
447:             * correlated variables that are successfully qualified are returned as
448:             * CorrelatedVariable objects.
449:             */
450:            Object qualifyVariable(Variable v_in) {
451:                Variable v = resolveReference(v_in);
452:                if (v == null) {
453:                    // If not found, try and resolve in parent set (correlated)
454:                    if (getParent() != null) {
455:                        CorrelatedVariable cv = getParent()
456:                                .globalResolveReference(1, v_in);
457:                        if (cv == null) {
458:                            throw new StatementException("Reference '" + v_in
459:                                    + "' not found.");
460:                        }
461:                        return cv;
462:                    }
463:                    if (v == null) {
464:                        throw new StatementException("Reference '" + v_in
465:                                + "' not found.");
466:                    }
467:                }
468:                return v;
469:            }
470:
471:            /**
472:             * Returns an ExpressionPreparer that qualifies all variables in an
473:             * expression to either a qualified Variable or a CorrelatedVariable object.
474:             */
475:            ExpressionPreparer expressionQualifier() {
476:                return new ExpressionPreparer() {
477:                    public boolean canPrepare(Object element) {
478:                        return element instanceof  Variable;
479:                    }
480:
481:                    public Object prepare(Object element)
482:                            throws DatabaseException {
483:                        return qualifyVariable((Variable) element);
484:                    }
485:                };
486:            }
487:
488:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.