Author: mattmann
Date: Mon Nov 28 04:41:43 2011
New Revision: 1206971
URL: http://svn.apache.org/viewvc?rev=1206971&view=rev
Log:
- fix for OODT-336 xmlps should omit joining of tables that are unnecessary to
fulfill query (contributed by Ricky Nguyen)
Added:
oodt/trunk/xmlps/src/test/resources/test-required-tables-ps.xml
Modified:
oodt/trunk/CHANGES.txt
oodt/trunk/xmlps/src/main/java/org/apache/oodt/xmlps/product/XMLPSProductHandler.java
oodt/trunk/xmlps/src/test/java/org/apache/oodt/xmlps/product/TestXMLPSProductHandler.java
Modified: oodt/trunk/CHANGES.txt
URL:
http://svn.apache.org/viewvc/oodt/trunk/CHANGES.txt?rev=1206971&r1=1206970&r2=1206971&view=diff
==============================================================================
--- oodt/trunk/CHANGES.txt (original)
+++ oodt/trunk/CHANGES.txt Mon Nov 28 04:41:43 2011
@@ -4,6 +4,9 @@ Apache OODT Change Log
Release 0.4: Current Development
--------------------------------------------
+* OODT-336 xmlps should omit joining of tables that are unnecessary to
+ fulfill query (Ricky Nguyen via mattmann)
+
* OODT-339 MappingReader should add default join table to DatabaseTable
if none defined (Ricky Nguyen via mattmann)
Modified:
oodt/trunk/xmlps/src/main/java/org/apache/oodt/xmlps/product/XMLPSProductHandler.java
URL:
http://svn.apache.org/viewvc/oodt/trunk/xmlps/src/main/java/org/apache/oodt/xmlps/product/XMLPSProductHandler.java?rev=1206971&r1=1206970&r2=1206971&view=diff
==============================================================================
---
oodt/trunk/xmlps/src/main/java/org/apache/oodt/xmlps/product/XMLPSProductHandler.java
(original)
+++
oodt/trunk/xmlps/src/main/java/org/apache/oodt/xmlps/product/XMLPSProductHandler.java
Mon Nov 28 04:41:43 2011
@@ -41,8 +41,10 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+import java.util.Set;
import java.util.Stack;
import java.util.Vector;
import java.util.logging.Level;
@@ -189,10 +191,10 @@ public class XMLPSProductHandler impleme
.createQueryStack(query.getWhereElementSet());
Expression parsedQuery = HandlerQueryParser.parse(queryStack,
this.mapping);
- List<QueryElement> names = getElemNamesFromQueryElemSet(query
+ List<QueryElement> selectNames = getElemNamesFromQueryElemSet(query
.getSelectElementSet());
- String querySelectNames = toSQLSelectColumns(names);
+ String querySelectNames = toSQLSelectColumns(selectNames);
StringBuffer sqlBuf = new StringBuffer("SELECT ");
sqlBuf.append(querySelectNames);
@@ -201,10 +203,9 @@ public class XMLPSProductHandler impleme
sqlBuf.append(" ");
if (mapping.getNumTables() > 0) {
- for (Iterator<String> i = mapping.getTableNames().iterator(); i
- .hasNext();) {
- String tableName = i.next();
- DatabaseTable tbl = mapping.getTableByName(tableName);
+ List<QueryElement> whereNames =
getElemNamesFromQueryElemSet(query.getWhereElementSet());
+ Set<DatabaseTable> requiredTables = getRequiredTables(whereNames,
selectNames);
+ for (DatabaseTable tbl : requiredTables) {
sqlBuf.append("INNER JOIN ");
sqlBuf.append(tbl.getName());
sqlBuf.append(" ON ");
@@ -229,7 +230,7 @@ public class XMLPSProductHandler impleme
if (executor != null) {
try {
CDEResult res = executor.executeLocalQuery(this.mapping,
- sqlBuf.toString(), toSQLResultSetColumns(names));
+ sqlBuf.toString(), toSQLResultSetColumns(selectNames));
res = addConstFields(res,
getConstElemNamesFromQueryElemSet(query
@@ -382,5 +383,49 @@ public class XMLPSProductHandler impleme
}
}
+
+ protected Set<DatabaseTable> getRequiredTables(
+ List<QueryElement> whereElemNames, List<QueryElement>
selectElemNames) {
+ Set<DatabaseTable> tables = new HashSet<DatabaseTable>();
+ // add tables from where element set
+ if (whereElemNames != null) {
+ for (QueryElement qe : whereElemNames) {
+ MappingField fld = mapping.getFieldByLocalName(qe.getValue());
+ if (fld != null) {
+ DatabaseTable t =
mapping.getTableByName(fld.getTableName());
+ if (t != null && !tables.contains(t)) {
+ tables.add(t);
+ }
+ }
+ }
+ }
+ // add tables from select element set
+ if (selectElemNames != null) {
+ for (QueryElement qe : selectElemNames) {
+ MappingField fld = mapping.getFieldByLocalName(qe.getValue());
+ if (fld != null) {
+ DatabaseTable t =
mapping.getTableByName(fld.getTableName());
+ if (t != null && !tables.contains(t)) {
+ tables.add(t);
+ }
+ }
+ }
+ }
+ // the tables found may be joined on columns from tables we haven't
found
+ // yet
+ // add additional required join tables
+ Set<DatabaseTable> moreTables = new HashSet<DatabaseTable>(tables);
+ for (DatabaseTable t : tables) {
+ DatabaseTable join =
mapping.getTableByName(t.getDefaultTableJoin());
+ // recursively add all join tables until we get to either
+ // (a) the mapping default table (join == null)
+ // (b) or a table already found (moreTables.contains(join))
+ while (join != null && !moreTables.contains(join)) {
+ moreTables.add(join);
+ join = mapping.getTableByName(join.getDefaultTableJoin());
+ }
+ }
+ return moreTables;
+ }
}
Modified:
oodt/trunk/xmlps/src/test/java/org/apache/oodt/xmlps/product/TestXMLPSProductHandler.java
URL:
http://svn.apache.org/viewvc/oodt/trunk/xmlps/src/test/java/org/apache/oodt/xmlps/product/TestXMLPSProductHandler.java?rev=1206971&r1=1206970&r2=1206971&view=diff
==============================================================================
---
oodt/trunk/xmlps/src/test/java/org/apache/oodt/xmlps/product/TestXMLPSProductHandler.java
(original)
+++
oodt/trunk/xmlps/src/test/java/org/apache/oodt/xmlps/product/TestXMLPSProductHandler.java
Mon Nov 28 04:41:43 2011
@@ -20,8 +20,10 @@ package org.apache.oodt.xmlps.product;
//JDK imports
import java.util.Iterator;
import java.util.List;
+import java.util.Set;
//APACHE imports
+import org.apache.oodt.xmlps.mapping.DatabaseTable;
import org.apache.oodt.xmlps.util.XMLQueryHelper;
import org.apache.oodt.xmlquery.QueryElement;
import org.apache.oodt.xmlquery.XMLQuery;
@@ -140,4 +142,43 @@ public class TestXMLPSProductHandler ext
expectedSpecimenFldName);
}
+
+ public void testGetRequiredTables() {
+ System.setProperty("org.apache.oodt.xmlps.xml.mapFilePath",
+ "./src/test/resources/test-required-tables-ps.xml");
+
+ try {
+ handler = new XMLPSProductHandler();
+ } catch (InstantiationException e) {
+ fail(e.getMessage());
+ }
+
+ String queryStr = "RETURN = id AND RETURN = id_1 AND RETURN = id_2 AND
RETURN = id_3 AND RETURN = id_4";
+ XMLQuery query =
XMLQueryHelper.getDefaultQueryFromQueryString(queryStr);
+
+ List<QueryElement> where = query.getWhereElementSet();
+ List<QueryElement> select = query.getSelectElementSet();
+
+ try {
+ handler.translateToDomain(where, false);
+ handler.translateToDomain(select, true);
+ } catch (Exception e) {
+ fail(e.getMessage());
+ }
+
+ List<QueryElement> whereNames =
handler.getElemNamesFromQueryElemSet(where);
+ List<QueryElement> selectNames =
handler.getElemNamesFromQueryElemSet(select);
+
+ Set<DatabaseTable> tables = handler.getRequiredTables(whereNames,
selectNames);
+
+ assertEquals(7, tables.size());
+
assertTrue(tables.contains(handler.mapping.getTableByName("joinToDefault")));
+
assertTrue(tables.contains(handler.mapping.getTableByName("joinToExtraDefault")));
+
assertTrue(tables.contains(handler.mapping.getTableByName("joinToExtraJoin")));
+
assertTrue(tables.contains(handler.mapping.getTableByName("joinToExtraOther")));
+
assertTrue(tables.contains(handler.mapping.getTableByName("extraDefault")));
+
assertTrue(tables.contains(handler.mapping.getTableByName("extraOther")));
+ assertTrue(tables.contains(handler.mapping.getTableByName("other")));
+
assertTrue(!tables.contains(handler.mapping.getTableByName("another")));
+ }
}
Added: oodt/trunk/xmlps/src/test/resources/test-required-tables-ps.xml
URL:
http://svn.apache.org/viewvc/oodt/trunk/xmlps/src/test/resources/test-required-tables-ps.xml?rev=1206971&view=auto
==============================================================================
--- oodt/trunk/xmlps/src/test/resources/test-required-tables-ps.xml (added)
+++ oodt/trunk/xmlps/src/test/resources/test-required-tables-ps.xml Mon Nov 28
04:41:43 2011
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<!-- Example XML mapping configuration file -->
+<oodt:xmlps xmlns:oodt="http://incubator.apache.org/oodt/0.1-incubating"
+ name="Example Query Handler" id="project:subproject:exampleps">
+ <tables default="defaultTable">
+ <table name="joinToDefault" join="id" tofld="id" />
+ <table name="joinToExtraDefault" join="id" to="extraDefault" tofld="id" />
+ <table name="joinToExtraJoin" join="id" to="joinToExtraDefault"
tofld="id"/>
+ <table name="joinToExtraOther" join="id" to="extraOther" tofld="id"/>
+ <table name="extraDefault" join="id" tofld="id"/>
+ <table name="extraOther" join="id" to="other" tofld="id"/>
+ <table name="other" join="id" tofld="id" />
+ <table name="another" join="id" tofld="id" />
+ </tables>
+ <!--
+ field:
+
+ type (required): dynamic or constant. If you choose dynamic, then the
field
+ value is read from the row in the ResultSet returned
+ from the database. If constant, then each returned row
+ from the ResultSet is annotated with the value specified
+ in the 'value' attribute.
+
+ name (required): the name of the attribute that you want returned
+ in the product server.
+
+ string (optional): whether or not the internal db representation at the
local
+ site for this field is a STRING, or something else (e.g., a number, etc.).
Possible
+ values for this attribute are "true", to indicate that the field is a
string, or
+ "false", to indicate that it is something else. If this attribute is
omitted, a value
+ of "false" is assumed, and the attribute will not be quoted in the where
clause of
+ the underlying SQL statement generated.
+
+ dbname (optional): the name of the field within the underlying db. If not
+ specified, then assumed to be name
+
+ table (optional): if provided, then the attribute a is selected as
+ 'table'.'a',and then returned. If omitted, the attribute
+ is assumed to come from the default table returned from the
+ PS query.
+
+ value (optional): is necessary to provide if type='constant' is selected.
+
+ scope (optional): limits the scope of a field's existence: acceptable
values
+ are "query", which signifies that the field is only applicable
when
+ translating queries: and "return", which signifies the field is
only
+ applicable as a return field when converting database results into
CDEResults.
+
+ -->
+ <field type="dynamic" name="id" dbname="id" table="defaultTable"/>
+ <field type="dynamic" name="id_1" dbname="id" table="joinToDefault"/>
+ <field type="dynamic" name="id_2" dbname="id" table="joinToExtraDefault"/>
+ <field type="dynamic" name="id_3" dbname="id" table="joinToExtraJoin"/>
+ <field type="dynamic" name="id_4" dbname="id" table="joinToExtraOther"/>
+</oodt:xmlps>