teiid SVN: r4518 - trunk/engine/src/main/java/org/teiid/query/processor/relational.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2012-10-05 10:12:08 -0400 (Fri, 05 Oct 2012)
New Revision: 4518
Modified:
trunk/engine/src/main/java/org/teiid/query/processor/relational/SourceState.java
Log:
TEIID-2171 reusing the existing buffer if possible
Modified: trunk/engine/src/main/java/org/teiid/query/processor/relational/SourceState.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/relational/SourceState.java 2012-10-05 14:10:27 UTC (rev 4517)
+++ trunk/engine/src/main/java/org/teiid/query/processor/relational/SourceState.java 2012-10-05 14:12:08 UTC (rev 4518)
@@ -98,7 +98,7 @@
return currentTuple;
}
- public void reset() throws TeiidComponentException {
+ public void reset() throws TeiidComponentException, TeiidProcessingException {
this.getIterator().reset();
this.getIterator().mark();
this.currentTuple = null;
@@ -127,17 +127,22 @@
return this.getTupleBuffer().getRowCount();
}
- IndexedTupleSource getIterator() throws TeiidComponentException {
+ IndexedTupleSource getIterator() throws TeiidComponentException, TeiidProcessingException {
if (this.iterator == null) {
if (this.buffer != null) {
iterator = buffer.createIndexedTupleSource();
} else {
- // return a TupleBatch tuplesource iterator
- BatchIterator bi = new BatchIterator(this.source);
- if (implicitBuffer != ImplicitBuffer.NONE) {
- bi.setBuffer(createSourceTupleBuffer(), implicitBuffer == ImplicitBuffer.ON_MARK);
- }
- this.iterator = bi;
+ if (this.source.hasFinalBuffer()) {
+ this.buffer = this.source.getFinalBuffer(-1);
+ iterator = buffer.createIndexedTupleSource();
+ } else {
+ // return a TupleBatch tuplesource iterator
+ BatchIterator bi = new BatchIterator(this.source);
+ if (implicitBuffer != ImplicitBuffer.NONE) {
+ bi.setBuffer(createSourceTupleBuffer(), implicitBuffer == ImplicitBuffer.ON_MARK);
+ }
+ this.iterator = bi;
+ }
}
}
return this.iterator;
@@ -239,7 +244,7 @@
this.maxProbeMatch = 1;
}
- public void setMaxProbePosition() throws TeiidComponentException {
+ public void setMaxProbePosition() throws TeiidComponentException, TeiidProcessingException {
this.getIterator().setPosition(this.getMaxProbeMatch());
this.currentTuple = null;
}
12 years, 2 months
teiid SVN: r4517 - trunk/connectors/translator-object/src/main/resources/org/teiid/translator/object.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2012-10-05 10:10:27 -0400 (Fri, 05 Oct 2012)
New Revision: 4517
Modified:
trunk/connectors/translator-object/src/main/resources/org/teiid/translator/object/i18n.properties
Log:
TEIID-2210 refinements to the object translator.
Modified: trunk/connectors/translator-object/src/main/resources/org/teiid/translator/object/i18n.properties
===================================================================
--- trunk/connectors/translator-object/src/main/resources/org/teiid/translator/object/i18n.properties 2012-10-05 13:39:14 UTC (rev 4516)
+++ trunk/connectors/translator-object/src/main/resources/org/teiid/translator/object/i18n.properties 2012-10-05 14:10:27 UTC (rev 4517)
@@ -19,22 +19,8 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 USA.
#
-ObjectExecutionFactory.cacheNotFoundinJNDI=Cache was not found using JNDI name {0}
-
-InfinispanBaseExecutionFactory.cacheNameNotDefined=CacheName is not defined
-InfinispanBaseExecutionFactory.cacheNotFound=No cache was found for {0} in Infinispan
-
-InfinispanExecutionFactory.undefinedHowToGetCache=Either CacheJndiName or ConfigurationFileName must be specified how the cache will be obtained
-InfinispanExecutionFactory.unsupportedContainerType=CacheContainer type {0} is not currently supported when connecting to Infinispan, must be {1}
-
LuceneSearch.invalidOperator=Unsupported operator {0} was encountered, only {1} are supported
LuceneSearch.unsupportedComparingByNull=Comparing using a NULL is not currently supported.
LuceneSearch.Unsupported_expression=Unsupported expression of {0} when performing {1}
MapCacheConnection.unexpectedObjectTypeInCache=Unexpected root object type in the cache is {0}, expected {1}
-
-MapCacheExecutionFactory.undefinedJndiName=CacheJndiName is undefined
-MapCacheExecutionFactory.unexpectedCacheType=Expected cache type to be of type Map, but its of type {0}
-
-BasicKeySearchCriteria.missingComparisonExpression=Comparison criteria is missing the expression
-BasicKeySearchCriteria.Unsupported_expression=Unsupported expression {0} found in the IN clause
\ No newline at end of file
12 years, 2 months
teiid SVN: r4516 - in trunk: engine/src/main/java/org/teiid/query/optimizer/relational and 3 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2012-10-05 09:39:14 -0400 (Fri, 05 Oct 2012)
New Revision: 4516
Modified:
trunk/engine/src/main/java/org/teiid/query/optimizer/capabilities/BasicSourceCapabilities.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCollapseSource.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleImplementJoinStrategy.java
trunk/engine/src/test/java/org/teiid/query/optimizer/TestJoinOptimization.java
trunk/test-integration/common/src/test/java/org/teiid/dqp/internal/process/TestTPCR.java
Log:
TEIID-2245 limiting when nulls first/last is pushed down
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/capabilities/BasicSourceCapabilities.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/capabilities/BasicSourceCapabilities.java 2012-10-05 12:36:44 UTC (rev 4515)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/capabilities/BasicSourceCapabilities.java 2012-10-05 13:39:14 UTC (rev 4516)
@@ -29,7 +29,6 @@
import org.teiid.translator.ExecutionFactory;
import org.teiid.translator.ExecutionFactory.Format;
-import org.teiid.translator.ExecutionFactory.NullOrder;
/**
*/
@@ -46,8 +45,6 @@
* Construct a basic capabilities object.
*/
public BasicSourceCapabilities() {
- //for test compatibility we'll assume low, this does get replaced by a proper value at runtime
- setSourceProperty(Capability.QUERY_ORDERBY_DEFAULT_NULL_ORDER, NullOrder.LOW);
}
public boolean supportsCapability(Capability capability) {
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.java 2012-10-05 12:36:44 UTC (rev 4515)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.java 2012-10-05 13:39:14 UTC (rev 4516)
@@ -501,6 +501,7 @@
} else {
JoinNode joinAsSet = new JoinNode(getID());
joinAsSet.setJoinStrategy(new MergeJoinStrategy(SortOption.SORT_DISTINCT, SortOption.SORT_DISTINCT, true));
+ //If we push these sorts, we will have to enforce null order, since nulls are equal here
List leftExpressions = (List) node.getFirstChild().getProperty(NodeConstants.Info.OUTPUT_COLS);
List rightExpressions = (List) node.getLastChild().getProperty(NodeConstants.Info.OUTPUT_COLS);
joinAsSet.setJoinType(setOp == Operation.EXCEPT ? JoinType.JOIN_ANTI_SEMI : JoinType.JOIN_SEMI);
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCollapseSource.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCollapseSource.java 2012-10-05 12:36:44 UTC (rev 4515)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCollapseSource.java 2012-10-05 13:39:14 UTC (rev 4516)
@@ -490,6 +490,7 @@
}
private void processOrderBy(PlanNode node, QueryCommand query, Object modelID, CommandContext context, CapabilitiesFinder capFinder) throws QueryMetadataException, TeiidComponentException {
+ boolean userOrdering = NodeEditor.findParent(node, NodeConstants.Types.JOIN|NodeConstants.Types.SOURCE) == null;
OrderBy orderBy = (OrderBy)node.getProperty(NodeConstants.Info.SORT_ORDER);
query.setOrderBy(orderBy);
if (query instanceof Query) {
@@ -506,7 +507,7 @@
if (!supportsNullOrdering) {
item.setNullOrdering(null);
}
- } else if (supportsNullOrdering && defaultNullOrder != NullOrder.LOW && context.getOptions().isPushdownDefaultNullOrder()) {
+ } else if (userOrdering && supportsNullOrdering && defaultNullOrder != NullOrder.LOW && context.getOptions().isPushdownDefaultNullOrder()) {
//try to match the expected default of low
if (item.isAscending()) {
if (defaultNullOrder != NullOrder.FIRST) {
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleImplementJoinStrategy.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleImplementJoinStrategy.java 2012-10-05 12:36:44 UTC (rev 4515)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleImplementJoinStrategy.java 2012-10-05 13:39:14 UTC (rev 4516)
@@ -34,11 +34,9 @@
import org.teiid.api.exception.query.QueryMetadataException;
import org.teiid.api.exception.query.QueryPlannerException;
import org.teiid.core.TeiidComponentException;
-import org.teiid.language.SortSpecification.NullOrdering;
import org.teiid.query.analysis.AnalysisRecord;
import org.teiid.query.metadata.QueryMetadataInterface;
import org.teiid.query.optimizer.capabilities.CapabilitiesFinder;
-import org.teiid.query.optimizer.capabilities.SourceCapabilities.Capability;
import org.teiid.query.optimizer.relational.OptimizerRule;
import org.teiid.query.optimizer.relational.RuleStack;
import org.teiid.query.optimizer.relational.plantree.NodeConstants;
@@ -50,19 +48,15 @@
import org.teiid.query.processor.relational.JoinNode.JoinStrategyType;
import org.teiid.query.processor.relational.MergeJoinStrategy.SortOption;
import org.teiid.query.sql.lang.CompareCriteria;
-import org.teiid.query.sql.lang.CompoundCriteria;
import org.teiid.query.sql.lang.Criteria;
-import org.teiid.query.sql.lang.IsNullCriteria;
import org.teiid.query.sql.lang.JoinType;
import org.teiid.query.sql.lang.OrderBy;
-import org.teiid.query.sql.lang.OrderByItem;
import org.teiid.query.sql.symbol.ElementSymbol;
import org.teiid.query.sql.symbol.Expression;
import org.teiid.query.sql.symbol.GroupSymbol;
import org.teiid.query.sql.util.SymbolMap;
import org.teiid.query.sql.visitor.GroupsUsedByElementsVisitor;
import org.teiid.query.util.CommandContext;
-import org.teiid.translator.ExecutionFactory.NullOrder;
/**
@@ -255,40 +249,12 @@
joinNode.setProperty(joinNode.getFirstChild() == childNode ? NodeConstants.Info.IS_LEFT_DISTINCT : NodeConstants.Info.IS_RIGHT_DISTINCT, true);
}
if (attemptPush && RuleRaiseAccess.canRaiseOverSort(sourceNode, metadata, capFinder, sortNode, null, false)) {
- boolean push = true;
- Object model = RuleRaiseAccess.getModelIDFromAccess(sourceNode, metadata);
- NullOrder order = CapabilitiesUtil.getDefaultNullOrder(model, metadata, capFinder);
- if (order != NullOrder.LOW && order != NullOrder.FIRST) {
- //TODO: check the metadata and query structure to see if nulls are possible
- JoinType joinType = (JoinType) joinNode.getProperty(NodeConstants.Info.JOIN_TYPE);
- if (joinType == JoinType.JOIN_INNER || joinType == JoinType.JOIN_SEMI || ((joinType == JoinType.JOIN_LEFT_OUTER || joinType == JoinType.JOIN_ANTI_SEMI) && joinNode.getLastChild() == childNode)) {
- //just filter nulls on the teiid side
- CompoundCriteria crit = new CompoundCriteria();
- for (Expression expression : orderSymbols) {
- IsNullCriteria inc = new IsNullCriteria((Expression) expression.clone());
- inc.setNegated(true);
- crit.addCriteria(inc);
- }
- PlanNode critNode = NodeFactory.getNewNode(NodeConstants.Types.SELECT);
- critNode.setProperty(NodeConstants.Info.OUTPUT_COLS, new ArrayList<Expression>(outputSymbols));
- critNode.setProperty(NodeConstants.Info.SELECT_CRITERIA, crit);
- sourceNode.addAsParent(critNode);
- } else if (CapabilitiesUtil.supports(Capability.QUERY_ORDERBY_NULL_ORDERING, model, metadata, capFinder)) {
- for (OrderByItem item : ((OrderBy)sortNode.getProperty(NodeConstants.Info.SORT_ORDER)).getOrderByItems()) {
- item.setNullOrdering(NullOrdering.FIRST);
- }
- } else {
- push = false;
- }
+ sourceNode.getFirstChild().addAsParent(sortNode);
+
+ if (needsCorrection) {
+ correctOutputElements(joinNode, outputSymbols, sortNode);
}
- if (push) {
- sourceNode.getFirstChild().addAsParent(sortNode);
-
- if (needsCorrection) {
- correctOutputElements(joinNode, outputSymbols, sortNode);
- }
- return true;
- }
+ return true;
}
} else if (sourceNode.getType() == NodeConstants.Types.GROUP) {
sourceNode.addAsParent(sortNode);
Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/TestJoinOptimization.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/TestJoinOptimization.java 2012-10-05 12:36:44 UTC (rev 4515)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/TestJoinOptimization.java 2012-10-05 13:39:14 UTC (rev 4516)
@@ -52,7 +52,6 @@
import org.teiid.query.sql.symbol.GroupSymbol;
import org.teiid.query.unittest.RealMetadataFactory;
import org.teiid.translator.SourceSystemFunctions;
-import org.teiid.translator.ExecutionFactory.NullOrder;
@SuppressWarnings("nls")
public class TestJoinOptimization {
@@ -1049,63 +1048,4 @@
}
- @Test public void testJoinNullHandling() throws Exception {
- FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
- BasicSourceCapabilities bqt1 = new BasicSourceCapabilities();
- bqt1.setCapabilitySupport(Capability.QUERY_ORDERBY, true);
- bqt1.setSourceProperty(Capability.QUERY_ORDERBY_DEFAULT_NULL_ORDER, NullOrder.HIGH);
- bqt1.setCapabilitySupport(Capability.QUERY_ORDERBY_NULL_ORDERING, true);
-
- BasicSourceCapabilities bqt2 = new BasicSourceCapabilities();
- bqt2.setCapabilitySupport(Capability.QUERY_ORDERBY, true);
- bqt2.setSourceProperty(Capability.QUERY_ORDERBY_DEFAULT_NULL_ORDER, NullOrder.HIGH);
-
- capFinder.addCapabilities("BQT1", bqt1); //$NON-NLS-1$
- capFinder.addCapabilities("BQT2", bqt2); //$NON-NLS-1$
-
- String sql = "select bqt1.smalla.intkey, bqt2.smalla.intkey from bqt1.smalla full outer join bqt2.smalla on (bqt1.smalla.intkey = bqt2.smalla.intkey)"; //$NON-NLS-1$
-
- // can't push order by to bqt2 as there is no compensating action available.
- ProcessorPlan plan = TestOptimizer.helpPlan(sql, RealMetadataFactory.exampleBQTCached(), new String[] {"SELECT BQT2.SmallA.IntKey FROM BQT2.SmallA", "SELECT BQT1.SmallA.IntKey FROM BQT1.SmallA ORDER BY BQT1.SmallA.IntKey NULLS FIRST"}, capFinder, ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$ //$NON-NLS-2$
-
- TestOptimizer.checkNodeTypes(plan, new int[] {
- 2, // Access
- 0, // DependentAccess
- 0, // DependentSelect
- 0, // DependentProject
- 0, // DupRemove
- 0, // Grouping
- 0, // Join
- 1, // MergeJoin
- 0, // Null
- 0, // PlanExecution
- 1, // Project
- 0, // Select
- 0, // Sort
- 0 // UnionAll
- });
-
- sql = "select bqt1.smalla.intkey, bqt2.smalla.intkey from bqt1.smalla left outer join bqt2.smalla on (bqt1.smalla.intkey = bqt2.smalla.intkey)"; //$NON-NLS-1$
-
- // can push order by to bqt2 by adding a null filter
- plan = TestOptimizer.helpPlan(sql, RealMetadataFactory.exampleBQTCached(), new String[] {"SELECT BQT2.SmallA.IntKey FROM BQT2.SmallA ORDER BY BQT2.SmallA.IntKey", "SELECT BQT1.SmallA.IntKey FROM BQT1.SmallA ORDER BY BQT1.SmallA.IntKey NULLS FIRST"}, capFinder, ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$ //$NON-NLS-2$
-
- TestOptimizer.checkNodeTypes(plan, new int[] {
- 2, // Access
- 0, // DependentAccess
- 0, // DependentSelect
- 0, // DependentProject
- 0, // DupRemove
- 0, // Grouping
- 0, // Join
- 1, // MergeJoin
- 0, // Null
- 0, // PlanExecution
- 1, // Project
- 1, // Select
- 0, // Sort
- 0 // UnionAll
- });
- }
-
}
Modified: trunk/test-integration/common/src/test/java/org/teiid/dqp/internal/process/TestTPCR.java
===================================================================
--- trunk/test-integration/common/src/test/java/org/teiid/dqp/internal/process/TestTPCR.java 2012-10-05 12:36:44 UTC (rev 4515)
+++ trunk/test-integration/common/src/test/java/org/teiid/dqp/internal/process/TestTPCR.java 2012-10-05 13:39:14 UTC (rev 4516)
@@ -121,7 +121,7 @@
new List<?>[] { Arrays.asList(new Object[] { new Long(5), "Bill", "101 Fake St.", "392839283", "21.12" } ), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
Arrays.asList(new Object[] { new Long(6), "Stu", "102 Fake St.", "385729385", "51.50" } )}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
- dataMgr.addData("SELECT g_0.C_CUSTKEY AS c_0, g_0.C_NAME AS c_1, g_0.C_ADDRESS AS c_2, g_0.C_PHONE AS c_3, g_0.C_ACCTBAL AS c_4 FROM TPCR_Ora.CUSTOMER AS g_0 WHERE g_0.C_ACCTBAL > 50 ORDER BY c_0 NULLS FIRST", //$NON-NLS-1$
+ dataMgr.addData("SELECT g_0.C_CUSTKEY AS c_0, g_0.C_NAME AS c_1, g_0.C_ADDRESS AS c_2, g_0.C_PHONE AS c_3, g_0.C_ACCTBAL AS c_4 FROM TPCR_Ora.CUSTOMER AS g_0 WHERE g_0.C_ACCTBAL > 50 ORDER BY c_0", //$NON-NLS-1$
oracleExpected);
List<?>[] sqlServerExpected =
@@ -161,7 +161,7 @@
new List<?>[] { Arrays.asList(new Object[] { new Long(5), "Bill", "101 Fake St.", "392839283", "51.12" } ), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
Arrays.asList(new Object[] { new Long(6), "Stu", "102 Fake St.", "385729385", "51.50" } )}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
- dataMgr.addData("SELECT g_0.C_CUSTKEY AS c_0, g_0.C_NAME AS c_1, g_0.C_ADDRESS AS c_2, g_0.C_PHONE AS c_3, g_0.C_ACCTBAL AS c_4 FROM TPCR_Ora.CUSTOMER AS g_0 WHERE g_0.C_ACCTBAL > 50 ORDER BY c_0 NULLS FIRST", //$NON-NLS-1$
+ dataMgr.addData("SELECT g_0.C_CUSTKEY AS c_0, g_0.C_NAME AS c_1, g_0.C_ADDRESS AS c_2, g_0.C_PHONE AS c_3, g_0.C_ACCTBAL AS c_4 FROM TPCR_Ora.CUSTOMER AS g_0 WHERE g_0.C_ACCTBAL > 50 ORDER BY c_0", //$NON-NLS-1$
oracleExpected);
List<?>[] sqlServerExpected =
12 years, 2 months
teiid SVN: r4515 - in trunk: engine/src/main/java/org/teiid/query/metadata and 7 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2012-10-05 08:36:44 -0400 (Fri, 05 Oct 2012)
New Revision: 4515
Modified:
trunk/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html
trunk/engine/src/main/java/org/teiid/query/metadata/TempMetadataAdapter.java
trunk/engine/src/main/java/org/teiid/query/optimizer/QueryOptimizer.java
trunk/engine/src/main/java/org/teiid/query/optimizer/capabilities/BasicSourceCapabilities.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CapabilitiesUtil.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCollapseSource.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleImplementJoinStrategy.java
trunk/engine/src/main/java/org/teiid/query/util/Options.java
trunk/engine/src/test/java/org/teiid/query/optimizer/TestJoinOptimization.java
trunk/engine/src/test/java/org/teiid/query/processor/TestOrderByProcessing.java
trunk/engine/src/test/java/org/teiid/query/processor/TestWindowFunctions.java
trunk/test-integration/common/src/test/java/org/teiid/dqp/internal/process/BaseQueryTest.java
trunk/test-integration/common/src/test/java/org/teiid/dqp/internal/process/TestTPCR.java
Log:
TEIID-2245 limiting when nulls first/last is pushed down
Modified: trunk/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html
===================================================================
--- trunk/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html 2012-10-04 16:49:23 UTC (rev 4514)
+++ trunk/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html 2012-10-05 12:36:44 UTC (rev 4515)
@@ -62,7 +62,8 @@
<li>TEIID-2226 All statements that return result sets that are executed as command statements in a procedure are validated against the expected resultset columns of the procedure.
If the statement is not intended to be returnable, WITHOUT RETURN can be added to the end of the statement.
<li>TEIID-2235 The MetadataRepository.setNext was removed. Also if an instance of a DefaultMetadataRepository is used, it will only affect metadata already loaded in the repository chain.
- <li>TEIID-2237 teiid_ is a reserved DDL namespace prefix and the MetadataFactory class no longer throws TranslatorExceptions, instead the unchecked MetadataException is thrown.
+ <li>TEIID-2237 teiid_ is a reserved DDL namespace prefix and the MetadataFactory class no longer throws TranslatorExceptions, instead the unchecked MetadataException is thrown.
+ <li>TEIID-2243 by default Teiid will not pushdown the default null sort order of nulls low when no null sort order is specified. Set the system property org.teiid.pushdownDefaultNullOrder to true mimic the 8.1 and older release behavior.
</ul>
<h4>from 8.0</h4>
Modified: trunk/engine/src/main/java/org/teiid/query/metadata/TempMetadataAdapter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/metadata/TempMetadataAdapter.java 2012-10-04 16:49:23 UTC (rev 4514)
+++ trunk/engine/src/main/java/org/teiid/query/metadata/TempMetadataAdapter.java 2012-10-05 12:36:44 UTC (rev 4515)
@@ -92,15 +92,11 @@
return this.actualMetadata.getSessionMetadata();
}
- public QueryMetadataInterface getDesignTimeMetadata() {
- if (isSession()) {
- return this.actualMetadata.getDesignTimeMetadata();
- }
- return super.getDesignTimeMetadata();
- }
-
@Override
protected QueryMetadataInterface createDesignTimeMetadata() {
+ if (isSession()) {
+ return new TempMetadataAdapter(this.actualMetadata.getDesignTimeMetadata(), new TempMetadataStore());
+ }
return new TempMetadataAdapter(this.actualMetadata.getDesignTimeMetadata(), tempStore, materializationTables, queryNodes);
}
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/QueryOptimizer.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/QueryOptimizer.java 2012-10-04 16:49:23 UTC (rev 4514)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/QueryOptimizer.java 2012-10-05 12:36:44 UTC (rev 4515)
@@ -82,13 +82,14 @@
boolean debug = analysisRecord.recordDebug();
- TempMetadataStore tempMetadata = command.getTemporaryMetadata();
- if (tempMetadata != null) {
- metadata = new TempMetadataAdapter(metadata, tempMetadata);
- } else if (!(metadata instanceof TempMetadataAdapter)) {
+ if (!(metadata instanceof TempMetadataAdapter)) {
metadata = new TempMetadataAdapter(metadata, new TempMetadataStore());
}
-
+
+ if (context.getMetadata() == null) {
+ context.setMetadata(metadata);
+ }
+
// Create an ID generator that can be used for all plans to generate unique data node IDs
if(idGenerator == null) {
idGenerator = new IDGenerator();
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/capabilities/BasicSourceCapabilities.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/capabilities/BasicSourceCapabilities.java 2012-10-04 16:49:23 UTC (rev 4514)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/capabilities/BasicSourceCapabilities.java 2012-10-05 12:36:44 UTC (rev 4515)
@@ -29,6 +29,7 @@
import org.teiid.translator.ExecutionFactory;
import org.teiid.translator.ExecutionFactory.Format;
+import org.teiid.translator.ExecutionFactory.NullOrder;
/**
*/
@@ -45,6 +46,8 @@
* Construct a basic capabilities object.
*/
public BasicSourceCapabilities() {
+ //for test compatibility we'll assume low, this does get replaced by a proper value at runtime
+ setSourceProperty(Capability.QUERY_ORDERBY_DEFAULT_NULL_ORDER, NullOrder.LOW);
}
public boolean supportsCapability(Capability capability) {
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CapabilitiesUtil.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CapabilitiesUtil.java 2012-10-04 16:49:23 UTC (rev 4514)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CapabilitiesUtil.java 2012-10-05 12:36:44 UTC (rev 4515)
@@ -469,28 +469,16 @@
throws QueryMetadataException, TeiidComponentException {
boolean supportsNullOrdering = CapabilitiesUtil.supports(Capability.QUERY_ORDERBY_NULL_ORDERING, modelID, metadata, capFinder);
NullOrder defaultNullOrder = CapabilitiesUtil.getDefaultNullOrder(modelID, metadata, capFinder);
- if (symbol.getNullOrdering() != null) {
- if (!supportsNullOrdering) {
- if (symbol.getNullOrdering() == NullOrdering.FIRST) {
- if (defaultNullOrder != NullOrder.FIRST && !(symbol.isAscending() && defaultNullOrder == NullOrder.LOW)
- && !(!symbol.isAscending() && defaultNullOrder == NullOrder.HIGH)) {
- return false;
- }
- } else if (defaultNullOrder != NullOrder.LAST && !(symbol.isAscending() && defaultNullOrder == NullOrder.HIGH)
- && !(!symbol.isAscending() && defaultNullOrder == NullOrder.LOW)) {
+ if (symbol.getNullOrdering() != null && !supportsNullOrdering) {
+ if (symbol.getNullOrdering() == NullOrdering.FIRST) {
+ if (defaultNullOrder != NullOrder.FIRST && !(symbol.isAscending() && defaultNullOrder == NullOrder.LOW)
+ && !(!symbol.isAscending() && defaultNullOrder == NullOrder.HIGH)) {
return false;
- }
- symbol.setNullOrdering(null);
- }
- } else if (supportsNullOrdering && defaultNullOrder != NullOrder.LOW) {
- //try to match the expected default of low
- if (symbol.isAscending()) {
- if (defaultNullOrder != NullOrder.FIRST) {
- symbol.setNullOrdering(NullOrdering.FIRST);
}
- } else if (defaultNullOrder != NullOrder.LAST) {
- symbol.setNullOrdering(NullOrdering.LAST);
- }
+ } else if (defaultNullOrder != NullOrder.LAST && !(symbol.isAscending() && defaultNullOrder == NullOrder.HIGH)
+ && !(!symbol.isAscending() && defaultNullOrder == NullOrder.LOW)) {
+ return false;
+ }
}
return true;
}
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCollapseSource.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCollapseSource.java 2012-10-04 16:49:23 UTC (rev 4514)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCollapseSource.java 2012-10-05 12:36:44 UTC (rev 4515)
@@ -38,6 +38,7 @@
import org.teiid.core.TeiidException;
import org.teiid.core.TeiidRuntimeException;
import org.teiid.core.types.DataTypeManager;
+import org.teiid.language.SortSpecification.NullOrdering;
import org.teiid.query.QueryPlugin;
import org.teiid.query.analysis.AnalysisRecord;
import org.teiid.query.metadata.QueryMetadataInterface;
@@ -71,6 +72,7 @@
import org.teiid.query.sql.visitor.ExpressionMappingVisitor;
import org.teiid.query.sql.visitor.ValueIteratorProviderCollectorVisitor;
import org.teiid.query.util.CommandContext;
+import org.teiid.translator.ExecutionFactory.NullOrder;
public final class RuleCollapseSource implements OptimizerRule {
@@ -96,7 +98,7 @@
commandRoot = NodeEditor.findNodePreOrder(accessNode, NodeConstants.Types.SOURCE).getFirstChild();
}
plan = removeUnnecessaryInlineView(plan, commandRoot);
- QueryCommand queryCommand = createQuery(metadata, capFinder, accessNode, commandRoot);
+ QueryCommand queryCommand = createQuery(context, capFinder, accessNode, commandRoot);
addDistinct(metadata, capFinder, accessNode, queryCommand);
command = queryCommand;
if (intoGroup != null) {
@@ -193,8 +195,10 @@
return root;
}
- private QueryCommand createQuery(QueryMetadataInterface metadata, CapabilitiesFinder capFinder, PlanNode accessRoot, PlanNode node) throws QueryMetadataException, TeiidComponentException, QueryPlannerException {
+ private QueryCommand createQuery(CommandContext context, CapabilitiesFinder capFinder, PlanNode accessRoot, PlanNode node) throws QueryMetadataException, TeiidComponentException, QueryPlannerException {
+ QueryMetadataInterface metadata = context.getMetadata();
PlanNode setOpNode = NodeEditor.findNodePreOrder(node, NodeConstants.Types.SET_OP, NodeConstants.Types.SOURCE);
+ Object modelID = RuleRaiseAccess.getModelIDFromAccess(accessRoot, metadata);
if (setOpNode != null) {
Operation setOp = (Operation)setOpNode.getProperty(NodeConstants.Info.SET_OPERATION);
SetQuery unionCommand = new SetQuery(setOp);
@@ -202,7 +206,7 @@
unionCommand.setAll(unionAll);
PlanNode sort = NodeEditor.findNodePreOrder(node, NodeConstants.Types.SORT, NodeConstants.Types.SET_OP);
if (sort != null) {
- processOrderBy(sort, unionCommand);
+ processOrderBy(sort, unionCommand, modelID, context, capFinder);
}
PlanNode limit = NodeEditor.findNodePreOrder(node, NodeConstants.Types.TUPLE_LIMIT, NodeConstants.Types.SET_OP);
if (limit != null) {
@@ -210,7 +214,7 @@
}
int count = 0;
for (PlanNode child : setOpNode.getChildren()) {
- QueryCommand command = createQuery(metadata, capFinder, accessRoot, child);
+ QueryCommand command = createQuery(context, capFinder, accessRoot, child);
if (count == 0) {
unionCommand.setLeftQuery(command);
} else if (count == 1) {
@@ -229,11 +233,10 @@
select.addSymbols(columns);
query.setSelect(select);
query.setFrom(new From());
- buildQuery(accessRoot, node, query, metadata, capFinder);
+ buildQuery(accessRoot, node, query, context, capFinder);
if (query.getCriteria() instanceof CompoundCriteria) {
query.setCriteria(QueryRewriter.optimizeCriteria((CompoundCriteria)query.getCriteria(), metadata));
}
- Object modelID = RuleRaiseAccess.getModelIDFromAccess(accessRoot, metadata);
if (!CapabilitiesUtil.useAnsiJoin(modelID, metadata, capFinder)) {
simplifyFromClause(query);
}
@@ -297,8 +300,8 @@
return null;
}
- void buildQuery(PlanNode accessRoot, PlanNode node, Query query, QueryMetadataInterface metadata, CapabilitiesFinder capFinder) throws QueryMetadataException, TeiidComponentException, QueryPlannerException {
-
+ void buildQuery(PlanNode accessRoot, PlanNode node, Query query, CommandContext context, CapabilitiesFinder capFinder) throws QueryMetadataException, TeiidComponentException, QueryPlannerException {
+ QueryMetadataInterface metadata = context.getMetadata();
//visit source and join nodes as they appear
switch(node.getType()) {
case NodeConstants.Types.JOIN:
@@ -324,12 +327,12 @@
* if the join is a left outer join, criteria from the right side will be added to the on clause
*/
Criteria savedCriteria = null;
- buildQuery(accessRoot, left, query, metadata, capFinder);
+ buildQuery(accessRoot, left, query, context, capFinder);
if (joinType == JoinType.JOIN_LEFT_OUTER) {
savedCriteria = query.getCriteria();
query.setCriteria(null);
}
- buildQuery(accessRoot, right, query, metadata, capFinder);
+ buildQuery(accessRoot, right, query, context, capFinder);
if (joinType == JoinType.JOIN_LEFT_OUTER) {
moveWhereClauseIntoOnClause(query, crits);
query.setCriteria(savedCriteria);
@@ -360,7 +363,7 @@
{
if (Boolean.TRUE.equals(node.getProperty(NodeConstants.Info.INLINE_VIEW))) {
PlanNode child = node.getFirstChild();
- QueryCommand newQuery = createQuery(metadata, capFinder, accessRoot, child);
+ QueryCommand newQuery = createQuery(context, capFinder, accessRoot, child);
//ensure that the group is consistent
GroupSymbol symbol = node.getGroups().iterator().next();
@@ -374,7 +377,7 @@
}
for (PlanNode childNode : node.getChildren()) {
- buildQuery(accessRoot, childNode, query, metadata, capFinder);
+ buildQuery(accessRoot, childNode, query, context, capFinder);
}
switch(node.getType()) {
@@ -391,7 +394,7 @@
}
case NodeConstants.Types.SORT:
{
- processOrderBy(node, query);
+ processOrderBy(node, query, RuleRaiseAccess.getModelIDFromAccess(accessRoot, metadata), context, capFinder);
break;
}
case NodeConstants.Types.DUP_REMOVE:
@@ -486,7 +489,7 @@
query.setCriteria(null);
}
- private void processOrderBy(PlanNode node, QueryCommand query) {
+ private void processOrderBy(PlanNode node, QueryCommand query, Object modelID, CommandContext context, CapabilitiesFinder capFinder) throws QueryMetadataException, TeiidComponentException {
OrderBy orderBy = (OrderBy)node.getProperty(NodeConstants.Info.SORT_ORDER);
query.setOrderBy(orderBy);
if (query instanceof Query) {
@@ -496,6 +499,24 @@
}
QueryRewriter.rewriteOrderBy(query, orderBy, query.getProjectedSymbols(), new LinkedList<OrderByItem>());
}
+ boolean supportsNullOrdering = CapabilitiesUtil.supports(Capability.QUERY_ORDERBY_NULL_ORDERING, modelID, context.getMetadata(), capFinder);
+ NullOrder defaultNullOrder = CapabilitiesUtil.getDefaultNullOrder(modelID, context.getMetadata(), capFinder);
+ for (OrderByItem item : orderBy.getOrderByItems()) {
+ if (item.getNullOrdering() != null) {
+ if (!supportsNullOrdering) {
+ item.setNullOrdering(null);
+ }
+ } else if (supportsNullOrdering && defaultNullOrder != NullOrder.LOW && context.getOptions().isPushdownDefaultNullOrder()) {
+ //try to match the expected default of low
+ if (item.isAscending()) {
+ if (defaultNullOrder != NullOrder.FIRST) {
+ item.setNullOrdering(NullOrdering.FIRST);
+ }
+ } else if (defaultNullOrder != NullOrder.LAST) {
+ item.setNullOrdering(NullOrdering.LAST);
+ }
+ }
+ }
}
/**
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleImplementJoinStrategy.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleImplementJoinStrategy.java 2012-10-04 16:49:23 UTC (rev 4514)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleImplementJoinStrategy.java 2012-10-05 12:36:44 UTC (rev 4515)
@@ -34,9 +34,11 @@
import org.teiid.api.exception.query.QueryMetadataException;
import org.teiid.api.exception.query.QueryPlannerException;
import org.teiid.core.TeiidComponentException;
+import org.teiid.language.SortSpecification.NullOrdering;
import org.teiid.query.analysis.AnalysisRecord;
import org.teiid.query.metadata.QueryMetadataInterface;
import org.teiid.query.optimizer.capabilities.CapabilitiesFinder;
+import org.teiid.query.optimizer.capabilities.SourceCapabilities.Capability;
import org.teiid.query.optimizer.relational.OptimizerRule;
import org.teiid.query.optimizer.relational.RuleStack;
import org.teiid.query.optimizer.relational.plantree.NodeConstants;
@@ -48,15 +50,19 @@
import org.teiid.query.processor.relational.JoinNode.JoinStrategyType;
import org.teiid.query.processor.relational.MergeJoinStrategy.SortOption;
import org.teiid.query.sql.lang.CompareCriteria;
+import org.teiid.query.sql.lang.CompoundCriteria;
import org.teiid.query.sql.lang.Criteria;
+import org.teiid.query.sql.lang.IsNullCriteria;
import org.teiid.query.sql.lang.JoinType;
import org.teiid.query.sql.lang.OrderBy;
+import org.teiid.query.sql.lang.OrderByItem;
import org.teiid.query.sql.symbol.ElementSymbol;
import org.teiid.query.sql.symbol.Expression;
import org.teiid.query.sql.symbol.GroupSymbol;
import org.teiid.query.sql.util.SymbolMap;
import org.teiid.query.sql.visitor.GroupsUsedByElementsVisitor;
import org.teiid.query.util.CommandContext;
+import org.teiid.translator.ExecutionFactory.NullOrder;
/**
@@ -249,12 +255,40 @@
joinNode.setProperty(joinNode.getFirstChild() == childNode ? NodeConstants.Info.IS_LEFT_DISTINCT : NodeConstants.Info.IS_RIGHT_DISTINCT, true);
}
if (attemptPush && RuleRaiseAccess.canRaiseOverSort(sourceNode, metadata, capFinder, sortNode, null, false)) {
- sourceNode.getFirstChild().addAsParent(sortNode);
-
- if (needsCorrection) {
- correctOutputElements(joinNode, outputSymbols, sortNode);
+ boolean push = true;
+ Object model = RuleRaiseAccess.getModelIDFromAccess(sourceNode, metadata);
+ NullOrder order = CapabilitiesUtil.getDefaultNullOrder(model, metadata, capFinder);
+ if (order != NullOrder.LOW && order != NullOrder.FIRST) {
+ //TODO: check the metadata and query structure to see if nulls are possible
+ JoinType joinType = (JoinType) joinNode.getProperty(NodeConstants.Info.JOIN_TYPE);
+ if (joinType == JoinType.JOIN_INNER || joinType == JoinType.JOIN_SEMI || ((joinType == JoinType.JOIN_LEFT_OUTER || joinType == JoinType.JOIN_ANTI_SEMI) && joinNode.getLastChild() == childNode)) {
+ //just filter nulls on the teiid side
+ CompoundCriteria crit = new CompoundCriteria();
+ for (Expression expression : orderSymbols) {
+ IsNullCriteria inc = new IsNullCriteria((Expression) expression.clone());
+ inc.setNegated(true);
+ crit.addCriteria(inc);
+ }
+ PlanNode critNode = NodeFactory.getNewNode(NodeConstants.Types.SELECT);
+ critNode.setProperty(NodeConstants.Info.OUTPUT_COLS, new ArrayList<Expression>(outputSymbols));
+ critNode.setProperty(NodeConstants.Info.SELECT_CRITERIA, crit);
+ sourceNode.addAsParent(critNode);
+ } else if (CapabilitiesUtil.supports(Capability.QUERY_ORDERBY_NULL_ORDERING, model, metadata, capFinder)) {
+ for (OrderByItem item : ((OrderBy)sortNode.getProperty(NodeConstants.Info.SORT_ORDER)).getOrderByItems()) {
+ item.setNullOrdering(NullOrdering.FIRST);
+ }
+ } else {
+ push = false;
+ }
}
- return true;
+ if (push) {
+ sourceNode.getFirstChild().addAsParent(sortNode);
+
+ if (needsCorrection) {
+ correctOutputElements(joinNode, outputSymbols, sortNode);
+ }
+ return true;
+ }
}
} else if (sourceNode.getType() == NodeConstants.Types.GROUP) {
sourceNode.addAsParent(sortNode);
@@ -271,7 +305,7 @@
if (needsCorrection) {
PlanNode projectNode = NodeFactory.getNewNode(NodeConstants.Types.PROJECT);
- projectNode.setProperty(NodeConstants.Info.PROJECT_COLS, new ArrayList(outputSymbols));
+ projectNode.setProperty(NodeConstants.Info.PROJECT_COLS, new ArrayList<Expression>(outputSymbols));
childNode.addAsParent(projectNode);
correctOutputElements(joinNode, outputSymbols, projectNode);
}
@@ -279,18 +313,19 @@
}
private static PlanNode createSortNode(List<Expression> orderSymbols,
- Collection outputElements) {
+ Collection<Expression> outputElements) {
PlanNode sortNode = NodeFactory.getNewNode(NodeConstants.Types.SORT);
- sortNode.setProperty(NodeConstants.Info.SORT_ORDER, new OrderBy(orderSymbols));
- sortNode.setProperty(NodeConstants.Info.OUTPUT_COLS, new ArrayList(outputElements));
+ OrderBy order = new OrderBy(orderSymbols);
+ sortNode.setProperty(NodeConstants.Info.SORT_ORDER, order);
+ sortNode.setProperty(NodeConstants.Info.OUTPUT_COLS, new ArrayList<Expression>(outputElements));
return sortNode;
}
private static void correctOutputElements(PlanNode endNode,
- Collection outputElements,
+ Collection<Expression> outputElements,
PlanNode startNode) {
while (startNode != endNode) {
- startNode.setProperty(NodeConstants.Info.OUTPUT_COLS, new ArrayList(outputElements));
+ startNode.setProperty(NodeConstants.Info.OUTPUT_COLS, new ArrayList<Expression>(outputElements));
startNode = startNode.getParent();
}
}
Modified: trunk/engine/src/main/java/org/teiid/query/util/Options.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/util/Options.java 2012-10-04 16:49:23 UTC (rev 4514)
+++ trunk/engine/src/main/java/org/teiid/query/util/Options.java 2012-10-05 12:36:44 UTC (rev 4515)
@@ -23,19 +23,18 @@
package org.teiid.query.util;
import java.util.Properties;
-import java.util.Set;
/**
* A holder for options
*/
public class Options {
- public static final String UNNEST_DEFAULT = "org.teiid.subqueryUnnestDefault"; //$NON-NLS-1$
- public static final String LANGUAGES_DEFAULT = "org.teiid.languagesWithoutDataRoles"; //$NON-NLS-1$
+ public static final String UNNEST_DEFAULT = "org.teiid.subqueryUnnestDefault"; //$NON-NLS-1$
+ public static final String PUSHDOWN_DEFAULT_NULL_ORDER = "org.teiid.pushdownDefaultNullOrder"; //$NON-NLS-1$
private Properties properties;
- private Set<String> languages;
private boolean subqueryUnnestDefault;
+ private boolean pushdownDefaultNullOrder;
public Properties getProperties() {
return properties;
@@ -45,14 +44,6 @@
this.properties = properties;
}
- public void setLanguages(Set<String> languages) {
- this.languages = languages;
- }
-
- public Set<String> getLanguages() {
- return languages;
- }
-
public boolean isSubqueryUnnestDefault() {
return subqueryUnnestDefault;
}
@@ -65,5 +56,18 @@
this.subqueryUnnestDefault = s;
return this;
}
+
+ public boolean isPushdownDefaultNullOrder() {
+ return pushdownDefaultNullOrder;
+ }
+
+ public void setPushdownDefaultNullOrder(boolean virtualizeDefaultNullOrdering) {
+ this.pushdownDefaultNullOrder = virtualizeDefaultNullOrdering;
+ }
+
+ public Options pushdownDefaultNullOrder(boolean p) {
+ this.pushdownDefaultNullOrder = p;
+ return this;
+ }
}
Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/TestJoinOptimization.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/TestJoinOptimization.java 2012-10-04 16:49:23 UTC (rev 4514)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/TestJoinOptimization.java 2012-10-05 12:36:44 UTC (rev 4515)
@@ -52,6 +52,7 @@
import org.teiid.query.sql.symbol.GroupSymbol;
import org.teiid.query.unittest.RealMetadataFactory;
import org.teiid.translator.SourceSystemFunctions;
+import org.teiid.translator.ExecutionFactory.NullOrder;
@SuppressWarnings("nls")
public class TestJoinOptimization {
@@ -1047,5 +1048,64 @@
ComparisonMode.EXACT_COMMAND_STRING );
}
+
+ @Test public void testJoinNullHandling() throws Exception {
+ FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
+ BasicSourceCapabilities bqt1 = new BasicSourceCapabilities();
+ bqt1.setCapabilitySupport(Capability.QUERY_ORDERBY, true);
+ bqt1.setSourceProperty(Capability.QUERY_ORDERBY_DEFAULT_NULL_ORDER, NullOrder.HIGH);
+ bqt1.setCapabilitySupport(Capability.QUERY_ORDERBY_NULL_ORDERING, true);
+
+ BasicSourceCapabilities bqt2 = new BasicSourceCapabilities();
+ bqt2.setCapabilitySupport(Capability.QUERY_ORDERBY, true);
+ bqt2.setSourceProperty(Capability.QUERY_ORDERBY_DEFAULT_NULL_ORDER, NullOrder.HIGH);
+
+ capFinder.addCapabilities("BQT1", bqt1); //$NON-NLS-1$
+ capFinder.addCapabilities("BQT2", bqt2); //$NON-NLS-1$
+
+ String sql = "select bqt1.smalla.intkey, bqt2.smalla.intkey from bqt1.smalla full outer join bqt2.smalla on (bqt1.smalla.intkey = bqt2.smalla.intkey)"; //$NON-NLS-1$
+ // can't push order by to bqt2 as there is no compensating action available.
+ ProcessorPlan plan = TestOptimizer.helpPlan(sql, RealMetadataFactory.exampleBQTCached(), new String[] {"SELECT BQT2.SmallA.IntKey FROM BQT2.SmallA", "SELECT BQT1.SmallA.IntKey FROM BQT1.SmallA ORDER BY BQT1.SmallA.IntKey NULLS FIRST"}, capFinder, ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$ //$NON-NLS-2$
+
+ TestOptimizer.checkNodeTypes(plan, new int[] {
+ 2, // Access
+ 0, // DependentAccess
+ 0, // DependentSelect
+ 0, // DependentProject
+ 0, // DupRemove
+ 0, // Grouping
+ 0, // Join
+ 1, // MergeJoin
+ 0, // Null
+ 0, // PlanExecution
+ 1, // Project
+ 0, // Select
+ 0, // Sort
+ 0 // UnionAll
+ });
+
+ sql = "select bqt1.smalla.intkey, bqt2.smalla.intkey from bqt1.smalla left outer join bqt2.smalla on (bqt1.smalla.intkey = bqt2.smalla.intkey)"; //$NON-NLS-1$
+
+ // can push order by to bqt2 by adding a null filter
+ plan = TestOptimizer.helpPlan(sql, RealMetadataFactory.exampleBQTCached(), new String[] {"SELECT BQT2.SmallA.IntKey FROM BQT2.SmallA ORDER BY BQT2.SmallA.IntKey", "SELECT BQT1.SmallA.IntKey FROM BQT1.SmallA ORDER BY BQT1.SmallA.IntKey NULLS FIRST"}, capFinder, ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$ //$NON-NLS-2$
+
+ TestOptimizer.checkNodeTypes(plan, new int[] {
+ 2, // Access
+ 0, // DependentAccess
+ 0, // DependentSelect
+ 0, // DependentProject
+ 0, // DupRemove
+ 0, // Grouping
+ 0, // Join
+ 1, // MergeJoin
+ 0, // Null
+ 0, // PlanExecution
+ 1, // Project
+ 1, // Select
+ 0, // Sort
+ 0 // UnionAll
+ });
+ }
+
}
Modified: trunk/engine/src/test/java/org/teiid/query/processor/TestOrderByProcessing.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestOrderByProcessing.java 2012-10-04 16:49:23 UTC (rev 4514)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestOrderByProcessing.java 2012-10-05 12:36:44 UTC (rev 4515)
@@ -34,6 +34,8 @@
import org.teiid.query.optimizer.capabilities.FakeCapabilitiesFinder;
import org.teiid.query.optimizer.capabilities.SourceCapabilities.Capability;
import org.teiid.query.unittest.RealMetadataFactory;
+import org.teiid.query.util.CommandContext;
+import org.teiid.query.util.Options;
import org.teiid.translator.ExecutionFactory.NullOrder;
@SuppressWarnings({"nls", "unchecked"})
@@ -146,56 +148,58 @@
ProcessorPlan plan = TestOptimizer.helpPlan("select e1 from pm1.g1 order by e1 desc, e2 asc", //$NON-NLS-1$
RealMetadataFactory.example1Cached(), null, capFinder,
- new String[] { "SELECT g_0.e1 AS c_0 FROM pm1.g1 AS g_0 ORDER BY c_0 DESC NULLS LAST, g_0.e2 NULLS FIRST"}, //$NON-NLS-1$
+ new String[] { "SELECT g_0.e1 AS c_0 FROM pm1.g1 AS g_0 ORDER BY c_0 DESC, g_0.e2"}, //$NON-NLS-1$
TestOptimizer.ComparisonMode.EXACT_COMMAND_STRING);
TestOptimizer.checkNodeTypes(plan, TestOptimizer.FULL_PUSHDOWN);
}
-
- @Test public void testNullOrdering1() throws Exception {
+
+ @Test public void testNullOrdering2() throws Exception {
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = TestOptimizer.getTypicalCapabilities();
caps.setCapabilitySupport(Capability.QUERY_ORDERBY_NULL_ORDERING, true);
- caps.setSourceProperty(Capability.QUERY_ORDERBY_DEFAULT_NULL_ORDER, NullOrder.LAST);
+ caps.setSourceProperty(Capability.QUERY_ORDERBY_DEFAULT_NULL_ORDER, NullOrder.FIRST);
capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$
-
- ProcessorPlan plan = TestOptimizer.helpPlan("select e1 from pm1.g1 order by e1 desc, e2 asc", //$NON-NLS-1$
- RealMetadataFactory.example1Cached(), null, capFinder,
- new String[] { "SELECT g_0.e1 AS c_0 FROM pm1.g1 AS g_0 ORDER BY c_0 DESC, g_0.e2 NULLS FIRST"}, //$NON-NLS-1$
- TestOptimizer.ComparisonMode.EXACT_COMMAND_STRING);
-
+ QueryMetadataInterface metadata = RealMetadataFactory.example1Cached();
+ CommandContext cc = new CommandContext();
+ cc.setOptions(new Options().pushdownDefaultNullOrder(true));
+ ProcessorPlan plan = TestOptimizer.getPlan(TestOptimizer.helpGetCommand("select e1 from pm1.g1 order by e1 desc, e2 asc NULLS LAST", metadata, null), metadata, capFinder, null, true, cc);
+ TestOptimizer.checkAtomicQueries(new String[] { "SELECT g_0.e1 AS c_0 FROM pm1.g1 AS g_0 ORDER BY c_0 DESC NULLS LAST, g_0.e2 NULLS LAST"}, plan); //$NON-NLS-1$
TestOptimizer.checkNodeTypes(plan, TestOptimizer.FULL_PUSHDOWN);
}
- @Test public void testNullOrdering2() throws Exception {
+ /**
+ * The engine will remove the null ordering if it's not needed
+ * @throws Exception
+ */
+ @Test public void testNullOrdering3() throws Exception {
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = TestOptimizer.getTypicalCapabilities();
- caps.setCapabilitySupport(Capability.QUERY_ORDERBY_NULL_ORDERING, true);
+ caps.setSourceProperty(Capability.QUERY_ORDERBY_DEFAULT_NULL_ORDER, NullOrder.HIGH);
capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$
-
- ProcessorPlan plan = TestOptimizer.helpPlan("select e1 from pm1.g1 order by e1 desc NULLS FIRST, e2 asc NULLS LAST", //$NON-NLS-1$
- RealMetadataFactory.example1Cached(), null, capFinder,
- new String[] { "SELECT g_0.e1 AS c_0 FROM pm1.g1 AS g_0 ORDER BY c_0 DESC NULLS FIRST, g_0.e2 NULLS LAST"}, //$NON-NLS-1$
- TestOptimizer.ComparisonMode.EXACT_COMMAND_STRING);
-
+ QueryMetadataInterface metadata = RealMetadataFactory.example1Cached();
+ CommandContext cc = new CommandContext();
+ cc.setOptions(new Options().pushdownDefaultNullOrder(true));
+ ProcessorPlan plan = TestOptimizer.getPlan(TestOptimizer.helpGetCommand("select e1 from pm1.g1 order by e1 desc, e2 asc NULLS LAST", metadata, null), metadata, capFinder, null, true, cc);
+ TestOptimizer.checkAtomicQueries(new String[] { "SELECT g_0.e1 AS c_0 FROM pm1.g1 AS g_0 ORDER BY c_0 DESC, g_0.e2"}, plan); //$NON-NLS-1$
TestOptimizer.checkNodeTypes(plan, TestOptimizer.FULL_PUSHDOWN);
}
/**
- * The engine will remove the null ordering if it's not needed
+ * turns on virtualization
* @throws Exception
*/
- @Test public void testNullOrdering3() throws Exception {
+ @Test public void testNullOrdering4() throws Exception {
FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
BasicSourceCapabilities caps = TestOptimizer.getTypicalCapabilities();
- caps.setSourceProperty(Capability.QUERY_ORDERBY_DEFAULT_NULL_ORDER, NullOrder.HIGH);
+ caps.setCapabilitySupport(Capability.QUERY_ORDERBY_NULL_ORDERING, true);
+ caps.setSourceProperty(Capability.QUERY_ORDERBY_DEFAULT_NULL_ORDER, NullOrder.UNKNOWN);
capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$
-
- ProcessorPlan plan = TestOptimizer.helpPlan("select e1 from pm1.g1 order by e1 desc, e2 asc NULLS LAST", //$NON-NLS-1$
- RealMetadataFactory.example1Cached(), null, capFinder,
- new String[] { "SELECT g_0.e1 AS c_0 FROM pm1.g1 AS g_0 ORDER BY c_0 DESC, g_0.e2"}, //$NON-NLS-1$
- TestOptimizer.ComparisonMode.EXACT_COMMAND_STRING);
-
+ QueryMetadataInterface metadata = RealMetadataFactory.example1Cached();
+ CommandContext cc = new CommandContext();
+ cc.setOptions(new Options().pushdownDefaultNullOrder(true));
+ ProcessorPlan plan = TestOptimizer.getPlan(TestOptimizer.helpGetCommand("select e1 from pm1.g1 order by e1 desc, e2 asc", metadata, null), metadata, capFinder, null, true, cc);
+ TestOptimizer.checkAtomicQueries(new String[] { "SELECT g_0.e1 AS c_0 FROM pm1.g1 AS g_0 ORDER BY c_0 DESC NULLS LAST, g_0.e2 NULLS FIRST"}, plan); //$NON-NLS-1$
TestOptimizer.checkNodeTypes(plan, TestOptimizer.FULL_PUSHDOWN);
}
Modified: trunk/engine/src/test/java/org/teiid/query/processor/TestWindowFunctions.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestWindowFunctions.java 2012-10-04 16:49:23 UTC (rev 4514)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestWindowFunctions.java 2012-10-05 12:36:44 UTC (rev 4515)
@@ -38,6 +38,7 @@
import org.teiid.query.processor.relational.ProjectNode;
import org.teiid.query.processor.relational.WindowFunctionProjectNode;
import org.teiid.query.unittest.RealMetadataFactory;
+import org.teiid.translator.ExecutionFactory.NullOrder;
@SuppressWarnings({"nls", "unchecked"})
public class TestWindowFunctions {
@@ -99,6 +100,7 @@
caps.setCapabilitySupport(Capability.ELEMENTARY_OLAP, true);
caps.setCapabilitySupport(Capability.WINDOW_FUNCTION_ORDER_BY_AGGREGATES, true);
caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_MAX, true);
+ caps.setSourceProperty(Capability.QUERY_ORDERBY_DEFAULT_NULL_ORDER, NullOrder.UNKNOWN);
ProcessorPlan plan = TestOptimizer.helpPlan("select max(e1) over (order by e1 nulls first) as y from pm1.g1", //$NON-NLS-1$
RealMetadataFactory.example1Cached(), null, new DefaultCapabilitiesFinder(caps),
new String[] {
Modified: trunk/test-integration/common/src/test/java/org/teiid/dqp/internal/process/BaseQueryTest.java
===================================================================
--- trunk/test-integration/common/src/test/java/org/teiid/dqp/internal/process/BaseQueryTest.java 2012-10-04 16:49:23 UTC (rev 4514)
+++ trunk/test-integration/common/src/test/java/org/teiid/dqp/internal/process/BaseQueryTest.java 2012-10-05 12:36:44 UTC (rev 4515)
@@ -56,9 +56,6 @@
protected void doProcess(QueryMetadataInterface metadata, String sql, CapabilitiesFinder capFinder, ProcessorDataManager dataManager, List[] expectedResults, boolean debug) throws Exception {
CommandContext context = createCommandContext();
- if (context.getMetadata() == null) {
- context.setMetadata(metadata);
- }
Command command = TestOptimizer.helpGetCommand(sql, metadata, null);
// plan
Modified: trunk/test-integration/common/src/test/java/org/teiid/dqp/internal/process/TestTPCR.java
===================================================================
--- trunk/test-integration/common/src/test/java/org/teiid/dqp/internal/process/TestTPCR.java 2012-10-04 16:49:23 UTC (rev 4514)
+++ trunk/test-integration/common/src/test/java/org/teiid/dqp/internal/process/TestTPCR.java 2012-10-05 12:36:44 UTC (rev 4515)
@@ -63,7 +63,7 @@
Arrays.asList(new Object[] { new Double(3459808.0), new BigDecimal("405838.6989"), TimestampUtil.createDate(95, 2, 4), new Double(0.0) }), //$NON-NLS-1$
Arrays.asList(new Object[] { new Double(492164.0), new BigDecimal("390324.0610"), TimestampUtil.createDate(95, 1, 19), new Double(0.0) }) }; //$NON-NLS-1$
- dataMgr.addData("SELECT g_2.L_ORDERKEY AS c_0, SUM((g_2.L_EXTENDEDPRICE * (1 - g_2.L_DISCOUNT))) AS c_1, g_1.O_ORDERDATE AS c_2, g_1.O_SHIPPRIORITY AS c_3 FROM TPCR_Oracle_9i.CUSTOMER AS g_0, TPCR_Oracle_9i.ORDERS AS g_1, TPCR_Oracle_9i.LINEITEM AS g_2 WHERE (g_0.C_CUSTKEY = g_1.O_CUSTKEY) AND (g_2.L_ORDERKEY = g_1.O_ORDERKEY) AND (g_0.C_MKTSEGMENT = 'BUILDING') AND (g_1.O_ORDERDATE < {d'1995-03-15'}) AND (g_2.L_SHIPDATE > {ts'1995-03-15 00:00:00.0'}) GROUP BY g_2.L_ORDERKEY, g_1.O_ORDERDATE, g_1.O_SHIPPRIORITY ORDER BY c_1 DESC NULLS LAST, c_2 NULLS FIRST", //$NON-NLS-1$
+ dataMgr.addData("SELECT g_2.L_ORDERKEY AS c_0, SUM((g_2.L_EXTENDEDPRICE * (1 - g_2.L_DISCOUNT))) AS c_1, g_1.O_ORDERDATE AS c_2, g_1.O_SHIPPRIORITY AS c_3 FROM TPCR_Oracle_9i.CUSTOMER AS g_0, TPCR_Oracle_9i.ORDERS AS g_1, TPCR_Oracle_9i.LINEITEM AS g_2 WHERE (g_0.C_CUSTKEY = g_1.O_CUSTKEY) AND (g_2.L_ORDERKEY = g_1.O_ORDERKEY) AND (g_0.C_MKTSEGMENT = 'BUILDING') AND (g_1.O_ORDERDATE < {d'1995-03-15'}) AND (g_2.L_SHIPDATE > {ts'1995-03-15 00:00:00.0'}) GROUP BY g_2.L_ORDERKEY, g_1.O_ORDERDATE, g_1.O_SHIPPRIORITY ORDER BY c_1 DESC, c_2", //$NON-NLS-1$
expected);
doProcess(METADATA,
@@ -191,7 +191,7 @@
ProcessorPlan plan = TestOptimizer.helpPlan("SELECT custsale.cntrycode, COUNT(*) AS numcust, SUM(c_acctbal) AS totacctbal FROM (SELECT left(C_PHONE, 2) AS cntrycode, CUSTOMER.C_ACCTBAL FROM CUSTOMER WHERE (left(C_PHONE, 2) IN ('13','31','23','29','30','18','17')) AND (CUSTOMER.C_ACCTBAL > (SELECT AVG(CUSTOMER.C_ACCTBAL) FROM CUSTOMER WHERE (CUSTOMER.C_ACCTBAL > 0.0) AND (left(C_PHONE, 2) IN ('13','31','23','29','30','18','17')))) AND (NOT (EXISTS (SELECT * FROM ORDERS WHERE O_CUSTKEY = C_CUSTKEY)))) AS custsale GROUP BY custsale.cntrycode ORDER BY custsale.cntrycode", //$NON-NLS-1$
METADATA, null, finder,
- new String[] {"SELECT left(g_0.C_PHONE, 2) AS c_0, COUNT(*) AS c_1, SUM(g_0.C_ACCTBAL) AS c_2 FROM TPCR_Oracle_9i.CUSTOMER AS g_0 WHERE (left(g_0.C_PHONE, 2) IN ('13', '31', '23', '29', '30', '18', '17')) AND (g_0.C_ACCTBAL > (SELECT AVG(g_1.C_ACCTBAL) FROM TPCR_Oracle_9i.CUSTOMER AS g_1 WHERE (g_1.C_ACCTBAL > 0.0) AND (left(g_1.C_PHONE, 2) IN ('13', '31', '23', '29', '30', '18', '17')))) AND (NOT EXISTS (SELECT 1 FROM TPCR_Oracle_9i.ORDERS AS g_2 WHERE g_2.O_CUSTKEY = g_0.C_CUSTKEY)) GROUP BY left(g_0.C_PHONE, 2) ORDER BY c_0 NULLS FIRST"}, ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$
+ new String[] {"SELECT left(g_0.C_PHONE, 2) AS c_0, COUNT(*) AS c_1, SUM(g_0.C_ACCTBAL) AS c_2 FROM TPCR_Oracle_9i.CUSTOMER AS g_0 WHERE (left(g_0.C_PHONE, 2) IN ('13', '31', '23', '29', '30', '18', '17')) AND (g_0.C_ACCTBAL > (SELECT AVG(g_1.C_ACCTBAL) FROM TPCR_Oracle_9i.CUSTOMER AS g_1 WHERE (g_1.C_ACCTBAL > 0.0) AND (left(g_1.C_PHONE, 2) IN ('13', '31', '23', '29', '30', '18', '17')))) AND (NOT EXISTS (SELECT 1 FROM TPCR_Oracle_9i.ORDERS AS g_2 WHERE g_2.O_CUSTKEY = g_0.C_CUSTKEY)) GROUP BY left(g_0.C_PHONE, 2) ORDER BY c_0"}, ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$
TestOptimizer.checkNodeTypes(plan, TestOptimizer.FULL_PUSHDOWN);
}
12 years, 2 months
teiid SVN: r4514 - in trunk/connectors/translator-jdbc/src: test/java/org/teiid/translator/jdbc/db2 and 1 other directory.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2012-10-04 12:49:23 -0400 (Thu, 04 Oct 2012)
New Revision: 4514
Modified:
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/db2/DB2ExecutionFactory.java
trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/db2/TestDB2SqlTranslator.java
Log:
TEIID-2202 adding a db2fori property on the db2 translator
Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/db2/DB2ExecutionFactory.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/db2/DB2ExecutionFactory.java 2012-10-04 16:08:45 UTC (rev 4513)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/db2/DB2ExecutionFactory.java 2012-10-04 16:49:23 UTC (rev 4514)
@@ -32,6 +32,7 @@
import org.teiid.translator.SourceSystemFunctions;
import org.teiid.translator.Translator;
import org.teiid.translator.TranslatorException;
+import org.teiid.translator.TranslatorProperty;
import org.teiid.translator.jdbc.FunctionModifier;
@Translator(name="db2", description="A translator for IBM DB2 Database")
@@ -39,9 +40,13 @@
public static final String EIGHT_0 = "8.0"; //$NON-NLS-1$
public static final String NINE_1 = "9.1"; //$NON-NLS-1$
+
+ public static final String FIVE_4 = "5.4"; //$NON-NLS-1$
+ public static final String SIX_1 = "6.1"; //$NON-NLS-1$
+ private boolean dB2ForI;
+
public DB2ExecutionFactory() {
- setDatabaseVersion(EIGHT_0);
}
@Override
@@ -115,7 +120,7 @@
@Override
public boolean supportsFunctionsInGroupBy() {
- return true;
+ return !dB2ForI;
}
@Override
@@ -135,10 +140,22 @@
@Override
public boolean supportsElementaryOlapOperations() {
- return getDatabaseVersion().compareTo(NINE_1) >= 0;
+ return getDatabaseVersion().compareTo(isdB2ForI()?SIX_1:NINE_1) >= 0;
}
@Override
+ public String getDatabaseVersion() {
+ String version = super.getDatabaseVersion();
+ if (version != null) {
+ return version;
+ }
+ if (dB2ForI) {
+ return FIVE_4;
+ }
+ return EIGHT_0;
+ }
+
+ @Override
public void start() throws TranslatorException {
super.start();
registerFunctionModifier(SourceSystemFunctions.TRIM, new FunctionModifier() {
@@ -151,4 +168,13 @@
});
}
+ @TranslatorProperty(display="Is DB2 for i", description="If the server is DB2 for i (formally known as DB2/AS).",advanced=true)
+ public boolean isdB2ForI() {
+ return dB2ForI;
+ }
+
+ public void setdB2ForI(boolean dB2ForI) {
+ this.dB2ForI = dB2ForI;
+ }
+
}
Modified: trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/db2/TestDB2SqlTranslator.java
===================================================================
--- trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/db2/TestDB2SqlTranslator.java 2012-10-04 16:08:45 UTC (rev 4513)
+++ trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/db2/TestDB2SqlTranslator.java 2012-10-04 16:49:23 UTC (rev 4514)
@@ -279,5 +279,14 @@
input, output,
TRANSLATOR);
}
+
+ @Test public void testDB2ForI() throws Exception {
+ DB2ExecutionFactory db2 = new DB2ExecutionFactory();
+ db2.setdB2ForI(true);
+ assertFalse(db2.supportsFunctionsInGroupBy());
+ assertFalse(db2.supportsElementaryOlapOperations());
+ db2.setDatabaseVersion(DB2ExecutionFactory.SIX_1);
+ assertTrue(db2.supportsElementaryOlapOperations());
+ }
}
12 years, 2 months
teiid SVN: r4513 - in trunk: client/src/test/java/org/teiid/jdbc and 6 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2012-10-04 12:08:45 -0400 (Thu, 04 Oct 2012)
New Revision: 4513
Modified:
trunk/client/src/main/java/org/teiid/jdbc/ConnectionImpl.java
trunk/client/src/main/java/org/teiid/jdbc/JDBCURL.java
trunk/client/src/main/java/org/teiid/jdbc/StatementImpl.java
trunk/client/src/main/java/org/teiid/jdbc/TeiidDriver.java
trunk/client/src/test/java/org/teiid/jdbc/TestStatement.java
trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java
trunk/runtime/src/main/java/org/teiid/deployers/PgCatalogMetadataStore.java
trunk/runtime/src/main/java/org/teiid/deployers/VDBRepository.java
trunk/runtime/src/main/java/org/teiid/odbc/ODBCClientRemote.java
trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemoteImpl.java
trunk/runtime/src/main/java/org/teiid/runtime/RuntimePlugin.java
trunk/runtime/src/main/java/org/teiid/transport/LocalServerConnection.java
trunk/runtime/src/main/java/org/teiid/transport/PGCharsetConverter.java
trunk/runtime/src/main/java/org/teiid/transport/PgBackendProtocol.java
trunk/runtime/src/main/java/org/teiid/transport/PgFrontendProtocol.java
trunk/runtime/src/main/resources/org/teiid/runtime/i18n.properties
trunk/test-integration/common/src/test/java/org/teiid/transport/TestODBCSocketTransport.java
Log:
TEIID-2228 adding support for pg_client_encoding
Modified: trunk/client/src/main/java/org/teiid/jdbc/ConnectionImpl.java
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/ConnectionImpl.java 2012-10-04 12:26:57 UTC (rev 4512)
+++ trunk/client/src/main/java/org/teiid/jdbc/ConnectionImpl.java 2012-10-04 16:08:45 UTC (rev 4513)
@@ -187,6 +187,14 @@
return this.propInfo;
}
+ public void setExecutionProperty(String key, String value) {
+ JDBCURL.addNormalizedProperty(key, value, getExecutionProperties());
+ }
+
+ public String getExecutionProperty(String key) {
+ return this.getExecutionProperties().getProperty(JDBCURL.getValidKey(key));
+ }
+
DQP getDQP() {
return this.dqp;
}
@@ -420,7 +428,7 @@
* <p>This method gets the ServerConnection object wrapped by this object.</p>
* @return ServerConnection object
*/
- ServerConnection getServerConnection() throws SQLException {
+ public ServerConnection getServerConnection() throws SQLException {
//Check to see the connection is open
checkConnection();
return serverConn;
Modified: trunk/client/src/main/java/org/teiid/jdbc/JDBCURL.java
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/JDBCURL.java 2012-10-04 12:26:57 UTC (rev 4512)
+++ trunk/client/src/main/java/org/teiid/jdbc/JDBCURL.java 2012-10-04 16:08:45 UTC (rev 4513)
@@ -69,9 +69,9 @@
return result;
}
- public static final Set<String> KNOWN_PROPERTIES = getKnownProperties();
+ public static final Map<String, String> KNOWN_PROPERTIES = getKnownProperties();
- private static Set<String> getKnownProperties() {
+ private static Map<String, String> getKnownProperties() {
Set<String> props = new HashSet<String>(Arrays.asList(
BaseDataSource.APP_NAME,
BaseDataSource.VDB_NAME,
@@ -87,7 +87,11 @@
TeiidURL.CONNECTION.KERBEROS_SERVICE_PRINCIPLE_NAME,
TeiidURL.CONNECTION.ENCRYPT_REQUESTS));
props.addAll(EXECUTION_PROPERTIES.keySet());
- return Collections.unmodifiableSet(props);
+ Map<String, String> result = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
+ for (String string : props) {
+ result.put(string, string);
+ }
+ return Collections.unmodifiableMap(result);
}
private String vdbName;
@@ -290,11 +294,10 @@
}
public static String getValidKey(String key) {
- for (String prop : KNOWN_PROPERTIES) {
- if (prop.equalsIgnoreCase(key)) {
- return prop;
- }
- }
+ String result = KNOWN_PROPERTIES.get(key);
+ if (result != null) {
+ return result;
+ }
return key;
}
Modified: trunk/client/src/main/java/org/teiid/jdbc/StatementImpl.java
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/StatementImpl.java 2012-10-04 12:26:57 UTC (rev 4512)
+++ trunk/client/src/main/java/org/teiid/jdbc/StatementImpl.java 2012-10-04 16:08:45 UTC (rev 4513)
@@ -445,7 +445,7 @@
this.getMMConnection().getServerConnection().cleanUp();
}
} else {
- JDBCURL.addNormalizedProperty(key, value, this.driverConnection.getExecutionProperties());
+ this.driverConnection.setExecutionProperty(key, value);
}
this.updateCounts = new int[] {0};
return booleanFuture(false);
@@ -589,7 +589,7 @@
new String[] {DataTypeManager.DefaultDataTypes.STRING, DataTypeManager.DefaultDataTypes.STRING});
return booleanFuture(true);
}
- List<List<String>> records = Collections.singletonList(Collections.singletonList(driverConnection.getExecutionProperties().getProperty(JDBCURL.getValidKey(show))));
+ List<List<String>> records = Collections.singletonList(Collections.singletonList(driverConnection.getExecutionProperty(show)));
createResultSet(records, new String[] {show}, new String[] {DataTypeManager.DefaultDataTypes.STRING});
return booleanFuture(true);
}
Modified: trunk/client/src/main/java/org/teiid/jdbc/TeiidDriver.java
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/TeiidDriver.java 2012-10-04 12:26:57 UTC (rev 4512)
+++ trunk/client/src/main/java/org/teiid/jdbc/TeiidDriver.java 2012-10-04 16:08:45 UTC (rev 4513)
@@ -26,7 +26,6 @@
import java.sql.DriverManager;
import java.sql.DriverPropertyInfo;
import java.sql.SQLException;
-import java.sql.SQLFeatureNotSupportedException;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
@@ -164,7 +163,7 @@
parseURL(url, info);
- for (String property: JDBCURL.KNOWN_PROPERTIES) {
+ for (String property: JDBCURL.KNOWN_PROPERTIES.keySet()) {
DriverPropertyInfo dpi = new DriverPropertyInfo(property, info.getProperty(property));
if (property.equals(BaseDataSource.VDB_NAME)) {
dpi.required = true;
@@ -199,7 +198,7 @@
}
Properties optionalParams = jdbcURL.getProperties();
JDBCURL.normalizeProperties(info);
- Enumeration keys = optionalParams.keys();
+ Enumeration<?> keys = optionalParams.keys();
while (keys.hasMoreElements()) {
String propName = (String)keys.nextElement();
// Don't let the URL properties override the passed-in Properties object.
@@ -229,7 +228,7 @@
return false;
}
- public Logger getParentLogger() throws SQLFeatureNotSupportedException {
+ public Logger getParentLogger() {
return logger;
}
}
Modified: trunk/client/src/test/java/org/teiid/jdbc/TestStatement.java
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestStatement.java 2012-10-04 12:26:57 UTC (rev 4512)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestStatement.java 2012-10-04 16:08:45 UTC (rev 4513)
@@ -86,14 +86,12 @@
@Test public void testSetStatement() throws Exception {
ConnectionImpl conn = Mockito.mock(ConnectionImpl.class);
- Properties p = new Properties();
- Mockito.stub(conn.getExecutionProperties()).toReturn(p);
StatementImpl statement = new StatementImpl(conn, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
assertFalse(statement.execute("set foo bar")); //$NON-NLS-1$
- assertEquals("bar", p.get("foo")); //$NON-NLS-1$ //$NON-NLS-2$
+ Mockito.verify(conn).setExecutionProperty("foo", "bar");
assertFalse(statement.execute("set foo 'b''ar'")); //$NON-NLS-1$
- assertEquals("b'ar", p.get("foo")); //$NON-NLS-1$ //$NON-NLS-2$
+ Mockito.verify(conn).setExecutionProperty("foo", "b'ar");
}
@Test public void testSetPayloadStatement() throws Exception {
Modified: trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java 2012-10-04 12:26:57 UTC (rev 4512)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java 2012-10-04 16:08:45 UTC (rev 4513)
@@ -139,9 +139,9 @@
DriverPropertyInfo info[] = drv.getPropertyInfo("jdbc:teiid:vdb@mm://localhost:12345;applicationName=x", null); //$NON-NLS-1$
assertEquals(25, info.length);
- assertEquals(false, info[0].required);
- assertEquals("ApplicationName", info[0].name); //$NON-NLS-1$
- assertEquals("x", info[0].value); //$NON-NLS-1$
+ assertEquals(false, info[1].required);
+ assertEquals("ApplicationName", info[1].name); //$NON-NLS-1$
+ assertEquals("x", info[1].value); //$NON-NLS-1$
}
}
Modified: trunk/runtime/src/main/java/org/teiid/deployers/PgCatalogMetadataStore.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/deployers/PgCatalogMetadataStore.java 2012-10-04 12:26:57 UTC (rev 4512)
+++ trunk/runtime/src/main/java/org/teiid/deployers/PgCatalogMetadataStore.java 2012-10-04 16:08:45 UTC (rev 4513)
@@ -28,6 +28,7 @@
import java.util.Map;
import java.util.Properties;
+import org.teiid.adminapi.impl.SessionMetadata;
import org.teiid.adminapi.impl.VDBMetaData;
import org.teiid.core.types.ArrayImpl;
import org.teiid.core.types.DataTypeManager;
@@ -36,16 +37,17 @@
import org.teiid.metadata.FunctionMethod;
import org.teiid.metadata.MetadataFactory;
import org.teiid.metadata.Table;
+import org.teiid.metadata.FunctionMethod.Determinism;
import org.teiid.metadata.Table.Type;
import org.teiid.odbc.ODBCServerRemoteImpl;
import org.teiid.query.metadata.TransformationMetadata;
import org.teiid.query.resolver.util.ResolverVisitor;
-import org.teiid.translator.TranslatorException;
+import org.teiid.transport.PgBackendProtocol;
public class PgCatalogMetadataStore extends MetadataFactory {
private static final long serialVersionUID = 2158418324376966987L;
- public PgCatalogMetadataStore(String modelName, Map<String, Datatype> dataTypes) throws TranslatorException {
+ public PgCatalogMetadataStore(String modelName, Map<String, Datatype> dataTypes) {
super(modelName, 1, modelName, dataTypes, new Properties(), null);
add_pg_namespace();
add_pg_class();
@@ -66,9 +68,11 @@
FunctionMethod func = addFunction("asPGVector", "asPGVector"); //$NON-NLS-1$ //$NON-NLS-2$
func.setProperty(ResolverVisitor.TEIID_PASS_THROUGH_TYPE, Boolean.TRUE.toString());
addFunction("getOid", "getOid"); //$NON-NLS-1$ //$NON-NLS-2$
+ func = addFunction("pg_client_encoding", "pg_client_encoding"); //$NON-NLS-1$ //$NON-NLS-2$
+ func.setDeterminism(Determinism.COMMAND_DETERMINISTIC);
}
- private Table createView(String name) throws TranslatorException {
+ private Table createView(String name) {
Table t = addTable(name);
t.setSystem(true);
t.setSupportsUpdate(false);
@@ -78,7 +82,7 @@
}
//index access methods
- private Table add_pg_am() throws TranslatorException {
+ private Table add_pg_am() {
Table t = createView("pg_am"); //$NON-NLS-1$
addColumn("oid", DataTypeManager.DefaultDataTypes.INTEGER, t); //$NON-NLS-1$
addColumn("amname", DataTypeManager.DefaultDataTypes.STRING, t); //$NON-NLS-1$
@@ -90,7 +94,7 @@
}
// column default values
- private Table add_pg_attrdef() throws TranslatorException {
+ private Table add_pg_attrdef() {
Table t = createView("pg_attrdef"); //$NON-NLS-1$
addColumn("adrelid", DataTypeManager.DefaultDataTypes.INTEGER, t); //$NON-NLS-1$
@@ -110,7 +114,7 @@
* table columns ("attributes")
* see also {@link ODBCServerRemoteImpl} getPGColInfo for the mod calculation
*/
- private Table add_pg_attribute() throws TranslatorException {
+ private Table add_pg_attribute() {
Table t = createView("pg_attribute"); //$NON-NLS-1$
addColumn("oid", DataTypeManager.DefaultDataTypes.INTEGER, t); //$NON-NLS-1$
@@ -175,7 +179,7 @@
}
// tables, indexes, sequences ("relations")
- private Table add_pg_class() throws TranslatorException {
+ private Table add_pg_class() {
Table t = createView("pg_class"); //$NON-NLS-1$
addColumn("oid", DataTypeManager.DefaultDataTypes.INTEGER, t); //$NON-NLS-1$
@@ -231,7 +235,7 @@
}
// additional index information
- private Table add_pg_index() throws TranslatorException {
+ private Table add_pg_index() {
Table t = createView("pg_index"); //$NON-NLS-1$
addColumn("oid", DataTypeManager.DefaultDataTypes.INTEGER, t); //$NON-NLS-1$
@@ -275,7 +279,7 @@
}
// schemas
- private Table add_pg_namespace() throws TranslatorException {
+ private Table add_pg_namespace() {
Table t = createView("pg_namespace"); //$NON-NLS-1$
addColumn("oid", DataTypeManager.DefaultDataTypes.INTEGER, t); //$NON-NLS-1$
addColumn("nspname", DataTypeManager.DefaultDataTypes.STRING, t); //$NON-NLS-1$
@@ -289,7 +293,7 @@
}
// functions and procedures
- private Table add_pg_proc() throws TranslatorException {
+ private Table add_pg_proc() {
Table t = createView("pg_proc"); //$NON-NLS-1$
addColumn("oid", DataTypeManager.DefaultDataTypes.INTEGER, t); //$NON-NLS-1$
@@ -355,7 +359,7 @@
}
// triggers
- private Table add_pg_trigger() throws TranslatorException {
+ private Table add_pg_trigger() {
Table t = createView("pg_trigger"); //$NON-NLS-1$
addColumn("oid", DataTypeManager.DefaultDataTypes.INTEGER, t); //$NON-NLS-1$
addColumn("tgconstrrelid", DataTypeManager.DefaultDataTypes.INTEGER, t); //$NON-NLS-1$
@@ -381,7 +385,7 @@
}
//data types
- private Table add_pg_type() throws TranslatorException {
+ private Table add_pg_type() {
Table t = createView("pg_type"); //$NON-NLS-1$
// Data type name
addColumn("oid", DataTypeManager.DefaultDataTypes.INTEGER, t); //$NON-NLS-1$
@@ -452,7 +456,7 @@
return t;
}
- private Table add_pg_database() throws TranslatorException {
+ private Table add_pg_database() {
Table t = createView("pg_database"); //$NON-NLS-1$
addColumn("oid", DataTypeManager.DefaultDataTypes.INTEGER, t); //$NON-NLS-1$
addColumn("datname", DataTypeManager.DefaultDataTypes.STRING, t); //$NON-NLS-1$
@@ -478,7 +482,7 @@
return t;
}
- private Table add_pg_user() throws TranslatorException {
+ private Table add_pg_user() {
Table t = createView("pg_user"); //$NON-NLS-1$
addColumn("oid", DataTypeManager.DefaultDataTypes.INTEGER, t); //$NON-NLS-1$
addColumn("usename", DataTypeManager.DefaultDataTypes.STRING, t); //$NON-NLS-1$
@@ -493,7 +497,7 @@
return t;
}
- private Table add_matpg_relatt() throws TranslatorException {
+ private Table add_matpg_relatt() {
Table t = createView("matpg_relatt"); //$NON-NLS-1$
addColumn("attrelid", DataTypeManager.DefaultDataTypes.INTEGER, t); //$NON-NLS-1$
addColumn("attnum", DataTypeManager.DefaultDataTypes.SHORT, t); //$NON-NLS-1$
@@ -514,7 +518,7 @@
return t;
}
- private Table add_matpg_datatype() throws TranslatorException {
+ private Table add_matpg_datatype() {
Table t = createView("matpg_datatype"); //$NON-NLS-1$
addColumn("oid", DataTypeManager.DefaultDataTypes.INTEGER, t); //$NON-NLS-1$
addColumn("typname", DataTypeManager.DefaultDataTypes.STRING, t); //$NON-NLS-1$
@@ -537,7 +541,7 @@
return t;
}
- private FunctionMethod addFunction(String javaFunction, String name) throws TranslatorException {
+ private FunctionMethod addFunction(String javaFunction, String name) {
Method[] methods = FunctionMethods.class.getMethods();
for (Method method : methods) {
if (!method.getName().equals(javaFunction)) {
@@ -580,5 +584,18 @@
TransformationMetadata tm = metadata.getAttachment(TransformationMetadata.class);
return tm.getMetadataStore().getOid(uid);
}
+
+ public static String pg_client_encoding(org.teiid.CommandContext cc) {
+ SessionMetadata session = (SessionMetadata)cc.getSession();
+ ODBCServerRemoteImpl server = session.getAttachment(ODBCServerRemoteImpl.class);
+ String encoding = null;
+ if (server != null) {
+ encoding = server.getEncoding();
+ }
+ if (encoding == null) {
+ return PgBackendProtocol.DEFAULT_ENCODING;
+ }
+ return encoding;
+ }
}
}
Modified: trunk/runtime/src/main/java/org/teiid/deployers/VDBRepository.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/deployers/VDBRepository.java 2012-10-04 12:26:57 UTC (rev 4512)
+++ trunk/runtime/src/main/java/org/teiid/deployers/VDBRepository.java 2012-10-04 16:08:45 UTC (rev 4513)
@@ -45,6 +45,7 @@
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
import org.teiid.metadata.Datatype;
+import org.teiid.metadata.MetadataException;
import org.teiid.metadata.MetadataStore;
import org.teiid.net.ConnectionException;
import org.teiid.query.function.SystemFunctionManager;
@@ -53,7 +54,6 @@
import org.teiid.query.metadata.TransformationMetadata.Resource;
import org.teiid.query.validator.ValidatorReport;
import org.teiid.runtime.RuntimePlugin;
-import org.teiid.translator.TranslatorException;
import org.teiid.vdb.runtime.VDBKey;
@@ -234,7 +234,7 @@
try {
PgCatalogMetadataStore pg = new PgCatalogMetadataStore(CoreConstants.ODBC_MODEL, getRuntimeTypeMap());
return pg.asMetadataStore();
- } catch (TranslatorException e) {
+ } catch (MetadataException e) {
LogManager.logError(LogConstants.CTX_DQP, e, RuntimePlugin.Util.gs(RuntimePlugin.Event.TEIID40002));
}
return null;
Modified: trunk/runtime/src/main/java/org/teiid/odbc/ODBCClientRemote.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/odbc/ODBCClientRemote.java 2012-10-04 12:26:57 UTC (rev 4512)
+++ trunk/runtime/src/main/java/org/teiid/odbc/ODBCClientRemote.java 2012-10-04 16:08:45 UTC (rev 4513)
@@ -33,7 +33,7 @@
void initialized(Properties props);
- void setEncoding(String value);
+ void setEncoding(String value, boolean init);
// AuthenticationCleartextPassword (B)
void useClearTextAuthentication();
Modified: trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemoteImpl.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemoteImpl.java 2012-10-04 12:26:57 UTC (rev 4512)
+++ trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemoteImpl.java 2012-10-04 16:08:45 UTC (rev 4513)
@@ -28,7 +28,6 @@
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
-import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
@@ -59,7 +58,9 @@
import org.teiid.odbc.PGUtil.PgColInfo;
import org.teiid.query.parser.SQLParserUtil;
import org.teiid.runtime.RuntimePlugin;
+import org.teiid.transport.LocalServerConnection;
import org.teiid.transport.ODBCClientInstance;
+import org.teiid.transport.PgBackendProtocol;
import org.teiid.transport.PgFrontendProtocol.NullTerminatedStringDataInputStream;
/**
@@ -224,14 +225,14 @@
info.put("password", password); //$NON-NLS-1$
}
- this.connection = (ConnectionImpl)driver.connect(url, info);
+ this.connection = driver.connect(url, info);
+ //Propagate so that we can use in pg methods
+ ((LocalServerConnection)this.connection.getServerConnection()).getWorkContext().getSession().addAttchment(ODBCServerRemoteImpl.class, this);
int hash = this.connection.getConnectionId().hashCode();
- Enumeration keys = this.props.propertyNames();
+ Enumeration<?> keys = this.props.propertyNames();
while (keys.hasMoreElements()) {
String key = (String)keys.nextElement();
- Statement stmt = this.connection.createStatement();
- stmt.execute("SET " + key + " '" + this.props.getProperty(key) + "'"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- stmt.close();
+ this.connection.setExecutionProperty(key, this.props.getProperty(key));
}
this.client.authenticationSucess(hash, hash);
ready();
@@ -851,30 +852,12 @@
String encoding = getEncoding();
if (encoding != null) {
//this may be unnecessary
- this.client.setEncoding(encoding);
+ this.client.setEncoding(encoding, false);
}
}
- private String getEncoding() {
- StatementImpl t = null;
- try {
- t = connection.createStatement();
- ResultSet rs = t.executeQuery("show client_encoding"); //$NON-NLS-1$
- if (rs.next()) {
- return rs.getString(1);
- }
- } catch (Exception e) {
- //don't care
- } finally {
- try {
- if (t != null) {
- t.close();
- }
- } catch (SQLException e) {
-
- }
- }
- return null;
+ public String getEncoding() {
+ return this.connection.getExecutionProperty(PgBackendProtocol.CLIENT_ENCODING);
}
private final class QueryWorkItem implements Runnable {
Modified: trunk/runtime/src/main/java/org/teiid/runtime/RuntimePlugin.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/runtime/RuntimePlugin.java 2012-10-04 12:26:57 UTC (rev 4512)
+++ trunk/runtime/src/main/java/org/teiid/runtime/RuntimePlugin.java 2012-10-04 16:08:45 UTC (rev 4513)
@@ -115,6 +115,7 @@
TEIID40101,
TEIID40102,
TEIID40103,
- TEIID40104
+ TEIID40104,
+ TEIID40105
}
}
Modified: trunk/runtime/src/main/java/org/teiid/transport/LocalServerConnection.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/transport/LocalServerConnection.java 2012-10-04 12:26:57 UTC (rev 4512)
+++ trunk/runtime/src/main/java/org/teiid/transport/LocalServerConnection.java 2012-10-04 16:08:45 UTC (rev 4513)
@@ -193,4 +193,8 @@
public boolean supportsContinuous() {
return true;
}
+
+ public DQPWorkContext getWorkContext() {
+ return workContext;
+ }
}
Modified: trunk/runtime/src/main/java/org/teiid/transport/PGCharsetConverter.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/transport/PGCharsetConverter.java 2012-10-04 12:26:57 UTC (rev 4512)
+++ trunk/runtime/src/main/java/org/teiid/transport/PGCharsetConverter.java 2012-10-04 16:08:45 UTC (rev 4513)
@@ -72,7 +72,15 @@
}
public static Charset getCharset(String name) {
- return charSetMap.get(name);
+ Charset cs = charSetMap.get(name);
+ if (cs == null) {
+ try {
+ return Charset.forName(name);
+ } catch (IllegalArgumentException e) {
+ return null;
+ }
+ }
+ return cs;
}
}
Modified: trunk/runtime/src/main/java/org/teiid/transport/PgBackendProtocol.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/transport/PgBackendProtocol.java 2012-10-04 12:26:57 UTC (rev 4512)
+++ trunk/runtime/src/main/java/org/teiid/transport/PgBackendProtocol.java 2012-10-04 16:08:45 UTC (rev 4513)
@@ -177,13 +177,16 @@
}
}
}
-
+
+ public static final String DEFAULT_ENCODING = "UTF8";
+ public static final String CLIENT_ENCODING = "client_encoding";
+
private ChannelBuffer dataOut;
private OutputStreamWriter writer;
private Properties props;
private Charset encoding = Charset.forName("UTF-8");
- private String clientEncoding = "UTF8";
+ private String clientEncoding = DEFAULT_ENCODING;
private ReflectionHelper clientProxy = new ReflectionHelper(ODBCClientRemote.class);
private ChannelHandlerContext ctx;
private MessageEvent message;
@@ -231,7 +234,7 @@
@Override
public void initialized(Properties props) {
this.props = props;
- setEncoding(props.getProperty("client_encoding", "UTF8"));
+ setEncoding(props.getProperty("client_encoding", this.clientEncoding), true);
}
@Override
@@ -301,15 +304,26 @@
sendReadyForQuery(inTransaction, failedTransaction);
}
- public void setEncoding(String value) {
+ public void setEncoding(String value, boolean init) {
+ if (value == null || value.equals(this.clientEncoding)) {
+ return;
+ }
+ this.clientEncoding = value;
Charset cs = PGCharsetConverter.getCharset(value);
if (cs != null) {
this.encoding = cs;
- this.clientEncoding = value;
- //TODO: for non-init this should send a parameter status
+ if (!init) {
+ sendParameterStatus(CLIENT_ENCODING, value);
+ }
+ } else {
+ LogManager.logWarning(LogConstants.CTX_ODBC, RuntimePlugin.Util.gs(RuntimePlugin.Event.TEIID40105, value));
}
}
+ public String getClientEncoding() {
+ return clientEncoding;
+ }
+
public Charset getEncoding() {
return encoding;
}
Modified: trunk/runtime/src/main/java/org/teiid/transport/PgFrontendProtocol.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/transport/PgFrontendProtocol.java 2012-10-04 12:26:57 UTC (rev 4512)
+++ trunk/runtime/src/main/java/org/teiid/transport/PgFrontendProtocol.java 2012-10-04 16:08:45 UTC (rev 4513)
@@ -209,7 +209,7 @@
}
this.user = props.getProperty("user");
this.databaseName = props.getProperty("database");
- String clientEncoding = props.getProperty("client_encoding", "UTF8");
+ String clientEncoding = props.getProperty("client_encoding", PgBackendProtocol.DEFAULT_ENCODING);
props.setProperty("client_encoding", clientEncoding);
props.setProperty("default_transaction_isolation", "read committed");
props.setProperty("DateStyle", "ISO");
Modified: trunk/runtime/src/main/resources/org/teiid/runtime/i18n.properties
===================================================================
--- trunk/runtime/src/main/resources/org/teiid/runtime/i18n.properties 2012-10-04 12:26:57 UTC (rev 4512)
+++ trunk/runtime/src/main/resources/org/teiid/runtime/i18n.properties 2012-10-04 16:08:45 UTC (rev 4513)
@@ -104,4 +104,5 @@
TEIID40101=error setting state {0}
TEIID40102= {0} Failed to Pull {1}
-TEIID40103={0} timeout pulling {1}
\ No newline at end of file
+TEIID40103={0} timeout pulling {1}
+TEIID40105=Unsupported ODBC client encoding {0}
\ No newline at end of file
Modified: trunk/test-integration/common/src/test/java/org/teiid/transport/TestODBCSocketTransport.java
===================================================================
--- trunk/test-integration/common/src/test/java/org/teiid/transport/TestODBCSocketTransport.java 2012-10-04 12:26:57 UTC (rev 4512)
+++ trunk/test-integration/common/src/test/java/org/teiid/transport/TestODBCSocketTransport.java 2012-10-04 16:08:45 UTC (rev 4513)
@@ -391,4 +391,27 @@
ResultSet rs = s.executeQuery("select indkey FROM pg_index");
TestMMDatabaseMetaData.compareResultSet(rs);
}
+
+ @Test public void test_pg_client_encoding() throws Exception {
+ Statement s = conn.createStatement();
+ ResultSet rs = s.executeQuery("select pg_client_encoding()");
+ rs.next();
+ assertEquals("UTF8", rs.getString(1));
+
+ s.execute("set client_encoding UTF8");
+ rs = s.executeQuery("select pg_client_encoding()");
+ rs.next();
+ assertEquals("UTF8", rs.getString(1));
+ }
+
+ /**
+ * Ensures that the client is notified about the change. However the driver will
+ * throw an exception as it requires UTF8
+ * @throws Exception
+ */
+ @Test(expected=SQLException.class) public void test_pg_client_encoding1() throws Exception {
+ Statement s = conn.createStatement();
+ s.execute("set client_encoding LATIN1");
+ }
+
}
12 years, 2 months
teiid SVN: r4512 - in trunk: connectors/translator-object/src/main/java/org/teiid/translator/object/infinispan and 7 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2012-10-04 08:26:57 -0400 (Thu, 04 Oct 2012)
New Revision: 4512
Added:
trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/SearchByKey.java
trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/infinispan/LuceneSearch.java
trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/TestMapCacheKeySearch.java
Removed:
trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/infinispan/InfinispanBaseExecutionFactory.java
trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/infinispan/InfinispanConnectionImpl.java
trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/infinispan/InfinispanRemoteExecutionFactory.java
trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/infinispan/search/
trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/mapcache/
trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/search/
trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/TestObjectExecution.java
trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/infinispan/TestInfinispanJndiKeySearch.java
trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/infinispan/TestInfinispanRemoteJndiKeySearch.java
trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/mapcache/TestMapCacheKeySearch.java
trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/search/
Modified:
trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/ObjectConnection.java
trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/ObjectExecution.java
trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/ObjectExecutionFactory.java
trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/infinispan/InfinispanExecutionFactory.java
trunk/connectors/translator-object/src/main/resources/META-INF/services/org.teiid.translator.ExecutionFactory
trunk/connectors/translator-object/src/main/resources/org/teiid/translator/object/i18n.properties
trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/BasicSearchTest.java
trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/TestObjectExecutionFactory.java
trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/infinispan/RemoteInfinispanTestHelper.java
trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/infinispan/TestInfinispanConfigFileKeySearch.java
trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/infinispan/TestInfinispanJndiILuceneSearch.java
trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/util/TradesCacheSource.java
trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/util/VDBUtility.java
trunk/engine/src/main/java/org/teiid/query/function/FunctionMethods.java
Log:
TEIID-2210 refinements to the object translator. decoupling the translator logic from the connection logic. this temporarily breaks the functionality
Modified: trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/ObjectConnection.java
===================================================================
--- trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/ObjectConnection.java 2012-10-03 19:05:34 UTC (rev 4511)
+++ trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/ObjectConnection.java 2012-10-04 12:26:57 UTC (rev 4512)
@@ -21,14 +21,12 @@
*/
package org.teiid.translator.object;
-import java.util.List;
+import java.util.Map;
-import org.teiid.language.Select;
import org.teiid.translator.TranslatorException;
/**
- * Each ObjectConnection implementation represents a connection instance and is responsible for
- * implementing the data source search language specifics for searching its cache.
+ * Each ObjectConnection implementation represents a connection to a set of maps or caches
*
* @author vhalbert
*
@@ -36,11 +34,15 @@
public interface ObjectConnection {
/**
- * Call to perform the search on the cache identified by this connection instance
- * @param command
- * @return List of Objects
+ * Return the map containing the desired objects
* @throws TranslatorException
*/
- public List<Object> performSearch(Select command) throws TranslatorException;
+ public Map<?, ?> getMap(String name) throws TranslatorException;
+
+ /**
+ * Return the type of the desired objects
+ * @throws TranslatorException
+ */
+ public Class<?> getType(String name) throws TranslatorException;
}
Modified: trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/ObjectExecution.java
===================================================================
--- trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/ObjectExecution.java 2012-10-03 19:05:34 UTC (rev 4511)
+++ trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/ObjectExecution.java 2012-10-04 12:26:57 UTC (rev 4512)
@@ -26,6 +26,7 @@
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import javax.script.CompiledScript;
import javax.script.ScriptContext;
@@ -34,9 +35,11 @@
import org.teiid.language.ColumnReference;
import org.teiid.language.DerivedColumn;
+import org.teiid.language.NamedTable;
import org.teiid.language.Select;
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
+import org.teiid.metadata.AbstractMetadataRecord;
import org.teiid.metadata.Column;
import org.teiid.metadata.RuntimeMetadata;
import org.teiid.query.eval.TeiidScriptEngine;
@@ -50,21 +53,23 @@
public class ObjectExecution implements ResultSetExecution {
private static final String OBJECT_NAME = "o"; //$NON-NLS-1$
- private Select query;
- private ObjectConnection connection;
+ protected Select query;
+ protected ObjectConnection connection;
private ArrayList<CompiledScript> projects;
private ScriptContext sc = new SimpleScriptContext();
private static TeiidScriptEngine scriptEngine = new TeiidScriptEngine();
private Iterator<Object> resultsIt = null;
+ private ObjectExecutionFactory factory;
public ObjectExecution(Select query, RuntimeMetadata metadata,
ObjectExecutionFactory factory, ObjectConnection connection) throws TranslatorException {
+ this.factory = factory;
this.query = query;
this.connection = connection;
projects = new ArrayList<CompiledScript>(query.getDerivedColumns().size());
for (DerivedColumn dc : query.getDerivedColumns()) {
Column c = ((ColumnReference) dc.getExpression()).getMetadataObject();
- String name = getNameInSourceFromColumn(c);
+ String name = getNameInSource(c);
if (name.equalsIgnoreCase("this")) { //$NON-NLS-1$
projects.add(null);
} else {
@@ -81,13 +86,16 @@
public void execute() throws TranslatorException {
LogManager.logTrace(LogConstants.CTX_CONNECTOR,
- "ObjectExecution command: " + query.toString()); //$NON-NLS-1$
+ "ObjectExecution command:", query.toString(), "using connection:", connection.getClass().getName()); //$NON-NLS-1$ //$NON-NLS-2$
- List<Object> results = executeQuery();
+ String nameInSource = getNameInSource(((NamedTable)query.getFrom().get(0)).getMetadataObject());
+ Map<?, ?> map = this.connection.getMap(nameInSource);
+ Class<?> type = this.connection.getType(nameInSource);
+ List<Object> results = factory.search(query, map, type);
if (results != null && results.size() > 0) {
LogManager.logDetail(LogConstants.CTX_CONNECTOR,
- "ObjectExecution number of returned objects is : " + results.size()); //$NON-NLS-1$
+ "ObjectExecution number of returned objects is :", results.size()); //$NON-NLS-1$
} else {
LogManager.logDetail(LogConstants.CTX_CONNECTOR,
@@ -99,18 +107,6 @@
this.resultsIt = results.iterator();
}
- protected List<Object> executeQuery()
- throws TranslatorException {
-
- LogManager
- .logTrace(
- LogConstants.CTX_CONNECTOR,
- "ObjectExecution calling search strategy : " + connection.getClass().getName()); //$NON-NLS-1$
-
- return connection.performSearch(query);
-
- }
-
@Override
public List<Object> next() throws TranslatorException,
DataNotAvailableException {
@@ -146,7 +142,7 @@
public void cancel() throws TranslatorException {
}
- public static String getNameInSourceFromColumn(Column c) {
+ public static String getNameInSource(AbstractMetadataRecord c) {
String name = c.getNameInSource();
if (name == null || name.trim().isEmpty()) {
return c.getName();
Modified: trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/ObjectExecutionFactory.java
===================================================================
--- trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/ObjectExecutionFactory.java 2012-10-03 19:05:34 UTC (rev 4511)
+++ trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/ObjectExecutionFactory.java 2012-10-04 12:26:57 UTC (rev 4512)
@@ -22,11 +22,9 @@
package org.teiid.translator.object;
+import java.util.List;
import java.util.Map;
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
import javax.resource.cci.ConnectionFactory;
import org.teiid.language.QueryExpression;
@@ -35,8 +33,8 @@
import org.teiid.translator.ExecutionContext;
import org.teiid.translator.ExecutionFactory;
import org.teiid.translator.ResultSetExecution;
+import org.teiid.translator.Translator;
import org.teiid.translator.TranslatorException;
-import org.teiid.translator.TranslatorProperty;
/**
@@ -46,20 +44,13 @@
* @author vhalbert
*
*/
-public abstract class ObjectExecutionFactory extends
+@Translator(name = "map-cache", description = "Searches a Map for Objects")
+public class ObjectExecutionFactory extends
ExecutionFactory<ConnectionFactory, ObjectConnection> {
public static final int MAX_SET_SIZE = 10000;
- // rootClassName identifies the name of the class that is identified by the
- // unique key in the cache
- private String rootClassName = null;
- private Class<?> rootClass = null;
- private String cacheJndiName;
-
-
public ObjectExecutionFactory() {
-
setSourceRequiredForMetadata(false);
setMaxInCriteriaSize(MAX_SET_SIZE);
setMaxDependentInPredicates(1);
@@ -69,42 +60,13 @@
setSupportsInnerJoins(false);
setSupportsFullOuterJoins(false);
setSupportsOuterJoins(false);
-
}
@Override
- public void start() throws TranslatorException {
- super.start();
-
- if (this.getRootClassName() == null
- || this.getRootClassName().trim().length() == -1) {
- String msg = ObjectPlugin.Util.getString(
- "ObjectExecutionFactory.rootClassNameNotDefined", //$NON-NLS-1$
- new Object[] {});
- throw new TranslatorException(msg);
- }
-
- try {
- rootClass = Class.forName(rootClassName.trim(), true, getClass()
- .getClassLoader());
-
- } catch (ClassNotFoundException e) {
- String msg = ObjectPlugin.Util.getString(
- "ObjectExecutionFactory.rootClassNotFound", //$NON-NLS-1$
- new Object[] { this.rootClassName });
- throw new TranslatorException(msg);
- }
-
- }
-
- @Override
public ResultSetExecution createResultSetExecution(QueryExpression command,
ExecutionContext executionContext, RuntimeMetadata metadata,
ObjectConnection connection) throws TranslatorException {
-
-
- return new ObjectExecution((Select) command, metadata, this, (connection == null ? getConnection(null, executionContext) : connection) );
-
+ return new ObjectExecution((Select) command, metadata, this, connection);
}
@Override
@@ -122,11 +84,6 @@
return false;
}
- @Override
- public boolean supportsConvert(int fromType, int toType) {
- return false;
- }
-
public boolean supportsCompareCriteriaEquals() {
return true;
}
@@ -136,119 +93,12 @@
}
@Override
- public boolean supportsLikeCriteria() {
- // at this point, i've been unable to get the Like to work.
- return false;
- }
-
- @Override
- public boolean supportsNotCriteria() {
- return false;
- }
-
- @Override
- public boolean supportsSubqueryInOn() {
- return false;
- }
-
- @Override
- public boolean supportsOrderBy() {
- return false;
- }
-
- /**
- * Call to get the class name of the root object in the cache. This
- * identifies the name of the class that is identified by the unique key in
- * the cache
- *
- * @return
- */
- @TranslatorProperty(display = "Root ClassName of Cached Object", advanced = true)
- public String getRootClassName() {
- return this.rootClassName;
- }
-
- /**
- * Call to set the root class name for the cache accessed by this factory
- * instance.
- * <p>
- * If the root class name has already been set, subsequent calls will have
- * no effect.
- *
- * @param rootClassName
- */
- public void setRootClassName(String rootClassName) {
- this.rootClassName = rootClassName;
- }
-
- /**
- * Get the JNDI name for the {@link Map cache} instance that should be used as the data source.
- *
- * @return the JNDI name of the {@link Map cache} instance that should be used,
- * @see #setCacheJndiName(String)
- */
- @TranslatorProperty(display = "CacheJndiName", advanced = true)
- public String getCacheJndiName() {
- return cacheJndiName;
- }
-
- /**
- * Set the JNDI name to a {@link Map cache} instance that should be used as this source.
- *
- * @param jndiName the JNDI name of the {@link Map cache} instance that should be used
- * @see #setCacheJndiName(String)
- */
- public void setCacheJndiName( String jndiName ) {
- this.cacheJndiName = jndiName;
- }
-
- /**
- * Call to get the class specified by calling
- * {@link #setRootClassName(String)}
- *
- * @return Class
- */
- public Class<?> getRootClass() {
- return this.rootClass;
- }
-
- /**
- * Utility method available to all implementations to find the Cache via JNDI.
- * @return Object located via JNDI
- * @throws TranslatorException
- */
- protected Object findCacheUsingJNDIName() throws TranslatorException {
-
- Object cache = null;
- String jndiName = getCacheJndiName();
- if (jndiName != null && jndiName.trim().length() != 0) {
- try {
- Context context = null;
- try {
- context = new InitialContext();
- } catch (NamingException err) {
- throw new TranslatorException(err);
- }
- cache = context.lookup(jndiName);
-
- if (cache == null) {
- String msg = ObjectPlugin.Util.getString(
- "ObjectExecutionFactory.cacheNotFoundinJNDI", //$NON-NLS-1$
- new Object[] { jndiName });
- throw new TranslatorException(msg);
-
- }
- } catch (Exception err) {
- if (err instanceof RuntimeException) throw (RuntimeException)err;
- throw new TranslatorException(err);
- }
- }
- return cache;
- }
-
- @Override
public boolean supportsOnlyLiteralComparison() {
return true;
}
+ public List<Object> search(Select query, Map<?, ?> map, Class<?> type) throws TranslatorException {
+ return SearchByKey.get(query.getWhere(), map, type);
+ }
+
}
Copied: trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/SearchByKey.java (from rev 4505, trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/infinispan/search/SearchByKey.java)
===================================================================
--- trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/SearchByKey.java (rev 0)
+++ trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/SearchByKey.java 2012-10-04 12:26:57 UTC (rev 4512)
@@ -0,0 +1,124 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.translator.object;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.infinispan.client.hotrod.RemoteCache;
+import org.teiid.core.util.Assertion;
+import org.teiid.language.Comparison;
+import org.teiid.language.Condition;
+import org.teiid.language.Expression;
+import org.teiid.language.In;
+import org.teiid.language.Literal;
+import org.teiid.language.Comparison.Operator;
+import org.teiid.logging.LogConstants;
+import org.teiid.logging.LogManager;
+import org.teiid.translator.TranslatorException;
+
+/**
+ * SearchByKey is a simple ObjectConnection that enables querying the cache by
+ * the key, using EQUI and IN clauses on the SELECT statement.
+ */
+public final class SearchByKey {
+
+ public static List<Object> get(Condition criterion,
+ Map<?, ?> cache, Class<?> rootClass)
+ throws TranslatorException {
+ List<Object> results = null;
+
+ if (criterion == null) {
+ Map<?, ?> map = cache;
+ if (cache instanceof RemoteCache<?, ?>) {
+ RemoteCache<?, ?> rc = (RemoteCache<?, ?>) cache;
+ map = (Map<Object, Object>) rc.getBulk();
+ }
+ Set<?> keys = map.keySet();
+ results = new ArrayList<Object>();
+ for (Iterator<?> it = keys.iterator(); it.hasNext();) {
+ Object v = cache.get(it.next());
+ addValue(v, results, rootClass);
+ }
+ return results;
+ }
+
+ results = new ArrayList<Object>();
+
+ if (criterion instanceof Comparison) {
+ Comparison obj = (Comparison)criterion;
+ LogManager.logTrace(LogConstants.CTX_CONNECTOR,
+ "Parsing Comparison criteria."); //$NON-NLS-1$
+ Comparison.Operator op = obj.getOperator();
+
+ Assertion.assertTrue(op == Operator.EQ);
+ Expression rhs = obj.getRightExpression();
+
+ Literal literal = (Literal)rhs;
+
+ Object v = cache.get(literal.getValue());
+ if (v != null) {
+ addValue(v, results, rootClass);
+ }
+ } else {
+ Assertion.assertTrue(criterion instanceof In, "unexpected condition " + criterion); //$NON-NLS-1$
+ In obj = (In)criterion;
+ Assertion.assertTrue(!obj.isNegated());
+ LogManager.logTrace(LogConstants.CTX_CONNECTOR, "Parsing IN criteria."); //$NON-NLS-1$
+
+ List<Expression> rhsList = obj.getRightExpressions();
+
+ for (Expression expr : rhsList) {
+ Literal literal = (Literal) expr;
+
+ Object v = cache.get(literal.getValue());
+ if (v != null) {
+ addValue(v, results, rootClass);
+ }
+ }
+ }
+ return results;
+ }
+
+ private static void addValue(Object value, List<Object> results, Class<?> rootNodeType) throws TranslatorException {
+ if (value == null) {
+ return;
+ }
+ if (!rootNodeType.isAssignableFrom(value.getClass())) {
+ // the object obtained from the cache has to be of the same root
+ // class type, otherwise, the modeling
+ // structure won't correspond correctly
+ String msg = ObjectPlugin.Util.getString(
+ "MapCacheConnection.unexpectedObjectTypeInCache", //$NON-NLS-1$
+ new Object[] { value.getClass().getName(),
+ rootNodeType.getName() });
+
+ throw new TranslatorException(msg);
+ }
+ results.add(value);
+ }
+
+}
Deleted: trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/infinispan/InfinispanBaseExecutionFactory.java
===================================================================
--- trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/infinispan/InfinispanBaseExecutionFactory.java 2012-10-03 19:05:34 UTC (rev 4511)
+++ trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/infinispan/InfinispanBaseExecutionFactory.java 2012-10-04 12:26:57 UTC (rev 4512)
@@ -1,196 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * See the COPYRIGHT.txt file distributed with this work for information
- * regarding copyright ownership. Some portions may be licensed
- * to Red Hat, Inc. under one or more contributor license agreements.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301 USA.
- */
-package org.teiid.translator.object.infinispan;
-
-import javax.resource.cci.ConnectionFactory;
-
-import org.infinispan.Cache;
-import org.infinispan.api.BasicCache;
-import org.infinispan.api.BasicCacheContainer;
-import org.infinispan.manager.CacheContainer;
-import org.infinispan.manager.DefaultCacheManager;
-import org.teiid.metadata.MetadataFactory;
-import org.teiid.translator.ExecutionContext;
-import org.teiid.translator.TranslatorException;
-import org.teiid.translator.TranslatorProperty;
-import org.teiid.translator.object.ObjectConnection;
-import org.teiid.translator.object.ObjectExecutionFactory;
-import org.teiid.translator.object.ObjectPlugin;
-
-/**
- *
- * @author vhalbert
- *
- */
-public abstract class InfinispanBaseExecutionFactory extends ObjectExecutionFactory {
-
- private String cacheName = null;
- private String configurationFileName = null;
-
- public InfinispanBaseExecutionFactory() {
- super();
- }
-
- @Override
- public void start() throws TranslatorException {
- super.start();
-
- if (this.getCacheName() == null || this.getCacheName().isEmpty()) {
- String msg = ObjectPlugin.Util.getString("InfinispanBaseExecutionFactory.cacheNameNotDefined"); //$NON-NLS-1$
- throw new TranslatorException(msg);
- }
-
- }
-
- /**
- * Will return <code>true</code> if FullText searching is supported for this implementation.
- *
- * @return True if full text searching is reported.
- */
- public abstract boolean isFullTextSearchingSupported();
-
- /**
- * Will return <code>true</code> if access to the cache is still allowed.
- * @return True if access is alive
- */
- public abstract boolean isAlive();
-
- /**
- * Method for obtaining the CacheContainer by {@link InfinispanConnectionImpl#getCache() the connection}.
- *
- * @return BasicCacheContainer
- * @throws TranslatorException
- * if there an issue obtaining the cache
- * @see #getCache()
- */
- protected abstract BasicCacheContainer getCacheContainer() throws TranslatorException;
-
-
-
- /**
- * Get the cacheName that will be used by this factory instance to access
- * the named cache. However, if not specified a default configuration will
- * be created.
- *
- * @return
- * @see #setCacheName(String)
- */
- @TranslatorProperty(display = "CacheName", advanced = true)
- public String getCacheName() {
- return this.cacheName;
- }
-
- /**
- * Set the cacheName that will be used to find the named cache.
- *
- * @param cacheName
- * @see #getCacheName()
- */
-
- public void setCacheName(String cacheName) {
- this.cacheName = cacheName;
- }
-
-
- /**
- * Get the name of the configuration resource or file that should be used if
- * a {@link Cache cache} is to be created using the
- * {@link DefaultCacheManager}. If not specified, a default configuration
- * will be used.
- *
- * @return the name of the resource or file configuration that should be
- * passed to the {@link CacheContainer}, or null if the default
- * configuration should be used
- * @see #setConfigurationFileName(String)
- */
- @TranslatorProperty(display = "ConfigurationFileName", advanced = true)
- public String getConfigurationFileName() {
- return configurationFileName;
- }
-
- /**
- * Set the name of the configuration that should be used if a {@link Cache
- * cache} is to be created using the {@link DefaultCacheManager}.
- *
- * @param configurationFileName
- * the name of the configuration file that should be used to load
- * the {@link CacheContainer}, or null if the default
- * configuration should be used
- * @see #getConfigurationFileName()
- */
- public synchronized void setConfigurationFileName(
- String configurationFileName) {
- if (this.configurationFileName == configurationFileName
- || this.configurationFileName != null
- && this.configurationFileName.equals(configurationFileName))
- return; // unchanged
- this.configurationFileName = configurationFileName;
- }
-
- public BasicCache<Object, Object> getCache() throws TranslatorException {
- BasicCache<Object, Object> cache = null;
- BasicCacheContainer container = getCacheContainer();
- if (getCacheName() != null) {
- cache = container.getCache(getCacheName());
- } else {
- cache = container.getCache();
- }
-
- if (cache == null) {
- String msg = ObjectPlugin.Util.getString(
- "InfinispanBaseExecutionFactory.cacheNotFound", new Object[] { (getCacheName() != null ? getCacheName() //$NON-NLS-1$
- : "DefaultCache") }); //$NON-NLS-1$
- throw new TranslatorException(msg);
- }
-
- return cache;
-
- }
-
- @Override
- public void getMetadata(MetadataFactory metadataFactory, ObjectConnection conn)
- throws TranslatorException {
-
- }
-
-
- @Override
- public ObjectConnection getConnection(ConnectionFactory factory,
- ExecutionContext executionContext) throws TranslatorException {
-
- return new InfinispanConnectionImpl(this);
- }
-
- public void cleanUp() {
-
- }
-
- @Override
- public boolean supportsOrCriteria() {
- return isFullTextSearchingSupported();
- }
-
- @Override
- public boolean supportsCompareCriteriaOrdered() {
- return isFullTextSearchingSupported();
- }
-}
Deleted: trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/infinispan/InfinispanConnectionImpl.java
===================================================================
--- trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/infinispan/InfinispanConnectionImpl.java 2012-10-03 19:05:34 UTC (rev 4511)
+++ trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/infinispan/InfinispanConnectionImpl.java 2012-10-04 12:26:57 UTC (rev 4512)
@@ -1,103 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * See the COPYRIGHT.txt file distributed with this work for information
- * regarding copyright ownership. Some portions may be licensed
- * to Red Hat, Inc. under one or more contributor license agreements.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301 USA.
- */
-
-package org.teiid.translator.object.infinispan;
-
-import java.util.List;
-
-import org.infinispan.api.BasicCache;
-import org.teiid.language.Select;
-import org.teiid.resource.spi.BasicConnection;
-import org.teiid.translator.TranslatorException;
-import org.teiid.translator.object.ObjectConnection;
-import org.teiid.translator.object.infinispan.search.LuceneSearch;
-import org.teiid.translator.object.infinispan.search.SearchByKey;
-
-
-/**
- * Represents an instance of a connection to an Infinispan cache. More than one connection can
- * be created to query to the cache.
- */
-public class InfinispanConnectionImpl extends BasicConnection implements ObjectConnection {
-
- private InfinispanBaseExecutionFactory factory = null;
-
- protected InfinispanConnectionImpl() {
- super();
- }
- public InfinispanConnectionImpl(InfinispanBaseExecutionFactory factory) {
- super();
- this.factory = factory;
- }
-
-
- /**
- * Close the connection, if a connection requires closing.
- * (non-Javadoc)
- */
- @Override
- public void close() {
- factory = null;
- }
-
- /**
- * Currently, this method always returns alive. We assume the connection is alive,
- * and rely on proper timeout values to automatically clean up connections before
- * any server-side timeout occurs. Rather than incur overhead by rebinding,
- * we'll assume the connection is always alive, and throw an error when it is actually used,
- * if the connection fails. This may be a more efficient way of handling failed connections,
- * with the one tradeoff that stale connections will not be detected until execution time. In
- * practice, there is no benefit to detecting stale connections before execution time.
- *
- * One possible extension is to implement a UnsolicitedNotificationListener.
- * (non-Javadoc)
- */
- public boolean isAlive() {
- return factory.isAlive();
- }
-
-
- @Override
- public void cleanUp() {
- factory = null;
-
- }
-
- public InfinispanBaseExecutionFactory getFactory() {
- return this.factory;
- }
-
- @Override
- public List<Object> performSearch(Select command)
- throws TranslatorException {
- if (factory.isFullTextSearchingSupported()) {
- return LuceneSearch.performSearch(command, this);
- }
- return SearchByKey.performSearch(command, this);
- }
-
- public BasicCache<Object, Object> getCache()
- throws TranslatorException {
- return factory.getCache();
- }
-
-}
Modified: trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/infinispan/InfinispanExecutionFactory.java
===================================================================
--- trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/infinispan/InfinispanExecutionFactory.java 2012-10-03 19:05:34 UTC (rev 4511)
+++ trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/infinispan/InfinispanExecutionFactory.java 2012-10-04 12:26:57 UTC (rev 4512)
@@ -21,16 +21,14 @@
*/
package org.teiid.translator.object.infinispan;
-import java.io.IOException;
+import java.util.List;
+import java.util.Map;
-import org.infinispan.api.BasicCacheContainer;
-import org.infinispan.manager.DefaultCacheManager;
-import org.teiid.logging.LogConstants;
-import org.teiid.logging.LogManager;
+import org.teiid.language.Select;
import org.teiid.translator.Translator;
import org.teiid.translator.TranslatorException;
import org.teiid.translator.TranslatorProperty;
-import org.teiid.translator.object.ObjectPlugin;
+import org.teiid.translator.object.ObjectExecutionFactory;
/**
* InfinispanExecutionFactory is the translator that will access an Infinispan local cache.
@@ -53,46 +51,17 @@
*
*/
@Translator(name = "infinispan-cache", description = "The Infinispan Cache Translator")
-public class InfinispanExecutionFactory extends InfinispanBaseExecutionFactory {
+public class InfinispanExecutionFactory extends ObjectExecutionFactory {
private boolean supportsLuceneSearching = false;
- protected BasicCacheContainer cacheContainer = null;
- private boolean useJndi = true;
-
public InfinispanExecutionFactory() {
super();
}
- @Override
- public void start() throws TranslatorException {
- super.start();
-
- String configFile = this.getConfigurationFileName();
- String jndiName = getCacheJndiName();
- if ( jndiName == null || jndiName.trim().length() == 0) {
- if (configFile == null || configFile.trim().length() == 0) {
- String msg = ObjectPlugin.Util
- .getString(
- "InfinispanExecutionFactory.undefinedHowToGetCache"); //$NON-NLS-1$
- throw new TranslatorException(msg);
- }
- useJndi = false;
-
- } else {
- useJndi = true;
- }
-
- }
-
- public boolean isAlive() {
- return (cacheContainer != null ? true : false);
- }
-
public boolean isFullTextSearchingSupported() {
return this.supportsLuceneSearching;
}
-
/**
* Indicates if Hibernate Search and Apache Lucene are used to index and
* search objects
@@ -108,61 +77,28 @@
this.supportsLuceneSearching = supportsLuceneSearching;
}
-
- /**
- * Method for obtaining the CacheContainer. This method will be called to
- * create a container based on the <code>configurationFileName</code>
- * specified.
- *
- * @return BasicCacheContainer
- * @throws TranslatorException
- * if there an issue obtaining the cache
- * @see #getCache()
- */
- protected synchronized BasicCacheContainer getCacheContainer()
- throws TranslatorException {
- if (this.cacheContainer != null) return this.cacheContainer;
-
- this.cacheContainer = createCacheContainer();
-
- return this.cacheContainer;
-
+ @Override
+ public boolean supportsOrCriteria() {
+ return isFullTextSearchingSupported();
}
- private BasicCacheContainer createCacheContainer() throws TranslatorException {
- BasicCacheContainer container = null;
-
- if (useJndi) {
- Object object = findCacheUsingJNDIName();
- if (object instanceof BasicCacheContainer) {
- LogManager
- .logInfo(LogConstants.CTX_CONNECTOR,
- "=== Using CacheContainer (loaded from Jndi) ==="); //$NON-NLS-1$
-
- return (BasicCacheContainer) object;
- }
- String msg = ObjectPlugin.Util.getString(
- "InfinispanExecutionFactory.unsupportedContainerType", //$NON-NLS-1$
- new Object[] { object.getClass().getName(),
- "BasicCacheContainer" }); //$NON-NLS-1$
- throw new TranslatorException(msg);
-
-
- }
- try {
- container = new DefaultCacheManager(
- this.getConfigurationFileName());
- LogManager
- .logInfo(LogConstants.CTX_CONNECTOR,
- "=== Using DefaultCacheManager (loaded by configuration) ==="); //$NON-NLS-1$
- } catch (IOException e) {
- throw new TranslatorException(e);
- }
-
- return container;
+ @Override
+ public boolean supportsCompareCriteriaOrdered() {
+ return isFullTextSearchingSupported();
}
-
- public void cleanUp() {
- this.cacheContainer = null;
+
+ @Override
+ public boolean supportsLikeCriteria() {
+ // at this point, i've been unable to get the Like to work.
+ return false;
}
+
+ @Override
+ public List<Object> search(Select query, Map<?, ?> map, Class<?> type)
+ throws TranslatorException {
+ if (this.supportsLuceneSearching) {
+ return LuceneSearch.performSearch(query, map, type);
+ }
+ return super.search(query, map, type);
+ }
}
Deleted: trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/infinispan/InfinispanRemoteExecutionFactory.java
===================================================================
--- trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/infinispan/InfinispanRemoteExecutionFactory.java 2012-10-03 19:05:34 UTC (rev 4511)
+++ trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/infinispan/InfinispanRemoteExecutionFactory.java 2012-10-04 12:26:57 UTC (rev 4512)
@@ -1,147 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * See the COPYRIGHT.txt file distributed with this work for information
- * regarding copyright ownership. Some portions may be licensed
- * to Red Hat, Inc. under one or more contributor license agreements.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301 USA.
- */
-package org.teiid.translator.object.infinispan;
-
-import org.infinispan.api.BasicCacheContainer;
-import org.infinispan.client.hotrod.RemoteCacheManager;
-import org.infinispan.manager.CacheContainer;
-import org.teiid.logging.LogConstants;
-import org.teiid.logging.LogManager;
-import org.teiid.translator.Translator;
-import org.teiid.translator.TranslatorProperty;
-
-/**
- * The InfinispanRemoteExecutionFactory is used to obtain a remote
- * {@link CacheContainer}. The {@link #getRemoteServerList() serverList} must
- * provide 1 or more <code>host:port[;host:port...]</code> combinations that
- * indicate where the remote server(s) are located.
- *
- * @author vhalbert
- *
- */
-
-@Translator(name = "infinispanremote-cache", description = "The Execution Factory for Remote Infinispan Cache")
-public class InfinispanRemoteExecutionFactory extends
- InfinispanBaseExecutionFactory {
-
- private RemoteCacheManager manager;
-
- private String remoteServerList;
-
- public InfinispanRemoteExecutionFactory() {
- super();
- }
-
- @Override
- public boolean isSourceRequired() {
- return false;
- }
-
- public boolean isAlive() {
- return (manager.isStarted());
- }
-
- public boolean isFullTextSearchingSupported() {
- return false;
- }
-
- /**
- * Get the list of remote servers that make up the Infinispan cluster. The
- * servers must be Infinispan HotRod servers. The list must be in the
- * appropriate format of <code>host:port[;host:port...]</code> that would be
- * used when defining an Infinispan {@link RemoteCacheManager} instance. If
- * the value is missing, <code>localhost:11311</code> is assumed.
- *
- * @return the names of the remote servers
- */
- @TranslatorProperty(display = "Server List", description = "Server List (host:port[;host:port...]) to connect to", advanced = true)
- public String getRemoteServerList() {
- return remoteServerList;
- }
-
- /**
- * Set the list of remote servers that make up the Infinispan cluster. The
- * servers must be Infinispan HotRod servers. The list must be in the
- * appropriate format of <code>host:port[;host:port...]</code> that would be
- * used when defining an Infinispan {@link RemoteCacheManager} instance. If
- * the value is missing, <code>localhost:11311</code> is assumed.
- *
- * @param remoteInfinispanServerList
- * the server list in appropriate
- * <code>server:port;server2:port2</code> format.
- *
- * @see #getRemoteServerList()
- */
- public void setRemoteServerList(
- String remoteInfinispanServerList) {
- if (this.remoteServerList == remoteInfinispanServerList
- || this.remoteServerList != null
- && this.remoteServerList.equals(remoteInfinispanServerList))
- return; // unchanged
- this.remoteServerList = remoteInfinispanServerList;
- }
-
- @Override
- protected synchronized BasicCacheContainer getCacheContainer() {
- if (this.manager != null) return this.manager;
-
- RemoteCacheManager container = null;
- if (this.getConfigurationFileName() != null) {
- container = new RemoteCacheManager(this.getConfigurationFileName());
-
- LogManager
- .logInfo(LogConstants.CTX_CONNECTOR,
- "=== Using RemoteCacheManager (loaded by configuration) ==="); //$NON-NLS-1$
-
- } else {
- if (this.getRemoteServerList() == null
- || this.getRemoteServerList().isEmpty()
- || this.getRemoteServerList().equals("")) { //$NON-NLS-1$
- container = new RemoteCacheManager();
-
- LogManager
- .logInfo(LogConstants.CTX_CONNECTOR,
- "=== Using RemoteCacheManager (no serverlist defined) ==="); //$NON-NLS-1$
-
- } else {
- container = new RemoteCacheManager(this.getRemoteServerList());
- LogManager
- .logInfo(LogConstants.CTX_CONNECTOR,
- "=== Using RemoteCacheManager (loaded by serverlist) ==="); //$NON-NLS-1$
-
- }
- }
-
-
- this.manager = container;
- return this.manager;
-
- }
-
- public void cleanUp() {
- if (this.manager != null) {
- manager.stop();
- }
- manager = null;
- }
-
-}
Copied: trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/infinispan/LuceneSearch.java (from rev 4505, trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/infinispan/search/LuceneSearch.java)
===================================================================
--- trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/infinispan/LuceneSearch.java (rev 0)
+++ trunk/connectors/translator-object/src/main/java/org/teiid/translator/object/infinispan/LuceneSearch.java 2012-10-04 12:26:57 UTC (rev 4512)
@@ -0,0 +1,373 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+package org.teiid.translator.object.infinispan;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.lucene.search.Query;
+import org.hibernate.search.query.dsl.BooleanJunction;
+import org.hibernate.search.query.dsl.QueryBuilder;
+import org.infinispan.Cache;
+import org.infinispan.query.CacheQuery;
+import org.infinispan.query.Search;
+import org.infinispan.query.SearchManager;
+import org.teiid.language.*;
+import org.teiid.logging.LogConstants;
+import org.teiid.logging.LogManager;
+import org.teiid.metadata.Column;
+import org.teiid.translator.TranslatorException;
+import org.teiid.translator.object.ObjectExecution;
+import org.teiid.translator.object.ObjectPlugin;
+
+/**
+ * LuceneSearch will parse the WHERE criteria and build the search query(s)
+ * that's used to retrieve the results from an Infinispan cache.
+ *
+ * Note: As of Infinispan 5.x, it doesn't support fulltext searching the RemoteCache
+ *
+ * @author vhalbert
+ *
+ */
+public final class LuceneSearch {
+
+
+ public static List<Object> performSearch(Select command, Map<?, ?> cache, Class<?> type)
+ throws TranslatorException {
+
+ SearchManager searchManager = Search
+ .getSearchManager((Cache<?, ?>) cache );
+
+ QueryBuilder queryBuilder = searchManager.buildQueryBuilderForClass(type).get();
+
+ BooleanJunction<BooleanJunction> junction = queryBuilder.bool();
+ boolean createdQueries = buildQueryFromWhereClause(command.getWhere(),
+ junction, queryBuilder);
+
+ Query query = null;
+ if (createdQueries) {
+ query = junction.createQuery();
+ } else {
+ query = queryBuilder.all().createQuery();
+ }
+
+ CacheQuery cacheQuery = searchManager.getQuery(query, type); // rootNodeType
+
+ List<Object> results = cacheQuery.list();
+ if (results == null || results.isEmpty()) {
+ return Collections.emptyList();
+ }
+
+ return results;
+ }
+
+ private static boolean buildQueryFromWhereClause(Condition criteria,
+ BooleanJunction<BooleanJunction> junction, QueryBuilder queryBuilder)
+ throws TranslatorException {
+ boolean createdQueries = false;
+ BooleanJunction<BooleanJunction> inUse = junction;
+
+ if (criteria instanceof AndOr) {
+ LogManager.logTrace(LogConstants.CTX_CONNECTOR,
+ "Parsing compound criteria."); //$NON-NLS-1$
+ AndOr crit = (AndOr) criteria;
+ AndOr.Operator op = crit.getOperator();
+
+ switch (op) {
+ case AND:
+
+ BooleanJunction<BooleanJunction> leftAnd = queryBuilder
+ .bool();
+ boolean andLeftHasQueries = buildQueryFromWhereClause(
+ crit.getLeftCondition(), leftAnd, queryBuilder);
+
+ BooleanJunction<BooleanJunction> rightAnd = queryBuilder
+ .bool();
+ boolean andRightHasQueries = buildQueryFromWhereClause(
+ crit.getRightCondition(), rightAnd, queryBuilder);
+
+ if (andLeftHasQueries && andRightHasQueries) {
+ leftAnd.must(rightAnd.createQuery());
+ inUse.should(leftAnd.createQuery());
+ } else if (andLeftHasQueries) {
+
+ inUse.should(leftAnd.createQuery());
+ } else if (andRightHasQueries) {
+ inUse.should(rightAnd.createQuery());
+ }
+
+ createdQueries = (andLeftHasQueries ? andLeftHasQueries
+ : andRightHasQueries);
+
+ break;
+
+ case OR:
+
+ boolean orLeftHasQueries = buildQueryFromWhereClause(
+ crit.getLeftCondition(), inUse, queryBuilder);
+ boolean orRightHasQueries = buildQueryFromWhereClause(
+ crit.getRightCondition(), inUse, queryBuilder);
+
+ createdQueries = (orLeftHasQueries ? orLeftHasQueries
+ : orRightHasQueries);
+
+ break;
+
+ default:
+ final String msg = ObjectPlugin.Util
+ .getString("LuceneSearch.invalidOperator", new Object[] { op, "And, Or" }); //$NON-NLS-1$ //$NON-NLS-2$
+ throw new TranslatorException(msg);
+ }
+
+ } else if (criteria instanceof Comparison) {
+ createdQueries = visit((Comparison) criteria, inUse, queryBuilder);
+
+ } else if (criteria instanceof Exists) {
+ LogManager.logTrace(LogConstants.CTX_CONNECTOR,
+ "Parsing EXISTS criteria: NOT IMPLEMENTED YET"); //$NON-NLS-1$
+ // TODO Exists should be supported in a future release.
+
+ } else if (criteria instanceof Like) {
+ createdQueries = visit((Like) criteria, inUse, queryBuilder);
+
+ } else if (criteria instanceof In) {
+ createdQueries = visit((In) criteria, inUse, queryBuilder);
+
+ }
+ // else if (criteria instanceof Not) {
+ // LogManager.logTrace(LogConstants.CTX_CONNECTOR, "Parsing NOT criteria."); //$NON-NLS-1$
+ // isNegated = true;
+ // filterList.addAll(getSearchFilterFromWhereClause(((Not)criteria).getCriteria(),
+ // new LinkedList<String>()));
+ // }
+
+ return createdQueries;
+ }
+
+ public static boolean visit(Comparison obj,
+ BooleanJunction<BooleanJunction> junction, QueryBuilder queryBuilder) throws TranslatorException {
+
+ LogManager.logTrace(LogConstants.CTX_CONNECTOR,
+ "Parsing Comparison criteria."); //$NON-NLS-1$
+ Comparison.Operator op = obj.getOperator();
+
+ Expression lhs = obj.getLeftExpression();
+ Expression rhs = obj.getRightExpression();
+
+ // joins between the objects in the same cache is not usable
+ if ((lhs instanceof ColumnReference && rhs instanceof ColumnReference)
+ || (lhs instanceof Literal && rhs instanceof Literal)) {
+ return false;
+ }
+
+ Object value = null;
+ Column mdIDElement = null;
+ Literal literal = null;
+ if (lhs instanceof ColumnReference) {
+
+ mdIDElement = ((ColumnReference) lhs).getMetadataObject();
+ literal = (Literal) rhs;
+ value = literal.getValue();
+
+ } else if (rhs instanceof ColumnReference ){
+ mdIDElement = ((ColumnReference) rhs).getMetadataObject();
+ literal = (Literal) lhs;
+ value = literal.getValue();
+ }
+
+ if (value == null) {
+ final String msg = ObjectPlugin.Util
+ .getString("LuceneSearch.unsupportedComparingByNull"); //$NON-NLS-1$
+ throw new TranslatorException(msg);
+ }
+
+ value = escapeReservedChars(value);
+ switch (op) {
+ case NE:
+ createEqualsQuery(mdIDElement, value, false, true, junction, queryBuilder);
+ break;
+
+ case EQ:
+ createEqualsQuery(mdIDElement, value, true, false, junction, queryBuilder);
+ break;
+
+ case GT:
+ createRangeAboveQuery(mdIDElement, value, junction, queryBuilder);
+ break;
+
+ case LT:
+ createRangeBelowQuery(mdIDElement, value, junction, queryBuilder);
+ break;
+
+ default:
+ final String msg = ObjectPlugin.Util
+ .getString("LuceneSearch.invalidOperator", new Object[] { op, "NE, EQ, GT, LT" }); //$NON-NLS-1$ //$NON-NLS-2$
+ throw new TranslatorException(msg);
+ }
+ return true;
+
+ }
+
+ public static boolean visit(In obj, BooleanJunction<BooleanJunction> junction, QueryBuilder queryBuilder) throws TranslatorException {
+ LogManager.logTrace(LogConstants.CTX_CONNECTOR, "Parsing IN criteria."); //$NON-NLS-1$
+
+ Expression lhs = obj.getLeftExpression();
+
+ Column mdIDElement = ((ColumnReference) lhs).getMetadataObject();
+
+ List<Expression> rhsList = obj.getRightExpressions();
+ boolean createdQuery = false;
+ for (Expression expr : rhsList) {
+
+ if (expr instanceof Literal) {
+ Literal literal = (Literal) expr;
+
+ // add these as OR queries
+ createEqualsQuery(mdIDElement,
+ escapeReservedChars(literal.getValue()), false, false,
+ junction, queryBuilder);
+ createdQuery = true;
+ } else {
+ String msg = ObjectPlugin.Util.getString(
+ "LuceneSearch.Unsupported_expression", //$NON-NLS-1$
+ new Object[] { expr, "IN" }); //$NON-NLS-1$
+ throw new TranslatorException(msg);
+ }
+ }
+ return createdQuery;
+ }
+
+ public static boolean visit(Like obj, BooleanJunction<BooleanJunction> junction, QueryBuilder queryBuilder) throws TranslatorException {
+ LogManager.logTrace(LogConstants.CTX_CONNECTOR,
+ "Parsing LIKE criteria."); //$NON-NLS-1$
+
+ Expression lhs = obj.getLeftExpression();
+ Expression rhs = obj.getRightExpression();
+
+ Column c = null;
+ Expression literalExp = null;
+ if (lhs instanceof ColumnReference) {
+ c = ((ColumnReference) lhs).getMetadataObject();
+ literalExp = rhs;
+ } else {
+ c = ((ColumnReference) rhs).getMetadataObject();
+ literalExp = lhs;
+ }
+
+ String value = null;
+ if (literalExp instanceof Literal) {
+
+ value = (String) escapeReservedChars(((Literal) literalExp)
+ .getValue());
+ createLikeQuery(c, value.replaceAll("%", ""), junction, queryBuilder); // "*" //$NON-NLS-1$ //$NON-NLS-2$
+ } else {
+ final String msg = ObjectPlugin.Util.getString(
+ "LuceneSearch.Unsupported_expression", //$NON-NLS-1$
+ new Object[] { literalExp.toString(), "LIKE" }); //$NON-NLS-1$
+ throw new TranslatorException(msg);
+ }
+
+ return true;
+ }
+
+ protected static Object escapeReservedChars(final Object value) {
+ if (value instanceof String) {
+ } else {
+ return value;
+ }
+
+ String expr = (String) value;
+
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < expr.length(); i++) {
+ char curChar = expr.charAt(i);
+ switch (curChar) {
+ case '\\':
+ sb.append("\\5c"); //$NON-NLS-1$
+ break;
+ case '*':
+ sb.append("\\2a"); //$NON-NLS-1$
+ break;
+ case '(':
+ sb.append("\\28"); //$NON-NLS-1$
+ break;
+ case ')':
+ sb.append("\\29"); //$NON-NLS-1$
+ break;
+ case '\u0000':
+ sb.append("\\00"); //$NON-NLS-1$
+ break;
+ default:
+ sb.append(curChar);
+ }
+ }
+ return sb.toString();
+ }
+
+ private static Query createEqualsQuery(Column column, Object value, boolean and,
+ boolean not, BooleanJunction<BooleanJunction> junction, QueryBuilder queryBuilder) {
+ Query queryKey = queryBuilder.keyword()
+ .onField(ObjectExecution.getNameInSource(column))
+ // .matching(value.toString() + "*")
+ .matching(value.toString()).createQuery();
+
+ if (not) {
+ junction.must(queryKey).not();
+ } else if (and) {
+ junction.must(queryKey);
+ } else {
+ junction.should(queryKey);
+ }
+ return queryKey;
+ }
+
+ private static Query createRangeAboveQuery(Column column, Object value,
+ BooleanJunction<BooleanJunction> junction, QueryBuilder queryBuilder) {
+
+ Query queryKey = queryBuilder.range()
+ .onField(ObjectExecution.getNameInSource(column))
+ .above(value.toString()).excludeLimit().createQuery();
+ junction.must(queryKey);
+ return queryKey;
+ }
+
+ private static Query createRangeBelowQuery(Column column, Object value,
+ BooleanJunction<BooleanJunction> junction, QueryBuilder queryBuilder) {
+
+ Query queryKey = queryBuilder.range()
+ .onField(ObjectExecution.getNameInSource(column))
+ .below(value.toString()).excludeLimit().createQuery();
+ junction.must(queryKey);
+ return queryKey;
+ }
+
+ private static Query createLikeQuery(Column column, String value,
+ BooleanJunction<BooleanJunction> junction, QueryBuilder queryBuilder) {
+ Query queryKey = queryBuilder.phrase()
+ .onField(ObjectExecution.getNameInSource(column)).sentence(value)
+ .createQuery();
+ junction.should(queryKey);
+ return queryKey;
+ }
+
+}
Modified: trunk/connectors/translator-object/src/main/resources/META-INF/services/org.teiid.translator.ExecutionFactory
===================================================================
--- trunk/connectors/translator-object/src/main/resources/META-INF/services/org.teiid.translator.ExecutionFactory 2012-10-03 19:05:34 UTC (rev 4511)
+++ trunk/connectors/translator-object/src/main/resources/META-INF/services/org.teiid.translator.ExecutionFactory 2012-10-04 12:26:57 UTC (rev 4512)
@@ -1,4 +1,3 @@
org.teiid.translator.object.infinispan.InfinispanExecutionFactory
-org.teiid.translator.object.infinispan.InfinispanRemoteExecutionFactory
-org.teiid.translator.object.mapcache.MapCacheExecutionFactory
+org.teiid.translator.object.ObjectExecutionFactory
Modified: trunk/connectors/translator-object/src/main/resources/org/teiid/translator/object/i18n.properties
===================================================================
--- trunk/connectors/translator-object/src/main/resources/org/teiid/translator/object/i18n.properties 2012-10-03 19:05:34 UTC (rev 4511)
+++ trunk/connectors/translator-object/src/main/resources/org/teiid/translator/object/i18n.properties 2012-10-04 12:26:57 UTC (rev 4512)
@@ -19,8 +19,6 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 USA.
#
-ObjectExecutionFactory.rootClassNameNotDefined=RootClassName is undefined
-ObjectExecutionFactory.rootClassNotFound=RootClass {0} not found to load
ObjectExecutionFactory.cacheNotFoundinJNDI=Cache was not found using JNDI name {0}
InfinispanBaseExecutionFactory.cacheNameNotDefined=CacheName is not defined
Modified: trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/BasicSearchTest.java
===================================================================
--- trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/BasicSearchTest.java 2012-10-03 19:05:34 UTC (rev 4511)
+++ trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/BasicSearchTest.java 2012-10-04 12:26:57 UTC (rev 4512)
@@ -28,6 +28,7 @@
import org.junit.Test;
import org.teiid.language.Select;
+import org.teiid.translator.TranslatorException;
import org.teiid.translator.object.util.TradesCacheSource;
import org.teiid.translator.object.util.VDBUtility;
@@ -41,35 +42,40 @@
@Test public void testQueryGetAllTrades() throws Exception {
Select command = (Select)VDBUtility.TRANSLATION_UTILITY.parseCommand("select * From Trade_Object.Trade as T"); //$NON-NLS-1$
- performTest(command, TradesCacheSource.NUMTRADES);
+ performTest(command, TradesCacheSource.NUMTRADES, 4);
}
@Test public void testTradeProjection() throws Exception {
Select command = (Select)VDBUtility.TRANSLATION_UTILITY.parseCommand("select T.TradeId From Trade_Object.Trade as T"); //$NON-NLS-1$
- performTest(command, TradesCacheSource.NUMTRADES);
+ performTest(command, TradesCacheSource.NUMTRADES, 1);
}
@Test public void testQueryGetOneTrade() throws Exception {
Select command = (Select)VDBUtility.TRANSLATION_UTILITY.parseCommand("select T.TradeId, T.Name as TradeName From Trade_Object.Trade as T WHERE T.TradeId = '1'"); //$NON-NLS-1$
- performTest(command, 1);
+ performTest(command, 1, 2);
}
@Test public void testQueryInCriteria() throws Exception {
Select command = (Select)VDBUtility.TRANSLATION_UTILITY.parseCommand("select T.TradeId, T.Name as TradeName From Trade_Object.Trade as T WHERE T.TradeId in ('1', '3')"); //$NON-NLS-1$
- performTest(command, 2);
+ performTest(command, 2, 2);
}
- protected List<Object> performTest(Select command, int rowcnt) throws Exception {
+ protected List<Object> performTest(Select command, int rowcnt, int colCount) throws Exception {
ObjectExecution exec = createExecution(command);
+ return performTest(rowcnt, colCount, exec);
+ }
+
+ static List<Object> performTest(int rowcnt, int colCount, ObjectExecution exec)
+ throws TranslatorException {
exec.execute();
List<Object> rows = new ArrayList<Object>();
@@ -79,6 +85,7 @@
while (row != null) {
rows.add(row);
+ assertEquals(colCount, row.size());
++cnt;
row = exec.next();
}
Copied: trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/TestMapCacheKeySearch.java (from rev 4505, trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/mapcache/TestMapCacheKeySearch.java)
===================================================================
--- trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/TestMapCacheKeySearch.java (rev 0)
+++ trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/TestMapCacheKeySearch.java 2012-10-04 12:26:57 UTC (rev 4512)
@@ -0,0 +1,105 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+package org.teiid.translator.object;
+
+import static org.mockito.Matchers.*;
+import static org.mockito.Mockito.*;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.naming.Context;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.teiid.language.Select;
+import org.teiid.metadata.Datatype;
+import org.teiid.metadata.MetadataFactory;
+import org.teiid.metadata.Table;
+import org.teiid.query.metadata.SystemMetadata;
+import org.teiid.translator.ExecutionContext;
+import org.teiid.translator.TranslatorException;
+import org.teiid.translator.object.util.TradesCacheSource;
+import org.teiid.translator.object.util.VDBUtility;
+
+
+@SuppressWarnings("nls")
+public class TestMapCacheKeySearch extends BasicSearchTest {
+
+ protected static final String JNDI_NAME = "java/MyCacheManager";
+
+ private static TradesCacheSource source = TradesCacheSource.loadCache();
+ private static ExecutionContext context;
+
+ private ObjectExecutionFactory factory = null;
+
+ @Mock
+ private static Context jndi;
+
+ protected static boolean print = false;
+
+ @BeforeClass
+ public static void beforeEachClass() throws Exception {
+
+ context = mock(ExecutionContext.class);
+
+ // Set up the mock JNDI ...
+ jndi = mock(Context.class);
+ when(jndi.lookup(anyString())).thenReturn(null);
+ when(jndi.lookup(JNDI_NAME)).thenReturn(source);
+
+ }
+
+ @Before public void beforeEach() throws Exception{
+
+ factory = new ObjectExecutionFactory();
+
+ factory.start();
+
+ }
+
+ @Override
+ protected ObjectExecution createExecution(Select command) throws TranslatorException {
+ return (ObjectExecution) factory.createExecution(command, context, VDBUtility.RUNTIME_METADATA, source);
+ }
+
+ @Ignore
+ @Test public void testGetMetadata() throws Exception {
+
+ Map<String, Datatype> dts = SystemMetadata.getInstance().getSystemStore().getDatatypes();
+
+ MetadataFactory mfactory = new MetadataFactory("TestVDB", 1, "Trade", dts, new Properties(), null);
+
+ factory.getMetadata(mfactory, null);
+
+ Map<String, Table> tables = mfactory.getSchema().getTables();
+ for (Iterator<Table> it=tables.values().iterator(); it.hasNext();) {
+ Table t = it.next();
+ }
+
+ }
+
+}
Deleted: trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/TestObjectExecution.java
===================================================================
--- trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/TestObjectExecution.java 2012-10-03 19:05:34 UTC (rev 4511)
+++ trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/TestObjectExecution.java 2012-10-04 12:26:57 UTC (rev 4512)
@@ -1,132 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * See the COPYRIGHT.txt file distributed with this work for information
- * regarding copyright ownership. Some portions may be licensed
- * to Red Hat, Inc. under one or more contributor license agreements.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301 USA.
- */
-package org.teiid.translator.object;
-
-import static org.junit.Assert.*;
-import static org.mockito.Matchers.*;
-import static org.mockito.Mockito.*;
-
-import java.util.List;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.teiid.language.Select;
-import org.teiid.translator.ExecutionContext;
-import org.teiid.translator.object.util.TradesCacheSource;
-import org.teiid.translator.object.util.VDBUtility;
-
-@SuppressWarnings("nls")
-public class TestObjectExecution {
-
-
- private static TradesCacheSource source = TradesCacheSource.loadCache();
- private static ObjectExecutionFactory factory;
-
- @Mock
- private ExecutionContext context;
- @Mock
- private ObjectConnection connection;
-
- @Before public void beforeEach() throws Exception{
-
- MockitoAnnotations.initMocks(this);
-
- when(connection.performSearch(any(Select.class))).thenReturn(source.getAll());
-
-
- factory = new ObjectExecutionFactory() { };
- factory.setRootClassName(TradesCacheSource.TRADE_CLASS_NAME);
-
- factory.start();
-
- }
-
-
- @Test public void testQueryRootObject() throws Exception {
- execute( createExecution("select * From Trade_Object.Trade"), 3, 4);
- }
-
- @Test public void testAtomicSelects() throws Exception {
-
- Thread[] threads = new Thread[20];
- for (int i = 0; i < threads.length; i++) {
- threads[i] = new Thread() {
- public void run() {
- for (int i=0; i<1000; i++) {
- test();
- }
- }
- public void test() {
- ObjectExecution exec = null;
- try {
- exec = createExecution("select * From Trade_Object.Trade");
- execute(exec, 3, 1);
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- if (exec != null) exec.close();
- }
- }
- };
-
- threads[i].start();
- }
- for (int i = 0; i < threads.length; i++) {
- try {
- threads[i].join();
- } catch (InterruptedException ignore) {}
- }
- }
-
- private ObjectExecution createExecution(String sql) throws Exception {
- Select command = (Select)VDBUtility.TRANSLATION_UTILITY.parseCommand(sql); //$NON-NLS-1$
-
- ObjectExecution exec = (ObjectExecution) factory.createExecution(command, context, VDBUtility.RUNTIME_METADATA, connection);
-
- return exec;
-
- }
-
- private void execute(ObjectExecution exec, int expected, int columns) throws Exception {
-
- exec.execute();
-
- int cnt = 0;
- List<?> row = exec.next();
-
- // check the number of columns
- assertEquals("Number of columns is incorrect", columns, row.size());
-
-
- while (row != null) {
- ++cnt;
- row = exec.next();
- }
- assertEquals("Did not get expected number of rows", expected, cnt); //$NON-NLS-1$
-
-
- exec.close();
- }
-
-}
Modified: trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/TestObjectExecutionFactory.java
===================================================================
--- trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/TestObjectExecutionFactory.java 2012-10-03 19:05:34 UTC (rev 4511)
+++ trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/TestObjectExecutionFactory.java 2012-10-04 12:26:57 UTC (rev 4512)
@@ -21,7 +21,7 @@
*/
package org.teiid.translator.object;
-import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.*;
import java.util.Properties;
@@ -33,7 +33,6 @@
import org.teiid.metadata.MetadataFactory;
import org.teiid.query.metadata.SystemMetadata;
import org.teiid.translator.ExecutionContext;
-import org.teiid.translator.object.testdata.Trade;
import org.teiid.translator.object.util.VDBUtility;
@SuppressWarnings("nls")
@@ -62,8 +61,6 @@
}
@Test public void testFactory() throws Exception {
- factory.setRootClassName(Trade.class.getName());
-
factory.start();
ObjectExecution exec = (ObjectExecution) factory.createExecution(command, context, VDBUtility.RUNTIME_METADATA, null);
@@ -72,10 +69,6 @@
}
@Test public void testFactoryLoadingJarClassNames() throws Exception {
-
-
- factory.setRootClassName(Trade.class.getName());
-
factory.start();
ObjectExecution exec = (ObjectExecution) factory.createExecution(command, context, VDBUtility.RUNTIME_METADATA, null);
@@ -87,8 +80,6 @@
@Test public void testGetMetadata() throws Exception {
MetadataFactory mfactory = new MetadataFactory("TestVDB", 1, "Trade", SystemMetadata.getInstance().getRuntimeTypeMap(), new Properties(), null);
-
- factory.setRootClassName(Trade.class.getName());
factory.start();
Modified: trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/infinispan/RemoteInfinispanTestHelper.java
===================================================================
--- trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/infinispan/RemoteInfinispanTestHelper.java 2012-10-03 19:05:34 UTC (rev 4511)
+++ trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/infinispan/RemoteInfinispanTestHelper.java 2012-10-04 12:26:57 UTC (rev 4512)
@@ -43,7 +43,7 @@
private static int count = 0;
private static DefaultCacheManager CACHEMANAGER = null;
- public static synchronized HotRodServer createServer() throws IOException {
+ public static synchronized HotRodServer createServer() {
count++;
if (server == null) {
Configuration c = new ConfigurationBuilder().clustering().cacheMode(CacheMode.REPL_SYNC).eviction().maxEntries(7).build();
Modified: trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/infinispan/TestInfinispanConfigFileKeySearch.java
===================================================================
--- trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/infinispan/TestInfinispanConfigFileKeySearch.java 2012-10-03 19:05:34 UTC (rev 4511)
+++ trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/infinispan/TestInfinispanConfigFileKeySearch.java 2012-10-04 12:26:57 UTC (rev 4512)
@@ -23,22 +23,49 @@
import static org.mockito.Mockito.*;
+import java.util.Map;
+
+import org.infinispan.manager.CacheContainer;
+import org.infinispan.manager.DefaultCacheManager;
import org.junit.BeforeClass;
import org.teiid.language.Select;
import org.teiid.translator.ExecutionContext;
import org.teiid.translator.TranslatorException;
import org.teiid.translator.object.BasicSearchTest;
+import org.teiid.translator.object.ObjectConnection;
import org.teiid.translator.object.ObjectExecution;
+import org.teiid.translator.object.testdata.Trade;
import org.teiid.translator.object.util.TradesCacheSource;
import org.teiid.translator.object.util.VDBUtility;
@SuppressWarnings("nls")
public class TestInfinispanConfigFileKeySearch extends BasicSearchTest {
+ static final class InfinispanConnection implements ObjectConnection {
+ private final CacheContainer container;
+
+ InfinispanConnection(CacheContainer container) {
+ this.container = container;
+ }
+
+ @Override
+ public Class<?> getType(String name) throws TranslatorException {
+ return Trade.class;
+ }
+
+ @Override
+ public Map<?, ?> getMap(String name) throws TranslatorException {
+ //the real connection should use the name in source to get the cache
+ return container.getCache(TradesCacheSource.TRADES_CACHE_NAME);
+ }
+ }
+
private static ExecutionContext context;
private static InfinispanExecutionFactory factory = null;
+
+ private static ObjectConnection conn;
@BeforeClass
@@ -49,20 +76,18 @@
factory = new InfinispanExecutionFactory();
- factory.setConfigurationFileName("./src/test/resources/infinispan_persistent_config.xml");
+ final DefaultCacheManager container = new DefaultCacheManager("./src/test/resources/infinispan_persistent_config.xml");
- factory.setCacheName(TradesCacheSource.TRADES_CACHE_NAME);
- factory.setRootClassName(TradesCacheSource.TRADE_CLASS_NAME);
factory.start();
- TradesCacheSource.loadCache(factory.getCacheContainer().getCache(TradesCacheSource.TRADES_CACHE_NAME));
+ TradesCacheSource.loadCache(container.getCache(TradesCacheSource.TRADES_CACHE_NAME));
-
+ conn = new InfinispanConnection(container);
}
@Override
protected ObjectExecution createExecution(Select command) throws TranslatorException {
- return (ObjectExecution) factory.createExecution(command, context, VDBUtility.RUNTIME_METADATA, null);
+ return (ObjectExecution) factory.createExecution(command, context, VDBUtility.RUNTIME_METADATA, conn);
}
}
Modified: trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/infinispan/TestInfinispanJndiILuceneSearch.java
===================================================================
--- trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/infinispan/TestInfinispanJndiILuceneSearch.java 2012-10-03 19:05:34 UTC (rev 4511)
+++ trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/infinispan/TestInfinispanJndiILuceneSearch.java 2012-10-04 12:26:57 UTC (rev 4512)
@@ -32,6 +32,7 @@
import org.teiid.translator.ExecutionContext;
import org.teiid.translator.TranslatorException;
import org.teiid.translator.object.BasicSearchTest;
+import org.teiid.translator.object.ObjectConnection;
import org.teiid.translator.object.ObjectExecution;
import org.teiid.translator.object.util.TradesCacheSource;
import org.teiid.translator.object.util.VDBUtility;
@@ -40,7 +41,7 @@
public class TestInfinispanJndiILuceneSearch extends BasicSearchTest {
private static CacheContainer container = null;
private static ExecutionContext context;
-
+ private static ObjectConnection conn;
private InfinispanExecutionFactory factory = null;
@BeforeClass
@@ -49,80 +50,68 @@
container = new DefaultCacheManager("infinispan_persistent_indexing_config.xml");
TradesCacheSource.loadCache(container.getCache(TradesCacheSource.TRADES_CACHE_NAME));
+
+ conn = new TestInfinispanConfigFileKeySearch.InfinispanConnection(container);
+
context = mock(ExecutionContext.class);
}
@Before public void beforeEachTest() throws Exception{
-
- factory = new InfinispanExecutionFactory() {
-
- @Override
- protected Object findCacheUsingJNDIName()
- throws TranslatorException {
- return container;
- }
-
- };
-
- factory.setCacheJndiName("JNDINAME");
- factory.setCacheName(TradesCacheSource.TRADES_CACHE_NAME);
- factory.setRootClassName(TradesCacheSource.TRADE_CLASS_NAME);
+ factory = new InfinispanExecutionFactory();
factory.setSupportsLuceneSearching(true);
factory.start();
-
-
}
@Override
protected ObjectExecution createExecution(Select command) throws TranslatorException {
- return (ObjectExecution) factory.createExecution(command, context, VDBUtility.RUNTIME_METADATA, null);
+ return (ObjectExecution) factory.createExecution(command, context, VDBUtility.RUNTIME_METADATA, conn);
}
@Test public void testQueryLikeCriteria1() throws Exception {
Select command = (Select)VDBUtility.TRANSLATION_UTILITY.parseCommand("select T.TradeId, T.Name From Trade_Object.Trade as T WHERE T.Name like 'TradeName%'"); //$NON-NLS-1$
- performTest(command, 3);
+ performTest(command, 3, 2);
}
@Test public void testQueryLikeCriteria2() throws Exception {
Select command = (Select)VDBUtility.TRANSLATION_UTILITY.parseCommand("select T.TradeId, T.Name From Trade_Object.Trade as T WHERE T.Name like 'TradeName 2%'"); //$NON-NLS-1$
- performTest(command, 1);
+ performTest(command, 1, 2);
}
@Test public void testQueryCompareEQBoolean() throws Exception {
Select command = (Select)VDBUtility.TRANSLATION_UTILITY.parseCommand("select T.TradeId, T.Name, T.Settled From Trade_Object.Trade as T WHERE T.Settled = 'false'"); //$NON-NLS-1$
- performTest(command, 2);
+ performTest(command, 2, 3);
}
@Test public void testQueryCompareNEBoolean() throws Exception {
Select command = (Select)VDBUtility.TRANSLATION_UTILITY.parseCommand("select T.TradeId, T.Name, T.Settled From Trade_Object.Trade as T WHERE T.Settled <> 'false'"); //$NON-NLS-1$
- performTest(command, 1);
+ performTest(command, 1, 3);
}
@Test public void testQueryRangeBetween() throws Exception {
Select command = (Select)VDBUtility.TRANSLATION_UTILITY.parseCommand("select T.TradeId, T.Name as TradeName From Trade_Object.Trade as T WHERE T.TradeId > '1' and T.TradeId < '3'"); //$NON-NLS-1$
- performTest(command, 1);
+ performTest(command, 1, 2);
}
@Test public void testQueryRangeAbove() throws Exception {
Select command = (Select)VDBUtility.TRANSLATION_UTILITY.parseCommand("select T.TradeId, T.Name as TradeName From Trade_Object.Trade as T WHERE T.TradeId > '1'"); //$NON-NLS-1$
- performTest(command, 2);
+ performTest(command, 2, 2);
}
@Test public void testQueryRangeBelow() throws Exception {
Select command = (Select)VDBUtility.TRANSLATION_UTILITY.parseCommand("select T.TradeId, T.Name as TradeName From Trade_Object.Trade as T WHERE T.TradeId < '2'"); //$NON-NLS-1$
- performTest(command, 1);
+ performTest(command, 1, 2);
}
@Test public void testQueryAnd() throws Exception {
Select command = (Select)VDBUtility.TRANSLATION_UTILITY.parseCommand("select T.TradeId, T.Name as TradeName From Trade_Object.Trade as T WHERE T.TradeId > '1' and T.Settled = 'false' "); //$NON-NLS-1$
- performTest(command, 1);
+ performTest(command, 1, 2);
}
}
Deleted: trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/infinispan/TestInfinispanJndiKeySearch.java
===================================================================
--- trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/infinispan/TestInfinispanJndiKeySearch.java 2012-10-03 19:05:34 UTC (rev 4511)
+++ trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/infinispan/TestInfinispanJndiKeySearch.java 2012-10-04 12:26:57 UTC (rev 4512)
@@ -1,78 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * See the COPYRIGHT.txt file distributed with this work for information
- * regarding copyright ownership. Some portions may be licensed
- * to Red Hat, Inc. under one or more contributor license agreements.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301 USA.
- */
-package org.teiid.translator.object.infinispan;
-
-import static org.mockito.Mockito.*;
-
-import org.infinispan.manager.CacheContainer;
-import org.infinispan.manager.DefaultCacheManager;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.teiid.language.Select;
-import org.teiid.translator.ExecutionContext;
-import org.teiid.translator.TranslatorException;
-import org.teiid.translator.object.BasicSearchTest;
-import org.teiid.translator.object.ObjectExecution;
-import org.teiid.translator.object.util.TradesCacheSource;
-import org.teiid.translator.object.util.VDBUtility;
-
-@SuppressWarnings("nls")
-public class TestInfinispanJndiKeySearch extends BasicSearchTest {
- private static CacheContainer container = null;
- private static ExecutionContext context;
-
- private InfinispanExecutionFactory factory = null;
-
- @BeforeClass
- public static void beforeEachClass() throws Exception {
- // Create the cache manager ...
- container = new DefaultCacheManager("infinispan_persistent_config.xml");
-
- TradesCacheSource.loadCache(container.getCache(TradesCacheSource.TRADES_CACHE_NAME));
- context = mock(ExecutionContext.class);
-
- }
-
- @Before public void beforeEachTest() throws Exception{
-
- factory = new InfinispanExecutionFactory() {
-
- @Override
- protected Object findCacheUsingJNDIName()
- throws TranslatorException {
- return container;
- }
-
- };
-
- factory.setCacheJndiName("JNDINAME");
- factory.setCacheName(TradesCacheSource.TRADES_CACHE_NAME);
- factory.setRootClassName(TradesCacheSource.TRADE_CLASS_NAME);
- factory.start();
- }
-
- @Override
- protected ObjectExecution createExecution(Select command) throws TranslatorException {
- return (ObjectExecution) factory.createExecution(command, context, VDBUtility.RUNTIME_METADATA, null);
- }
-
-}
Deleted: trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/infinispan/TestInfinispanRemoteJndiKeySearch.java
===================================================================
--- trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/infinispan/TestInfinispanRemoteJndiKeySearch.java 2012-10-03 19:05:34 UTC (rev 4511)
+++ trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/infinispan/TestInfinispanRemoteJndiKeySearch.java 2012-10-04 12:26:57 UTC (rev 4512)
@@ -1,100 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * See the COPYRIGHT.txt file distributed with this work for information
- * regarding copyright ownership. Some portions may be licensed
- * to Red Hat, Inc. under one or more contributor license agreements.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301 USA.
- */
-package org.teiid.translator.object.infinispan;
-
-import static org.junit.Assert.*;
-import static org.mockito.Matchers.*;
-import static org.mockito.Mockito.*;
-
-import javax.naming.Context;
-
-import org.infinispan.client.hotrod.RemoteCacheManager;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Ignore;
-import org.mockito.Mock;
-import org.teiid.language.Select;
-import org.teiid.translator.ExecutionContext;
-import org.teiid.translator.object.BasicSearchTest;
-import org.teiid.translator.object.ObjectExecution;
-import org.teiid.translator.object.util.TradesCacheSource;
-import org.teiid.translator.object.util.VDBUtility;
-
-@SuppressWarnings("nls")
-@Ignore
-public class TestInfinispanRemoteJndiKeySearch extends BasicSearchTest {
- protected static final String JNDI_NAME = "java/MyCacheManager";
-
- private static RemoteCacheManager container = null;
- private static ExecutionContext context;
-
-
- private InfinispanRemoteExecutionFactory factory = null;
-
- @Mock
- private static Context jndi;
-
- @BeforeClass
- public static void beforeEachClass() throws Exception {
- RemoteInfinispanTestHelper.createServer();
- // Create the cache manager ...
-
- // Set up the mock JNDI ...
- jndi = mock(Context.class);
- when(jndi.lookup(anyString())).thenReturn(null);
-
- context = mock(ExecutionContext.class);
-
-
- }
-
- @Before public void beforeEachTest() throws Exception{
-
- factory = new InfinispanRemoteExecutionFactory();
-
- factory.setRemoteServerList(RemoteInfinispanTestHelper.hostAddress() + ":" + RemoteInfinispanTestHelper.hostPort());
- factory.setCacheName(TradesCacheSource.TRADES_CACHE_NAME);
- factory.setRootClassName(TradesCacheSource.TRADE_CLASS_NAME);
- factory.start();
-
- }
-
- @AfterClass
- public static void closeConnection() throws Exception {
- RemoteInfinispanTestHelper.releaseServer();
- }
-
- @Override
- protected ObjectExecution createExecution(Select command)
- throws Exception {
- when(jndi.lookup(JNDI_NAME)).thenReturn(container);
-
- Object t = RemoteInfinispanTestHelper.getCacheManager().getCache(TradesCacheSource.TRADES_CACHE_NAME).get("1");
-
- assertNotNull(t);
-
- return (ObjectExecution) factory.createExecution(command, context, VDBUtility.RUNTIME_METADATA, null);
- }
-
-
-}
Deleted: trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/mapcache/TestMapCacheKeySearch.java
===================================================================
--- trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/mapcache/TestMapCacheKeySearch.java 2012-10-03 19:05:34 UTC (rev 4511)
+++ trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/mapcache/TestMapCacheKeySearch.java 2012-10-04 12:26:57 UTC (rev 4512)
@@ -1,124 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * See the COPYRIGHT.txt file distributed with this work for information
- * regarding copyright ownership. Some portions may be licensed
- * to Red Hat, Inc. under one or more contributor license agreements.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301 USA.
- */
-package org.teiid.translator.object.mapcache;
-
-import static org.mockito.Matchers.*;
-import static org.mockito.Mockito.*;
-
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Properties;
-
-import javax.naming.Context;
-
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.teiid.language.Select;
-import org.teiid.metadata.MetadataFactory;
-import org.teiid.metadata.Table;
-import org.teiid.query.metadata.SystemMetadata;
-import org.teiid.translator.ExecutionContext;
-import org.teiid.translator.TranslatorException;
-import org.teiid.translator.object.BasicSearchTest;
-import org.teiid.translator.object.ObjectExecution;
-import org.teiid.translator.object.util.TradesCacheSource;
-import org.teiid.translator.object.util.VDBUtility;
-
-
-@SuppressWarnings("nls")
-public class TestMapCacheKeySearch extends BasicSearchTest {
-
- protected static final String JNDI_NAME = "java/MyCacheManager";
-
- private static TradesCacheSource source = TradesCacheSource.loadCache();
- private static ExecutionContext context;
-
- private MapCacheExecutionFactory factory = null;
-
- @Mock
- private static Context jndi;
-
- protected static boolean print = false;
-
- @BeforeClass
- public static void beforeEachClass() throws Exception {
-
- context = mock(ExecutionContext.class);
-
- // Set up the mock JNDI ...
- jndi = mock(Context.class);
- when(jndi.lookup(anyString())).thenReturn(null);
- when(jndi.lookup(JNDI_NAME)).thenReturn(source);
-
- }
-
- @Before public void beforeEach() throws Exception{
-
- factory = new MapCacheExecutionFactory() {
-
- @Override
- protected Map<?, ?> getCache() throws TranslatorException {
- return source;
- }
-
- };
-
- factory.setCacheJndiName(JNDI_NAME);
- factory.setRootClassName(TradesCacheSource.TRADE_CLASS_NAME);
- factory.start();
-
- }
-
- @Override
- protected ObjectExecution createExecution(Select command) throws TranslatorException {
- return (ObjectExecution) factory.createExecution(command, context, VDBUtility.RUNTIME_METADATA, null);
- }
-
- @Test public void testGetMetadata() throws Exception {
-
- Map dts = SystemMetadata.getInstance().getSystemStore().getDatatypes();
-
- MetadataFactory mfactory = new MetadataFactory("TestVDB", 1, "Trade", dts, new Properties(), null);
-
- MapCacheExecutionFactory factory = new MapCacheExecutionFactory() {
-
- };
-
- factory.setCacheJndiName(JNDI_NAME);
- factory.setRootClassName(TradesCacheSource.TRADE_CLASS_NAME);
- factory.start();
-
- factory.getMetadata(mfactory, null);
-
- Map<String, Table> tables = mfactory.getSchema().getTables();
- for (Iterator<Table> it=tables.values().iterator(); it.hasNext();) {
- Table t = it.next();
- System.out.println(t.getName() + " - " + (t.getSelectTransformation() != null ? t.getSelectTransformation() : t.getSQLString()));
- }
-
- }
-
-
-
-}
Modified: trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/util/TradesCacheSource.java
===================================================================
--- trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/util/TradesCacheSource.java 2012-10-03 19:05:34 UTC (rev 4511)
+++ trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/util/TradesCacheSource.java 2012-10-04 12:26:57 UTC (rev 4512)
@@ -29,6 +29,8 @@
import java.util.Map;
import org.infinispan.api.BasicCache;
+import org.teiid.translator.TranslatorException;
+import org.teiid.translator.object.ObjectConnection;
import org.teiid.translator.object.testdata.Leg;
import org.teiid.translator.object.testdata.Trade;
import org.teiid.translator.object.testdata.Transaction;
@@ -40,8 +42,8 @@
* @author vhalbert
*
*/
-@SuppressWarnings("rawtypes")
-public class TradesCacheSource extends HashMap <Object, Object> {
+@SuppressWarnings("nls")
+public class TradesCacheSource extends HashMap <Object, Object> implements ObjectConnection {
/**
*
@@ -146,4 +148,14 @@
objs.add(super.get(key));
return objs;
}
+
+ @Override
+ public Map<?, ?> getMap(String name) throws TranslatorException {
+ return this;
+ }
+
+ @Override
+ public Class<?> getType(String name) throws TranslatorException {
+ return Trade.class;
+ }
}
Modified: trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/util/VDBUtility.java
===================================================================
--- trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/util/VDBUtility.java 2012-10-03 19:05:34 UTC (rev 4511)
+++ trunk/connectors/translator-object/src/test/java/org/teiid/translator/object/util/VDBUtility.java 2012-10-04 12:26:57 UTC (rev 4512)
@@ -27,7 +27,7 @@
import org.teiid.core.util.UnitTestUtil;
import org.teiid.metadata.RuntimeMetadata;
-
+@SuppressWarnings("nls")
public class VDBUtility {
public static TranslationUtility TRANSLATION_UTILITY = null;
Modified: trunk/engine/src/main/java/org/teiid/query/function/FunctionMethods.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/FunctionMethods.java 2012-10-03 19:05:34 UTC (rev 4511)
+++ trunk/engine/src/main/java/org/teiid/query/function/FunctionMethods.java 2012-10-04 12:26:57 UTC (rev 4512)
@@ -59,6 +59,7 @@
import org.teiid.core.types.InputStreamFactory.BlobInputStreamFactory;
import org.teiid.core.types.InputStreamFactory.ClobInputStreamFactory;
import org.teiid.core.util.PropertiesUtils;
+import org.teiid.core.util.StringUtil;
import org.teiid.core.util.TimestampWithTimezone;
import org.teiid.language.SQLConstants;
import org.teiid.language.SQLConstants.NonReserved;
@@ -799,37 +800,7 @@
// ================== Function = replace =====================
public static Object replace(String string, String subString, String replaceString) {
- // Check some simple cases that require no work
- if(subString.length() > string.length() || string.length() == 0 || subString.length() == 0) {
- return string;
- }
-
- StringBuffer result = new StringBuffer();
- int index = 0;
-
- while(true) {
- int newIndex = string.indexOf(subString, index);
- if(newIndex < 0) {
- // No more replacement sections, grab from old index to end of string
- result.append( string.substring(index));
-
- // Break out of loop
- break;
-
- }
- // Matched the substring at newIndex
-
- // First append section from old index to new
- result.append( string.substring( index, newIndex));
-
- // Then append replacement section for sub
- result.append( replaceString );
-
- // Then move the index counter forward
- index = newIndex + subString.length();
- }
-
- return result.toString();
+ return StringUtil.replaceAll(string, subString, replaceString);
}
// ================== Function = insert =====================
12 years, 2 months
teiid SVN: r4511 - in trunk: common-core/src/test/java/org/teiid/core/util and 3 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2012-10-03 15:05:34 -0400 (Wed, 03 Oct 2012)
New Revision: 4511
Modified:
trunk/common-core/src/main/java/org/teiid/core/util/StringUtil.java
trunk/common-core/src/test/java/org/teiid/core/util/TestStringUtil.java
trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/IQueryToLdapSearchParser.java
trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPDirectCreateUpdateDeleteQueryExecution.java
trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPDirectSearchQueryExecution.java
trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPExecutionFactory.java
trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPPlugin.java
trunk/connectors/translator-ldap/src/main/resources/org/teiid/translator/ldap/i18n.properties
trunk/connectors/translator-ldap/src/test/java/org/teiid/translator/ldap/TestIQueryToLdapSearchParser.java
trunk/connectors/translator-ldap/src/test/java/org/teiid/translator/ldap/TestLDAPDirectQueryExecution.java
Log:
TEIID-2177 adding ldap canned queries
Modified: trunk/common-core/src/main/java/org/teiid/core/util/StringUtil.java
===================================================================
--- trunk/common-core/src/main/java/org/teiid/core/util/StringUtil.java 2012-10-03 16:54:06 UTC (rev 4510)
+++ trunk/common-core/src/main/java/org/teiid/core/util/StringUtil.java 2012-10-03 19:05:34 UTC (rev 4511)
@@ -109,18 +109,6 @@
return LINE_SEPARATOR;
}
- /**
- * Utility to return a string enclosed in ''.
- * Creation date: (12/2/99 12:05:10 PM)
- */
- public static String enclosedInSingleQuotes(String aString) {
- StringBuffer sb = new StringBuffer();
- sb.append(SINGLE_QUOTE);
- sb.append(aString);
- sb.append(SINGLE_QUOTE);
- return sb.toString();
- }
-
/**
* Join string pieces and separate with a delimiter. Similar to the perl function of
* the same name. If strings or delimiter are null, null is returned. Otherwise, at
@@ -131,7 +119,7 @@
* @param delimiter Delimiter to put between string pieces
* @return One merged string
*/
- public static String join(List strings, String delimiter) {
+ public static String join(List<String> strings, String delimiter) {
if(strings == null || delimiter == null) {
return null;
}
@@ -147,7 +135,7 @@
// put the piece and a delimiter after it. An iterator is used to walk the list.
int most = strings.size()-1;
if(strings.size() > 1) {
- Iterator iter = strings.iterator();
+ Iterator<String> iter = strings.iterator();
for(int i=0; i<most; i++) {
str.append(iter.next());
str.append(delimiter);
@@ -215,64 +203,6 @@
return l;
}
- /**
- * Break a string into pieces based on matching the full delimiter string in the text.
- * The delimiter is not included in the returned strings.
- * @param target The text to break up.
- * @param delimiter The sub-string which is used to break the target.
- * @return List of String from the target.
- */
- public static List<String> splitOnEntireString(String target, String delimiter) {
- ArrayList<String> result = new ArrayList<String>();
- if (delimiter.length() > 0) {
- int index = 0;
- int indexOfNextMatch = target.indexOf(delimiter);
- while (indexOfNextMatch > -1) {
- result.add(target.substring(index, indexOfNextMatch));
- index = indexOfNextMatch + delimiter.length();
- indexOfNextMatch = target.indexOf(delimiter, index);
- }
- if (index <= target.length()) {
- result.add(target.substring(index));
- }
- } else {
- result.add(target);
- }
- return result;
- }
-
- /**
- * Split a string into pieces based on delimiters preserving spaces in
- * quoted substring as on element in the returned list. The delimiters are
- * not included in the returned strings.
- * @see #join
- *
- * @param str Full string
- * @param splitter Characters to split on
- * @return List of String pieces from full string
- */
- public static List splitPreservingQuotedSubstring(String str, String splitter) {
- ArrayList l = new ArrayList();
- StringTokenizer tokens = new StringTokenizer(str, splitter);
- StringBuffer token = new StringBuffer();
- while(tokens.hasMoreTokens()) {
- token.setLength(0);
- token.append(tokens.nextToken());
- if ( token.charAt(0) == '"' ) {
- token.deleteCharAt(0);
- while ( tokens.hasMoreTokens() ) {
- token.append(Constants.SPACE + tokens.nextToken());
- if ( token.charAt(token.length() -1) == '"' ) {
- token.deleteCharAt(token.length() - 1);
- break;
- }
- }
- }
- l.add(token.toString().trim());
- }
- return l;
- }
-
/*
* Replace a single occurrence of the search string with the replace string
* in the source string. If any of the strings is null or the search string
@@ -353,10 +283,10 @@
if (strLength > maxCharPerLine) {
StringBuffer sb = new StringBuffer(str.length()+(strLength/maxCharPerLine)+1);
strLength = 0;
- List tokens = StringUtil.split(str,Constants.SPACE);
- Iterator itr = tokens.iterator();
+ List<String> tokens = StringUtil.split(str,Constants.SPACE);
+ Iterator<String> itr = tokens.iterator();
while (itr.hasNext()) {
- String token = (String) itr.next();
+ String token = itr.next();
if ( strLength+token.length() > maxCharPerLine ) {
// sb.append(getLineSeparator());
sb.append(Constants.NEW_LINE);
@@ -389,36 +319,6 @@
return l;
}
- /**
- * Return the number of tokens in a string that are seperated by the delimiter.
- *
- * @param str String to be tokenized
- * @param delimiter Characters which are delimit tokens
- * @return Number of tokens seperated by the delimiter
- */
- public static int getTokenCount(String str, String delimiter) {
- StringTokenizer tokens = new StringTokenizer(str, delimiter);
- return tokens.countTokens();
- }
-
- /**
- * Return the number of occurrences of token string that occurs in input string.
- * Note: token is case sensitive.
- *
- * @param input
- * @param token
- * @return int
- */
- public static int occurrences(String input, String token) {
- int num = 0;
- int index = input.indexOf(token);
- while (index >= 0) {
- num++;
- index = input.indexOf(token, index+1);
- }
- return num;
- }
-
/**
* Return the last token in the string.
*
@@ -473,32 +373,6 @@
* <li>"SQLIndexT" is converted to "SQL Index T"</li>
* <li>"SQLIndex T" is converted to "SQL Index T"</li>
* <li>"SQLIndex t" is converted to "SQL Index T"</li>
- *
- * @param str String to be converted; may be null
- * @return the displayable form of <code>str</code>, or an empty string if
- * <code>str</code> is either null or zero-length; never null
- */
- public static String computeDisplayableForm(String str) {
- return computeDisplayableForm(str, Constants.EMPTY_STRING);
- }
-
- /**
- * Compute a displayable form of the specified string. This algorithm
- * attempts to create a string that contains words that begin with uppercase
- * characters and that are separated by a single space. For example,
- * the following are the outputs of some sample inputs:
- * <li>"aName" is converted to "A Name"</li>
- * <li>"Name" is converted to "Name"</li>
- * <li>"NAME" is converted to "NAME"</li>
- * <li>"theName" is converted to "The Name"</li>
- * <li>"theBIGName" is converted to "The BIG Name"</li>
- * <li>"the BIG Name" is converted to "The BIG Name"</li>
- * <li>"the big Name" is converted to "The Big Name"</li>
- * <li>"theBIG" is converted to "The BIG"</li>
- * <li>"SQLIndex" is converted to "SQL Index"</li>
- * <li>"SQLIndexT" is converted to "SQL Index T"</li>
- * <li>"SQLIndex T" is converted to "SQL Index T"</li>
- * <li>"SQLIndex t" is converted to "SQL Index T"</li>
* <p>
* An exception is "MetaMatrix", which is always treated as a single word
* </p>
@@ -572,33 +446,6 @@
return newName.toString();
}
- /**
- * @since 3.0
- */
- public static String computeDisplayableFormOfConstant(final String text) {
- return computeDisplayableFormOfConstant(text, Constants.EMPTY_STRING);
- }
-
- /**
- * @since 3.0
- */
- public static String computeDisplayableFormOfConstant(final String text, final String defaultValue) {
- if (text == null || text.length() == 0) {
- return defaultValue;
- }
- final StringBuffer buf = new StringBuffer();
- String token;
- for (final StringTokenizer iter = new StringTokenizer(text, "_"); iter.hasMoreTokens();) { //$NON-NLS-1$
- token = iter.nextToken().toLowerCase();
- if (buf.length() > 0) {
- buf.append(' ');
- }
- buf.append(Character.toUpperCase(token.charAt(0)));
- buf.append(token.substring(1));
- }
- return buf.toString();
- }
-
public static String computePluralForm(String str) {
return computePluralForm(str, Constants.EMPTY_STRING);
}
@@ -786,28 +633,6 @@
}
/**
- * Removes extraneous whitespace from a string. By it's nature, it will be trimmed also.
- * @param raw
- * @return
- * @since 5.0
- */
- public static String collapseWhitespace(String raw) {
- StringBuffer rv = new StringBuffer(raw.length());
-
- StringTokenizer izer = new StringTokenizer(raw, " "); //$NON-NLS-1$
- while (izer.hasMoreTokens()) {
- String tok = izer.nextToken();
- // Added one last check here so we don't append a "space" on the end of the string
- rv.append(tok);
- if( izer.hasMoreTokens() ) {
- rv.append(' ');
- }
- } // endwhile
-
- return rv.toString();
- }
-
- /**
* If input == null OR input.length() < desiredLength, pad to desiredLength with spaces.
* If input.length() > desiredLength, chop at desiredLength.
* @param input Input text
@@ -1012,4 +837,32 @@
}
}
+ public static List<String> tokenize(String str, char delim) {
+ ArrayList<String> result = new ArrayList<String>();
+ StringBuilder current = new StringBuilder();
+ boolean escaped = false;
+ for (int i = 0; i < str.length(); i++) {
+ char c = str.charAt(i);
+ if (c == delim) {
+ if (escaped) {
+ current.append(c);
+ escaped = false;
+ } else {
+ escaped = true;
+ }
+ } else {
+ if (escaped && current.length() > 0) {
+ result.add(current.toString());
+ current.setLength(0);
+ escaped = false;
+ }
+ current.append(c);
+ }
+ }
+ if (current.length()>0) {
+ result.add(current.toString());
+ }
+ return result;
+ }
+
}
Modified: trunk/common-core/src/test/java/org/teiid/core/util/TestStringUtil.java
===================================================================
--- trunk/common-core/src/test/java/org/teiid/core/util/TestStringUtil.java 2012-10-03 16:54:06 UTC (rev 4510)
+++ trunk/common-core/src/test/java/org/teiid/core/util/TestStringUtil.java 2012-10-03 19:05:34 UTC (rev 4511)
@@ -37,12 +37,6 @@
*/
public class TestStringUtil {
- // ********* H E L P E R M E T H O D S *********
- public void helpTestEncloseInSingleQuotes(String input, String expectedResult){
- String result = StringUtil.enclosedInSingleQuotes(input);
- assertEquals("Unexpected encloseInSignleQuotes result", expectedResult, result ); //$NON-NLS-1$
- }
-
public void helpTestComputeDisplayableForm(String input, String expectedResult){
String result = StringUtil.computeDisplayableForm(input, input);
assertEquals("Unexpected ComputeDisplayableForm result", expectedResult, result ); //$NON-NLS-1$
@@ -73,11 +67,6 @@
assertEquals("Unexpected TruncString result", expectedResult, result ); //$NON-NLS-1$
}
- // ********* T E S T S U I T E M E T H O D S *********
- @Test public void testEncloseInSingleQuotes() {
- helpTestEncloseInSingleQuotes("testString", "\'testString\'"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
@Test public void testComputeDisplayableForm1() {
helpTestComputeDisplayableForm("testString", "Test String"); //$NON-NLS-1$ //$NON-NLS-2$
}
@@ -228,41 +217,6 @@
assertEquals(" are 7 tokens.", tokens.get(6)); //$NON-NLS-1$
}
- @Test public void testSplitOnEntireString() {
- List<String> result = StringUtil.splitOnEntireString("thisNEXTcanNEXTbe", "NEXT"); //$NON-NLS-1$ //$NON-NLS-2$
- assertEquals(3, result.size());
- assertEquals("this", result.get(0)); //$NON-NLS-1$
- assertEquals("can", result.get(1)); //$NON-NLS-1$
- assertEquals("be", result.get(2)); //$NON-NLS-1$
-
- }
-
- @Test public void testSplitOnEntireStringEmptyString() {
- List<String> result = StringUtil.splitOnEntireString("", "NEXT"); //$NON-NLS-1$ //$NON-NLS-2$
- assertEquals(1, result.size());
- assertEquals("", result.get(0)); //$NON-NLS-1$
- }
-
- @Test public void testSplitOnEntireStringEntireStringIsDelimiter() {
- List<String> result = StringUtil.splitOnEntireString("NEXT", "NEXT"); //$NON-NLS-1$ //$NON-NLS-2$
- assertEquals(2, result.size());
- assertEquals("", result.get(0)); //$NON-NLS-1$
- assertEquals("", result.get(1)); //$NON-NLS-1$
- }
-
- @Test public void testSplitOnEntireStringEmptyDelimiter() {
- List<String> result = StringUtil.splitOnEntireString("test", ""); //$NON-NLS-1$ //$NON-NLS-2$
- assertEquals(1, result.size());
- assertEquals("test", result.get(0)); //$NON-NLS-1$
- }
-
- @Test public void testSplitOnEntireStringEndsWithDelimiter() {
- List<String> result = StringUtil.splitOnEntireString("testNEXT", "NEXT"); //$NON-NLS-1$ //$NON-NLS-2$
- assertEquals(2, result.size());
- assertEquals("test", result.get(0)); //$NON-NLS-1$
- assertEquals("", result.get(1)); //$NON-NLS-1$
- }
-
@Test public void testIndexOfIgnoreCase() {
String text = "test"; //$NON-NLS-1$
assertEquals(-1,StringUtil.indexOfIgnoreCase(null,text));
Modified: trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/IQueryToLdapSearchParser.java
===================================================================
--- trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/IQueryToLdapSearchParser.java 2012-10-03 16:54:06 UTC (rev 4510)
+++ trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/IQueryToLdapSearchParser.java 2012-10-03 19:05:34 UTC (rev 4511)
@@ -45,12 +45,12 @@
import javax.naming.directory.SearchControls;
import javax.naming.ldap.SortKey;
+import org.teiid.core.util.StringUtil;
import org.teiid.language.*;
import org.teiid.language.Comparison.Operator;
import org.teiid.language.SortSpecification.Ordering;
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
-import org.teiid.metadata.AbstractMetadataRecord;
import org.teiid.metadata.Column;
import org.teiid.metadata.Datatype;
import org.teiid.metadata.Table;
@@ -70,7 +70,6 @@
private static final String SEARCH_SCOPE = "search-scope";//$NON-NLS-1$
private static final String CRITERIA = "filter";//$NON-NLS-1$
private static final String CONTEXT_NAME = "context-name";//$NON-NLS-1$
- public static final String TEIID_NATIVE_QUERY = AbstractMetadataRecord.RELATIONAL_URI + "native-query"; //$NON-NLS-1$
LDAPExecutionFactory executionFactory;
/**
@@ -119,50 +118,43 @@
}
LDAPSearchDetails sd = null;
- Table table = ((NamedTable)fItm).getMetadataObject();
- String nativeQuery = table.getProperty(TEIID_NATIVE_QUERY, false);
- if (nativeQuery != null) {
- sd = buildRequest(nativeQuery);
- }
- else {
- String contextName = getContextNameFromFromItem(fItm);
- int searchScope = getSearchScopeFromFromItem(fItm);
- // GHH 20080326 - added check for RESTRICT parameter in
- // NameInSource of from item
- String classRestriction = getRestrictToNamedClass(fItm);
-
- // Parse the WHERE clause.
- // Create an equivalent LDAP search filter.
- List<String> searchStringList = new LinkedList<String>();
- searchStringList = getSearchFilterFromWhereClause(query.getWhere(), searchStringList);
- StringBuilder filterBuilder = new StringBuilder();
- for (String string : searchStringList) {
- filterBuilder.append(string);
- }
- // GHH 20080326 - if there is a class restriction,
- // add it to the search filter
- if (classRestriction != null && classRestriction.trim().length()>0) {
- filterBuilder.insert(0, "(&").append("(objectClass=").append(classRestriction).append("))"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- }
-
- // Parse the ORDER BY clause.
- // Create an ordered sort list.
- OrderBy orderBy = query.getOrderBy();
- // Referenced the JNDI standard...arguably, this should not be done inside this
- // class, and we should make our own key class. In practice, this makes things simpler.
- SortKey[] sortKeys = getSortKeysFromOrderByClause(orderBy);
-
- // Parse LIMIT clause.
- // Note that offsets are not supported.
- Limit limit = query.getLimit();
- long countLimit = -1;
- if(limit != null) {
- countLimit = limit.getRowLimit();
- }
-
- // Create Search Details
- sd = new LDAPSearchDetails(contextName, searchScope, filterBuilder.toString(), sortKeys, countLimit, elementList, 0);
- }
+ String contextName = getContextNameFromFromItem(fItm);
+ int searchScope = getSearchScopeFromFromItem(fItm);
+ // GHH 20080326 - added check for RESTRICT parameter in
+ // NameInSource of from item
+ String classRestriction = getRestrictToNamedClass(fItm);
+
+ // Parse the WHERE clause.
+ // Create an equivalent LDAP search filter.
+ List<String> searchStringList = new LinkedList<String>();
+ searchStringList = getSearchFilterFromWhereClause(query.getWhere(), searchStringList);
+ StringBuilder filterBuilder = new StringBuilder();
+ for (String string : searchStringList) {
+ filterBuilder.append(string);
+ }
+ // GHH 20080326 - if there is a class restriction,
+ // add it to the search filter
+ if (classRestriction != null && classRestriction.trim().length()>0) {
+ filterBuilder.insert(0, "(&").append("(objectClass=").append(classRestriction).append("))"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+
+ // Parse the ORDER BY clause.
+ // Create an ordered sort list.
+ OrderBy orderBy = query.getOrderBy();
+ // Referenced the JNDI standard...arguably, this should not be done inside this
+ // class, and we should make our own key class. In practice, this makes things simpler.
+ SortKey[] sortKeys = getSortKeysFromOrderByClause(orderBy);
+
+ // Parse LIMIT clause.
+ // Note that offsets are not supported.
+ Limit limit = query.getLimit();
+ long countLimit = -1;
+ if(limit != null) {
+ countLimit = limit.getRowLimit();
+ }
+
+ // Create Search Details
+ sd = new LDAPSearchDetails(contextName, searchScope, filterBuilder.toString(), sortKeys, countLimit, elementList, 0);
// Search Details logging
sd.printDetailsToLog();
return sd;
@@ -371,42 +363,33 @@
expressionName = mdIDElement.getName();
}
} else if(e instanceof Literal) {
- try {
- if(((Literal)e).getType().equals(Class.forName(Timestamp.class.getName()))) {
- LogManager.logTrace(LogConstants.CTX_CONNECTOR, "Found an expression that uses timestamp; converting to LDAP string format."); //$NON-NLS-1$
- Timestamp ts = (Timestamp)((Literal)e).getValue();
- Date dt = new Date(ts.getTime());
- //TODO: Fetch format if provided.
- SimpleDateFormat sdf = new SimpleDateFormat(LDAPConnectorConstants.ldapTimestampFormat);
- expressionName = sdf.format(dt);
- LogManager.logTrace(LogConstants.CTX_CONNECTOR, "Timestamp to stsring is: " + expressionName); //$NON-NLS-1$
- }
- else {
- expressionName = ((Literal)e).getValue().toString();
- }
- } catch (ClassNotFoundException cce) {
- final String msg = LDAPPlugin.Util.getString("IQueryToLdapSearchParser.timestampClassNotFoundError"); //$NON-NLS-1$
- throw new TranslatorException(cce, msg);
- }
-
+ expressionName = getExpressionString((Literal)e);
} else {
- if(e instanceof AggregateFunction) {
- LogManager.logError(LogConstants.CTX_CONNECTOR, LDAPPlugin.Util.gs(LDAPPlugin.Event.TEIID12001));
- } else if(e instanceof Function) {
- LogManager.logError(LogConstants.CTX_CONNECTOR, LDAPPlugin.Util.gs(LDAPPlugin.Event.TEIID12005));
- } else if(e instanceof ScalarSubquery) {
- LogManager.logError(LogConstants.CTX_CONNECTOR, LDAPPlugin.Util.gs(LDAPPlugin.Event.TEIID12006));
- } else if (e instanceof SearchedCase) {
- LogManager.logError(LogConstants.CTX_CONNECTOR, LDAPPlugin.Util.gs(LDAPPlugin.Event.TEIID12007));
- }
- final String msg = LDAPPlugin.Util.getString("IQueryToLdapSearchParser.unsupportedElementError"); //$NON-NLS-1$
+ final String msg = LDAPPlugin.Util.getString("IQueryToLdapSearchParser.unsupportedElementError", e.getClass().getSimpleName()); //$NON-NLS-1$
throw new TranslatorException(msg + e.toString());
}
expressionName = escapeReservedChars(expressionName);
return expressionName;
}
+
+ static String getExpressionString(Literal l) {
+ if(l.getValue() instanceof Timestamp) {
+ LogManager.logTrace(LogConstants.CTX_CONNECTOR, "Found an expression that uses timestamp; converting to LDAP string format."); //$NON-NLS-1$
+ Timestamp ts = (Timestamp)l.getValue();
+ Date dt = new Date(ts.getTime());
+ //TODO: Fetch format if provided.
+ SimpleDateFormat sdf = new SimpleDateFormat(LDAPConnectorConstants.ldapTimestampFormat);
+ String expressionName = sdf.format(dt);
+ LogManager.logTrace(LogConstants.CTX_CONNECTOR, "Timestamp to string is: " + expressionName); //$NON-NLS-1$
+ return expressionName;
+ }
+ if (l.getValue() != null) {
+ return l.getValue().toString();
+ }
+ return "null"; //$NON-NLS-1$
+ }
- private String escapeReservedChars(String expr) {
+ static String escapeReservedChars(String expr) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < expr.length(); i++) {
char curChar = expr.charAt(i);
@@ -617,23 +600,21 @@
return expr.getMetadataObject();
}
- public LDAPSearchDetails buildRequest(String query) {
+ public LDAPSearchDetails buildRequest(String query) throws TranslatorException {
ArrayList<String> attributes = new ArrayList<String>();
ArrayList<Column> columns = new ArrayList<Column>();
String contextName = null;
String criteria = ""; //$NON-NLS-1$
String searchScope = this.executionFactory.getSearchDefaultScope().name();
int timeLimit = 0;
- long countLimit = 0;
-
- StringTokenizer st = new StringTokenizer(query, ";"); //$NON-NLS-1$
- while (st.hasMoreTokens()) {
- String var = st.nextToken();
+ long countLimit = -1;
+ List<String> parts = StringUtil.tokenize(query, ';');
+ for (String var : parts) {
int index = var.indexOf('=');
if (index == -1) {
- continue;
+ throw new TranslatorException(LDAPPlugin.Util.gs(LDAPPlugin.Event.TEIID12013, var));
}
- String key = var.substring(0, index).trim().toLowerCase();
+ String key = var.substring(0, index).trim();
String value = var.substring(index+1).trim();
if (key.equalsIgnoreCase(CONTEXT_NAME)) {
@@ -665,6 +646,8 @@
column.setDatatype(type, true);
columns.add(column);
}
+ } else {
+ throw new TranslatorException(LDAPPlugin.Util.gs(LDAPPlugin.Event.TEIID12013, var));
}
}
Modified: trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPDirectCreateUpdateDeleteQueryExecution.java
===================================================================
--- trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPDirectCreateUpdateDeleteQueryExecution.java 2012-10-03 16:54:06 UTC (rev 4510)
+++ trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPDirectCreateUpdateDeleteQueryExecution.java 2012-10-03 19:05:34 UTC (rev 4511)
@@ -22,6 +22,7 @@
package org.teiid.translator.ldap;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.StringTokenizer;
@@ -45,27 +46,29 @@
protected LDAPExecutionFactory executionFactory;
protected ExecutionContext executionContext;
private int updateCount = -1;
+ private boolean returnsArray = true;
+ private String query;
- public LDAPDirectCreateUpdateDeleteQueryExecution(List<Argument> arguments, LDAPExecutionFactory factory, ExecutionContext executionContext, LdapContext connection) {
+ public LDAPDirectCreateUpdateDeleteQueryExecution(List<Argument> arguments, LDAPExecutionFactory factory, ExecutionContext executionContext, LdapContext connection, String query, boolean returnsArray) {
this.arguments = arguments;
this.executionFactory = factory;
this.executionContext = executionContext;
this.ldapConnection = connection;
+ this.query = query;
+ this.returnsArray = returnsArray;
}
@Override
public void execute() throws TranslatorException {
- String query = (String)arguments.get(0).getArgumentValue().getValue();
String firstToken = null;
StringTokenizer st = new StringTokenizer(query, ";"); //$NON-NLS-1$
if (st.hasMoreTokens()) {
firstToken = st.nextToken();
- if (!firstToken.equalsIgnoreCase("create") && !firstToken.equalsIgnoreCase("update") && !firstToken.equalsIgnoreCase("delete")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- throw new TranslatorException(LDAPPlugin.Util.gs(LDAPPlugin.Event.TEIID12009));
- }
}
-
+ if (firstToken == null || (!firstToken.equalsIgnoreCase("create") && !firstToken.equalsIgnoreCase("update") && !firstToken.equalsIgnoreCase("delete"))) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ throw new TranslatorException(LDAPPlugin.Util.gs(LDAPPlugin.Event.TEIID12009));
+ }
LdapContext ldapCtx = null;
try {
ldapCtx = (LdapContext)this.ldapConnection.lookup(""); //$NON-NLS-1$
@@ -75,6 +78,9 @@
if (firstToken.equalsIgnoreCase("delete")) { // //$NON-NLS-1$
String theDN = getDN(st); // the token after the marker is always DN
+ if (st.hasMoreTokens()) {
+ throw new TranslatorException(LDAPPlugin.Util.gs(LDAPPlugin.Event.TEIID12013, st.nextToken()));
+ }
try {
ldapCtx.destroySubcontext(theDN);
this.updateCount = 1;
@@ -86,7 +92,10 @@
}
else if (firstToken.equalsIgnoreCase("create")) { //$NON-NLS-1$
String theDN = getDN(st); // the token after the marker is always DN
- ArrayList<BasicAttribute> attributes = getAttributes(st, this.arguments);
+ ArrayList<BasicAttribute> attributes = getAttributes(st);
+ if (st.hasMoreTokens()) {
+ throw new TranslatorException(LDAPPlugin.Util.gs(LDAPPlugin.Event.TEIID12013, st.nextToken()));
+ }
BasicAttributes attrs = new BasicAttributes();
for (BasicAttribute ba:attributes) {
attrs.put(ba);
@@ -102,7 +111,10 @@
}
else if (firstToken.equalsIgnoreCase("update")) { //$NON-NLS-1$
String theDN = getDN(st); // the token after the marker is always DN
- ArrayList<BasicAttribute> attributes = getAttributes(st, this.arguments);
+ ArrayList<BasicAttribute> attributes = getAttributes(st);
+ if (st.hasMoreTokens()) {
+ throw new TranslatorException(LDAPPlugin.Util.gs(LDAPPlugin.Event.TEIID12013, st.nextToken()));
+ }
ModificationItem[] updateMods = new ModificationItem[attributes.size()];
int i=0;
for (BasicAttribute ba:attributes) {
@@ -117,7 +129,6 @@
throw new TranslatorException(e, LDAPPlugin.Util.getString("LDAPUpdateExecution.updateFailedUnexpected",theDN));//$NON-NLS-1$
}
}
-
}
private String getDN(StringTokenizer st) throws TranslatorException {
@@ -127,26 +138,26 @@
return st.nextToken();
}
- private ArrayList<BasicAttribute> getAttributes(StringTokenizer st, List<Argument> arguments) throws TranslatorException {
+ private ArrayList<BasicAttribute> getAttributes(StringTokenizer st) throws TranslatorException {
if (!st.hasMoreTokens()) {
throw new TranslatorException(LDAPPlugin.Util.gs(LDAPPlugin.Event.TEIID12011));
}
ArrayList<BasicAttribute> attributes = new ArrayList<BasicAttribute>();
- while(st.hasMoreElements()) {
+ if(st.hasMoreElements()) {
String var = st.nextToken();
int index = var.indexOf('=');
if (index == -1) {
- continue;
+ throw new TranslatorException(LDAPPlugin.Util.gs(LDAPPlugin.Event.TEIID12011));
}
- String key = var.substring(0, index).trim().toLowerCase();
+ String key = var.substring(0, index).trim();
String value = var.substring(index+1).trim();
if (key.equalsIgnoreCase(ATTRIBUTES)) {
StringTokenizer attrTokens = new StringTokenizer(value, ","); //$NON-NLS-1$
- int attrCount = 1;
+ int attrCount = 0;
while(attrTokens.hasMoreElements()) {
String name = attrTokens.nextToken().trim();
if (arguments.size() <= attrCount) {
@@ -156,7 +167,8 @@
Object anObj = argument.getArgumentValue().getValue();
attributes.add(new BasicAttribute(name, anObj));
}
-
+ } else {
+ throw new TranslatorException(LDAPPlugin.Util.gs(LDAPPlugin.Event.TEIID12011));
}
}
return attributes;
@@ -170,10 +182,12 @@
@Override
public List<?> next() throws TranslatorException, DataNotAvailableException {
if (this.updateCount != -1) {
- Object[] columns = new Object[1];
- columns[0] = this.updateCount;
- List<Object[]> row = new ArrayList<Object[]>(1);
- row.add(columns);
+ List<Object> row = Arrays.asList((Object)Integer.valueOf(this.updateCount));
+ if (returnsArray) {
+ Object[] columns = new Object[1];
+ columns[0] = this.updateCount;
+ row.set(0, columns);
+ }
this.updateCount = -1;
return row;
}
Modified: trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPDirectSearchQueryExecution.java
===================================================================
--- trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPDirectSearchQueryExecution.java 2012-10-03 16:54:06 UTC (rev 4510)
+++ trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPDirectSearchQueryExecution.java 2012-10-03 19:05:34 UTC (rev 4511)
@@ -28,6 +28,7 @@
import javax.naming.ldap.LdapContext;
import org.teiid.language.Argument;
+import org.teiid.language.visitor.SQLStringVisitor;
import org.teiid.translator.DataNotAvailableException;
import org.teiid.translator.ExecutionContext;
import org.teiid.translator.ProcedureExecution;
@@ -35,16 +36,26 @@
public class LDAPDirectSearchQueryExecution extends LDAPSyncQueryExecution implements ProcedureExecution {
- private List<Argument> arguments;
+ private String query;
+ private boolean returnsArray = true;
- public LDAPDirectSearchQueryExecution(List<Argument> arguments, LDAPExecutionFactory factory, ExecutionContext executionContext, LdapContext connection) {
+ public LDAPDirectSearchQueryExecution(List<Argument> arguments, LDAPExecutionFactory factory, ExecutionContext executionContext, LdapContext connection, String query, boolean returnsArray) {
super(null, factory, executionContext, connection);
- this.arguments = arguments;
+ //perform substitution
+ StringBuilder sb = new StringBuilder();
+ SQLStringVisitor.parseNativeQueryParts(query.substring(7), arguments, sb, new SQLStringVisitor.Substitutor() {
+
+ @Override
+ public void substitute(Argument arg, StringBuilder builder, int index) {
+ builder.append(IQueryToLdapSearchParser.escapeReservedChars(IQueryToLdapSearchParser.getExpressionString(arg.getArgumentValue())));
+ }
+ });
+ this.query = sb.toString();
+ this.returnsArray = returnsArray;
}
@Override
public void execute() throws TranslatorException {
- String query = (String)arguments.get(0).getArgumentValue().getValue();
IQueryToLdapSearchParser parser = new IQueryToLdapSearchParser(this.executionFactory);
LDAPSearchDetails details = parser.buildRequest(query);
// Create and configure the new search context.
@@ -67,9 +78,12 @@
if (vals == null) {
return null;
}
- List<Object[]> row = new ArrayList<Object[]>(1);
- row.add(vals.toArray(new Object[vals.size()]));
- return row;
+ if (returnsArray) {
+ List<Object[]> row = new ArrayList<Object[]>(1);
+ row.add(vals.toArray(new Object[vals.size()]));
+ return row;
+ }
+ return vals;
}
@Override
Modified: trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPExecutionFactory.java
===================================================================
--- trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPExecutionFactory.java 2012-10-03 16:54:06 UTC (rev 4510)
+++ trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPExecutionFactory.java 2012-10-03 19:05:34 UTC (rev 4511)
@@ -27,9 +27,11 @@
import javax.resource.cci.ConnectionFactory;
import org.teiid.language.Argument;
+import org.teiid.language.Call;
import org.teiid.language.Command;
import org.teiid.language.QueryExpression;
import org.teiid.language.Select;
+import org.teiid.language.visitor.SQLStringVisitor;
import org.teiid.metadata.RuntimeMetadata;
import org.teiid.translator.ExecutionContext;
import org.teiid.translator.ExecutionFactory;
@@ -108,12 +110,26 @@
public ProcedureExecution createDirectExecution(List<Argument> arguments,Command command, ExecutionContext executionContext,RuntimeMetadata metadata, LdapContext context) throws TranslatorException {
String query = (String) arguments.get(0).getArgumentValue().getValue();
if (query.startsWith("search;")) { //$NON-NLS-1$
- return new LDAPDirectSearchQueryExecution(arguments, this, executionContext, context);
+ return new LDAPDirectSearchQueryExecution(arguments.subList(1, arguments.size()), this, executionContext, context, query, true);
}
- return new LDAPDirectCreateUpdateDeleteQueryExecution(arguments, this, executionContext, context);
+ return new LDAPDirectCreateUpdateDeleteQueryExecution(arguments.subList(1, arguments.size()), this, executionContext, context, query, true);
}
@Override
+ public ProcedureExecution createProcedureExecution(Call command,
+ ExecutionContext executionContext, RuntimeMetadata metadata,
+ LdapContext connection) throws TranslatorException {
+ String nativeQuery = command.getMetadataObject().getProperty(SQLStringVisitor.TEIID_NATIVE_QUERY, false);
+ if (nativeQuery != null) {
+ if (nativeQuery.startsWith("search;")) { //$NON-NLS-1$
+ return new LDAPDirectSearchQueryExecution(command.getArguments(), this, executionContext, connection, nativeQuery, false);
+ }
+ return new LDAPDirectCreateUpdateDeleteQueryExecution(command.getArguments(), this, executionContext, connection, nativeQuery, false);
+ }
+ throw new TranslatorException("Missing native-query extension metadata."); //$NON-NLS-1$
+ }
+
+ @Override
public boolean supportsCompareCriteriaEquals() {
return true;
}
Modified: trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPPlugin.java
===================================================================
--- trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPPlugin.java 2012-10-03 16:54:06 UTC (rev 4510)
+++ trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPPlugin.java 2012-10-03 19:05:34 UTC (rev 4511)
@@ -39,17 +39,14 @@
public static final BundleUtil Util = new BundleUtil(PLUGIN_ID, PLUGIN_ID + ".i18n", ResourceBundle.getBundle(PLUGIN_ID + ".i18n")); //$NON-NLS-1$ //$NON-NLS-2$
public static enum Event implements BundleUtil.Event {
- TEIID12001, // unsupported capability
TEIID12002, // search failed
TEIID12003, // close context
TEIID12004, // attribute fetch error
- TEIID12005,
- TEIID12006,
- TEIID12007,
TEIID12008,
TEIID12009,
TEIID12010,
TEIID12011,
- TEIID12012,
+ TEIID12012,
+ TEIID12013,
}
}
Modified: trunk/connectors/translator-ldap/src/main/resources/org/teiid/translator/ldap/i18n.properties
===================================================================
--- trunk/connectors/translator-ldap/src/main/resources/org/teiid/translator/ldap/i18n.properties 2012-10-03 16:54:06 UTC (rev 4510)
+++ trunk/connectors/translator-ldap/src/main/resources/org/teiid/translator/ldap/i18n.properties 2012-10-03 19:05:34 UTC (rev 4511)
@@ -25,8 +25,7 @@
IQueryToLdapSearchParser.baseContextNameError=Base context name (DN) not specified in Name In Source or connector properties.
IQueryToLdapSearchParser.groupCountExceededError=Query contained from clause that did not have exactly and only one group. Query not supported.
IQueryToLdapSearchParser.criteriaNotParsableError=Compound criteria operator was not parsable.
-IQueryToLdapSearchParser.timestampClassNotFoundError=Timestamp class was not found.
-IQueryToLdapSearchParser.unsupportedElementError=Encountered an element type that is not supported. Revise the capabilities.
+IQueryToLdapSearchParser.unsupportedElementError=Encountered an {0} that is not supported. Revise the capabilities.
IQueryToLdapSearchParser.missingNISError=An element (or expression) found in the query's compare criteria was missing a NameInSource definition (or name). Please ensure the name in source is defined for each element.
IQueryToLdapSearchParser.criteriaNotSupportedError=Encountered a criteria that is not supported.
IQueryToLdapSearchParser.searchDetailsLoggingError=Error writing LDAP search details to log
@@ -62,13 +61,10 @@
ldap_error=Ldap error while processing next batch of results
-TEIID12001=Received IAggregate, but it is not supported. Check capabilities.
-TEIID12005=Received IFunction, but it is not supported. Check capabilties.
-TEIID12006=Received IScalarSubquery, but it is not supported. Check capabilties.
-TEIID12007=Received ISearchedCaseExpression, but it is not supported. Check capabilties.
TEIID12002=Attempted to search context: {0}
TEIID12008=LDAP Search results exceeded size limit. Results may be incomplete.
TEIID12009=Unknown LDAP Request; the query string must start with [search|create|update|delete]
TEIID12010=The DN is not defined; DN should be the token after the marker tokens [search|create|update|delete]
TEIID12011=attributes are not defined; use "attributes=..." form using the comma delimited to specify all the names.
-TEIID12012=create/update operation did not find the value for attribute {0}; Each attribute value is defined as the separate parameter in the procedure call.
\ No newline at end of file
+TEIID12012=create/update operation did not find the value for attribute {0}; Each attribute value is defined as the separate parameter in the procedure call.
+TEIID12013=unknown option: {0}
\ No newline at end of file
Modified: trunk/connectors/translator-ldap/src/test/java/org/teiid/translator/ldap/TestIQueryToLdapSearchParser.java
===================================================================
--- trunk/connectors/translator-ldap/src/test/java/org/teiid/translator/ldap/TestIQueryToLdapSearchParser.java 2012-10-03 16:54:06 UTC (rev 4510)
+++ trunk/connectors/translator-ldap/src/test/java/org/teiid/translator/ldap/TestIQueryToLdapSearchParser.java 2012-10-03 19:05:34 UTC (rev 4511)
@@ -35,10 +35,10 @@
import org.teiid.language.Command;
import org.teiid.language.Select;
import org.teiid.metadata.Column;
-import org.teiid.metadata.Column.SearchType;
import org.teiid.metadata.MetadataStore;
import org.teiid.metadata.Schema;
import org.teiid.metadata.Table;
+import org.teiid.metadata.Column.SearchType;
import org.teiid.query.metadata.CompositeMetadataStore;
import org.teiid.query.metadata.QueryMetadataInterface;
import org.teiid.query.metadata.TransformationMetadata;
@@ -246,25 +246,6 @@
expectedCountLimit, expectedSearchScope, expectedSortKeys);
}
- public void testNativeQueryExtension() throws Exception {
- LDAPSearchDetails searchDetails = helpGetSearchDetails("SELECT * FROM LdapModel.Employee"); //$NON-NLS-1$
-
- String expectedContextName = "corporate"; //$NON-NLS-1$
- String expectedContextFilter = "(objectClass=*)"; //$NON-NLS-1$
-
- List expectedAttrNameList = new ArrayList();
- expectedAttrNameList.add("uid"); //$NON-NLS-1$
- expectedAttrNameList.add("cn"); //$NON-NLS-1$
-
- long expectedCountLimit = 5;
- int expectedSearchScope = SearchControls.ONELEVEL_SCOPE;
- SortKey[] expectedSortKeys = null;
-
- helpTestSearchDetails(searchDetails, expectedContextName, expectedContextFilter, expectedAttrNameList,
- expectedCountLimit, expectedSearchScope, expectedSortKeys);
-
- }
-
private LDAPSearchDetails helpGetSearchDetails(String queryString) throws TranslatorException {
QueryMetadataInterface metadata = exampleLdap();
@@ -312,19 +293,6 @@
cols.get(i).setSearchType(SearchType.Unsearchable);
}
- Table employees = RealMetadataFactory.createPhysicalGroup("Employee", ldapModel); //$NON-NLS-1$
- List<Column> employeeCols = RealMetadataFactory.createElements(employees, elemNames, elemTypes);
- for(int i=0; i<2; i++) {
- Column obj = employeeCols.get(i);
- obj.setNameInSource(nameInSource[i]);
- }
-
- // Set column-specific properties
- for(int i=1; i<2; i++) {
- employeeCols.get(i).setSearchType(SearchType.Unsearchable);
- }
- employees.setProperty(IQueryToLdapSearchParser.TEIID_NATIVE_QUERY, "context-name=corporate;filter=(objectClass=*);count-limit=5;timout=6;search-scope=ONELEVEL_SCOPE;attributes=uid,cn"); //$NON-NLS-1$
-
// Create the facade from the store
return new TransformationMetadata(null, new CompositeMetadataStore(metadataStore), null, RealMetadataFactory.SFM.getSystemFunctions(), null);
}
Modified: trunk/connectors/translator-ldap/src/test/java/org/teiid/translator/ldap/TestLDAPDirectQueryExecution.java
===================================================================
--- trunk/connectors/translator-ldap/src/test/java/org/teiid/translator/ldap/TestLDAPDirectQueryExecution.java 2012-10-03 16:54:06 UTC (rev 4510)
+++ trunk/connectors/translator-ldap/src/test/java/org/teiid/translator/ldap/TestLDAPDirectQueryExecution.java 2012-10-03 19:05:34 UTC (rev 4511)
@@ -21,8 +21,7 @@
*/
package org.teiid.translator.ldap;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
+import static org.junit.Assert.*;
import java.math.BigDecimal;
@@ -38,6 +37,7 @@
import org.teiid.cdk.unittest.FakeTranslationFactory;
import org.teiid.language.Command;
import org.teiid.metadata.RuntimeMetadata;
+import org.teiid.translator.Execution;
import org.teiid.translator.ExecutionContext;
import org.teiid.translator.TranslatorException;
@@ -54,7 +54,7 @@
}
@Test public void testSearch() throws Exception {
- String input = "exec native('search;context-name=corporate;filter=(objectClass=*);count-limit=5;timout=6;search-scope=ONELEVEL_SCOPE;attributes=uid,cn')";
+ String input = "exec native('search;context-name=corporate;filter=(objectClass=*);count-limit=5;timeout=6;search-scope=ONELEVEL_SCOPE;attributes=uid,cn')";
TranslationUtility util = FakeTranslationFactory.getInstance().getExampleTranslationUtility();
Command command = util.parseCommand(input);
@@ -71,13 +71,37 @@
assertEquals("corporate", details.getContextName());
assertEquals("(objectClass=*)", details.getContextFilter());
assertEquals(5, details.getCountLimit());
+ assertEquals(6, details.getTimeLimit());
assertEquals(1, details.getSearchScope());
assertEquals(2, details.getElementList().size());
assertEquals("uid", details.getElementList().get(0).getName());
assertEquals("cn", details.getElementList().get(1).getName());
- }
+ }
- @Test public void testWithoutMarker() throws Exception {
+ @Test public void testSearchDefaultsAndEscaping() throws Exception {
+ String input = "exec native('search;context-name=corporate;filter=(;;)')";
+
+ TranslationUtility util = FakeTranslationFactory.getInstance().getExampleTranslationUtility();
+ Command command = util.parseCommand(input);
+ ExecutionContext ec = Mockito.mock(ExecutionContext.class);
+ RuntimeMetadata rm = Mockito.mock(RuntimeMetadata.class);
+ LdapContext connection = Mockito.mock(LdapContext.class);
+ LdapContext ctx = Mockito.mock(LdapContext.class);
+ Mockito.stub(connection.lookup("corporate")).toReturn(ctx);
+
+ LDAPDirectSearchQueryExecution execution = (LDAPDirectSearchQueryExecution)TRANSLATOR.createExecution(command, ec, rm, connection);
+ execution.execute();
+ LDAPSearchDetails details = execution.getDelegate().getSearchDetails();
+
+ assertEquals("corporate", details.getContextName());
+ assertEquals("(;)", details.getContextFilter());
+ assertEquals(-1, details.getCountLimit());
+ assertEquals(0, details.getTimeLimit());
+ assertEquals(1, details.getSearchScope());
+ assertEquals(0, details.getElementList().size());
+ }
+
+ @Test(expected=TranslatorException.class) public void testWithoutMarker() throws Exception {
String input = "exec native('context-name=corporate;filter=(objectClass=*);count-limit=5;timout=6;search-scope=ONELEVEL_SCOPE;attributes=uid,cn')";
TranslationUtility util = FakeTranslationFactory.getInstance().getExampleTranslationUtility();
@@ -88,12 +112,9 @@
LdapContext ctx = Mockito.mock(LdapContext.class);
Mockito.stub(connection.lookup("corporate")).toReturn(ctx);
- try {
- LDAPDirectSearchQueryExecution execution = (LDAPDirectSearchQueryExecution)TRANSLATOR.createExecution(command, ec, rm, connection);
- execution.execute();
- fail("the above should have thrown exception");
- } catch (ClassCastException e) {
- }
+ Execution execution = TRANSLATOR.createExecution(command, ec, rm, connection);
+ assertTrue(!(execution instanceof LDAPDirectSearchQueryExecution));
+ execution.execute();
}
@Test public void testDelete() throws Exception {
@@ -167,7 +188,7 @@
assertEquals(new BigDecimal("3.0"), createItemArgument.getValue().get("three").get());
}
- @Test public void testCreateFail() throws Exception {
+ @Test(expected=TranslatorException.class) public void testCreateFail() throws Exception {
String input = "exec native('create;uid=doe,ou=people,o=teiid.org;attributes=one,two,three', 'one')";
TranslationUtility util = FakeTranslationFactory.getInstance().getExampleTranslationUtility();
@@ -178,11 +199,7 @@
LdapContext ctx = Mockito.mock(LdapContext.class);
Mockito.stub(connection.lookup("")).toReturn(ctx);
- try {
- LDAPDirectCreateUpdateDeleteQueryExecution execution = (LDAPDirectCreateUpdateDeleteQueryExecution)TRANSLATOR.createExecution(command, ec, rm, connection);
- execution.execute();
- fail("should have failed because there are not enough values");
- } catch (TranslatorException e) {
- }
+ LDAPDirectCreateUpdateDeleteQueryExecution execution = (LDAPDirectCreateUpdateDeleteQueryExecution)TRANSLATOR.createExecution(command, ec, rm, connection);
+ execution.execute();
}
}
12 years, 2 months
teiid SVN: r4510 - in trunk: connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc and 11 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2012-10-03 12:54:06 -0400 (Wed, 03 Oct 2012)
New Revision: 4510
Added:
trunk/connectors/translator-olap/src/test/
trunk/connectors/translator-olap/src/test/java/
trunk/connectors/translator-olap/src/test/java/org/
trunk/connectors/translator-olap/src/test/java/org/teiid/
trunk/connectors/translator-olap/src/test/java/org/teiid/translator/
trunk/connectors/translator-olap/src/test/java/org/teiid/translator/olap/
trunk/connectors/translator-olap/src/test/java/org/teiid/translator/olap/TestOlapTranslator.java
Modified:
trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/SQLConversionVisitor.java
trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPA2ExecutionFactory.java
trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPQLDirectQueryExecution.java
trunk/connectors/translator-olap/src/main/java/org/teiid/translator/olap/OlapQueryExecution.java
trunk/connectors/translator-salesforce/src/main/java/org/teiid/translator/salesforce/execution/DirectQueryExecution.java
trunk/test-integration/common/src/test/java/org/teiid/connector/visitor/util/TestSQLStringVisitor.java
Log:
TEIID-2177 adding jpa canned queries
Modified: trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java 2012-10-03 14:27:31 UTC (rev 4509)
+++ trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java 2012-10-03 16:54:06 UTC (rev 4510)
@@ -26,7 +26,6 @@
import java.util.Arrays;
import java.util.HashSet;
-import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
@@ -980,26 +979,29 @@
return false;
}
- public static List<Object> parseNativeQueryParts(String nativeQuery, List<Argument> list) {
+ public interface Substitutor {
+ void substitute(Argument arg, StringBuilder builder, int index);
+ }
+
+ public static void parseNativeQueryParts(String nativeQuery, List<Argument> list, StringBuilder stringBuilder, Substitutor substitutor) {
Pattern pattern = Pattern.compile("\\$+\\d+"); //$NON-NLS-1$
- List<Object> parts = new LinkedList<Object>();
Matcher m = pattern.matcher(nativeQuery);
for (int i = 0; i < nativeQuery.length();) {
if (!m.find(i)) {
- parts.add(nativeQuery.substring(i));
+ stringBuilder.append(nativeQuery.substring(i));
break;
}
if (m.start() != i) {
- parts.add(nativeQuery.substring(i, m.start()));
+ stringBuilder.append(nativeQuery.substring(i, m.start()));
}
String match = m.group();
int end = match.lastIndexOf('$');
if ((end&0x1) == 1) {
//escaped
- parts.add(match.substring((end+1)/2));
+ stringBuilder.append(match.substring((end+1)/2));
} else {
if (end != 0) {
- parts.add(match.substring(0, end/2));
+ stringBuilder.append(match.substring(0, end/2));
}
int index = Integer.parseInt(match.substring(end + 1))-1;
if (index < 0 || index >= list.size()) {
@@ -1009,10 +1011,9 @@
if (arg.getDirection() != Direction.IN) {
throw new IllegalArgumentException(JDBCPlugin.Util.getString("SQLConversionVisitor.not_in_parameter", index+1)); //$NON-NLS-1$
}
- parts.add(index);
+ substitutor.substitute(arg, stringBuilder, index);
}
i = m.end();
}
- return parts;
}
}
Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/SQLConversionVisitor.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/SQLConversionVisitor.java 2012-10-03 14:27:31 UTC (rev 4509)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/SQLConversionVisitor.java 2012-10-03 16:54:06 UTC (rev 4510)
@@ -52,7 +52,7 @@
* This visitor takes an ICommand and does DBMS-specific conversion on it
* to produce a SQL String. This class is expected to be subclassed.
*/
-public class SQLConversionVisitor extends SQLStringVisitor{
+public class SQLConversionVisitor extends SQLStringVisitor implements SQLStringVisitor.Substitutor {
public static final String TEIID_NON_PREPARED = AbstractMetadataRecord.RELATIONAL_URI + "non-prepared"; //$NON-NLS-1$
private static DecimalFormat DECIMAL_FORMAT =
@@ -178,23 +178,11 @@
if (p != null) {
String nativeQuery = p.getProperty(TEIID_NATIVE_QUERY, false);
if (nativeQuery != null) {
- List<Object> parts = parseNativeQueryParts(nativeQuery, obj.getArguments());
this.prepared = !Boolean.valueOf(p.getProperty(TEIID_NON_PREPARED, false));
if (this.prepared) {
this.preparedValues = new ArrayList<Object>();
}
- for (Object o : parts) {
- if (o instanceof String) {
- buffer.append(o);
- } else {
- if (this.prepared) {
- buffer.append('?');
- this.preparedValues = obj.getArguments();
- } else {
- visit(obj.getArguments().get((Integer)o));
- }
- }
- }
+ parseNativeQueryParts(nativeQuery, obj.getArguments(), buffer, this);
return;
}
}
@@ -394,5 +382,15 @@
}
super.appendBaseName(obj);
}
+
+ @Override
+ public void substitute(Argument arg, StringBuilder builder, int index) {
+ if (this.prepared) {
+ buffer.append('?');
+ this.preparedValues.add(arg);
+ } else {
+ visit(arg);
+ }
+ }
}
Modified: trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPA2ExecutionFactory.java
===================================================================
--- trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPA2ExecutionFactory.java 2012-10-03 14:27:31 UTC (rev 4509)
+++ trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPA2ExecutionFactory.java 2012-10-03 16:54:06 UTC (rev 4510)
@@ -35,6 +35,7 @@
import org.teiid.language.Call;
import org.teiid.language.Command;
import org.teiid.language.QueryExpression;
+import org.teiid.language.visitor.SQLStringVisitor;
import org.teiid.metadata.MetadataFactory;
import org.teiid.metadata.RuntimeMetadata;
import org.teiid.translator.ExecutionContext;
@@ -87,7 +88,11 @@
@Override
public ProcedureExecution createProcedureExecution(Call command, ExecutionContext executionContext, RuntimeMetadata metadata, EntityManager connection) throws TranslatorException {
- return super.createProcedureExecution(command, executionContext, metadata, connection);
+ String nativeQuery = command.getMetadataObject().getProperty(SQLStringVisitor.TEIID_NATIVE_QUERY, false);
+ if (nativeQuery != null) {
+ return new JPQLDirectQueryExecution(command.getArguments(), command, executionContext, metadata, connection, nativeQuery, false);
+ }
+ throw new TranslatorException("Missing native-query extension metadata."); //$NON-NLS-1$
}
@Override
@@ -97,10 +102,9 @@
@Override
public ProcedureExecution createDirectExecution(List<Argument> arguments, Command command, ExecutionContext executionContext, RuntimeMetadata metadata, EntityManager connection) throws TranslatorException {
- return new JPQLDirectQueryExecution(arguments, command, executionContext, metadata, connection);
+ return new JPQLDirectQueryExecution(arguments.subList(1, arguments.size()), command, executionContext, metadata, connection, (String)arguments.get(0).getArgumentValue().getValue(), true);
}
-
@Override
public void getMetadata(MetadataFactory mf, EntityManager em) throws TranslatorException {
JPAMetadataProcessor metadataProcessor = new JPAMetadataProcessor();
Modified: trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPQLDirectQueryExecution.java
===================================================================
--- trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPQLDirectQueryExecution.java 2012-10-03 14:27:31 UTC (rev 4509)
+++ trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPQLDirectQueryExecution.java 2012-10-03 16:54:06 UTC (rev 4510)
@@ -21,8 +21,8 @@
*/
package org.teiid.translator.jpa;
-import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.Iterator;
import java.util.List;
@@ -31,6 +31,8 @@
import org.teiid.language.Argument;
import org.teiid.language.Command;
+import org.teiid.language.Literal;
+import org.teiid.language.visitor.SQLStringVisitor;
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
import org.teiid.metadata.RuntimeMetadata;
@@ -42,41 +44,50 @@
public class JPQLDirectQueryExecution extends JPQLBaseExecution implements ProcedureExecution{
private Iterator<?> resultsIterator;
private List<Argument> arguments;
- private int updateCount = -1;
- private boolean updateQuery;
+ private boolean returnsArray = true;
+ private String query;
@SuppressWarnings("unused")
- public JPQLDirectQueryExecution(List<Argument> arguments, Command command, ExecutionContext executionContext, RuntimeMetadata metadata, EntityManager em) {
+ public JPQLDirectQueryExecution(List<Argument> arguments, Command command, ExecutionContext executionContext, RuntimeMetadata metadata, EntityManager em, String query, boolean returnsArray) {
super(executionContext, metadata, em);
this.arguments = arguments;
+ this.returnsArray = returnsArray;
+ this.query = query;
}
@Override
public void execute() throws TranslatorException {
- String query = (String)arguments.get(0).getArgumentValue().getValue();
if (query.length() < 7) {
throw new TranslatorException(JPAPlugin.Util.gs(JPAPlugin.Event.TEIID14008));
}
- String firstToken = query.substring(0, 6);
+ String firstToken = query.substring(0, 7);
String jpql = query.substring(7);
LogManager.logTrace(LogConstants.CTX_CONNECTOR, "JPA Source-Query:", jpql); //$NON-NLS-1$
- if (firstToken.equalsIgnoreCase("search")) { // //$NON-NLS-1$
+ if (firstToken.equalsIgnoreCase("search;")) { // //$NON-NLS-1$
+ StringBuilder buffer = new StringBuilder();
+ SQLStringVisitor.parseNativeQueryParts(jpql, arguments, buffer, new SQLStringVisitor.Substitutor() {
+
+ @Override
+ public void substitute(Argument arg, StringBuilder builder, int index) {
+ Literal argumentValue = arg.getArgumentValue();
+ builder.append(argumentValue);
+ }
+ });
+ jpql = buffer.toString();
Query queryCommand = this.enityManager.createQuery(jpql);
List<?> results = queryCommand.getResultList();
this.resultsIterator = results.iterator();
}
- else if (firstToken.equalsIgnoreCase("create")) { // //$NON-NLS-1$
- Object entity = arguments.get(1).getArgumentValue().getValue();
+ else if (firstToken.equalsIgnoreCase("create;")) { // //$NON-NLS-1$
+ Object entity = arguments.get(0).getArgumentValue().getValue();
this.enityManager.merge(entity);
- this.updateCount = 1;
- this.updateQuery = true;
+ this.resultsIterator = Arrays.asList(1).iterator();
}
- else if (firstToken.equalsIgnoreCase("update") || firstToken.equalsIgnoreCase("delete")) { // //$NON-NLS-1$ //$NON-NLS-2$
+ else if (firstToken.equalsIgnoreCase("update;") || firstToken.equalsIgnoreCase("delete;")) { // //$NON-NLS-1$ //$NON-NLS-2$
Query queryCmd = this.enityManager.createQuery(jpql);
- this.updateCount = queryCmd.executeUpdate();
- this.updateQuery = true;
+ this.resultsIterator = Arrays.asList(queryCmd.executeUpdate()).iterator();
} else {
throw new TranslatorException(JPAPlugin.Util.gs(JPAPlugin.Event.TEIID14008));
}
@@ -84,27 +95,20 @@
@Override
public List<?> next() throws TranslatorException, DataNotAvailableException {
-
- // for insert/update/delete clauses
- if (this.updateQuery) {
- if (this.updateCount != -1) {
- List<Object[]> row = new ArrayList<Object[]>(1);
- row.add(new Object[] {this.updateCount});
- this.updateCount = -1;
- return row;
- }
- return null;
- }
-
if (this.resultsIterator != null && this.resultsIterator.hasNext()) {
Object obj = this.resultsIterator.next();
if (obj instanceof Object[]) {
- List<Object[]> row = new ArrayList<Object[]>(1);
- row.add((Object[])obj);
- return row;
+ if (returnsArray) {
+ return Arrays.asList(obj);
+ }
+ return Arrays.asList((Object[])obj);
}
- return Arrays.asList(new Object[] {obj});
+ if (returnsArray) {
+ return Collections.singletonList(new Object[] {obj});
+ }
+ return Arrays.asList(obj);
}
+ this.resultsIterator = null;
return null;
}
Modified: trunk/connectors/translator-olap/src/main/java/org/teiid/translator/olap/OlapQueryExecution.java
===================================================================
--- trunk/connectors/translator-olap/src/main/java/org/teiid/translator/olap/OlapQueryExecution.java 2012-10-03 14:27:31 UTC (rev 4509)
+++ trunk/connectors/translator-olap/src/main/java/org/teiid/translator/olap/OlapQueryExecution.java 2012-10-03 16:54:06 UTC (rev 4510)
@@ -24,6 +24,7 @@
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Date;
import java.util.List;
import java.util.ListIterator;
@@ -37,6 +38,7 @@
import org.olap4j.metadata.Member;
import org.teiid.language.Argument;
import org.teiid.language.Command;
+import org.teiid.language.Literal;
import org.teiid.language.visitor.SQLStringVisitor;
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
@@ -65,15 +67,24 @@
this.mdxQuery = mdxQuery;
if (arguments.size() > 0 || !returnsArray) { //TODO this is a hack at backwards compatibility
StringBuilder buffer = new StringBuilder();
- List<Object> parts = SQLStringVisitor.parseNativeQueryParts(this.mdxQuery, arguments);
- for (Object o : parts) {
- if (o instanceof String) {
- buffer.append(o);
- } else {
- Integer i = (Integer)o;
- buffer.append(arguments.get(i).getArgumentValue().getValue());
+ SQLStringVisitor.parseNativeQueryParts(mdxQuery, arguments, buffer, new SQLStringVisitor.Substitutor() {
+
+ @Override
+ public void substitute(Argument arg, StringBuilder builder, int index) {
+ Literal argumentValue = arg.getArgumentValue();
+ Object value = argumentValue.getValue();
+ if (value == null || value instanceof Number || value instanceof Boolean || value instanceof String) {
+ builder.append(argumentValue);
+ } else if (value instanceof Date) {
+ //bind as a string literal
+ builder.append(new Literal(value.toString(), String.class));
+ } else {
+ //bind as a string literal using the teiid format - this is likely not what the user wants
+ builder.append(new Literal(argumentValue.toString(), String.class));
+ }
}
- }
+ });
+ this.mdxQuery = buffer.toString();
}
this.command = command;
this.connection = connection;
Added: trunk/connectors/translator-olap/src/test/java/org/teiid/translator/olap/TestOlapTranslator.java
===================================================================
--- trunk/connectors/translator-olap/src/test/java/org/teiid/translator/olap/TestOlapTranslator.java (rev 0)
+++ trunk/connectors/translator-olap/src/test/java/org/teiid/translator/olap/TestOlapTranslator.java 2012-10-03 16:54:06 UTC (rev 4510)
@@ -0,0 +1,74 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.translator.olap;
+
+import static org.junit.Assert.*;
+
+import java.sql.Connection;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.olap4j.OlapConnection;
+import org.olap4j.OlapStatement;
+import org.olap4j.OlapWrapper;
+import org.teiid.cdk.CommandBuilder;
+import org.teiid.core.TeiidRuntimeException;
+import org.teiid.dqp.internal.datamgr.RuntimeMetadataImpl;
+import org.teiid.language.Call;
+import org.teiid.language.Command;
+import org.teiid.query.metadata.TransformationMetadata;
+import org.teiid.query.unittest.RealMetadataFactory;
+import org.teiid.translator.ExecutionContext;
+import org.teiid.translator.ProcedureExecution;
+
+@SuppressWarnings("nls")
+public class TestOlapTranslator {
+
+ @Test public void testCannedProcedure() throws Exception {
+ String ddl = "create foreign procedure proc(arg integer, arg1 date) returns table (x string) options (\"teiid_rel:native-query\" '$2 $1 something')";
+ String query = "exec proc(2, {d'1970-01-01'})";
+
+ TransformationMetadata tm = RealMetadataFactory.fromDDL(ddl, "x", "phy");
+
+ CommandBuilder commandBuilder = new CommandBuilder(tm);
+ Command obj = commandBuilder.getCommand(query);
+
+ OlapExecutionFactory oef = new OlapExecutionFactory();
+ Connection mock = Mockito.mock(java.sql.Connection.class);
+ OlapWrapper mock2 = Mockito.mock(OlapWrapper.class);
+ OlapConnection mock3 = Mockito.mock(OlapConnection.class);
+ OlapStatement mock4 = Mockito.mock(OlapStatement.class);
+ Mockito.stub(mock4.executeOlapQuery(Mockito.anyString())).toThrow(new TeiidRuntimeException());
+ Mockito.stub(mock3.createStatement()).toReturn(mock4);
+ Mockito.stub(mock2.unwrap(OlapConnection.class)).toReturn(mock3);
+ Mockito.stub(mock.unwrap(OlapWrapper.class)).toReturn(mock2);
+ ProcedureExecution pe = oef.createProcedureExecution((Call)obj, Mockito.mock(ExecutionContext.class), new RuntimeMetadataImpl(tm), mock);
+ try {
+ pe.execute();
+ fail();
+ } catch (TeiidRuntimeException e) {
+ Mockito.verify(mock4).executeOlapQuery("'1970-01-01' 2 something");
+ }
+ }
+
+}
Property changes on: trunk/connectors/translator-olap/src/test/java/org/teiid/translator/olap/TestOlapTranslator.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/connectors/translator-salesforce/src/main/java/org/teiid/translator/salesforce/execution/DirectQueryExecution.java
===================================================================
--- trunk/connectors/translator-salesforce/src/main/java/org/teiid/translator/salesforce/execution/DirectQueryExecution.java 2012-10-03 14:27:31 UTC (rev 4509)
+++ trunk/connectors/translator-salesforce/src/main/java/org/teiid/translator/salesforce/execution/DirectQueryExecution.java 2012-10-03 16:54:06 UTC (rev 4510)
@@ -32,6 +32,7 @@
import org.teiid.language.Argument;
import org.teiid.language.Command;
+import org.teiid.language.Literal;
import org.teiid.language.visitor.SQLStringVisitor;
import org.teiid.metadata.RuntimeMetadata;
import org.teiid.translator.DataNotAvailableException;
@@ -89,15 +90,14 @@
public void execute() throws TranslatorException {
if (query.startsWith(SEARCH)) {
StringBuilder buffer = new StringBuilder();
- List<Object> parts = SQLStringVisitor.parseNativeQueryParts(query, arguments);
- for (Object o : parts) {
- if (o instanceof String) {
- buffer.append(o);
- } else {
- Integer i = (Integer)o;
- CriteriaVisitor.appendLiteralValue(buffer, arguments.get(i).getArgumentValue());
+ SQLStringVisitor.parseNativeQueryParts(query, arguments, buffer, new SQLStringVisitor.Substitutor() {
+
+ @Override
+ public void substitute(Argument arg, StringBuilder builder, int index) {
+ Literal argumentValue = arg.getArgumentValue();
+ CriteriaVisitor.appendLiteralValue(builder, argumentValue);
}
- }
+ });
doSelect(buffer.toString().substring(7));
}
else if (query.startsWith("create;")) { //$NON-NLS-1$
Modified: trunk/test-integration/common/src/test/java/org/teiid/connector/visitor/util/TestSQLStringVisitor.java
===================================================================
--- trunk/test-integration/common/src/test/java/org/teiid/connector/visitor/util/TestSQLStringVisitor.java 2012-10-03 14:27:31 UTC (rev 4509)
+++ trunk/test-integration/common/src/test/java/org/teiid/connector/visitor/util/TestSQLStringVisitor.java 2012-10-03 16:54:06 UTC (rev 4510)
@@ -37,6 +37,7 @@
import org.teiid.language.Argument.Direction;
import org.teiid.language.SQLConstants.NonReserved;
import org.teiid.language.visitor.SQLStringVisitor;
+import org.teiid.language.visitor.SQLStringVisitor.Substitutor;
import org.teiid.metadata.RuntimeMetadata;
import org.teiid.query.sql.lang.CompareCriteria;
import org.teiid.query.sql.lang.JoinType;
@@ -410,14 +411,34 @@
@Test public void testNativeParsing() throws Exception {
String sql = "select $1 from $2";
- List<Object> parts = SQLStringVisitor.parseNativeQueryParts(sql, Arrays.asList(new Argument(Direction.IN, null, String.class, null), new Argument(Direction.IN, null, String.class, null)));
- assertEquals(Arrays.asList((Object)"select ", 0, " from ", 1), parts);
+ String expected = "select *0 from *1";
+ helpTestNativeParsing(sql, expected);
}
+
+ private void helpTestNativeParsing(String sql, String expected) {
+ StringBuilder sb = new StringBuilder();
+
+ Substitutor sub = new Substitutor() {
+ @Override
+ public void substitute(Argument arg, StringBuilder builder, int index) {
+ builder.append("*").append(index);
+ }
+ };
+
+ SQLStringVisitor.parseNativeQueryParts(sql, Arrays.asList(new Argument(Direction.IN, null, String.class, null), new Argument(Direction.IN, null, String.class, null)), sb, sub);
+ assertEquals(expected, sb.toString());
+ }
@Test public void testNativeParsing1() throws Exception {
String sql = "select $$1 from $$$2";
- List<Object> parts = SQLStringVisitor.parseNativeQueryParts(sql, Arrays.asList(new Argument(Direction.IN, null, String.class, null), new Argument(Direction.IN, null, String.class, null)));
- assertEquals(Arrays.asList((Object)"select ", "$1", " from ", "$", 1), parts);
+ String expected = "select $1 from $*1";
+ helpTestNativeParsing(sql, expected);
}
+
+ @Test(expected=IllegalArgumentException.class) public void testNativeParsing2() throws Exception {
+ String sql = "select $$1 from $$$3";
+ String expected = "select $1 from $*1";
+ helpTestNativeParsing(sql, expected);
+ }
}
12 years, 2 months