teiid SVN: r1267 - in trunk/connectors/connector-salesforce/src: main/java/com/metamatrix/connector/salesforce/connection and 4 other directories.
by teiid-commits@lists.jboss.org
Author: jdoyle
Date: 2009-08-21 14:59:08 -0400 (Fri, 21 Aug 2009)
New Revision: 1267
Added:
trunk/connectors/connector-salesforce/src/main/java/com/metamatrix/connector/salesforce/Constants.java
trunk/connectors/connector-salesforce/src/main/java/com/metamatrix/connector/salesforce/execution/visitors/JoinQueryVisitor.java
Modified:
trunk/connectors/connector-salesforce/src/main/java/com/metamatrix/connector/salesforce/SalesforceCapabilities.java
trunk/connectors/connector-salesforce/src/main/java/com/metamatrix/connector/salesforce/connection/SalesforceConnection.java
trunk/connectors/connector-salesforce/src/main/java/com/metamatrix/connector/salesforce/connection/impl/ConnectionImpl.java
trunk/connectors/connector-salesforce/src/main/java/com/metamatrix/connector/salesforce/execution/QueryExecutionImpl.java
trunk/connectors/connector-salesforce/src/main/java/com/metamatrix/connector/salesforce/execution/visitors/CriteriaVisitor.java
trunk/connectors/connector-salesforce/src/main/java/com/metamatrix/connector/salesforce/execution/visitors/SelectVisitor.java
trunk/connectors/connector-salesforce/src/test/java/com/metamatrix/connector/salesforce/execution/visitors/TestVisitors.java
Log:
TEIID-202
TEIID-209
Support for SOQL relationship queries via outer joins.
Removed 'ping timeout' from the connection.
Added: trunk/connectors/connector-salesforce/src/main/java/com/metamatrix/connector/salesforce/Constants.java
===================================================================
--- trunk/connectors/connector-salesforce/src/main/java/com/metamatrix/connector/salesforce/Constants.java (rev 0)
+++ trunk/connectors/connector-salesforce/src/main/java/com/metamatrix/connector/salesforce/Constants.java 2009-08-21 18:59:08 UTC (rev 1267)
@@ -0,0 +1,49 @@
+package com.metamatrix.connector.salesforce;
+
+public interface Constants {
+
+ public static final String PICKLIST_TYPE = "picklist"; //$NON-NLS-1$
+
+ public static final String MULTIPICKLIST_TYPE = "multipicklist"; //$NON-NLS-1$
+
+ public static final String COMBOBOX_TYPE = "combobox"; //$NON-NLS-1$
+
+ public static final String ANYTYPE_TYPE = "anyType"; //$NON-NLS-1$
+
+ public static final String REFERENCE_TYPE = "reference"; //$NON-NLS-1$
+
+ public static final String STRING_TYPE = "string"; //$NON-NLS-1$
+
+ public static final String BASE64_TYPE = "base64"; //$NON-NLS-1$
+
+ public static final String BOOLEAN_TYPE = "boolean"; //$NON-NLS-1$
+
+ public static final String CURRENCY_TYPE = "currency"; //$NON-NLS-1$
+
+ public static final String TEXTAREA_TYPE = "textarea"; //$NON-NLS-1$
+
+ public static final String INT_TYPE = "int"; //$NON-NLS-1$
+
+ public static final String DOUBLE_TYPE = "double"; //$NON-NLS-1$
+
+ public static final String PERCENT_TYPE = "percent"; //$NON-NLS-1$
+
+ public static final String PHONE_TYPE = "phone"; //$NON-NLS-1$
+
+ public static final String ID_TYPE = "id"; //$NON-NLS-1$
+
+ public static final String DATE_TYPE = "date"; //$NON-NLS-1$
+
+ public static final String DATETIME_TYPE = "datetime"; //$NON-NLS-1$
+
+ public static final String URL_TYPE = "url"; //$NON-NLS-1$
+
+ public static final String EMAIL_TYPE = "email"; //$NON-NLS-1$
+
+ public static final String RESTRICTED_PICKLIST_TYPE = "restrictedpicklist"; //$NON-NLS-1$
+
+ public static final String RESTRICTED_MULTISELECT_PICKLIST_TYPE = "restrictedmultiselectpicklist"; //$NON-NLS-1$
+
+ public static final String SUPPORTS_QUERY = "Supports Query";
+
+}
Modified: trunk/connectors/connector-salesforce/src/main/java/com/metamatrix/connector/salesforce/SalesforceCapabilities.java
===================================================================
--- trunk/connectors/connector-salesforce/src/main/java/com/metamatrix/connector/salesforce/SalesforceCapabilities.java 2009-08-20 13:14:46 UTC (rev 1266)
+++ trunk/connectors/connector-salesforce/src/main/java/com/metamatrix/connector/salesforce/SalesforceCapabilities.java 2009-08-21 18:59:08 UTC (rev 1267)
@@ -80,4 +80,16 @@
return true;
}
+ @Override
+ public SupportedJoinCriteria getSupportedJoinCriteria() {
+ return SupportedJoinCriteria.KEY;
+ }
+
+ @Override
+ public boolean supportsOuterJoins() {
+ return true;
+ }
+
+
+
}
Modified: trunk/connectors/connector-salesforce/src/main/java/com/metamatrix/connector/salesforce/connection/SalesforceConnection.java
===================================================================
--- trunk/connectors/connector-salesforce/src/main/java/com/metamatrix/connector/salesforce/connection/SalesforceConnection.java 2009-08-20 13:14:46 UTC (rev 1266)
+++ trunk/connectors/connector-salesforce/src/main/java/com/metamatrix/connector/salesforce/connection/SalesforceConnection.java 2009-08-21 18:59:08 UTC (rev 1267)
@@ -64,8 +64,19 @@
}
} catch (NumberFormatException e) {
throw new ConnectorException(Messages.getString("SalesforceConnection.bad.ping.value"));
- }
- connection = new ConnectionImpl(username, password, url, pingInterval, env.getLogger());
+ }
+ //600000 - 10 minutes
+ int timeout = 120000; // two minutes
+ try {
+ String timeoutString = env.getProperties().getProperty("SourceConnectionTimeout");
+ if(null != timeoutString) {
+ timeout = Integer.decode(timeoutString).intValue();
+ }
+ } catch (NumberFormatException e) {
+ throw new ConnectorException(Messages.getString("SalesforceConnection.bad.timeout.value"));
+ }
+
+ connection = new ConnectionImpl(username, password, url, pingInterval, env.getLogger(), timeout);
} catch(Throwable t) {
env.getLogger().logError("SalesforceConnection() ErrorMessage: " + t.getMessage());
if(t instanceof ConnectorException) {
Modified: trunk/connectors/connector-salesforce/src/main/java/com/metamatrix/connector/salesforce/connection/impl/ConnectionImpl.java
===================================================================
--- trunk/connectors/connector-salesforce/src/main/java/com/metamatrix/connector/salesforce/connection/impl/ConnectionImpl.java 2009-08-20 13:14:46 UTC (rev 1266)
+++ trunk/connectors/connector-salesforce/src/main/java/com/metamatrix/connector/salesforce/connection/impl/ConnectionImpl.java 2009-08-21 18:59:08 UTC (rev 1267)
@@ -58,22 +58,18 @@
import com.sforce.soap.partner.SforceServiceLocator;
import com.sforce.soap.partner.SoapBindingStub;
import com.sforce.soap.partner.fault.ApiFault;
+import com.sforce.soap.partner.fault.InvalidQueryLocatorFault;
import com.sforce.soap.partner.fault.InvalidSObjectFault;
import com.sforce.soap.partner.fault.UnexpectedErrorFault;
-import com.sforce.soap.partner.fault.InvalidQueryLocatorFault;
import com.sforce.soap.partner.sobject.SObject;
public class ConnectionImpl {
private SoapBindingStub binding;
private ConnectorLogger logger;
- private long prevTime;
- private long pingInterval;
- public ConnectionImpl(String username, String password, URL url, long pingInterval, ConnectorLogger logger) throws ConnectorException {
- this.pingInterval = pingInterval;
+ public ConnectionImpl(String username, String password, URL url, long pingInterval, ConnectorLogger logger, int timeout) throws ConnectorException {
this.logger = logger;
- login(username, password, url);
- prevTime = System.currentTimeMillis();
+ login(username, password, url, timeout);
}
String getUserName() throws ConnectorException {
@@ -90,7 +86,7 @@
return binding;
}
- private void login(String username, String password, URL url)
+ private void login(String username, String password, URL url, int timeout)
throws ConnectorException {
if (!isAlive()) {
LoginResult loginResult = null;
@@ -108,6 +104,7 @@
CallOptions co = new CallOptions();
co.setClient("RedHat/MetaMatrix/");
binding.setHeader("SforceService", "CallOptions", co);
+ binding.setTimeout(timeout);
loginResult = binding.login(username, password);
} catch (ApiFault ex) {
throw new ConnectorException(ex.getExceptionMessage());
@@ -157,20 +154,15 @@
public boolean isAlive() {
boolean result = true;
- if(null != binding) {
+ if(binding == null) {
+ result = false;
+ } else {
try {
- long currentTime = System.currentTimeMillis();
- if ((currentTime - prevTime)/1000 > pingInterval) {
- prevTime = currentTime;
- binding.getServerTimestamp();
- }
- } catch (UnexpectedErrorFault e) {
+ binding.getServerTimestamp();
+ } catch (Throwable t) {
+ logger.logDetail("Caught Throwable in isAlive", t);
result = false;
- } catch (RemoteException e) {
- result = false;
}
- } else {
- result = false;
}
return result;
}
Modified: trunk/connectors/connector-salesforce/src/main/java/com/metamatrix/connector/salesforce/execution/QueryExecutionImpl.java
===================================================================
--- trunk/connectors/connector-salesforce/src/main/java/com/metamatrix/connector/salesforce/execution/QueryExecutionImpl.java 2009-08-20 13:14:46 UTC (rev 1266)
+++ trunk/connectors/connector-salesforce/src/main/java/com/metamatrix/connector/salesforce/execution/QueryExecutionImpl.java 2009-08-21 18:59:08 UTC (rev 1267)
@@ -27,9 +27,12 @@
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import javax.xml.namespace.QName;
+
import org.apache.axis.message.MessageElement;
import org.teiid.connector.api.ConnectorEnvironment;
import org.teiid.connector.api.ConnectorException;
@@ -39,6 +42,9 @@
import org.teiid.connector.api.ResultSetExecution;
import org.teiid.connector.basic.BasicExecution;
import org.teiid.connector.language.IAggregate;
+import org.teiid.connector.language.IFrom;
+import org.teiid.connector.language.IJoin;
+import org.teiid.connector.language.IQuery;
import org.teiid.connector.language.IQueryCommand;
import org.teiid.connector.metadata.runtime.Element;
import org.teiid.connector.metadata.runtime.RuntimeMetadata;
@@ -46,6 +52,7 @@
import com.metamatrix.connector.salesforce.Messages;
import com.metamatrix.connector.salesforce.Util;
import com.metamatrix.connector.salesforce.connection.SalesforceConnection;
+import com.metamatrix.connector.salesforce.execution.visitors.JoinQueryVisitor;
import com.metamatrix.connector.salesforce.execution.visitors.SelectVisitor;
import com.sforce.soap.partner.QueryResult;
import com.sforce.soap.partner.sobject.SObject;
@@ -63,6 +70,8 @@
private SelectVisitor visitor;
private QueryResult results;
+
+ private List<List<Object>> resultBatch;
// Identifying values
private String connectionIdentifier;
@@ -75,11 +84,11 @@
private String logPreamble;
- private Map<String,Integer> fieldMap;
-
private IQueryCommand query;
- private int i;
+ Map<String, Map<String,Integer>> sObjectToResponseField = new HashMap<String, Map<String,Integer>>();
+
+ private int topResultIndex = 0;
public QueryExecutionImpl(IQueryCommand command, SalesforceConnection connection,
RuntimeMetadata metadata, ExecutionContext context,
@@ -108,7 +117,12 @@
public void execute() throws ConnectorException {
connectorEnv.getLogger().logInfo(
getLogPreamble() + "Incoming Query: " + query.toString());
- visitor = new SelectVisitor(metadata);
+ IFrom from = ((IQuery)query).getFrom();
+ if(from.getItems().get(0) instanceof IJoin) {
+ visitor = new JoinQueryVisitor(metadata);
+ } else {
+ visitor = new SelectVisitor(metadata);
+ }
visitor.visitNode(query);
String finalQuery;
finalQuery = visitor.getQuery().trim();
@@ -118,66 +132,138 @@
results = connection.query(finalQuery, this.context.getBatchSize(), visitor.getQueryAll());
}
+ @SuppressWarnings("unchecked")
@Override
public List next() throws ConnectorException, DataNotAvailableException {
- while (results != null) {
- if (query.getProjectedQuery().getSelect().getSelectSymbols().get(0).getExpression() instanceof IAggregate) {
- List<?> result = Arrays.asList(results.getSize());
- results = null;
- return result;
- }
- if (i < results.getSize()) {
- SObject sObject = results.getRecords(i++);
- org.apache.axis.message.MessageElement[] fields = sObject.get_any();
- if (null == fieldMap) {
- logAndMapFields(fields);
+ List<?> result;
+ if (query.getProjectedQuery().getSelect().getSelectSymbols().get(0)
+ .getExpression() instanceof IAggregate) {
+ result = Arrays.asList(results.getSize());
+ results = null;
+
+ } else {
+ result = getRow(results);
+ }
+ return result;
+ }
+
+ private List<Object> getRow(QueryResult result) throws ConnectorException {
+ List<Object> row;
+ if(null == resultBatch) {
+ loadBatch();
+ }
+ if(resultBatch.size() == topResultIndex) {
+ row = null;
+ } else {
+ row = resultBatch.get(topResultIndex);
+ topResultIndex++;
+ if(resultBatch.size() == topResultIndex) {
+ if(!result.isDone()) {
+ loadBatch();
}
- return extractRowFromFields(sObject, fields);
}
-
- if (results.isDone()) { // no more batches on sf.
- results = null;
- break;
- }
- results = connection.queryMore(results.getQueryLocator());
- i = 0;
+
}
- return null;
+ return row;
}
- private List<Object> extractRowFromFields(SObject sObject, MessageElement[] fields) throws ConnectorException {
- List<Object> row = new ArrayList<Object>();
- for (int j = 0; j < visitor.getSelectSymbolCount(); j++) {
- Element element = visitor.getSelectSymbolMetadata(j);
- Integer index = fieldMap.get(element.getNameInSource());
- // id gets dropped from the result if it is not the
- // first field in the querystring. Add it back in.
- if (null == index) {
- if (element.getNameInSource().equalsIgnoreCase("id")) {
- row.add(sObject.getId());
- } else {
- throw new ConnectorException("SalesforceQueryExecutionImpl.missing.field"
- + element.getNameInSource());
+ private void loadBatch() throws ConnectorException {
+ if(null != resultBatch) { // if we have an old batch, then we have to get new results
+ results = connection.queryMore(results.getQueryLocator());
+ }
+ resultBatch = new ArrayList<List<Object>>();
+
+ for(int resultIndex = 0; resultIndex < results.getSize(); resultIndex++) {
+ SObject sObject = results.getRecords(resultIndex);
+ List<Object[]> result = getObjectData(sObject);
+ for(Iterator<Object[]> i = result.iterator(); i.hasNext(); ) {
+ resultBatch.add(Arrays.asList(i.next()));
}
- } else {
- Object cell;
- cell = getCellDatum(element, fields[index]);
- row.add(cell);
}
}
- return row;
+
+ private List<Object[]> getObjectData(SObject sObject) throws ConnectorException {
+ org.apache.axis.message.MessageElement[] topFields = sObject.get_any();
+ logAndMapFields(sObject.getType(), topFields);
+ List<Object[]> result = new ArrayList<Object[]>();
+ for(int i = 0; i < topFields.length; i++) {
+ QName qName = topFields[i].getType();
+ if(null != qName) {
+ String type = qName.getLocalPart();
+ if(type.equals("sObject")) {
+ SObject parent = (SObject)topFields[i].getObjectValue();
+ result.addAll(getObjectData(parent));
+ } else if(type.equals("QueryResult")) {
+ QueryResult subResult = (QueryResult)topFields[i].getObjectValue();
+ for(int resultIndex = 0; resultIndex < subResult.getSize(); resultIndex++) {
+ SObject subObject = subResult.getRecords(resultIndex);
+ result.addAll(getObjectData(subObject));
+ }
+ }
+ }
+ }
+ return extractDataFromFields(sObject, topFields,result);
+
+ }
+
+ private List<Object[]> extractDataFromFields(SObject sObject,
+ MessageElement[] fields, List<Object[]> result) throws ConnectorException {
+ Map<String,Integer> fieldToIndexMap = sObjectToResponseField.get(sObject.getType());
+ for (int j = 0; j < visitor.getSelectSymbolCount(); j++) {
+ Element element = visitor.getSelectSymbolMetadata(j);
+ if(element.getParent().getNameInSource().equals(sObject.getType())) {
+ Integer index = fieldToIndexMap.get(element.getNameInSource());
+ // id gets dropped from the result if it is not the
+ // first field in the querystring. Add it back in.
+ if (null == index) {
+ if (element.getNameInSource().equalsIgnoreCase("id")) {
+ setValueInColumn(j, sObject.getId(), result);
+ } else {
+ throw new ConnectorException("SalesforceQueryExecutionImpl.missing.field"
+ + element.getNameInSource());
+ }
+ } else {
+ Object cell;
+ cell = getCellDatum(element, fields[index]);
+ setValueInColumn(j, cell, result);
+ }
+ }
+ }
+ return result;
}
+
+ private void setValueInColumn(int columnIndex, Object value, List<Object[]> result) {
+ if(result.isEmpty()) {
+ Object[] row = new Object[visitor.getSelectSymbolCount()];
+ result.add(row);
+ }
+ Iterator<Object[]> iter = result.iterator();
+ while (iter.hasNext()) {
+ Object[] row = iter.next();
+ row[columnIndex] = value;
+ }
+ }
- private void logAndMapFields(org.apache.axis.message.MessageElement[] fields) {
- logFields(fields);
- fieldMap = new HashMap<String, Integer>();
- for (int x = 0; x < fields.length; x++) {
- fieldMap.put(fields[x].getLocalName(), x);
+ /**
+ * Load the map of response field names to index.
+ * @param fields
+ */
+ private void logAndMapFields(String sObjectName,
+ org.apache.axis.message.MessageElement[] fields) {
+ if (!sObjectToResponseField.containsKey(sObjectName)) {
+ logFields(sObjectName, fields);
+ Map<String, Integer> responseFieldToIndexMap;
+ responseFieldToIndexMap = new HashMap<String, Integer>();
+ for (int x = 0; x < fields.length; x++) {
+ responseFieldToIndexMap.put(fields[x].getLocalName(), x);
+ }
+ sObjectToResponseField.put(sObjectName, responseFieldToIndexMap);
}
}
- private void logFields(MessageElement[] fields) {
+ private void logFields(String sObjectName, MessageElement[] fields) {
ConnectorLogger logger = connectorEnv.getLogger();
+ logger.logDetail("SalesForce Object Name = " + sObjectName);
logger.logDetail("FieldCount = " + fields.length);
for(int i = 0; i < fields.length; i++) {
logger.logDetail("Field # " + i + " is " + fields[i].getLocalName());
Modified: trunk/connectors/connector-salesforce/src/main/java/com/metamatrix/connector/salesforce/execution/visitors/CriteriaVisitor.java
===================================================================
--- trunk/connectors/connector-salesforce/src/main/java/com/metamatrix/connector/salesforce/execution/visitors/CriteriaVisitor.java 2009-08-20 13:14:46 UTC (rev 1266)
+++ trunk/connectors/connector-salesforce/src/main/java/com/metamatrix/connector/salesforce/execution/visitors/CriteriaVisitor.java 2009-08-21 18:59:08 UTC (rev 1267)
@@ -277,25 +277,35 @@
Element column = left.getMetadataObject();
String columnName = column.getNameInSource();
StringBuffer queryString = new StringBuffer();
+ queryString.append(column.getParent().getNameInSource());
+ queryString.append('.');
queryString.append(columnName).append(SPACE);
queryString.append(comparisonOperators.get(compCriteria.getOperator()));
queryString.append(' ');
- ILiteral literal = (ILiteral)compCriteria.getRightExpression();
- if (column.getJavaType().equals(Boolean.class)) {
- queryString.append(((Boolean)literal.getValue()).toString());
- } else if (column.getJavaType().equals(java.sql.Timestamp.class)) {
- Timestamp datetime = (java.sql.Timestamp)literal.getValue();
- String value = Util.getSalesforceDateTimeFormat().format(datetime);
- String zoneValue = Util.getTimeZoneOffsetFormat().format(datetime);
- queryString.append(value).append(zoneValue.subSequence(0, 3)).append(':').append(zoneValue.subSequence(3, 5));
- } else if (column.getJavaType().equals(java.sql.Time.class)) {
- String value = Util.getSalesforceDateTimeFormat().format((java.sql.Time)literal.getValue());
- queryString.append(value);
- } else if (column.getJavaType().equals(java.sql.Date.class)) {
- String value = Util.getSalesforceDateFormat().format((java.sql.Date)literal.getValue());
- queryString.append(value);
- } else {
- queryString.append(compCriteria.getRightExpression().toString());
+ IExpression rExp = compCriteria.getRightExpression();
+ if(rExp instanceof ILiteral) {
+ ILiteral literal = (ILiteral)rExp;
+ if (column.getJavaType().equals(Boolean.class)) {
+ queryString.append(((Boolean)literal.getValue()).toString());
+ } else if (column.getJavaType().equals(java.sql.Timestamp.class)) {
+ Timestamp datetime = (java.sql.Timestamp)literal.getValue();
+ String value = Util.getSalesforceDateTimeFormat().format(datetime);
+ String zoneValue = Util.getTimeZoneOffsetFormat().format(datetime);
+ queryString.append(value).append(zoneValue.subSequence(0, 3)).append(':').append(zoneValue.subSequence(3, 5));
+ } else if (column.getJavaType().equals(java.sql.Time.class)) {
+ String value = Util.getSalesforceDateTimeFormat().format((java.sql.Time)literal.getValue());
+ queryString.append(value);
+ } else if (column.getJavaType().equals(java.sql.Date.class)) {
+ String value = Util.getSalesforceDateFormat().format((java.sql.Date)literal.getValue());
+ queryString.append(value);
+ } else {
+ queryString.append(compCriteria.getRightExpression().toString());
+ }
+ } else if(rExp instanceof IElement) {
+ IElement right = (IElement)lExpr;
+ column = left.getMetadataObject();
+ columnName = column.getNameInSource();
+ queryString.append(columnName);
}
criteriaList.add(queryString.toString());
Added: trunk/connectors/connector-salesforce/src/main/java/com/metamatrix/connector/salesforce/execution/visitors/JoinQueryVisitor.java
===================================================================
--- trunk/connectors/connector-salesforce/src/main/java/com/metamatrix/connector/salesforce/execution/visitors/JoinQueryVisitor.java (rev 0)
+++ trunk/connectors/connector-salesforce/src/main/java/com/metamatrix/connector/salesforce/execution/visitors/JoinQueryVisitor.java 2009-08-21 18:59:08 UTC (rev 1267)
@@ -0,0 +1,167 @@
+package com.metamatrix.connector.salesforce.execution.visitors;
+
+import org.teiid.connector.api.ConnectorException;
+import org.teiid.connector.language.IAggregate;
+import org.teiid.connector.language.ICompareCriteria;
+import org.teiid.connector.language.IElement;
+import org.teiid.connector.language.IExpression;
+import org.teiid.connector.language.IFromItem;
+import org.teiid.connector.language.IGroup;
+import org.teiid.connector.language.IJoin;
+import org.teiid.connector.language.ISelectSymbol;
+import org.teiid.connector.metadata.runtime.Element;
+import org.teiid.connector.metadata.runtime.Group;
+import org.teiid.connector.metadata.runtime.RuntimeMetadata;
+
+import com.metamatrix.connector.salesforce.Util;
+
+/**
+ * Salesforce supports joins only on primary key/foreign key relationships. The connector
+ * is supporting these joins through the OUTER JOIN syntax. All RIGHT OUTER JOINS are
+ * rewritten by the query processor as LEFT OUTER JOINS, so that is all this visitor has
+ * to expect.
+ *
+ * Salesforce also requires a different syntax depending upon if you are joining from parent
+ * to child, or from child to parent.
+ * http://www.salesforce.com/us/developer/docs/api/index_Left.htm#StartTopic...
+ *
+ */
+
+public class JoinQueryVisitor extends SelectVisitor implements
+ IQueryProvidingVisitor {
+
+ private Group leftTableInJoin;
+ private Group rightTableInJoin;
+ private Group childTable;
+
+ public JoinQueryVisitor(RuntimeMetadata metadata) {
+ super(metadata);
+ }
+
+ // Has to be a left outer join
+ @Override
+ public void visit(IJoin join) {
+ try {
+ IFromItem left = join.getLeftItem();
+ if (left instanceof IGroup) {
+ IGroup leftGroup = (IGroup) left;
+ leftTableInJoin = leftGroup.getMetadataObject();
+ loadColumnMetadata(leftGroup);
+ }
+
+ IFromItem right = join.getRightItem();
+ if (right instanceof IGroup) {
+ IGroup rightGroup = (IGroup) right;
+ rightTableInJoin = rightGroup.getMetadataObject();
+ loadColumnMetadata((IGroup) right);
+ }
+ super.visit(join);
+ } catch (ConnectorException ce) {
+ exceptions.add(ce);
+ }
+
+ }
+
+ @Override
+ public void visit(ICompareCriteria criteria) {
+
+ // Find the criteria that joins the two tables
+ try {
+ IExpression rExp = criteria.getRightExpression();
+ if (rExp instanceof IElement) {
+ IExpression lExp = criteria.getLeftExpression();
+ if (isIdColumn((IExpression) rExp) || isIdColumn(lExp)) {
+
+ Element rColumn = ((IElement) rExp).getMetadataObject();
+ String rTableName = rColumn.getParent().getNameInSource();
+
+ Element lColumn = ((IElement) lExp).getMetadataObject();
+ String lTableName = lColumn.getParent().getNameInSource();
+
+ if (leftTableInJoin.getNameInSource().equals(rTableName)
+ || leftTableInJoin.getNameInSource().equals(lTableName)
+ && rightTableInJoin.getNameInSource().equals(rTableName)
+ || rightTableInJoin.getNameInSource().equals(lTableName)
+ && !rTableName.equals(lTableName)) {
+ // This is the join criteria, the one that is the ID is the parent.
+ IExpression fKey = !isIdColumn(lExp) ? lExp : rExp;
+ table = childTable = ((IElement) fKey).getMetadataObject().getParent();
+ } else {
+ // Only add the criteria to the query if it is not the join criteria.
+ // The join criteria is implicit in the salesforce syntax.
+ super.visit(criteria);
+ }
+ }
+ } else {
+ super.visit(criteria);
+ }
+ } catch (ConnectorException e) {
+ exceptions.add(e);
+ }
+ }
+
+ @Override
+ public String getQuery() throws ConnectorException {
+
+ if (isParentToChildJoin()) {
+ return super.getQuery();
+ } else {
+ if (!exceptions.isEmpty()) {
+ throw ((ConnectorException) exceptions.get(0));
+ }
+ StringBuffer select = new StringBuffer();
+ select.append(SELECT).append(SPACE);
+ addSelectSymbols(leftTableInJoin.getNameInSource(), select);
+ select.append(COMMA).append(SPACE).append(OPEN);
+
+ StringBuffer subselect = new StringBuffer();
+ subselect.append(SELECT).append(SPACE);
+ addSelectSymbols(rightTableInJoin.getNameInSource(), subselect);
+ subselect.append(SPACE);
+ subselect.append(FROM).append(SPACE);
+ subselect.append(rightTableInJoin.getNameInSource()).append('s');
+ subselect.append(CLOSE).append(SPACE);
+ select.append(subselect);
+ select.append(FROM).append(SPACE);
+ select.append(leftTableInJoin.getNameInSource()).append(SPACE);
+ addCriteriaString(select);
+ select.append(limitClause);
+ Util.validateQueryLength(select);
+ return select.toString();
+ }
+ }
+
+ public boolean isParentToChildJoin() {
+ return childTable.equals(leftTableInJoin);
+ }
+
+ protected void addSelectSymbols(String tableNameInSource, StringBuffer result) throws ConnectorException {
+ boolean firstTime = true;
+ for (ISelectSymbol symbol : selectSymbols) {
+ IExpression expression = symbol.getExpression();
+ if (expression instanceof IElement) {
+ Element element = ((IElement) expression).getMetadataObject();
+ String tableName = element.getParent().getNameInSource();
+ if(!isParentToChildJoin() && tableNameInSource.equals(tableName) ||
+ isParentToChildJoin()) {
+ if (!firstTime) {
+ result.append(", ");
+ } else {
+ firstTime = false;
+ }
+ result.append(tableName);
+ result.append('.');
+ result.append(element.getNameInSource());
+ }
+ } else if (expression instanceof IAggregate) {
+ if (!firstTime) {
+ result.append(", ");
+ } else {
+ firstTime = false;
+ }
+ result.append("count()"); //$NON-NLS-1$
+ }
+ }
+ }
+
+}
Modified: trunk/connectors/connector-salesforce/src/main/java/com/metamatrix/connector/salesforce/execution/visitors/SelectVisitor.java
===================================================================
--- trunk/connectors/connector-salesforce/src/main/java/com/metamatrix/connector/salesforce/execution/visitors/SelectVisitor.java 2009-08-20 13:14:46 UTC (rev 1266)
+++ trunk/connectors/connector-salesforce/src/main/java/com/metamatrix/connector/salesforce/execution/visitors/SelectVisitor.java 2009-08-21 18:59:08 UTC (rev 1267)
@@ -31,6 +31,7 @@
import org.teiid.connector.language.IElement;
import org.teiid.connector.language.IExpression;
import org.teiid.connector.language.IFrom;
+import org.teiid.connector.language.IFromItem;
import org.teiid.connector.language.IGroup;
import org.teiid.connector.language.IQuery;
import org.teiid.connector.language.ISelect;
@@ -38,6 +39,7 @@
import org.teiid.connector.metadata.runtime.Element;
import org.teiid.connector.metadata.runtime.RuntimeMetadata;
+import com.metamatrix.connector.salesforce.Constants;
import com.metamatrix.connector.salesforce.Messages;
import com.metamatrix.connector.salesforce.Util;
@@ -47,10 +49,9 @@
private Map<String, Integer> selectSymbolNameToIndex = new HashMap<String, Integer>();
private int selectSymbolCount;
private int idIndex = -1; // index of the ID select symbol.
- private StringBuffer selectSymbols = new StringBuffer();
- private StringBuffer limitClause = new StringBuffer();
- //private StringBuffer orderByClause = new StringBuffer();
-
+ protected List<ISelectSymbol> selectSymbols;
+ protected StringBuffer limitClause = new StringBuffer();
+
public SelectVisitor(RuntimeMetadata metadata) {
super(metadata);
}
@@ -71,10 +72,9 @@
Messages.getString("SelectVisitor.distinct.not.supported")));
}
try {
- List<ISelectSymbol> symbols = select.getSelectSymbols();
- selectSymbolCount = symbols.size();
- Iterator<ISelectSymbol> symbolIter = symbols.iterator();
- boolean firstTime = true;
+ selectSymbols = select.getSelectSymbols();
+ selectSymbolCount = selectSymbols.size();
+ Iterator<ISelectSymbol> symbolIter = selectSymbols.iterator();
int index = 0;
while (symbolIter.hasNext()) {
ISelectSymbol symbol = symbolIter.next();
@@ -94,14 +94,6 @@
if (nameInSource.equalsIgnoreCase("id")) {
idIndex = index;
}
- if (!firstTime) {
- selectSymbols.append(", ");
- } else {
- firstTime = false;
- }
- selectSymbols.append(nameInSource);
- } else if (expression instanceof IAggregate) {
- selectSymbols.append("count()"); //$NON-NLS-1$
}
++index;
}
@@ -114,27 +106,23 @@
public void visit(IFrom from) {
super.visit(from);
try {
- IGroup group = (IGroup) from.getItems().get(0);
- loadColumnMetadata(group);
+ // could be a join here, but if so we do nothing and handle
+ // it in visit(IJoin join).
+ IFromItem fromItem = (IFromItem) from.getItems().get(0);
+ if(fromItem instanceof IGroup) {
+ table = ((IGroup)fromItem).getMetadataObject();
+ String supportsQuery = (String)table.getProperties().get(Constants.SUPPORTS_QUERY);
+ if (!Boolean.valueOf(supportsQuery)) {
+ throw new ConnectorException(table.getNameInSource() + " "
+ + Messages.getString("CriteriaVisitor.query.not.supported"));
+ }
+ loadColumnMetadata((IGroup)fromItem);
+ }
} catch (ConnectorException ce) {
exceptions.add(ce);
}
}
-
-/*
- @Override
- public void visit(IOrderBy orderBy) {
- super.visit(orderBy);
- List items = orderBy.getItems();
- if(items.size() > 1) {
- exceptions.add(new ConnectorException("Salesforce cannot support more than one item in the ORDER BY clause"));
- }
- StringBuffer result = new StringBuffer();
- result.append(ORDER_BY).append(SPACE);
- result.append(items.get(0));
- orderByClause = result;
- }
-*/
+
/*
* The SOQL SELECT command uses the following syntax: SELECT fieldList FROM
* objectType [WHERE The Condition Expression (WHERE Clause)] [ORDER BY]
@@ -147,7 +135,8 @@
}
StringBuffer result = new StringBuffer();
result.append(SELECT).append(SPACE);
- result.append(selectSymbols).append(SPACE);
+ addSelectSymbols(table.getNameInSource(), result);
+ result.append(SPACE);
result.append(FROM).append(SPACE);
result.append(table.getNameInSource()).append(SPACE);
addCriteriaString(result);
@@ -157,6 +146,28 @@
return result.toString();
}
+ protected void addSelectSymbols(String tableNameInSource, StringBuffer result) throws ConnectorException {
+ boolean firstTime = true;
+ for (ISelectSymbol symbol : selectSymbols) {
+ if (!firstTime) {
+ result.append(", ");
+ } else {
+ firstTime = false;
+ }
+ IExpression expression = symbol.getExpression();
+ if (expression instanceof IElement) {
+ Element element = ((IElement) expression).getMetadataObject();
+ String tableName = element.getParent().getNameInSource();
+ result.append(tableName);
+ result.append('.');
+ result.append(element.getNameInSource());
+ } else if (expression instanceof IAggregate) {
+ result.append("count()"); //$NON-NLS-1$
+ }
+ }
+ }
+
+
public int getSelectSymbolCount() {
return selectSymbolCount;
}
Modified: trunk/connectors/connector-salesforce/src/test/java/com/metamatrix/connector/salesforce/execution/visitors/TestVisitors.java
===================================================================
--- trunk/connectors/connector-salesforce/src/test/java/com/metamatrix/connector/salesforce/execution/visitors/TestVisitors.java 2009-08-20 13:14:46 UTC (rev 1266)
+++ trunk/connectors/connector-salesforce/src/test/java/com/metamatrix/connector/salesforce/execution/visitors/TestVisitors.java 2009-08-21 18:59:08 UTC (rev 1267)
@@ -40,37 +40,64 @@
public static FakeMetadataFacade exampleSalesforce() {
// Create models
FakeMetadataObject salesforceModel = FakeMetadataFactory.createPhysicalModel("SalesforceModel"); //$NON-NLS-1$
+
+ // Create Account group
+ FakeMetadataObject accounTable = FakeMetadataFactory.createPhysicalGroup("SalesforceModel.Account", salesforceModel); //$NON-NLS-1$
+ accounTable.putProperty(FakeMetadataObject.Props.NAME_IN_SOURCE, "Account"); //$NON-NLS-1$
+ accounTable.setExtensionProp("Supports Query", Boolean.TRUE.toString()); //$NON-NLS-1$
+ // Create Account Columns
+ String[] acctNames = new String[] {
+ "ID", "Name", "Stuff", "Industry" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ };
+ String[] acctTypes = new String[] {
+ DataTypeManager.DefaultDataTypes.STRING, DataTypeManager.DefaultDataTypes.STRING, DataTypeManager.DefaultDataTypes.STRING, DataTypeManager.DefaultDataTypes.STRING
+ };
- // Create physical groups
- FakeMetadataObject table = FakeMetadataFactory.createPhysicalGroup("SalesforceModel.Account", salesforceModel); //$NON-NLS-1$
- table.putProperty(FakeMetadataObject.Props.NAME_IN_SOURCE, "Account"); //$NON-NLS-1$
- table.setExtensionProp("Supports Query", Boolean.TRUE.toString()); //$NON-NLS-1$
- // Create physical elements
+ List<FakeMetadataObject> acctCols = FakeMetadataFactory.createElements(accounTable, acctNames, acctTypes);
+ acctCols.get(2).putProperty(FakeMetadataObject.Props.NATIVE_TYPE, "multipicklist"); //$NON-NLS-1$
+ acctCols.get(2).putProperty(FakeMetadataObject.Props.SEARCHABLE_COMPARE, false);
+ acctCols.get(2).putProperty(FakeMetadataObject.Props.SEARCHABLE_LIKE, true);
+ // Set name in source on each column
+ String[] accountNameInSource = new String[] {
+ "id", "AccountName", "Stuff", "Industry" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ };
+ for(int i=0; i<2; i++) {
+ FakeMetadataObject obj = acctCols.get(i);
+ obj.putProperty(FakeMetadataObject.Props.NAME_IN_SOURCE, accountNameInSource[i]);
+ }
+
+ // Add all Account to the store
+ FakeMetadataStore store = new FakeMetadataStore();
+ store.addObject(salesforceModel);
+ store.addObject(accounTable);
+ store.addObjects(acctCols);
+
+ // Create Contact group
+ FakeMetadataObject contactTable = FakeMetadataFactory.createPhysicalGroup("SalesforceModel.Contact", salesforceModel); //$NON-NLS-1$
+ contactTable.putProperty(FakeMetadataObject.Props.NAME_IN_SOURCE, "Contact"); //$NON-NLS-1$
+ contactTable.setExtensionProp("Supports Query", Boolean.TRUE.toString()); //$NON-NLS-1$
+ // Create Contact Columns
String[] elemNames = new String[] {
- "AccountID", "Name", "Stuff" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ "ContactID", "Name", "AccountId" //$NON-NLS-1$ //$NON-NLS-2$
};
String[] elemTypes = new String[] {
DataTypeManager.DefaultDataTypes.STRING, DataTypeManager.DefaultDataTypes.STRING, DataTypeManager.DefaultDataTypes.STRING
};
- List<FakeMetadataObject> cols = FakeMetadataFactory.createElements(table, elemNames, elemTypes);
- cols.get(2).putProperty(FakeMetadataObject.Props.NATIVE_TYPE, "multipicklist"); //$NON-NLS-1$
- cols.get(2).putProperty(FakeMetadataObject.Props.SEARCHABLE_COMPARE, false);
- cols.get(2).putProperty(FakeMetadataObject.Props.SEARCHABLE_LIKE, true);
+ List<FakeMetadataObject> contactCols = FakeMetadataFactory.createElements(contactTable, elemNames, elemTypes);
// Set name in source on each column
- String[] nameInSource = new String[] {
- "id", "AccountName", "Stuff" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ String[] contactNameInSource = new String[] {
+ "id", "ContactName", "accountid" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
};
for(int i=0; i<2; i++) {
- FakeMetadataObject obj = cols.get(i);
- obj.putProperty(FakeMetadataObject.Props.NAME_IN_SOURCE, nameInSource[i]);
+ FakeMetadataObject obj = contactCols.get(i);
+ obj.putProperty(FakeMetadataObject.Props.NAME_IN_SOURCE, contactNameInSource[i]);
}
- // Add all objects to the store
- FakeMetadataStore store = new FakeMetadataStore();
+ // Add all Account to the store
store.addObject(salesforceModel);
- store.addObject(table);
- store.addObjects(cols);
+ store.addObject(contactTable);
+ store.addObjects(contactCols);
// Create the facade from the store
return new FakeMetadataFacade(store);
@@ -82,14 +109,14 @@
IQuery command = (IQuery)translationUtility.parseCommand("select * from Account where Name = 'foo' or Stuff = 'bar'"); //$NON-NLS-1$
SelectVisitor visitor = new SelectVisitor(translationUtility.createRuntimeMetadata());
visitor.visit(command);
- assertEquals("SELECT id, AccountName, Stuff FROM Account WHERE (AccountName = 'foo') OR (Stuff = 'bar')", visitor.getQuery().toString().trim()); //$NON-NLS-1$
+ assertEquals("SELECT Account.id, Account.AccountName, Account.Stuff, Account.Industry FROM Account WHERE (Account.AccountName = 'foo') OR (Account.Stuff = 'bar')", visitor.getQuery().toString().trim()); //$NON-NLS-1$
}
@Test public void testNot() throws Exception {
IQuery command = (IQuery)translationUtility.parseCommand("select * from Account where not (Name = 'foo' and Stuff = 'bar')"); //$NON-NLS-1$
SelectVisitor visitor = new SelectVisitor(translationUtility.createRuntimeMetadata());
visitor.visit(command);
- assertEquals("SELECT id, AccountName, Stuff FROM Account WHERE (AccountName != 'foo') OR (Stuff != 'bar')", visitor.getQuery().toString().trim()); //$NON-NLS-1$
+ assertEquals("SELECT Account.id, Account.AccountName, Account.Stuff, Account.Industry FROM Account WHERE NOT ((Account.AccountName = 'foo') AND (Account.Stuff = 'bar'))", visitor.getQuery().toString().trim()); //$NON-NLS-1$
}
@Test public void testCountStart() throws Exception {
@@ -103,7 +130,28 @@
IQuery command = (IQuery)translationUtility.parseCommand("select * from Account where Name not like '%foo' or Stuff = 'bar'"); //$NON-NLS-1$
SelectVisitor visitor = new SelectVisitor(translationUtility.createRuntimeMetadata());
visitor.visit(command);
- assertEquals("SELECT id, AccountName, Stuff FROM Account WHERE (NOT (Account.AccountName LIKE '%foo')) OR (Stuff = 'bar')", visitor.getQuery().toString().trim()); //$NON-NLS-1$
+ assertEquals("SELECT Account.id, Account.AccountName, Account.Stuff, Account.Industry FROM Account WHERE (NOT (Account.AccountName LIKE '%foo')) OR (Account.Stuff = 'bar')", visitor.getQuery().toString().trim()); //$NON-NLS-1$
}
+
+ // I can't really write this test until I see what teiid is going to pass the connectro based upon the user query.
+ // SELECT Account.Name AS c_0, Contact.Name AS c_1 FROM Contact LEFT OUTER JOIN Account ON Account.Id = Contact.AccountId
+ @Test public void testJoin() throws Exception {
+ IQuery command = (IQuery)translationUtility.parseCommand("SELECT Account.Name, Contact.Name FROM Contact LEFT OUTER JOIN Account ON Account.Id = Contact.AccountId"); //$NON-NLS-1$
+
+ SelectVisitor visitor = new JoinQueryVisitor(translationUtility.createRuntimeMetadata());
+ visitor.visit(command);
+ assertEquals("SELECT Account.AccountName, Contact.ContactName FROM Contact", visitor.getQuery().toString().trim()); //$NON-NLS-1$
+ // SELECT Contact.Id, Contact.Name, Account.Name FROM Contact WHERE Account.Industry != 'media'
+ // Looks like using q names will work, but we need to distinguish between the parent and child table somehow cannot send
+ // SELECT Contact.Id, Contact.Name, Account.Name FROM Contact, Account WHERE Account.Industry != 'media'
+ }
+
+ @Test public void testJoin2() throws Exception {
+ IQuery command = (IQuery)translationUtility.parseCommand("SELECT Account.Name, Contact.Name FROM Account LEFT OUTER JOIN Contact ON Account.Id = Contact.AccountId"); //$NON-NLS-1$
+
+ SelectVisitor visitor = new JoinQueryVisitor(translationUtility.createRuntimeMetadata());
+ visitor.visit(command);
+ assertEquals("SELECT Account.AccountName, (SELECT Contact.ContactName FROM Contacts) FROM Account", visitor.getQuery().toString().trim()); //$NON-NLS-1$
+ }
}
16 years, 1 month
teiid SVN: r1266 - in trunk: connectors/connector-ldap/src/test/java/com/metamatrix/connector/ldap and 8 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2009-08-20 09:14:46 -0400 (Thu, 20 Aug 2009)
New Revision: 1266
Modified:
trunk/connectors/connector-ldap/src/main/java/com/metamatrix/connector/ldap/IQueryToLdapSearchParser.java
trunk/connectors/connector-ldap/src/test/java/com/metamatrix/connector/ldap/TestIQueryToLdapSearchParser.java
trunk/connectors/connector-salesforce/src/test/java/com/metamatrix/connector/salesforce/execution/visitors/TestVisitors.java
trunk/engine/src/main/java/com/metamatrix/query/rewriter/QueryRewriter.java
trunk/engine/src/main/java/com/metamatrix/query/sql/lang/AbstractCompareCriteria.java
trunk/engine/src/main/java/com/metamatrix/query/sql/lang/AbstractSetCriteria.java
trunk/engine/src/main/java/com/metamatrix/query/sql/lang/CompareCriteria.java
trunk/engine/src/main/java/com/metamatrix/query/sql/lang/IsNullCriteria.java
trunk/engine/src/main/java/com/metamatrix/query/sql/lang/MatchCriteria.java
trunk/engine/src/main/java/com/metamatrix/query/sql/lang/PredicateCriteria.java
trunk/engine/src/test/java/com/metamatrix/query/rewriter/TestQueryRewriter.java
trunk/metadata/src/main/java/org/teiid/connector/metadata/MetadataResultsPostProcessor.java
trunk/metadata/src/main/java/org/teiid/metadata/index/CharOperation.java
trunk/metadata/src/test/java/com/metamatrix/connector/metadata/index/TestMetadataResultsPostProcessor.java
trunk/test-integration/src/test/java/org/teiid/connector/language/TestLanguageUtil.java
Log:
TEIID-748 updating the queryrewriter handling of possible null values.
Modified: trunk/connectors/connector-ldap/src/main/java/com/metamatrix/connector/ldap/IQueryToLdapSearchParser.java
===================================================================
--- trunk/connectors/connector-ldap/src/main/java/com/metamatrix/connector/ldap/IQueryToLdapSearchParser.java 2009-08-19 21:08:00 UTC (rev 1265)
+++ trunk/connectors/connector-ldap/src/main/java/com/metamatrix/connector/ldap/IQueryToLdapSearchParser.java 2009-08-20 13:14:46 UTC (rev 1266)
@@ -476,7 +476,7 @@
while(itr.hasNext()) {
ICriteria c = (ICriteria)itr.next();
// recurse on each criterion
- filterList = getSearchFilterFromWhereClause(c, filterList);
+ filterList.addAll(getSearchFilterFromWhereClause(c, new LinkedList()));
}
filterList.add(")"); //$NON-NLS-1$
@@ -527,7 +527,7 @@
} else if (criteria instanceof INotCriteria) {
logger.logTrace("Parsing NOT criteria."); //$NON-NLS-1$
isNegated = true;
- filterList = getSearchFilterFromWhereClause(((INotCriteria)criteria).getCriteria(), filterList);
+ filterList.addAll(getSearchFilterFromWhereClause(((INotCriteria)criteria).getCriteria(), new LinkedList()));
}
if (isNegated) {
Modified: trunk/connectors/connector-ldap/src/test/java/com/metamatrix/connector/ldap/TestIQueryToLdapSearchParser.java
===================================================================
--- trunk/connectors/connector-ldap/src/test/java/com/metamatrix/connector/ldap/TestIQueryToLdapSearchParser.java 2009-08-19 21:08:00 UTC (rev 1265)
+++ trunk/connectors/connector-ldap/src/test/java/com/metamatrix/connector/ldap/TestIQueryToLdapSearchParser.java 2009-08-20 13:14:46 UTC (rev 1266)
@@ -191,7 +191,7 @@
// Set Expected SearchDetails Values
//-----------------------------------
String expectedContextName = "ou=people,dc=metamatrix,dc=com"; //$NON-NLS-1$
- String expectedContextFilter = "(!(|(cn=R*)(cn=S*)))"; //$NON-NLS-1$
+ String expectedContextFilter = "(&(!(cn=R*))(!(cn=S*)))"; //$NON-NLS-1$
List expectedAttrNameList = new ArrayList();
expectedAttrNameList.add("uid"); //$NON-NLS-1$
Modified: trunk/connectors/connector-salesforce/src/test/java/com/metamatrix/connector/salesforce/execution/visitors/TestVisitors.java
===================================================================
--- trunk/connectors/connector-salesforce/src/test/java/com/metamatrix/connector/salesforce/execution/visitors/TestVisitors.java 2009-08-19 21:08:00 UTC (rev 1265)
+++ trunk/connectors/connector-salesforce/src/test/java/com/metamatrix/connector/salesforce/execution/visitors/TestVisitors.java 2009-08-20 13:14:46 UTC (rev 1266)
@@ -89,7 +89,7 @@
IQuery command = (IQuery)translationUtility.parseCommand("select * from Account where not (Name = 'foo' and Stuff = 'bar')"); //$NON-NLS-1$
SelectVisitor visitor = new SelectVisitor(translationUtility.createRuntimeMetadata());
visitor.visit(command);
- assertEquals("SELECT id, AccountName, Stuff FROM Account WHERE NOT ((AccountName = 'foo') AND (Stuff = 'bar'))", visitor.getQuery().toString().trim()); //$NON-NLS-1$
+ assertEquals("SELECT id, AccountName, Stuff FROM Account WHERE (AccountName != 'foo') OR (Stuff != 'bar')", visitor.getQuery().toString().trim()); //$NON-NLS-1$
}
@Test public void testCountStart() throws Exception {
Modified: trunk/engine/src/main/java/com/metamatrix/query/rewriter/QueryRewriter.java
===================================================================
--- trunk/engine/src/main/java/com/metamatrix/query/rewriter/QueryRewriter.java 2009-08-19 21:08:00 UTC (rev 1265)
+++ trunk/engine/src/main/java/com/metamatrix/query/rewriter/QueryRewriter.java 2009-08-20 13:14:46 UTC (rev 1266)
@@ -116,6 +116,7 @@
import com.metamatrix.query.sql.lang.UnaryFromClause;
import com.metamatrix.query.sql.lang.Update;
import com.metamatrix.query.sql.lang.XQuery;
+import com.metamatrix.query.sql.lang.PredicateCriteria.Negatable;
import com.metamatrix.query.sql.navigator.PostOrderNavigator;
import com.metamatrix.query.sql.navigator.PreOrderNavigator;
import com.metamatrix.query.sql.proc.AssignmentStatement;
@@ -186,7 +187,7 @@
private ProcessorDataManager dataMgr;
private Map variables; //constant propagation
private int commandType;
-
+
private QueryRewriter(QueryMetadataInterface metadata,
CommandContext context, CreateUpdateProcedureCommand procCommand) {
this.metadata = metadata;
@@ -314,23 +315,17 @@
return result;
}
- private Option mergeOptions( Option sourceOption, Option targetOption ) {
- if ( sourceOption == null ) {
- return targetOption;
- }
- if ( sourceOption.getPlanOnly() == true ) {
+ private void mergeOptions( Option sourceOption, Option targetOption ) {
+ if ( sourceOption.getPlanOnly()) {
targetOption.setPlanOnly( true );
}
- if ( sourceOption.getDebug() == true ) {
+ if ( sourceOption.getDebug()) {
targetOption.setDebug( true );
}
- if ( sourceOption.getShowPlan() == true ) {
+ if ( sourceOption.getShowPlan()) {
targetOption.setShowPlan( true );
}
-
- return targetOption;
}
-
private Command removeProceduralWrapper(Command command) throws QueryValidatorException {
@@ -361,7 +356,7 @@
return command;
}
try {
- Object value = Evaluator.evaluate(expr);
+ Object value = new Evaluator(Collections.emptyMap(), this.dataMgr, context).evaluate(expr, Collections.emptyList());
//check contraint
if (value == null && !metadata.elementSupports(param.getMetadataID(), SupportConstants.Element.NULL)) {
@@ -388,11 +383,9 @@
if (child != null && child.getType() != Command.TYPE_DYNAMIC) {
if ( child.getOption() == null ) {
child.setOption( command.getOption() );
- } else {
- Option merged = mergeOptions( command.getOption(), child.getOption() );
- child.setOption(merged);
+ } else if (command.getOption() != null) {
+ mergeOptions( command.getOption(), child.getOption() );
}
-
return child;
}
return command;
@@ -438,8 +431,7 @@
case Statement.TYPE_IF:
IfStatement ifStmt = (IfStatement) statement;
Criteria ifCrit = ifStmt.getCondition();
- Criteria evalCrit = rewriteCriteria(ifCrit, false);
- evalCrit = evaluateCriteria(evalCrit);
+ Criteria evalCrit = rewriteCriteria(ifCrit);
ifStmt.setCondition(evalCrit);
if(evalCrit.equals(TRUE_CRITERIA)) {
@@ -507,13 +499,12 @@
case Statement.TYPE_WHILE:
WhileStatement whileStatement = (WhileStatement) statement;
Criteria crit = whileStatement.getCondition();
- crit = rewriteCriteria(crit, false);
- evalCrit = evaluateCriteria(crit);
+ crit = rewriteCriteria(crit);
- whileStatement.setCondition(evalCrit);
- if(evalCrit.equals(TRUE_CRITERIA)) {
+ whileStatement.setCondition(crit);
+ if(crit.equals(TRUE_CRITERIA)) {
throw new QueryValidatorException(QueryExecPlugin.Util.getString("QueryRewriter.infinite_while")); //$NON-NLS-1$
- } else if(evalCrit.equals(FALSE_CRITERIA) || evalCrit.equals(UNKNOWN_CRITERIA)) {
+ } else if(crit.equals(FALSE_CRITERIA) || crit.equals(UNKNOWN_CRITERIA)) {
return null;
}
whileStatement.setBlock(rewriteBlock(whileStatement.getBlock()));
@@ -571,7 +562,7 @@
hasCritElmts = selector.getElements();
// collect elements present on the user's criteria and check if
// all of the hasCriteria elements are among them
- Collection userElmnts = ElementCollectorVisitor.getElements(userCrit, true);
+ Collection<ElementSymbol> userElmnts = ElementCollectorVisitor.getElements(userCrit, true);
if(!userElmnts.containsAll(hasCritElmts)) {
return FALSE_CRITERIA;
}
@@ -590,7 +581,7 @@
Criteria predicateCriteria = (Criteria) criteriaIter.next();
// atleast one of the hasElemnets should be on this predicate else
// proceed to the next predicate
- Collection predElmnts = ElementCollectorVisitor.getElements(predicateCriteria, true);
+ Collection<ElementSymbol> predElmnts = ElementCollectorVisitor.getElements(predicateCriteria, true);
if(selector.hasElements()) {
Iterator hasIter = hasCritElmts.iterator();
boolean containsElmnt = false;
@@ -701,7 +692,7 @@
translatedCriteria = translateVisitor.getTranslatedCriteria();
((TranslatableProcedureContainer)userCmd).addImplicitParameters(translateVisitor.getImplicitParams());
- translatedCriteria = rewriteCriteria(translatedCriteria, false);
+ translatedCriteria = rewriteCriteria(translatedCriteria);
// apply any implicit conversions
try {
@@ -732,7 +723,7 @@
// Rewrite criteria
Criteria crit = query.getCriteria();
if(crit != null) {
- crit = rewriteCriteria(crit, false);
+ crit = rewriteCriteria(crit);
if(crit == TRUE_CRITERIA) {
query.setCriteria(null);
} else {
@@ -817,7 +808,7 @@
// Rewrite having
Criteria having = query.getHaving();
if(having != null) {
- query.setHaving(rewriteCriteria(having, false));
+ query.setHaving(rewriteCriteria(having));
}
rewriteExpressions(query.getSelect());
@@ -1018,7 +1009,7 @@
//rewrite join crits by rewriting a compound criteria
Criteria criteria = new CompoundCriteria(new ArrayList(joinCrits));
joinCrits.clear();
- criteria = rewriteCriteria(criteria, false);
+ criteria = rewriteCriteria(criteria);
if (criteria instanceof CompoundCriteria && ((CompoundCriteria)criteria).getOperator() == CompoundCriteria.AND) {
joinCrits.addAll(((CompoundCriteria)criteria).getCriteria());
} else {
@@ -1052,7 +1043,7 @@
* @return The re-written criteria
*/
public static Criteria rewriteCriteria(Criteria criteria, CreateUpdateProcedureCommand procCommand, CommandContext context, QueryMetadataInterface metadata) throws QueryValidatorException {
- return new QueryRewriter(metadata, context, procCommand).rewriteCriteria(criteria, false);
+ return new QueryRewriter(metadata, context, procCommand).rewriteCriteria(criteria);
}
/**
@@ -1062,9 +1053,9 @@
* in the procedural language.
* @return The re-written criteria
*/
- private Criteria rewriteCriteria(Criteria criteria, boolean preserveUnknown) throws QueryValidatorException {
- if(criteria instanceof CompoundCriteria) {
- return rewriteCriteria((CompoundCriteria)criteria, true, preserveUnknown);
+ private Criteria rewriteCriteria(Criteria criteria) throws QueryValidatorException {
+ if(criteria instanceof CompoundCriteria) {
+ return rewriteCriteria((CompoundCriteria)criteria, true);
} else if(criteria instanceof NotCriteria) {
criteria = rewriteCriteria((NotCriteria)criteria);
} else if(criteria instanceof CompareCriteria) {
@@ -1078,7 +1069,7 @@
} else if(criteria instanceof IsNullCriteria) {
criteria = rewriteCriteria((IsNullCriteria)criteria);
} else if(criteria instanceof BetweenCriteria) {
- criteria = rewriteCriteria((BetweenCriteria)criteria, preserveUnknown);
+ criteria = rewriteCriteria((BetweenCriteria)criteria);
} else if(criteria instanceof HasCriteria) {
criteria = rewriteCriteria((HasCriteria)criteria);
} else if(criteria instanceof TranslateCriteria) {
@@ -1094,7 +1085,7 @@
} else if (criteria instanceof DependentSetCriteria) {
criteria = rewriteCriteria((AbstractSetCriteria)criteria);
}
-
+
return evaluateCriteria(criteria);
}
@@ -1106,7 +1097,7 @@
*/
public static Criteria optimizeCriteria(CompoundCriteria criteria) {
try {
- return new QueryRewriter(null, null, null).rewriteCriteria(criteria, false, false);
+ return new QueryRewriter(null, null, null).rewriteCriteria(criteria, false);
} catch (QueryValidatorException err) {
//shouldn't happen
return criteria;
@@ -1116,20 +1107,17 @@
/** May be simplified if this is an AND and a sub criteria is always
* false or if this is an OR and a sub criteria is always true
*/
- private Criteria rewriteCriteria(CompoundCriteria criteria, boolean rewrite, boolean preserveUnknown) throws QueryValidatorException {
- List crits = criteria.getCriteria();
+ private Criteria rewriteCriteria(CompoundCriteria criteria, boolean rewrite) throws QueryValidatorException {
+ List<Criteria> crits = criteria.getCriteria();
int operator = criteria.getOperator();
// Walk through crits and collect converted ones
- LinkedHashSet newCrits = new LinkedHashSet(crits.size());
- Iterator critIter = crits.iterator();
- while(critIter.hasNext()) {
- Criteria converted = (Criteria) critIter.next();
+ LinkedHashSet<Criteria> newCrits = new LinkedHashSet<Criteria>(crits.size());
+ for (Criteria converted : crits) {
if (rewrite) {
- converted = rewriteCriteria(converted, preserveUnknown);
- converted = evaluateCriteria(converted);
+ converted = rewriteCriteria(converted);
} else if (converted instanceof CompoundCriteria) {
- converted = rewriteCriteria((CompoundCriteria)converted, false, preserveUnknown);
+ converted = rewriteCriteria((CompoundCriteria)converted, false);
}
//begin boolean optimizations
@@ -1143,25 +1131,20 @@
// this AND must be false as at least one branch is always false
return converted;
}
+ } else if (converted == UNKNOWN_CRITERIA) {
+ if (operator == CompoundCriteria.AND) {
+ return FALSE_CRITERIA;
+ }
+ continue;
} else {
if (converted instanceof CompoundCriteria) {
CompoundCriteria other = (CompoundCriteria)converted;
if (other.getOperator() == criteria.getOperator()) {
- Iterator i = other.getCriteria().iterator();
- while (i.hasNext()) {
- newCrits.add(i.next());
- }
+ newCrits.addAll(other.getCriteria());
continue;
}
}
- //if we're not interested in preserving unknowns, then treat unknown as false
- if (!preserveUnknown && converted == UNKNOWN_CRITERIA) {
- if (operator == CompoundCriteria.AND) {
- return FALSE_CRITERIA;
- }
- } else {
- newCrits.add(converted);
- }
+ newCrits.add(converted);
}
}
@@ -1172,7 +1155,7 @@
return FALSE_CRITERIA;
} else if(newCrits.size() == 1) {
// Only one sub crit now, so just return it
- return (Criteria) newCrits.iterator().next();
+ return newCrits.iterator().next();
} else {
criteria.getCriteria().clear();
criteria.getCriteria().addAll(newCrits);
@@ -1183,7 +1166,7 @@
private Criteria evaluateCriteria(Criteria crit) throws QueryValidatorException {
if(EvaluatableVisitor.isFullyEvaluatable(crit, true)) {
try {
- Boolean eval = new Evaluator(Collections.emptyMap(), null, null).evaluateTVL(crit, Collections.emptyList());
+ Boolean eval = new Evaluator(Collections.emptyMap(), this.dataMgr, context).evaluateTVL(crit, Collections.emptyList());
if (eval == null) {
return UNKNOWN_CRITERIA;
@@ -1204,12 +1187,21 @@
return crit;
}
-
private Criteria rewriteCriteria(NotCriteria criteria) throws QueryValidatorException {
- Criteria innerCrit = rewriteCriteria(criteria.getCriteria(), true);
-
- innerCrit = evaluateCriteria(innerCrit);
+ Criteria innerCrit = criteria.getCriteria();
+ if (innerCrit instanceof CompoundCriteria) {
+ //reduce to only negation of predicates, so that the null/unknown handling criteria is applied appropriately
+ return rewriteCriteria(Criteria.toConjunctiveNormalForm(criteria));
+ }
+ if (innerCrit instanceof Negatable) {
+ ((Negatable) innerCrit).negate();
+ return rewriteCriteria(innerCrit);
+ }
+ if (innerCrit instanceof NotCriteria) {
+ return rewriteCriteria(((NotCriteria)innerCrit).getCriteria());
+ }
+ innerCrit = rewriteCriteria(innerCrit);
if(innerCrit == TRUE_CRITERIA) {
return FALSE_CRITERIA;
} else if(innerCrit == FALSE_CRITERIA) {
@@ -1217,11 +1209,6 @@
} else if (innerCrit == UNKNOWN_CRITERIA) {
return UNKNOWN_CRITERIA;
}
-
- if (innerCrit instanceof NotCriteria) {
- return ((NotCriteria)innerCrit).getCriteria();
- }
-
criteria.setCriteria(innerCrit);
return criteria;
}
@@ -1232,7 +1219,7 @@
* @return
* @throws QueryValidatorException
*/
- private Criteria rewriteCriteria(BetweenCriteria criteria, boolean preserveUnknown) throws QueryValidatorException {
+ private Criteria rewriteCriteria(BetweenCriteria criteria) throws QueryValidatorException {
CompareCriteria lowerCriteria = new CompareCriteria(criteria.getExpression(),
criteria.isNegated() ? CompareCriteria.LT: CompareCriteria.GE,
criteria.getLowerExpression());
@@ -1243,14 +1230,23 @@
lowerCriteria,
upperCriteria);
- return rewriteCriteria(newCriteria, preserveUnknown);
+ return rewriteCriteria(newCriteria);
}
private Criteria rewriteCriteria(CompareCriteria criteria) throws QueryValidatorException {
Expression leftExpr = rewriteExpressionDirect(criteria.getLeftExpression());
Expression rightExpr = rewriteExpressionDirect(criteria.getRightExpression());
+ criteria.setLeftExpression(leftExpr);
+ criteria.setRightExpression(rightExpr);
- if(!EvaluatableVisitor.willBecomeConstant(rightExpr) && EvaluatableVisitor.willBecomeConstant(leftExpr)) {
+ if (isNull(leftExpr) || isNull(rightExpr)) {
+ return UNKNOWN_CRITERIA;
+ }
+
+ boolean rightConstant = false;
+ if(EvaluatableVisitor.willBecomeConstant(rightExpr)) {
+ rightConstant = true;
+ } else if (EvaluatableVisitor.willBecomeConstant(leftExpr)) {
// Swap in this particular case for connectors
criteria.setLeftExpression(rightExpr);
criteria.setRightExpression(leftExpr);
@@ -1262,19 +1258,18 @@
case CompareCriteria.GT: criteria.setOperator(CompareCriteria.LT); break;
case CompareCriteria.GE: criteria.setOperator(CompareCriteria.LE); break;
}
-
- } else {
- criteria.setLeftExpression(leftExpr);
- criteria.setRightExpression(rightExpr);
- }
-
- if(criteria.getLeftExpression() instanceof Function && EvaluatableVisitor.willBecomeConstant(criteria.getRightExpression())) {
- criteria = simplifyWithInverse(criteria);
- }
+ rightConstant = true;
+ }
- if (isNull(criteria.getLeftExpression()) || isNull(criteria.getRightExpression())) {
- return UNKNOWN_CRITERIA;
- }
+ Function f = null;
+ while (rightConstant && f != criteria.getLeftExpression() && criteria.getLeftExpression() instanceof Function) {
+ f = (Function)criteria.getLeftExpression();
+ Criteria result = simplifyWithInverse(criteria);
+ if (!(result instanceof CompareCriteria)) {
+ return result;
+ }
+ criteria = (CompareCriteria)result;
+ }
Criteria modCriteria = simplifyTimestampMerge(criteria);
if(modCriteria instanceof CompareCriteria) {
@@ -1310,7 +1305,7 @@
return criteria;
}
- private CompareCriteria simplifyWithInverse(CompareCriteria criteria) throws QueryValidatorException {
+ private Criteria simplifyWithInverse(CompareCriteria criteria) throws QueryValidatorException {
Expression leftExpr = criteria.getLeftExpression();
Function leftFunction = (Function) leftExpr;
@@ -1465,10 +1460,6 @@
criteria.setRightExpression(combinedConst);
criteria.setOperator(operator);
- if (expr instanceof Function) {
- return simplifyWithInverse(criteria);
- }
-
// Return new simplified criteria
return criteria;
}
@@ -1496,17 +1487,13 @@
* @throws QueryValidatorException
* @since 4.2
*/
- private CompareCriteria simplifyConvertFunction(CompareCriteria crit) throws QueryValidatorException {
+ private Criteria simplifyConvertFunction(CompareCriteria crit) throws QueryValidatorException {
Function leftFunction = (Function) crit.getLeftExpression();
Constant rightConstant = (Constant) crit.getRightExpression();
Expression leftExpr = leftFunction.getArgs()[0];
String leftExprTypeName = DataTypeManager.getDataTypeName(leftExpr.getType());
- if (leftExpr.getType() == DataTypeManager.DefaultDataClasses.NULL) {
- return crit;
- }
-
Constant result = null;
try {
result = ResolverUtil.convertConstant(DataTypeManager.getDataTypeName(rightConstant.getType()), leftExprTypeName, rightConstant);
@@ -1515,19 +1502,12 @@
}
if (result == null) {
- if (crit.getOperator() == CompareCriteria.EQ) {
- return FALSE_CRITERIA;
- }
- return TRUE_CRITERIA;
+ return getSimpliedCriteria(crit, leftExpr, crit.getOperator() != CompareCriteria.EQ, true);
}
- crit.setRightExpression(result);
+ crit.setRightExpression(result);
crit.setLeftExpression(leftExpr);
- if (leftExpr instanceof Function) {
- return simplifyWithInverse(crit);
- }
-
return crit;
}
@@ -1595,14 +1575,17 @@
if (!removedSome) {
return crit; //just return as is
}
- return rewriteCriteria(crit);
+ } else {
+ if (newValues.isEmpty()) {
+ return getSimpliedCriteria(crit, leftExpr, !crit.isNegated(), true);
+ }
+ crit.setExpression(leftExpr);
+ crit.setValues(newValues);
}
- crit.setExpression(leftExpr);
- crit.setValues(newValues);
return rewriteCriteria(crit);
}
- private CompareCriteria simplifyParseFormatFunction(CompareCriteria crit) throws QueryValidatorException {
+ private Criteria simplifyParseFormatFunction(CompareCriteria crit) throws QueryValidatorException {
Function leftFunction = (Function) crit.getLeftExpression();
String funcName = leftFunction.getName().toLowerCase();
String inverseFunction = null;
@@ -1668,10 +1651,7 @@
result = funcLib.invokeFunction(reverseFunction, new Object[] { result, format } );
if (!example.equals(result)) {
if (parseFunction) {
- if (crit.getOperator() == CompareCriteria.EQ) {
- return FALSE_CRITERIA;
- }
- return TRUE_CRITERIA;
+ return getSimpliedCriteria(crit, leftExpr, crit.getOperator() != CompareCriteria.EQ, true);
}
//the format is loosing information, so it must not be invertable
return crit;
@@ -1706,9 +1686,6 @@
//Not all numeric formats are invertable, so just return the criteria as it may still be valid
return crit;
}
- if (leftExpr instanceof Function) {
- return simplifyWithInverse(crit);
- }
return crit;
}
@@ -1880,40 +1857,49 @@
}
Expression rightExpr = criteria.getRightExpression();
- if(rightExpr instanceof Constant) {
+ if(rightExpr instanceof Constant && rightExpr.getType().equals(DataTypeManager.DefaultDataClasses.STRING)) {
Constant constant = (Constant) rightExpr;
- if(constant.getType().equals(DataTypeManager.DefaultDataClasses.STRING)) {
- String value = (String) constant.getValue();
+ String value = (String) constant.getValue();
- char escape = criteria.getEscapeChar();
+ char escape = criteria.getEscapeChar();
- // Check whether escape char is unnecessary and remove it
- if(escape != MatchCriteria.NULL_ESCAPE_CHAR) {
- if(value.indexOf(escape) < 0) {
- criteria.setEscapeChar(MatchCriteria.NULL_ESCAPE_CHAR);
- }
- }
+ // Check whether escape char is unnecessary and remove it
+ if(escape != MatchCriteria.NULL_ESCAPE_CHAR && value.indexOf(escape) < 0) {
+ criteria.setEscapeChar(MatchCriteria.NULL_ESCAPE_CHAR);
+ }
- // if the value of this string constant is '%', then we know the crit will
- // always be true
- if ( value.equals( String.valueOf(MatchCriteria.WILDCARD_CHAR)) ) {
- return criteria.isNegated()?FALSE_CRITERIA:TRUE_CRITERIA;
- }
-
- // if both left and right expressions are strings, and the LIKE match characters ('*', '_') are not present
- // in the right expression, rewrite the criteria as EQUALs rather than LIKE
- if(DataTypeManager.DefaultDataClasses.STRING.equals(criteria.getLeftExpression().getType()) && value.indexOf(escape) < 0 && value.indexOf(MatchCriteria.MATCH_CHAR) < 0 && value.indexOf(MatchCriteria.WILDCARD_CHAR) < 0) {
- if (value.equals(MatchCriteria.WILDCARD_CHAR)) {
- return TRUE_CRITERIA;
- }
- return rewriteCriteria(new CompareCriteria(criteria.getLeftExpression(), criteria.isNegated()?CompareCriteria.NE:CompareCriteria.EQ, criteria.getRightExpression()));
- }
+ // if the value of this string constant is '%', then we know the crit will
+ // always be true
+ if ( value.equals( String.valueOf(MatchCriteria.WILDCARD_CHAR)) ) {
+ return getSimpliedCriteria(criteria, criteria.getLeftExpression(), !criteria.isNegated(), true);
+ }
+
+ // if both left and right expressions are strings, and the LIKE match characters ('*', '_') are not present
+ // in the right expression, rewrite the criteria as EQUALs rather than LIKE
+ if(DataTypeManager.DefaultDataClasses.STRING.equals(criteria.getLeftExpression().getType()) && value.indexOf(escape) < 0 && value.indexOf(MatchCriteria.MATCH_CHAR) < 0 && value.indexOf(MatchCriteria.WILDCARD_CHAR) < 0) {
+ return rewriteCriteria(new CompareCriteria(criteria.getLeftExpression(), criteria.isNegated()?CompareCriteria.NE:CompareCriteria.EQ, criteria.getRightExpression()));
}
}
return criteria;
}
+ private Criteria getSimpliedCriteria(Criteria crit, Expression a, boolean outcome, boolean nullPossible) {
+ if (nullPossible) {
+ if (outcome) {
+ if (this.dataMgr != null) {
+ return crit;
+ }
+ IsNullCriteria inc = new IsNullCriteria(a);
+ inc.setNegated(true);
+ return inc;
+ }
+ } else if (outcome) {
+ return TRUE_CRITERIA;
+ }
+ return FALSE_CRITERIA;
+ }
+
private Criteria rewriteCriteria(AbstractSetCriteria criteria) throws QueryValidatorException {
criteria.setExpression(rewriteExpressionDirect(criteria.getExpression()));
@@ -1924,7 +1910,6 @@
return criteria;
}
-
private Criteria rewriteCriteria(SetCriteria criteria) throws QueryValidatorException {
criteria.setExpression(rewriteExpressionDirect(criteria.getExpression()));
@@ -2202,8 +2187,8 @@
if(exprs.length == 3){
decodeDelimiter = (String)((Constant)exprs[2]).getValue();
}
- List newWhens = new ArrayList();
- List newThens = new ArrayList();
+ List<Criteria> newWhens = new ArrayList<Criteria>();
+ List<Constant> newThens = new ArrayList<Constant>();
Constant elseConst = null;
StringTokenizer tokenizer = new StringTokenizer(decodeString, decodeDelimiter);
while (tokenizer.hasMoreTokens()) {
@@ -2295,13 +2280,13 @@
private Expression rewriteCaseExpression(SearchedCaseExpression expr)
throws QueryValidatorException {
int whenCount = expr.getWhenCount();
- ArrayList whens = new ArrayList(whenCount);
- ArrayList thens = new ArrayList(whenCount);
+ ArrayList<Criteria> whens = new ArrayList<Criteria>(whenCount);
+ ArrayList<Expression> thens = new ArrayList<Expression>(whenCount);
for (int i = 0; i < whenCount; i++) {
// Check the when to see if this CASE can be rewritten due to an always true/false when
- Criteria rewrittenWhen = rewriteCriteria(expr.getWhenCriteria(i), false);
+ Criteria rewrittenWhen = rewriteCriteria(expr.getWhenCriteria(i));
if(rewrittenWhen == TRUE_CRITERIA) {
// WHEN is always true, so just return the THEN
return rewriteExpressionDirect(expr.getThenExpression(i));
@@ -2521,7 +2506,7 @@
// Rewrite criteria
Criteria crit = update.getCriteria();
if(crit != null) {
- update.setCriteria(rewriteCriteria(crit, false));
+ update.setCriteria(rewriteCriteria(crit));
}
return update;
@@ -2563,7 +2548,7 @@
// Rewrite criteria
Criteria crit = delete.getCriteria();
if(crit != null) {
- delete.setCriteria(rewriteCriteria(crit, false));
+ delete.setCriteria(rewriteCriteria(crit));
}
return delete;
Modified: trunk/engine/src/main/java/com/metamatrix/query/sql/lang/AbstractCompareCriteria.java
===================================================================
--- trunk/engine/src/main/java/com/metamatrix/query/sql/lang/AbstractCompareCriteria.java 2009-08-19 21:08:00 UTC (rev 1265)
+++ trunk/engine/src/main/java/com/metamatrix/query/sql/lang/AbstractCompareCriteria.java 2009-08-20 13:14:46 UTC (rev 1266)
@@ -65,27 +65,6 @@
*/
private int operator = EQ;
-// /**
-// * Constructs a default instance of this class.
-// */
-// public AbstractCompareCriteria() {
-// super();
-// }
-
-// /**
-// * Constructs an instance of this class for a specific "operand operator
-// * operand" clause.
-// *
-// * @param identifier The variable being compared
-// * @param value The value the variable is being compared to (literal or variable)
-// * @param operator The operator representing how the variable and value are to
-// * be compared
-// */
-// public AbstractCompareCriteria( Expression leftExpression, int operator, Expression rightExpression ) {
-// super();
-// set(leftExpression, operator, rightExpression);
-// }
-
/**
* Returns the operator.
* @return The operator
@@ -154,6 +133,5 @@
default: return "??"; //$NON-NLS-1$
}
}
-
-
+
} // END CLASS
Modified: trunk/engine/src/main/java/com/metamatrix/query/sql/lang/AbstractSetCriteria.java
===================================================================
--- trunk/engine/src/main/java/com/metamatrix/query/sql/lang/AbstractSetCriteria.java 2009-08-19 21:08:00 UTC (rev 1265)
+++ trunk/engine/src/main/java/com/metamatrix/query/sql/lang/AbstractSetCriteria.java 2009-08-20 13:14:46 UTC (rev 1266)
@@ -22,6 +22,7 @@
package com.metamatrix.query.sql.lang;
+import com.metamatrix.query.sql.lang.PredicateCriteria.Negatable;
import com.metamatrix.query.sql.symbol.Expression;
/**
@@ -29,7 +30,7 @@
* IN criteria: {@link SetCriteria} (where values are specified) and {@link SubquerySetCriteria}
* (where a subquery is defined and will supply the values for the IN set).
*/
-public abstract class AbstractSetCriteria extends PredicateCriteria {
+public abstract class AbstractSetCriteria extends PredicateCriteria implements Negatable {
/** The left expression */
private Expression expression;
@@ -75,6 +76,11 @@
public void setNegated(boolean negationFlag) {
negated = negationFlag;
}
+
+ @Override
+ public void negate() {
+ this.negated = !this.negated;
+ }
/**
* Deep copy of object
Modified: trunk/engine/src/main/java/com/metamatrix/query/sql/lang/CompareCriteria.java
===================================================================
--- trunk/engine/src/main/java/com/metamatrix/query/sql/lang/CompareCriteria.java 2009-08-19 21:08:00 UTC (rev 1265)
+++ trunk/engine/src/main/java/com/metamatrix/query/sql/lang/CompareCriteria.java 2009-08-20 13:14:46 UTC (rev 1266)
@@ -25,6 +25,7 @@
import com.metamatrix.core.util.EquivalenceUtil;
import com.metamatrix.core.util.HashCodeUtil;
import com.metamatrix.query.sql.LanguageVisitor;
+import com.metamatrix.query.sql.lang.PredicateCriteria.Negatable;
import com.metamatrix.query.sql.symbol.Expression;
/**
@@ -40,7 +41,7 @@
* <LI>5 <= length(companyName)</LI>
* </UL>
*/
-public class CompareCriteria extends AbstractCompareCriteria {
+public class CompareCriteria extends AbstractCompareCriteria implements Negatable {
/** The right-hand expression. */
private Expression rightExpression;
@@ -172,4 +173,21 @@
return result;
}
+ @Override
+ public void negate() {
+ this.setOperator(getInverseOperator(this.getOperator()));
+ }
+
+ public static int getInverseOperator(int op) {
+ switch ( op ) {
+ case EQ: return NE;
+ case NE: return EQ;
+ case LT: return GE;
+ case GT: return LE;
+ case LE: return GT;
+ case GE: return LT;
+ default: return -1;
+ }
+ }
+
} // END CLASS
Modified: trunk/engine/src/main/java/com/metamatrix/query/sql/lang/IsNullCriteria.java
===================================================================
--- trunk/engine/src/main/java/com/metamatrix/query/sql/lang/IsNullCriteria.java 2009-08-19 21:08:00 UTC (rev 1265)
+++ trunk/engine/src/main/java/com/metamatrix/query/sql/lang/IsNullCriteria.java 2009-08-20 13:14:46 UTC (rev 1266)
@@ -23,17 +23,18 @@
package com.metamatrix.query.sql.lang;
import com.metamatrix.query.sql.*;
+import com.metamatrix.query.sql.lang.PredicateCriteria.Negatable;
import com.metamatrix.query.sql.symbol.Expression;
import com.metamatrix.core.util.EquivalenceUtil;
/**
* Represents criteria such as: "<expression> IS NULL".
*/
-public class IsNullCriteria extends PredicateCriteria {
+public class IsNullCriteria extends PredicateCriteria implements Negatable {
private Expression expression;
/** Negation flag. Indicates whether the criteria expression contains a NOT. */
- private boolean negated = false;
+ private boolean negated;
/**
* Constructs a default instance of this class.
@@ -79,6 +80,11 @@
public void setNegated(boolean negationFlag) {
negated = negationFlag;
}
+
+ @Override
+ public void negate() {
+ this.negated = !this.negated;
+ }
public void acceptVisitor(LanguageVisitor visitor) {
visitor.visit(this);
Modified: trunk/engine/src/main/java/com/metamatrix/query/sql/lang/MatchCriteria.java
===================================================================
--- trunk/engine/src/main/java/com/metamatrix/query/sql/lang/MatchCriteria.java 2009-08-19 21:08:00 UTC (rev 1265)
+++ trunk/engine/src/main/java/com/metamatrix/query/sql/lang/MatchCriteria.java 2009-08-20 13:14:46 UTC (rev 1266)
@@ -29,6 +29,7 @@
import com.metamatrix.core.util.HashCodeUtil;
import com.metamatrix.query.QueryPlugin;
import com.metamatrix.query.sql.LanguageVisitor;
+import com.metamatrix.query.sql.lang.PredicateCriteria.Negatable;
import com.metamatrix.query.sql.symbol.Expression;
/**
@@ -38,7 +39,7 @@
* match character. The escape character can be used to escape an actual % or _ within a
* match string.
*/
-public class MatchCriteria extends PredicateCriteria {
+public class MatchCriteria extends PredicateCriteria implements Negatable {
/** The default wildcard character - '%' */
public static final char WILDCARD_CHAR = '%';
@@ -158,6 +159,11 @@
public void setNegated(boolean negationFlag) {
negated = negationFlag;
}
+
+ @Override
+ public void negate() {
+ this.negated = !this.negated;
+ }
public void acceptVisitor(LanguageVisitor visitor) {
visitor.visit(this);
Modified: trunk/engine/src/main/java/com/metamatrix/query/sql/lang/PredicateCriteria.java
===================================================================
--- trunk/engine/src/main/java/com/metamatrix/query/sql/lang/PredicateCriteria.java 2009-08-19 21:08:00 UTC (rev 1265)
+++ trunk/engine/src/main/java/com/metamatrix/query/sql/lang/PredicateCriteria.java 2009-08-20 13:14:46 UTC (rev 1266)
@@ -34,6 +34,12 @@
*/
public abstract class PredicateCriteria extends Criteria {
+ public interface Negatable {
+
+ void negate();
+
+ }
+
/**
* Constructs a default instance of this class.
*/
Modified: trunk/engine/src/test/java/com/metamatrix/query/rewriter/TestQueryRewriter.java
===================================================================
--- trunk/engine/src/test/java/com/metamatrix/query/rewriter/TestQueryRewriter.java 2009-08-19 21:08:00 UTC (rev 1265)
+++ trunk/engine/src/test/java/com/metamatrix/query/rewriter/TestQueryRewriter.java 2009-08-20 13:14:46 UTC (rev 1266)
@@ -203,11 +203,11 @@
}
@Test public void testRewriteUnknown6() {
- helpTestRewriteCriteria("not(pm1.g1.e1 = '1' and '1' = convert(null, string))", "NOT ((pm1.g1.e1 = '1') and (NULL <> NULL))"); //$NON-NLS-1$ //$NON-NLS-2$
+ helpTestRewriteCriteria("not(pm1.g1.e1 = '1' and '1' = convert(null, string))", "pm1.g1.e1 <> '1'"); //$NON-NLS-1$ //$NON-NLS-2$
}
@Test public void testRewriteUnknown7() {
- helpTestRewriteCriteria("not(pm1.g1.e1 = '1' or '1' = convert(null, string))", "NOT ((pm1.g1.e1 = '1') or (NULL <> NULL))"); //$NON-NLS-1$ //$NON-NLS-2$
+ helpTestRewriteCriteria("not(pm1.g1.e1 = '1' or '1' = convert(null, string))", "1 = 0"); //$NON-NLS-1$ //$NON-NLS-2$
}
@Test public void testRewriteUnknown8() {
@@ -224,7 +224,11 @@
@Test public void testRewriteInCriteriaWithSingleValue1() {
helpTestRewriteCriteria("pm1.g1.e1 not in ('1')", "pm1.g1.e1 != '1'"); //$NON-NLS-1$ //$NON-NLS-2$
- }
+ }
+
+ @Test public void testRewriteInCriteriaWithConvert() {
+ helpTestRewriteCriteria("convert(pm1.g1.e2, string) not in ('x')", "pm1.g1.e2 IS NOT NULL"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
@Test public void testRewriteInCriteriaWithNoValues() throws Exception {
Criteria crit = new SetCriteria(new ElementSymbol("e1"), Collections.EMPTY_LIST); //$NON-NLS-1$
@@ -435,7 +439,7 @@
@Test public void testRewriteCrit_parseTimestamp3() {
helpTestRewriteCriteria("PARSETimestamp(pm3.g1.e1, 'yyyy dd mm') <> {ts'2003-05-01 13:25:04.5'}", //$NON-NLS-1$
- "1 = 1" ); //$NON-NLS-1$
+ "pm3.g1.e1 is not null" ); //$NON-NLS-1$
}
@Test public void testRewriteCrit_parseTimestamp4() {
@@ -743,7 +747,7 @@
}
@Test public void testRewriteNot3() {
- helpTestRewriteCriteria("NOT (pm1.g1.e1='x')", "NOT (pm1.g1.e1 = 'x')"); //$NON-NLS-1$ //$NON-NLS-2$
+ helpTestRewriteCriteria("NOT (pm1.g1.e1='x')", "pm1.g1.e1 <> 'x'"); //$NON-NLS-1$ //$NON-NLS-2$
}
@Test public void testRewriteDefect1() {
@@ -1597,7 +1601,7 @@
/** Check that this returns true, x is not convertable to an int */
@Test public void testRewriteCase1954f1() {
- helpTestRewriteCriteria("convert(pm1.g1.e2, string) != 'x'", "1 = 1"); //$NON-NLS-1$ //$NON-NLS-2$
+ helpTestRewriteCriteria("convert(pm1.g1.e2, string) != 'x'", "pm1.g1.e2 is not null"); //$NON-NLS-1$ //$NON-NLS-2$
}
@Test public void testRewriteCase1954Set() {
@@ -1957,16 +1961,16 @@
new Class[] { DataTypeManager.DefaultDataClasses.STRING});
}
- private void verifyProjectedTypesOnUnionBranches(String unionQuery, Class[] types) throws QueryValidatorException, QueryParserException, QueryResolverException, MetaMatrixComponentException {
+ private void verifyProjectedTypesOnUnionBranches(String unionQuery, Class<?>[] types) throws QueryValidatorException, QueryParserException, QueryResolverException, MetaMatrixComponentException {
SetQuery union = (SetQuery)QueryParser.getQueryParser().parseCommand(unionQuery);
QueryResolver.resolveCommand(union, FakeMetadataFactory.example1Cached());
union = (SetQuery)QueryRewriter.rewrite(union, null, FakeMetadataFactory.example1Cached(), null);
for (QueryCommand query : union.getQueryCommands()) {
- List projSymbols = query.getProjectedSymbols();
+ List<SingleElementSymbol> projSymbols = query.getProjectedSymbols();
for(int i=0; i<projSymbols.size(); i++) {
- assertEquals("Found type mismatch at column " + i, types[i], ((SingleElementSymbol) projSymbols.get(i)).getType()); //$NON-NLS-1$
+ assertEquals("Found type mismatch at column " + i, types[i], projSymbols.get(i).getType()); //$NON-NLS-1$
}
}
}
@@ -2074,16 +2078,14 @@
helpTestRewriteCriteria("coalesce(convert(pm1.g1.e2, double), pm1.g1.e4) = 1", "ifnull(convert(pm1.g1.e2, double), pm1.g1.e4) = 1", true); //$NON-NLS-1$ //$NON-NLS-2$
}
- @Test public void testProcWithNull() throws Exception {
+ /**
+ * Should fail since null is not allowed as an input
+ * @throws Exception
+ */
+ @Test(expected=QueryValidatorException.class) public void testProcWithNull() throws Exception {
String sql = "exec pm1.vsp26(1, null)"; //$NON-NLS-1$
- try {
- helpTestRewriteCommand(sql, "", FakeMetadataFactory.example1Cached());
- fail("expected exception");
- } catch (QueryValidatorException e) {
-
- }
-
+ helpTestRewriteCommand(sql, "", FakeMetadataFactory.example1Cached()); //$NON-NLS-1$
}
/**
@@ -2201,11 +2203,46 @@
assertEquals( "e2 <= 5", ccrit.getCriteria(1).toString() ); //$NON-NLS-1$
}
- @Test public void testRewriteLike() {
+ @Test public void testRewriteNullHandling() {
String original = "pm1.g1.e1 like '%'"; //$NON-NLS-1$
- String expected = "1 = 1"; //$NON-NLS-1$
+ String expected = "pm1.g1.e1 is not null"; //$NON-NLS-1$
helpTestRewriteCriteria(original, expected);
}
+ @Test public void testRewriteNullHandling1() {
+ String original = "not(pm1.g1.e1 like '%' or pm1.g1.e1 = '1')"; //$NON-NLS-1$
+ String expected = "1 = 0"; //$NON-NLS-1$
+
+ helpTestRewriteCriteria(original, expected);
+ }
+
+ @Test public void testRewriteNullHandling2() {
+ String original = "not(pm1.g1.e1 like '%' and pm1.g1.e1 = '1')"; //$NON-NLS-1$
+ String expected = "pm1.g1.e1 <> '1'"; //$NON-NLS-1$
+
+ helpTestRewriteCriteria(original, expected);
+ }
+
+ @Test public void testRewriteNullHandling3() {
+ String original = "pm1.g1.e1 like '%' or pm1.g1.e1 = '1'"; //$NON-NLS-1$
+ String expected = "(pm1.g1.e1 IS NOT NULL) OR (pm1.g1.e1 = '1')"; //$NON-NLS-1$
+
+ helpTestRewriteCriteria(original, expected);
+ }
+
+ @Test public void testRewriteNullHandling4() {
+ String original = "not((pm1.g1.e1 like '%' or pm1.g1.e1 = '1') and pm1.g1.e2 < 5)"; //$NON-NLS-1$
+ String expected = "(pm1.g1.e2 < 5) AND ((pm1.g1.e2 < 5) OR (pm1.g1.e1 <> '1'))"; //$NON-NLS-1$
+
+ helpTestRewriteCriteria(original, expected);
+ }
+
+ @Test public void testRewriteNullHandling5() {
+ String original = "not(pm1.g1.e1 not like '%' and pm1.g1.e3 = '1') or pm1.g1.e2 < 5"; //$NON-NLS-1$
+ String expected = "(pm1.g1.e1 IS NOT NULL) OR (pm1.g1.e3 <> TRUE) OR (pm1.g1.e2 < 5)"; //$NON-NLS-1$
+
+ helpTestRewriteCriteria(original, expected);
+ }
+
}
Modified: trunk/metadata/src/main/java/org/teiid/connector/metadata/MetadataResultsPostProcessor.java
===================================================================
--- trunk/metadata/src/main/java/org/teiid/connector/metadata/MetadataResultsPostProcessor.java 2009-08-19 21:08:00 UTC (rev 1265)
+++ trunk/metadata/src/main/java/org/teiid/connector/metadata/MetadataResultsPostProcessor.java 2009-08-20 13:14:46 UTC (rev 1266)
@@ -344,13 +344,10 @@
if(!CharOperation.match(literalString.toCharArray(), valueString.toCharArray(), !literalCriteria.hasFieldWithCaseFunctions())) {
criteriaPassed = false;
}
- } else {
- // non string just check if they equal
- if(value != null && !value.equals(evaluatedLiteral)) {
- criteriaPassed = false;
- } else if(value == null && evaluatedLiteral != null) {
- criteriaPassed = false;
- }
+ } else if(value == null || evaluatedLiteral == null) {
+ criteriaPassed = false;
+ } else if (((Comparable)value).compareTo(evaluatedLiteral) != 0) {
+ criteriaPassed = false;
}
// post processing literal criteria
}
Modified: trunk/metadata/src/main/java/org/teiid/metadata/index/CharOperation.java
===================================================================
--- trunk/metadata/src/main/java/org/teiid/metadata/index/CharOperation.java 2009-08-19 21:08:00 UTC (rev 1265)
+++ trunk/metadata/src/main/java/org/teiid/metadata/index/CharOperation.java 2009-08-20 13:14:46 UTC (rev 1266)
@@ -89,11 +89,6 @@
int iPattern = 0;
int iName = 0;
- if (patternEnd < 0)
- patternEnd = pattern.length;
- if (nameEnd < 0)
- nameEnd = name.length;
-
/* check first segment */
char patternChar = 0;
while ((iPattern < patternEnd)
@@ -114,6 +109,9 @@
/* check sequence of star+segment */
int segmentStart;
if (patternChar == '*') {
+ if (patternEnd == 1) {
+ return true;
+ }
segmentStart = ++iPattern; // skip star
} else {
segmentStart = 0; // force iName check
Modified: trunk/metadata/src/test/java/com/metamatrix/connector/metadata/index/TestMetadataResultsPostProcessor.java
===================================================================
--- trunk/metadata/src/test/java/com/metamatrix/connector/metadata/index/TestMetadataResultsPostProcessor.java 2009-08-19 21:08:00 UTC (rev 1265)
+++ trunk/metadata/src/test/java/com/metamatrix/connector/metadata/index/TestMetadataResultsPostProcessor.java 2009-08-20 13:14:46 UTC (rev 1266)
@@ -112,7 +112,7 @@
assertNotNull(filteredRecord);
}
- public void testFilterNullMatch() {
+ public void testFilterNullNotEqualNull() {
String uuid = null;
MetadataLiteralCriteria literalcriteria = new MetadataLiteralCriteria(AbstractMetadataRecord.MetadataFieldNames.UUID_FIELD, uuid);
@@ -126,7 +126,7 @@
MetadataResultsPostProcessor processor = helpGetProcessor();
Object filteredRecord = processor.filterBySearchCriteria(columnRecord, criteria);
- assertNotNull(filteredRecord);
+ assertNull(filteredRecord);
}
public void testFilterNullMisMatch() {
Modified: trunk/test-integration/src/test/java/org/teiid/connector/language/TestLanguageUtil.java
===================================================================
--- trunk/test-integration/src/test/java/org/teiid/connector/language/TestLanguageUtil.java 2009-08-19 21:08:00 UTC (rev 1265)
+++ trunk/test-integration/src/test/java/org/teiid/connector/language/TestLanguageUtil.java 2009-08-20 13:14:46 UTC (rev 1266)
@@ -95,7 +95,7 @@
public void testSeparateCrit_NOT() throws Exception {
helpTestSeparateByAnd("((NOT (intkey = 1 AND intkey = 2)) AND (intkey = 3) AND (intkey = 4))", //$NON-NLS-1$
- new String[] { "NOT ((SmallA.IntKey = 1) AND (SmallA.IntKey = 2))", //$NON-NLS-1$
+ new String[] { "(SmallA.IntKey <> 1) OR (SmallA.IntKey <> 2)", //$NON-NLS-1$
"SmallA.IntKey = 3", //$NON-NLS-1$
"SmallA.IntKey = 4" }); //$NON-NLS-1$
}
16 years, 1 month
teiid SVN: r1265 - in trunk/connectors/connector-jdbc/src: main/java/org/teiid/connector/jdbc/derby and 5 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2009-08-19 17:08:00 -0400 (Wed, 19 Aug 2009)
New Revision: 1265
Added:
trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/postgresql/LocateFunctionModifier.java
trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/translator/LocateFunctionModifier.java
trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/translator/ModFunctionModifier.java
trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/translator/TestModFunctionModifier.java
Removed:
trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/postgresql/LOCATEFunctionModifier.java
trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/translator/LOCATEFunctionModifier.java
trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/translator/MODFunctionModifier.java
trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/translator/TestMODFunctionModifier.java
Modified:
trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/db2/DB2SQLTranslator.java
trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/derby/DerbySQLTranslator.java
trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/mysql/MySQLTranslator.java
trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/oracle/OracleSQLTranslator.java
trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/postgresql/PostgreSQLTranslator.java
trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/translator/TestLOCATEFunctionModifier.java
Log:
TEIID-754: LOCATE() function isn't being translated correctly by Oracle Connector
Modified: trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/db2/DB2SQLTranslator.java
===================================================================
--- trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/db2/DB2SQLTranslator.java 2009-08-19 19:50:56 UTC (rev 1264)
+++ trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/db2/DB2SQLTranslator.java 2009-08-19 21:08:00 UTC (rev 1265)
@@ -34,8 +34,8 @@
import org.teiid.connector.api.TypeFacility;
import org.teiid.connector.api.TypeFacility.RUNTIME_TYPES;
import org.teiid.connector.jdbc.translator.AliasModifier;
-import org.teiid.connector.jdbc.translator.LOCATEFunctionModifier;
-import org.teiid.connector.jdbc.translator.MODFunctionModifier;
+import org.teiid.connector.jdbc.translator.LocateFunctionModifier;
+import org.teiid.connector.jdbc.translator.ModFunctionModifier;
import org.teiid.connector.jdbc.translator.Translator;
import org.teiid.connector.language.ICommand;
import org.teiid.connector.language.IExpression;
@@ -59,14 +59,14 @@
registerFunctionModifier(SourceSystemFunctions.CHAR, new AliasModifier("chr")); //$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.DAYOFMONTH, new AliasModifier("day")); //$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.IFNULL, new AliasModifier("coalesce")); //$NON-NLS-1$
- registerFunctionModifier(SourceSystemFunctions.LOCATE, new LOCATEFunctionModifier(getLanguageFactory(), "LOCATE")); //$NON-NLS-1$
+ registerFunctionModifier(SourceSystemFunctions.LOCATE, new LocateFunctionModifier(getLanguageFactory()));
registerFunctionModifier(SourceSystemFunctions.SUBSTRING, new AliasModifier("substr")); //$NON-NLS-1$
List<Class<?>> supportedModTypes = new ArrayList<Class<?>>(3);
supportedModTypes.add(RUNTIME_TYPES.SHORT);
supportedModTypes.add(RUNTIME_TYPES.INTEGER);
supportedModTypes.add(RUNTIME_TYPES.LONG);
- registerFunctionModifier(SourceSystemFunctions.MOD, new MODFunctionModifier(getLanguageFactory(), "MOD", supportedModTypes)); //$NON-NLS-1$
+ registerFunctionModifier(SourceSystemFunctions.MOD, new ModFunctionModifier(getLanguageFactory(), "MOD", supportedModTypes)); //$NON-NLS-1$
}
@SuppressWarnings("unchecked")
Modified: trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/derby/DerbySQLTranslator.java
===================================================================
--- trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/derby/DerbySQLTranslator.java 2009-08-19 19:50:56 UTC (rev 1264)
+++ trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/derby/DerbySQLTranslator.java 2009-08-19 21:08:00 UTC (rev 1265)
@@ -29,7 +29,6 @@
import org.teiid.connector.jdbc.db2.DB2SQLTranslator;
import org.teiid.connector.jdbc.oracle.LeftOrRightFunctionModifier;
import org.teiid.connector.jdbc.translator.EscapeSyntaxModifier;
-import org.teiid.connector.jdbc.translator.LOCATEFunctionModifier;
@@ -47,7 +46,6 @@
registerFunctionModifier(SourceSystemFunctions.TIMESTAMPADD, new EscapeSyntaxModifier());
registerFunctionModifier(SourceSystemFunctions.TIMESTAMPDIFF, new EscapeSyntaxModifier());
registerFunctionModifier(SourceSystemFunctions.LEFT, new LeftOrRightFunctionModifier(getLanguageFactory()));
- registerFunctionModifier(SourceSystemFunctions.LOCATE, new LOCATEFunctionModifier(getLanguageFactory(), "LOCATE")); //$NON-NLS-1$
//overrides of db2 functions
registerFunctionModifier(SourceSystemFunctions.CONCAT, new EscapeSyntaxModifier());
Modified: trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/mysql/MySQLTranslator.java
===================================================================
--- trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/mysql/MySQLTranslator.java 2009-08-19 19:50:56 UTC (rev 1264)
+++ trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/mysql/MySQLTranslator.java 2009-08-19 21:08:00 UTC (rev 1265)
@@ -33,7 +33,7 @@
import org.teiid.connector.api.ConnectorEnvironment;
import org.teiid.connector.api.ConnectorException;
import org.teiid.connector.api.SourceSystemFunctions;
-import org.teiid.connector.jdbc.translator.LOCATEFunctionModifier;
+import org.teiid.connector.jdbc.translator.LocateFunctionModifier;
import org.teiid.connector.jdbc.translator.Translator;
@@ -51,7 +51,7 @@
registerFunctionModifier(SourceSystemFunctions.BITNOT, new BitFunctionModifier("~", getLanguageFactory())); //$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.BITOR, new BitFunctionModifier("|", getLanguageFactory())); //$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.BITXOR, new BitFunctionModifier("^", getLanguageFactory())); //$NON-NLS-1$
- registerFunctionModifier(SourceSystemFunctions.LOCATE, new LOCATEFunctionModifier(getLanguageFactory(), "LOCATE")); //$NON-NLS-1$
+ registerFunctionModifier(SourceSystemFunctions.LOCATE, new LocateFunctionModifier(getLanguageFactory()));
}
@Override
Modified: trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/oracle/OracleSQLTranslator.java
===================================================================
--- trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/oracle/OracleSQLTranslator.java 2009-08-19 19:50:56 UTC (rev 1264)
+++ trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/oracle/OracleSQLTranslator.java 2009-08-19 21:08:00 UTC (rev 1265)
@@ -42,9 +42,8 @@
import org.teiid.connector.jdbc.JDBCPlugin;
import org.teiid.connector.jdbc.translator.AliasModifier;
import org.teiid.connector.jdbc.translator.ExtractFunctionModifier;
-import org.teiid.connector.jdbc.translator.LOCATEFunctionModifier;
+import org.teiid.connector.jdbc.translator.LocateFunctionModifier;
import org.teiid.connector.jdbc.translator.Translator;
-import org.teiid.connector.jdbc.translator.LOCATEFunctionModifier.ParameterOrder;
import org.teiid.connector.language.ICommand;
import org.teiid.connector.language.IElement;
import org.teiid.connector.language.IFunction;
@@ -98,7 +97,7 @@
registerFunctionModifier(SourceSystemFunctions.QUARTER, new DayWeekQuarterFunctionModifier(getLanguageFactory(), "Q"));//$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.DAYOFWEEK, new DayWeekQuarterFunctionModifier(getLanguageFactory(), "D"));//$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.DAYOFYEAR, new DayWeekQuarterFunctionModifier(getLanguageFactory(), "DDD"));//$NON-NLS-1$
- registerFunctionModifier(SourceSystemFunctions.LOCATE, new LOCATEFunctionModifier(getLanguageFactory(), "INSTR", ParameterOrder.SOURCE_SEARCH_INDEX)); //$NON-NLS-1$
+ registerFunctionModifier(SourceSystemFunctions.LOCATE, new LocateFunctionModifier(getLanguageFactory(), "INSTR", true)); //$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.SUBSTRING, new AliasModifier("substr"));//$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.LEFT, new LeftOrRightFunctionModifier(getLanguageFactory()));
registerFunctionModifier(SourceSystemFunctions.RIGHT, new LeftOrRightFunctionModifier(getLanguageFactory()));
Deleted: trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/postgresql/LOCATEFunctionModifier.java
===================================================================
--- trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/postgresql/LOCATEFunctionModifier.java 2009-08-19 19:50:56 UTC (rev 1264)
+++ trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/postgresql/LOCATEFunctionModifier.java 2009-08-19 21:08:00 UTC (rev 1265)
@@ -1,55 +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.connector.jdbc.postgresql;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.teiid.connector.api.TypeFacility;
-import org.teiid.connector.language.IExpression;
-import org.teiid.connector.language.IFunction;
-import org.teiid.connector.language.ILanguageFactory;
-
-public class LOCATEFunctionModifier extends org.teiid.connector.jdbc.translator.LOCATEFunctionModifier {
-
- public LOCATEFunctionModifier(ILanguageFactory factory) {
- super(factory);
- }
-
- @Override
- public List<?> translate(IFunction function) {
- List<Object> parts = new ArrayList<Object>();
- List<IExpression> params = function.getParameters();
- parts.add("position("); //$NON-NLS-1$
- parts.add(params.get(0));
- parts.add(" in "); //$NON-NLS-1$
- if (params.size() == 3) {
- parts.add(this.getLanguageFactory().createFunction("substr", params.subList(1, 3), TypeFacility.RUNTIME_TYPES.STRING)); //$NON-NLS-1$
- } else {
- parts.add(params.get(1));
- }
- parts.add(")"); //$NON-NLS-1$
- return parts;
- }
-
-}
Copied: trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/postgresql/LocateFunctionModifier.java (from rev 1264, trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/postgresql/LOCATEFunctionModifier.java)
===================================================================
--- trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/postgresql/LocateFunctionModifier.java (rev 0)
+++ trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/postgresql/LocateFunctionModifier.java 2009-08-19 21:08:00 UTC (rev 1265)
@@ -0,0 +1,55 @@
+/*
+ * 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.connector.jdbc.postgresql;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.teiid.connector.api.TypeFacility;
+import org.teiid.connector.language.IExpression;
+import org.teiid.connector.language.IFunction;
+import org.teiid.connector.language.ILanguageFactory;
+
+public class LocateFunctionModifier extends org.teiid.connector.jdbc.translator.LocateFunctionModifier {
+
+ public LocateFunctionModifier(ILanguageFactory factory) {
+ super(factory);
+ }
+
+ @Override
+ public List<?> translate(IFunction function) {
+ List<Object> parts = new ArrayList<Object>();
+ List<IExpression> params = function.getParameters();
+ parts.add("position("); //$NON-NLS-1$
+ parts.add(params.get(0));
+ parts.add(" in "); //$NON-NLS-1$
+ if (params.size() == 3) {
+ parts.add(this.getLanguageFactory().createFunction("substr", params.subList(1, 3), TypeFacility.RUNTIME_TYPES.STRING)); //$NON-NLS-1$
+ } else {
+ parts.add(params.get(1));
+ }
+ parts.add(")"); //$NON-NLS-1$
+ return parts;
+ }
+
+}
Property changes on: trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/postgresql/LocateFunctionModifier.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/postgresql/PostgreSQLTranslator.java
===================================================================
--- trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/postgresql/PostgreSQLTranslator.java 2009-08-19 19:50:56 UTC (rev 1264)
+++ trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/postgresql/PostgreSQLTranslator.java 2009-08-19 21:08:00 UTC (rev 1265)
@@ -95,7 +95,7 @@
registerFunctionModifier(SourceSystemFunctions.IFNULL, new AliasModifier("coalesce")); //$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.CONVERT, new PostgreSQLConvertModifier(getLanguageFactory()));
- registerFunctionModifier(SourceSystemFunctions.LOCATE, new LOCATEFunctionModifier(getLanguageFactory()));
+ registerFunctionModifier(SourceSystemFunctions.LOCATE, new LocateFunctionModifier(getLanguageFactory()));
}
@Override
Deleted: trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/translator/LOCATEFunctionModifier.java
===================================================================
--- trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/translator/LOCATEFunctionModifier.java 2009-08-19 19:50:56 UTC (rev 1264)
+++ trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/translator/LOCATEFunctionModifier.java 2009-08-19 21:08:00 UTC (rev 1265)
@@ -1,323 +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.connector.jdbc.translator;
-
-import java.util.Arrays;
-import java.util.List;
-
-import org.teiid.connector.jdbc.translator.BasicFunctionModifier;
-import org.teiid.connector.jdbc.translator.FunctionModifier;
-import org.teiid.connector.language.ICompareCriteria;
-import org.teiid.connector.language.IExpression;
-import org.teiid.connector.language.IFunction;
-import org.teiid.connector.language.ILanguageFactory;
-import org.teiid.connector.language.ILiteral;
-import org.teiid.connector.language.ICompareCriteria.Operator;
-
-
-/**
- * A modifier class that can be used to translate the scalar function
- * <code>locate(search_string, source_string)</code> and
- * <code>locate(search_string, source_string, start_index)</code> to a function
- * or expression that can be used at the data source.
- * <p>
- * If the default implementation is used, a function name of LOCATE will be used
- * for the function name.
- * <p>
- * If the default implementation is used, the expression will not be modified if:
- * <li><code>locate(search_string, source_string)</code> is used</li>
- * <li><code>locate(search_string, source_string, start_index)</code> is used
- * and <code>start_index</code> is a literal integer greater then 0</li>
- * <li>the default function parameter order is used or unspecified</li>
- * <p>
- * If the default implementation is used, the expression will be modified if:
- * <li><code>locate(search_string, source_string, start_index)</code> is used
- * and <code>start_index</code> is a literal integer less then 1</li>
- * <li><code>locate(search_string, source_string, start_index)</code> is used
- * and <code>start_index</code> is not a literal integer</li>
- * <li>the function parameter order is something other than the default</li>
- * <p>
- * If the default implementation is used and the expression is modified, it is
- * modified to ensure that any literal integer value less than 1 is made equal
- * to 1 and any non literal value is wrapped by a searched case expression
- * to ensure that a value of less then 1 will be equal to 1 and the parameter
- * order matches that of what the data source expects.
- * <p>
- * For example:
- * <li><code>locate('a', 'abcdef')</code> --> <code>LOCATE('a', 'abcdef')</code></li>
- * <li><code>locate('a', 'abcdef', 2)</code> --> <code>LOCATE('a', 'abcdef', 2)</code></li>
- * <li><code>locate('a', 'abcdef', 0)</code> --> <code>LOCATE('a', 'abcdef', 1)</code></li>
- * <li><code>locate('a', 'abcdef', intCol)</code> --> <code>LOCATE('a', 'abcdef', CASE WHEN intCol < 1 THEN 1 ELSE intCol END)</code></li>
- *
- * @since 6.2
- */
-public class LOCATEFunctionModifier extends BasicFunctionModifier implements FunctionModifier {
-
- /**
- * An <code>enum</code> that defines the parameter orders that can be used
- * with <code>LOCATEFunctionModifier</code>
- *
- */
- public static enum ParameterOrder {
- /**
- * Indicates that the parameter order should be consistent with the
- * built-in system function <code>LOCATE(searchStr, sourceStr, startIndex)</code>.
- */
- DEFAULT,
-
- /**
- * Indicates that the parameter order should be changed from the default
- * built-in system function <code>LOCATE(searchStr, sourceStr, startIndex)</code>
- * to <code>LOCATE(sourceStr, searchStr, startIndex)</code>.
- */
- SOURCE_SEARCH_INDEX,
-
- /**
- * Indicates that the parameter order should be changed from the default
- * built-in system function <code>LOCATE(searchStr, sourceStr, startIndex)</code>
- * to <code>LOCATE(startIndex, sourceStr, searchStr)</code>.
- */
- INDEX_SOURCE_SEARCH
-
- }
-
- private ILanguageFactory langFactory;
- private String functionName = "LOCATE"; //$NON-NLS-1$
- private ParameterOrder parameterOrder = ParameterOrder.DEFAULT;
- private final Integer systemStringIndexBase = 1;
-
- /**
- * Constructs a {@link BasicFunctionModifier} object that can be used to
- * translate the scalar function LOCATE() to a source specific scalar
- * function or expression.
- * <p>
- * This constructor invokes {@link #LOCATEFunctionModifier(ILanguageFactory, String, ParameterOrder)}
- * passing it <code>langFactory</code>, <code>null</code>, <code>null</code>.
- *
- * @param langFactory the language factory associated with translation
- */
- public LOCATEFunctionModifier(ILanguageFactory langFactory) {
- this(langFactory, null, null);
- }
-
- /**
- * Constructs a {@link BasicFunctionModifier} object that can be used to
- * translate the scalar function LOCATE() to a source specific scalar
- * function or expression.
- * <p>
- * This constructor invokes {@link #LOCATEFunctionModifier(ILanguageFactory, String, ParameterOrder)}
- * passing it <code>langFactory</code>, <code>functionName</code>,
- * <code>null</code>.
- *
- * @param langFactory the language factory associated with translation
- * @param functionName the function name or alias to be used instead of LOCATE
- */
- public LOCATEFunctionModifier(ILanguageFactory langFactory, final String functionName) {
- this(langFactory, functionName, null);
- }
-
- /**
- * Constructs a {@link BasicFunctionModifier} object that can be used to
- * translate the scalar function LOCATE() to a source specific scalar
- * function or expression.
- * <p>
- * <code>functionName</code> should represent the default function name or
- * alias used by the data source. If this value is <code>null</code> a
- * default value will be used.
- * <p>
- * <code>paramOrder</code> should represent how the data source's version of
- * the LOCATE() function expects its parameters. This value can be any
- * supported value offered by {@link ParameterOrder}. If this value is
- * <code>null</code> a default value will be used.
- * <p>
- *
- * @param langFactory the language factory associated with translation
- * @param functionName the function name or alias to be used instead of
- * LOCATE, or <code>null</code> if the default should be used
- * @param paramOrder the order in which parameters should be translated, or
- * <code>null</code> if the default should be used
- */
- public LOCATEFunctionModifier(ILanguageFactory langFactory, final String functionName, final ParameterOrder paramOrder) {
- if (functionName != null) this.functionName = functionName;
- if (paramOrder != null) this.parameterOrder = paramOrder;
- this.langFactory = langFactory;
- }
-
- /**
- * Returns a version of <code>function</code> suitable for executing at the
- * data source.
- * <p>
- * First, a default function name or the value specified during construction
- * of <code>MODFunctionModifier</code> is set on <code>function</code>.
- * <p>
- * If <code>function</code> represents <code>LOCATE(searchStr, sourceStr, startIndex)</code>
- * and <code>startIndex</code> is a literal value, it is translated for
- * consistency between the built-in system function
- * <code>LOCATE(searchStr, sourceStr, startIndex)</code> and the sources
- * implementation. This is done by calling {@link #getStartIndexExpression(ILiteral)}
- * and passing it the literal <code>startIndex</code> value.
- * <p>
- * If <code>function</code> represents <code>LOCATE(searchStr, sourceStr, startIndex)</code>
- * and <code>startIndex</code> is not a literal value, it is translated for
- * consistency between the built-in system function
- * <code>LOCATE(searchStr, sourceStr, startIndex)</code> and the sources
- * implementation. This is done by calling {@link #getStartIndexExpression(IExpression)}
- * and passing it the non-literal <code>startIndex</code> value.
- * <p>
- * Finally, <code>function</code>'s parameters may be rearranged depending
- * on the value specified by {@link ParameterOrder} during construction of
- * <code>MODFunctionModifier</code>.
- * <p>
- * The translated <code>function</code> is then returned.
- * <p>
- * For example:
- * <ul>
- * <code>locate('a', 'abcdefg') ---> LOCATE('a', 'abcdefg')</code><br />
- * <code>locate('a', 'abcdefg', 1) ---> LOCATE('a', 'abcdefg', 1)</code><br />
- * <code>locate('a', 'abcdefg', 1) ---> INSTR('abcdefg', 'a', 1)</code><br />
- * <code>locate('a', 'abcdefg', -5) ---> INSTR('abcdefg', 'a', 1)</code><br />
- * <code>locate('a', 'abcdefg', 1) ---> FINDSTR('a', 'abcdefg', 1)</code><br />
- * <code>locate('a', 'abcdefg', myCol) ---> LOCATE('a', 'abcdefg', CASE WHEN myCol < 1 THEN 1 ELSE myCol END)</code>
- * </ul>
- *
- * @param function the LOCATE function that may need to be modified
- */
- public IExpression modify(IFunction function) {
- function.setName(this.functionName);
- List<IExpression> args = function.getParameters();
- IExpression searchStr = args.get(0);
- IExpression sourceStr = args.get(1);
- IExpression startIndex = (args.size() > 2 ? args.get(2) : null);
-
- // if startIndex was given then we may need to do additional work
- if (startIndex != null) {
- if (startIndex instanceof ILiteral) {
- startIndex = this.getStartIndexExpression((ILiteral)startIndex);
- } else {
- startIndex = this.getStartIndexExpression((IExpression)startIndex);
- }
- }
- switch (this.parameterOrder) {
- case SOURCE_SEARCH_INDEX:
- args.set(0, sourceStr);
- args.set(1, searchStr);
- if (startIndex != null) args.set(2, startIndex);
- break;
- case INDEX_SOURCE_SEARCH:
- if (startIndex != null) args.set(0, startIndex);
- args.set(1, sourceStr);
- args.set(2, searchStr);
- break;
- case DEFAULT:
- args.set(0, searchStr);
- args.set(1, sourceStr);
- if (startIndex != null) args.set(2, startIndex);
- break;
- }
- return function;
- }
-
- /**
- * Return an expression that represents <code>startIndex</code> rewritten to
- * be consistent with the built-in system function's
- * <code>LOCATE(searchStr, sourceStr, startIndex)</code> <code>startIndex</code>
- * parameter.
- * <p>
- * <code>startIndex</code> represents the unmodified parameter as passed to
- * the <code>LOCATE(searchStr, sourceStr, startIndex)</code> function. The
- * returned value will represent a normalized version of the expression that
- * is consistent to the built-in system function. For example, a value for
- * <code>startIndex</code> should not be less than <code>1</code>.
- * <p>
- * If this method is not overriden, the result will be:
- * <p>
- * <ul>If <code>startIndex</code> is <code>null</code>, <code>startIndex</code></ul>
- * <ul>If <code>startIndex</code> is not <code>null</code> and its value is
- * less than <code>1</code>, <code>1</code></ul>
- *
- * @param startIndex an expression representing the <code>startIndex</code>
- * parameter used in <code>LOCATE(searchStr, sourceStr, startIndex)</code>
- * @return an expression that represents a normalized <code>startIndex</code>
- */
- protected IExpression getStartIndexExpression(ILiteral startIndex) {
- if (startIndex.getValue() != null) {
- if ((Integer)startIndex.getValue() < this.getSystemStringIndexBase()) {
- startIndex.setValue(this.getSystemStringIndexBase());
- }
- }
- return startIndex;
- }
-
- /**
- * Return an expression that represents <code>startIndex</code> rewritten to
- * be consistent with the built-in system function's
- * <code>LOCATE(searchStr, sourceStr, startIndex)</code> <code>startIndex</code>
- * parameter.
- * <p>
- * <code>startIndex</code> represents the unmodified parameter as passed to
- * the <code>LOCATE(searchStr, sourceStr, startIndex)</code> function. The
- * returned value will represent a normalized version of the expression that
- * is consistent to the built-in system function. For example, a value for
- * <code>startIndex</code> should not be less than <code>1</code>.
- * <p>
- * If this method is not overriden, the result will be:
- * <p>
- * <ul><code>CASE WHEN <startIndex> < 1; THEN 1; ELSE <startIndex> END</code></ul>
- * <p>
- * For the default searched case expression to work, the source must support
- * searched case.
- *
- * @param startIndex an expression representing the <code>startIndex</code>
- * parameter used in <code>LOCATE(searchStr, sourceStr, startIndex)</code>
- * @return an expression that represents a normalized <code>startIndex</code>
- */
- protected IExpression getStartIndexExpression(IExpression startIndex) {
- ICompareCriteria[] whenExpr = {langFactory.createCompareCriteria(
- Operator.LT,
- startIndex,
- langFactory.createLiteral(this.getSystemStringIndexBase(), Integer.class)
- )};
- ILiteral[] thenExpr = {langFactory.createLiteral(this.getSystemStringIndexBase(), Integer.class)};
- return langFactory.createSearchedCaseExpression(Arrays.asList(whenExpr), Arrays.asList(thenExpr), startIndex, Integer.class);
- }
-
- /**
- * Get the string index base used by built-in system functions. The value
- * represents what is considered the first character of a string.
- *
- * @return the data source's string index base
- */
- protected Integer getSystemStringIndexBase() {
- return this.systemStringIndexBase;
- }
-
- /**
- * Get the instance of {@link ILanguageFactory} set during construction.
- *
- * @return the <code>ILanguageFactory</code> instance
- */
- protected ILanguageFactory getLanguageFactory() {
- return this.langFactory;
- }
-
-}
Copied: trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/translator/LocateFunctionModifier.java (from rev 1264, trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/translator/LOCATEFunctionModifier.java)
===================================================================
--- trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/translator/LocateFunctionModifier.java (rev 0)
+++ trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/translator/LocateFunctionModifier.java 2009-08-19 21:08:00 UTC (rev 1265)
@@ -0,0 +1,189 @@
+/*
+ * 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.connector.jdbc.translator;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.teiid.connector.language.ICompareCriteria;
+import org.teiid.connector.language.IExpression;
+import org.teiid.connector.language.IFunction;
+import org.teiid.connector.language.ILanguageFactory;
+import org.teiid.connector.language.ILiteral;
+import org.teiid.connector.language.ICompareCriteria.Operator;
+
+
+/**
+ * A modifier class that can be used to translate the scalar function
+ * <code>locate(search_string, source_string)</code> and
+ * <code>locate(search_string, source_string, start_index)</code> to a function
+ * or expression that can be used at the data source.
+ * <p>
+ * If the default implementation is used, a function name of LOCATE will be used
+ * for the function name.
+ * <p>
+ * If the default implementation is used, the expression will not be modified if:
+ * <li><code>locate(search_string, source_string)</code> is used</li>
+ * <li><code>locate(search_string, source_string, start_index)</code> is used
+ * and <code>start_index</code> is a literal integer greater then 0</li>
+ * <li>the default function parameter order is used or unspecified</li>
+ * <p>
+ * If the default implementation is used, the expression will be modified if:
+ * <li><code>locate(search_string, source_string, start_index)</code> is used
+ * and <code>start_index</code> is a literal integer less then 1</li>
+ * <li><code>locate(search_string, source_string, start_index)</code> is used
+ * and <code>start_index</code> is not a literal integer</li>
+ * <li>the function parameter order is something other than the default</li>
+ * <p>
+ * If the default implementation is used and the expression is modified, it is
+ * modified to ensure that any literal integer value less than 1 is made equal
+ * to 1 and any non literal value is wrapped by a searched case expression
+ * to ensure that a value of less then 1 will be equal to 1 and the parameter
+ * order matches that of what the data source expects.
+ * <p>
+ * For example:
+ * <li><code>locate('a', 'abcdef')</code> --> <code>LOCATE('a', 'abcdef')</code></li>
+ * <li><code>locate('a', 'abcdef', 2)</code> --> <code>LOCATE('a', 'abcdef', 2)</code></li>
+ * <li><code>locate('a', 'abcdef', 0)</code> --> <code>LOCATE('a', 'abcdef', 1)</code></li>
+ * <li><code>locate('a', 'abcdef', intCol)</code> --> <code>LOCATE('a', 'abcdef', CASE WHEN intCol < 1 THEN 1 ELSE intCol END)</code></li>
+ *
+ * @since 6.2
+ */
+public class LocateFunctionModifier extends BasicFunctionModifier {
+
+ public static String LOCATE = "LOCATE"; //$NON-NLS-1$
+
+ private ILanguageFactory langFactory;
+ private String functionName = LOCATE;
+ private boolean sourceStringFirst;
+
+ /**
+ * Constructs a {@link BasicFunctionModifier} object that can be used to
+ * translate the scalar function LOCATE() to a source specific scalar
+ * function or expression.
+ *
+ * @param langFactory the language factory associated with translation
+ */
+ public LocateFunctionModifier(ILanguageFactory langFactory) {
+ this(langFactory, LOCATE, false);
+ }
+
+ /**
+ * Constructs a {@link BasicFunctionModifier} object that can be used to
+ * translate the scalar function LOCATE() to a source specific scalar
+ * function or expression.
+ *
+ * @param langFactory the language factory associated with translation
+ * @param functionName the function name or alias to be used instead of LOCATE
+ * @param sourceStringFirst
+ */
+ public LocateFunctionModifier(ILanguageFactory langFactory, final String functionName, boolean sourceStringFirst) {
+ this.langFactory = langFactory;
+ this.functionName = functionName;
+ this.sourceStringFirst = sourceStringFirst;
+ }
+
+ /**
+ * Returns a version of <code>function</code> suitable for executing at the
+ * data source.
+ * <p>
+ * First, a default function name or the value specified during construction
+ * of <code>MODFunctionModifier</code> is set on <code>function</code>.
+ * <p>
+ * If <code>function</code> represents <code>LOCATE(searchStr, sourceStr, startIndex)</code>
+ * and <code>startIndex</code> is a literal value, it is translated for
+ * consistency between the built-in system function
+ * <code>LOCATE(searchStr, sourceStr, startIndex)</code> and the sources
+ * implementation. This is done by calling {@link #getStartIndexExpression(ILiteral)}
+ * and passing it the literal <code>startIndex</code> value.
+ * <p>
+ * If <code>function</code> represents <code>LOCATE(searchStr, sourceStr, startIndex)</code>
+ * and <code>startIndex</code> is not a literal value, it is translated for
+ * consistency between the built-in system function
+ * <code>LOCATE(searchStr, sourceStr, startIndex)</code> and the sources
+ * implementation. This is done by calling {@link #getStartIndexExpression(IExpression)}
+ * and passing it the non-literal <code>startIndex</code> value.
+ * <p>
+ * Finally, <code>function</code>'s parameters may be rearranged depending
+ * on the value specified by {@link ParameterOrder} during construction of
+ * <code>MODFunctionModifier</code>.
+ * <p>
+ * The translated <code>function</code> is then returned.
+ * <p>
+ * For example:
+ * <ul>
+ * <code>locate('a', 'abcdefg') ---> LOCATE('a', 'abcdefg')</code><br />
+ * <code>locate('a', 'abcdefg', 1) ---> LOCATE('a', 'abcdefg', 1)</code><br />
+ * <code>locate('a', 'abcdefg', 1) ---> INSTR('abcdefg', 'a', 1)</code><br />
+ * <code>locate('a', 'abcdefg', -5) ---> INSTR('abcdefg', 'a', 1)</code><br />
+ * <code>locate('a', 'abcdefg', 1) ---> FINDSTR('a', 'abcdefg', 1)</code><br />
+ * <code>locate('a', 'abcdefg', myCol) ---> LOCATE('a', 'abcdefg', CASE WHEN myCol < 1 THEN 1 ELSE myCol END)</code>
+ * </ul>
+ *
+ * @param function the LOCATE function that may need to be modified
+ */
+ public IExpression modify(IFunction function) {
+ function.setName(this.functionName);
+ List<IExpression> args = function.getParameters();
+ IExpression searchStr = args.get(0);
+ IExpression sourceStr = args.get(1);
+
+ // if startIndex was given then we may need to do additional work
+ if (args.size() > 2) {
+ args.set(2, ensurePositiveStartIndex(args.get(2)));
+ }
+ if (sourceStringFirst) {
+ args.set(0, sourceStr);
+ args.set(1, searchStr);
+ }
+ return function;
+ }
+
+ private IExpression ensurePositiveStartIndex(IExpression startIndex) {
+ if (startIndex instanceof ILiteral) {
+ ILiteral literal = (ILiteral)startIndex;
+ if (literal.getValue() != null && ((Integer)literal.getValue() < 1)) {
+ literal.setValue(1);
+ }
+ } else {
+ ICompareCriteria[] whenExpr = {langFactory.createCompareCriteria(
+ Operator.LT,
+ startIndex,
+ langFactory.createLiteral(1, Integer.class)
+ )};
+ ILiteral[] thenExpr = {langFactory.createLiteral(1, Integer.class)};
+ startIndex = langFactory.createSearchedCaseExpression(Arrays.asList(whenExpr), Arrays.asList(thenExpr), startIndex, Integer.class);
+ }
+ return startIndex;
+ }
+
+ /**
+ * Get the instance of {@link ILanguageFactory} set during construction.
+ *
+ * @return the <code>ILanguageFactory</code> instance
+ */
+ protected ILanguageFactory getLanguageFactory() {
+ return this.langFactory;
+ }
+
+}
Property changes on: trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/translator/LocateFunctionModifier.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Deleted: trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/translator/MODFunctionModifier.java
===================================================================
--- trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/translator/MODFunctionModifier.java 2009-08-19 19:50:56 UTC (rev 1264)
+++ trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/translator/MODFunctionModifier.java 2009-08-19 21:08:00 UTC (rev 1265)
@@ -1,185 +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.connector.jdbc.translator;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import org.teiid.connector.api.TypeFacility.RUNTIME_TYPES;
-import org.teiid.connector.language.IExpression;
-import org.teiid.connector.language.IFunction;
-import org.teiid.connector.language.ILanguageFactory;
-
-/**
- * A modifier class that can be used to translate the scalar function
- * <code>mod(x, y)</code> to a function or expression that can be used at the
- * data source.
- * <p>
- * If the default implementation is used, a function name of MOD will be used
- * for the alias name and the expression will be unmodified if the data type
- * of the <code>x</code> parameter is one of {@link RUNTIME_TYPES#BYTE},
- * {@link RUNTIME_TYPES#SHORT}, {@link RUNTIME_TYPES#INTEGER}, or
- * {@link RUNTIME_TYPES#LONG}. If the data type is not one of these types, the
- * expression will be modified to return: <code>(x - (TRUNC((x / y), 0) * y))</code>
- *
- * @since 6.2
- */
-public class MODFunctionModifier extends AliasModifier {
-
- private static List<Class<?>> DEFAULT_TYPELIST = new ArrayList<Class<?>>(4);
- static {
- DEFAULT_TYPELIST.add(RUNTIME_TYPES.BYTE);
- DEFAULT_TYPELIST.add(RUNTIME_TYPES.SHORT);
- DEFAULT_TYPELIST.add(RUNTIME_TYPES.INTEGER);
- DEFAULT_TYPELIST.add(RUNTIME_TYPES.LONG);
- }
- private static String DEFAULT_FUNCTIONNAME = "MOD"; //$NON-NLS-1$
-
- private ILanguageFactory langFactory;
- private List<Class<?>> supTypeList;
-
- /**
- * Constructs a {@link AliasModifier} object that can be used to translate
- * the use of the scalar function MOD() to a source specific scalar function
- * or expression.
- * <p>
- * This constructor invokes {@link #MODFunctionModifier(ILanguageFactory, String, List)}
- * passing it <code>langFactory</code>, {@link #DEFAULT_FUNCTIONNAME}, and
- * {@link #DEFAULT_TYPELIST}.
- *
- * @param langFactory the language factory associated with translation
- */
- public MODFunctionModifier(ILanguageFactory langFactory) {
- this(langFactory, DEFAULT_FUNCTIONNAME, DEFAULT_TYPELIST);
- }
-
- /**
- * Constructs a {@link AliasModifier} object that can be used to translate
- * the use of the scalar function MOD() to a source specific scalar function
- * or expression.
- * <p>
- * <code>functionName</code> is used to construct the parent {@link AliasModifier}
- * and should represent the default function name or alias used by the data
- * source.
- * <p>
- * <code>supportedTypeList</code> should contain a list of <code>Class</code>
- * objects that represent the data types that the data source can support
- * with its implementation of the MOD() scalar function.
- *
- * @param langFactory the language factory associated with translation
- * @param functionName the function name or alias that should be used
- * instead of MOD
- * @param supportedTypeList a list of type classes that is supported by the
- * data source's MOD function
- */
- public MODFunctionModifier(ILanguageFactory langFactory, String functionName, List<Class<?>>supportedTypeList) {
- super(functionName);
- this.langFactory = langFactory;
- if ( supportedTypeList != null ) {
- this.supTypeList = supportedTypeList;
- } else {
- this.supTypeList = MODFunctionModifier.DEFAULT_TYPELIST;
- }
- }
-
- /**
- * Returns a version of <code>function</code> suitable for executing at the
- * data source.
- * <p>
- * If the data type of the parameters in <code>function</code> is in the
- * list of supported data types, this method simply returns <code>super.modify(function)</code>.
- * <p>
- * If the data type of the parameters in <code>function</code are not in the
- * list of supported data types, this method will return an expression that
- * is valid at the data source and will yield the same result as the original
- * MOD() scalar function. To build the expression, a call is make to
- * {@link #getQuotientExpression(IExpression)} and its result is multiplied
- * by the second parameter of <code>function</code> and that result is then
- * subtracted from the first parameter of <code>function</code>.
- * <p>
- * For example:
- * <code>mod(x, y) ---> (x - (getQuotientExpression((x / y)) * y))</code>
- *
- * @param function the MOD function that may need to be modified
- * @see org.teiid.connector.jdbc.translator.AliasModifier#modify(org.teiid.connector.language.IFunction)
- */
- @Override
- public IExpression modify(IFunction function) {
- List<IExpression> expressions = function.getParameters();
- IExpression dividend = expressions.get(0);
- IExpression divisor = expressions.get(1);
-
- // Check to see if parameters are supported by source MOD function
- if (this.supTypeList.contains(dividend.getType())) {
- return super.modify(function);
- }
-
- /*
- * Parameters are not supported by source MOD function so modify
- * MOD(<dividend>, <divisor>) --> (<dividend> - (<func_getQuotient((<dividend> / <divisor>))> * <divisor>))
- */
- // --> (<dividend> / <divisor>)
- IFunction divide = langFactory.createFunction("/", Arrays.asList(dividend, divisor), dividend.getType()); //$NON-NLS-1$
- // --> <func_getQuotient(<divide>)> -- i.e. TRUNC(<divide>, 0)
- IFunction quotient = (IFunction) this.getQuotientExpression(divide);
- // --> (<quotient> * <divisor>)
- List<IExpression> multiplyArgs = Arrays.asList(quotient, divisor);
- IFunction multiply = langFactory.createFunction("*", multiplyArgs, divisor.getType()); //$NON-NLS-1$
- // --> (<dividend> - <multiply>)
- List<IExpression> minusArgs = Arrays.asList(dividend, multiply);
- return langFactory.createFunction("-", minusArgs, dividend.getType()); //$NON-NLS-1$
- }
-
- /**
- * Return an expression that will result in the quotient of </code>division</code>.
- * Quotient should always be represented as an integer (no remainder).
- * <p>
- * <code>division</code> will represent simple division that may result in a
- * fraction. <code>division</code> should be returned within a helper
- * function or expression that will result in an integer return value (no
- * decimal or fraction).
- * <p>
- * If this method is not overriden, the result will be:
- * <p>
- * <ul>TRUNC(<code>division</code>, 0)</ul>
- * <p>
- * For the default TRUNC() function to work, the source must support it.
- * TRUNC was used instead of FLOOR because FLOOR rounds to the nearest
- * integer toward negative infinity. This would result in incorrect values
- * when performing MOD on negative float, double, etc. values.
- *
- * @param division an expression representing simple division
- * @return an expression that will extract the quotient from the
- * <code>division</code> expression
- */
- protected IExpression getQuotientExpression(IExpression division) {
- // --> TRUNC(<division>, 0)
- return langFactory.createFunction("TRUNC", Arrays.asList(division, langFactory.createLiteral(0, RUNTIME_TYPES.SHORT)), division.getType()); //$NON-NLS-1$
- }
-
- protected ILanguageFactory getLanguageFactory() {
- return this.langFactory;
- }
-
-}
Copied: trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/translator/ModFunctionModifier.java (from rev 1264, trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/translator/MODFunctionModifier.java)
===================================================================
--- trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/translator/ModFunctionModifier.java (rev 0)
+++ trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/translator/ModFunctionModifier.java 2009-08-19 21:08:00 UTC (rev 1265)
@@ -0,0 +1,185 @@
+/*
+ * 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.connector.jdbc.translator;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.teiid.connector.api.TypeFacility.RUNTIME_TYPES;
+import org.teiid.connector.language.IExpression;
+import org.teiid.connector.language.IFunction;
+import org.teiid.connector.language.ILanguageFactory;
+
+/**
+ * A modifier class that can be used to translate the scalar function
+ * <code>mod(x, y)</code> to a function or expression that can be used at the
+ * data source.
+ * <p>
+ * If the default implementation is used, a function name of MOD will be used
+ * for the alias name and the expression will be unmodified if the data type
+ * of the <code>x</code> parameter is one of {@link RUNTIME_TYPES#BYTE},
+ * {@link RUNTIME_TYPES#SHORT}, {@link RUNTIME_TYPES#INTEGER}, or
+ * {@link RUNTIME_TYPES#LONG}. If the data type is not one of these types, the
+ * expression will be modified to return: <code>(x - (TRUNC((x / y), 0) * y))</code>
+ *
+ * @since 6.2
+ */
+public class ModFunctionModifier extends AliasModifier {
+
+ private static List<Class<?>> DEFAULT_TYPELIST = new ArrayList<Class<?>>(4);
+ static {
+ DEFAULT_TYPELIST.add(RUNTIME_TYPES.BYTE);
+ DEFAULT_TYPELIST.add(RUNTIME_TYPES.SHORT);
+ DEFAULT_TYPELIST.add(RUNTIME_TYPES.INTEGER);
+ DEFAULT_TYPELIST.add(RUNTIME_TYPES.LONG);
+ }
+ private static String DEFAULT_FUNCTIONNAME = "MOD"; //$NON-NLS-1$
+
+ private ILanguageFactory langFactory;
+ private List<Class<?>> supTypeList;
+
+ /**
+ * Constructs a {@link AliasModifier} object that can be used to translate
+ * the use of the scalar function MOD() to a source specific scalar function
+ * or expression.
+ * <p>
+ * This constructor invokes {@link #MODFunctionModifier(ILanguageFactory, String, List)}
+ * passing it <code>langFactory</code>, {@link #DEFAULT_FUNCTIONNAME}, and
+ * {@link #DEFAULT_TYPELIST}.
+ *
+ * @param langFactory the language factory associated with translation
+ */
+ public ModFunctionModifier(ILanguageFactory langFactory) {
+ this(langFactory, DEFAULT_FUNCTIONNAME, DEFAULT_TYPELIST);
+ }
+
+ /**
+ * Constructs a {@link AliasModifier} object that can be used to translate
+ * the use of the scalar function MOD() to a source specific scalar function
+ * or expression.
+ * <p>
+ * <code>functionName</code> is used to construct the parent {@link AliasModifier}
+ * and should represent the default function name or alias used by the data
+ * source.
+ * <p>
+ * <code>supportedTypeList</code> should contain a list of <code>Class</code>
+ * objects that represent the data types that the data source can support
+ * with its implementation of the MOD() scalar function.
+ *
+ * @param langFactory the language factory associated with translation
+ * @param functionName the function name or alias that should be used
+ * instead of MOD
+ * @param supportedTypeList a list of type classes that is supported by the
+ * data source's MOD function
+ */
+ public ModFunctionModifier(ILanguageFactory langFactory, String functionName, List<Class<?>>supportedTypeList) {
+ super(functionName);
+ this.langFactory = langFactory;
+ if ( supportedTypeList != null ) {
+ this.supTypeList = supportedTypeList;
+ } else {
+ this.supTypeList = ModFunctionModifier.DEFAULT_TYPELIST;
+ }
+ }
+
+ /**
+ * Returns a version of <code>function</code> suitable for executing at the
+ * data source.
+ * <p>
+ * If the data type of the parameters in <code>function</code> is in the
+ * list of supported data types, this method simply returns <code>super.modify(function)</code>.
+ * <p>
+ * If the data type of the parameters in <code>function</code are not in the
+ * list of supported data types, this method will return an expression that
+ * is valid at the data source and will yield the same result as the original
+ * MOD() scalar function. To build the expression, a call is make to
+ * {@link #getQuotientExpression(IExpression)} and its result is multiplied
+ * by the second parameter of <code>function</code> and that result is then
+ * subtracted from the first parameter of <code>function</code>.
+ * <p>
+ * For example:
+ * <code>mod(x, y) ---> (x - (getQuotientExpression((x / y)) * y))</code>
+ *
+ * @param function the MOD function that may need to be modified
+ * @see org.teiid.connector.jdbc.translator.AliasModifier#modify(org.teiid.connector.language.IFunction)
+ */
+ @Override
+ public IExpression modify(IFunction function) {
+ List<IExpression> expressions = function.getParameters();
+ IExpression dividend = expressions.get(0);
+ IExpression divisor = expressions.get(1);
+
+ // Check to see if parameters are supported by source MOD function
+ if (this.supTypeList.contains(dividend.getType())) {
+ return super.modify(function);
+ }
+
+ /*
+ * Parameters are not supported by source MOD function so modify
+ * MOD(<dividend>, <divisor>) --> (<dividend> - (<func_getQuotient((<dividend> / <divisor>))> * <divisor>))
+ */
+ // --> (<dividend> / <divisor>)
+ IFunction divide = langFactory.createFunction("/", Arrays.asList(dividend, divisor), dividend.getType()); //$NON-NLS-1$
+ // --> <func_getQuotient(<divide>)> -- i.e. TRUNC(<divide>, 0)
+ IFunction quotient = (IFunction) this.getQuotientExpression(divide);
+ // --> (<quotient> * <divisor>)
+ List<IExpression> multiplyArgs = Arrays.asList(quotient, divisor);
+ IFunction multiply = langFactory.createFunction("*", multiplyArgs, divisor.getType()); //$NON-NLS-1$
+ // --> (<dividend> - <multiply>)
+ List<IExpression> minusArgs = Arrays.asList(dividend, multiply);
+ return langFactory.createFunction("-", minusArgs, dividend.getType()); //$NON-NLS-1$
+ }
+
+ /**
+ * Return an expression that will result in the quotient of </code>division</code>.
+ * Quotient should always be represented as an integer (no remainder).
+ * <p>
+ * <code>division</code> will represent simple division that may result in a
+ * fraction. <code>division</code> should be returned within a helper
+ * function or expression that will result in an integer return value (no
+ * decimal or fraction).
+ * <p>
+ * If this method is not overriden, the result will be:
+ * <p>
+ * <ul>TRUNC(<code>division</code>, 0)</ul>
+ * <p>
+ * For the default TRUNC() function to work, the source must support it.
+ * TRUNC was used instead of FLOOR because FLOOR rounds to the nearest
+ * integer toward negative infinity. This would result in incorrect values
+ * when performing MOD on negative float, double, etc. values.
+ *
+ * @param division an expression representing simple division
+ * @return an expression that will extract the quotient from the
+ * <code>division</code> expression
+ */
+ protected IExpression getQuotientExpression(IExpression division) {
+ // --> TRUNC(<division>, 0)
+ return langFactory.createFunction("TRUNC", Arrays.asList(division, langFactory.createLiteral(0, RUNTIME_TYPES.SHORT)), division.getType()); //$NON-NLS-1$
+ }
+
+ protected ILanguageFactory getLanguageFactory() {
+ return this.langFactory;
+ }
+
+}
Property changes on: trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/translator/ModFunctionModifier.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/translator/TestLOCATEFunctionModifier.java
===================================================================
--- trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/translator/TestLOCATEFunctionModifier.java 2009-08-19 19:50:56 UTC (rev 1264)
+++ trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/translator/TestLOCATEFunctionModifier.java 2009-08-19 21:08:00 UTC (rev 1265)
@@ -31,11 +31,9 @@
import org.teiid.connector.api.ConnectorEnvironment;
import org.teiid.connector.api.ConnectorException;
import org.teiid.connector.api.SourceSystemFunctions;
-import org.teiid.connector.jdbc.translator.LOCATEFunctionModifier.ParameterOrder;
import org.teiid.connector.language.IExpression;
import org.teiid.connector.language.IFunction;
import org.teiid.connector.language.ILanguageFactory;
-import org.teiid.connector.language.ILiteral;
import com.metamatrix.cdk.CommandBuilder;
import com.metamatrix.cdk.api.EnvironmentUtility;
@@ -60,7 +58,7 @@
* @throws Exception
*/
public IExpression helpTestLocate(IExpression[] args, String expectedStr) throws Exception {
- return this.helpTestLocate(null, null, args, expectedStr);
+ return this.helpTestLocate(LocateFunctionModifier.LOCATE, false, args, expectedStr);
}
/**
@@ -82,7 +80,7 @@
* @return On success, the modified expression.
* @throws Exception
*/
- public IExpression helpTestLocate(final String locateFunctionName, final ParameterOrder parameterOrder, IExpression[] args, String expectedStr) throws Exception {
+ public IExpression helpTestLocate(final String locateFunctionName, final boolean parameterOrder, IExpression[] args, String expectedStr) throws Exception {
IExpression param1 = null;
IExpression param2 = null;
IExpression param3 = null;
@@ -106,7 +104,7 @@
public void initialize(ConnectorEnvironment env)
throws ConnectorException {
super.initialize(env);
- registerFunctionModifier(SourceSystemFunctions.LOCATE, new LOCATEFunctionModifier(getLanguageFactory(), locateFunctionName, parameterOrder));
+ registerFunctionModifier(SourceSystemFunctions.LOCATE, new LocateFunctionModifier(getLanguageFactory(), locateFunctionName, parameterOrder));
}
};
@@ -123,11 +121,11 @@
}
/**
- * Test {@link LOCATEFunctionModifier#modify(IFunction)} to validate a call
+ * Test {@link LocateFunctionModifier#modify(IFunction)} to validate a call
* to LOCATE(search_str, source_str) using constants for both parameters
* returns LOCATE(search_str, source_str).
* <p>
- * {@link LOCATEFunctionModifier} will be constructed without specifying a
+ * {@link LocateFunctionModifier} will be constructed without specifying a
* function name or parameter order.
*
* @throws Exception
@@ -142,11 +140,11 @@
}
/**
- * Test {@link LOCATEFunctionModifier#modify(IFunction)} to validate a call
+ * Test {@link LocateFunctionModifier#modify(IFunction)} to validate a call
* to LOCATE(search_str, source_str) using constants for both parameters
* returns locate(search_str, source_str).
* <p>
- * {@link LOCATEFunctionModifier} will be constructed specifying a function
+ * {@link LocateFunctionModifier} will be constructed specifying a function
* name of locate but no parameter order.
*
* @throws Exception
@@ -157,15 +155,15 @@
LANG_FACTORY.createLiteral("abcdefg", String.class) //$NON-NLS-1$
};
// locate / default
- helpTestLocate("locate", null, args, "locate('a', 'abcdefg')"); //$NON-NLS-1$ //$NON-NLS-2$
+ helpTestLocate("locate", false, args, "locate('a', 'abcdefg')"); //$NON-NLS-1$ //$NON-NLS-2$
}
/**
- * Test {@link LOCATEFunctionModifier#modify(IFunction)} to validate a call
+ * Test {@link LocateFunctionModifier#modify(IFunction)} to validate a call
* to LOCATE(search_str, source_str) using constants for both parameters
* returns INSTR(source_str, search_str).
* <p>
- * {@link LOCATEFunctionModifier} will be constructed specifying a function
+ * {@link LocateFunctionModifier} will be constructed specifying a function
* name of INSTR and a parameter order of {@link ParameterOrder#SOURCE_SEARCH_INDEX}.
*
* @throws Exception
@@ -176,15 +174,15 @@
LANG_FACTORY.createLiteral("abcdefg", String.class) //$NON-NLS-1$
};
// INSTR / SOURCE_SEARCH_INDEX
- helpTestLocate("INSTR", ParameterOrder.SOURCE_SEARCH_INDEX, args, "INSTR('abcdefg', 'a')"); //$NON-NLS-1$ //$NON-NLS-2$
+ helpTestLocate("INSTR", true, args, "INSTR('abcdefg', 'a')"); //$NON-NLS-1$ //$NON-NLS-2$
}
/**
- * Test {@link LOCATEFunctionModifier#modify(IFunction)} to validate a call
+ * Test {@link LocateFunctionModifier#modify(IFunction)} to validate a call
* to LOCATE(search_str, source_str) using constants for both parameters
* returns locate(search_str, source_str).
* <p>
- * {@link LOCATEFunctionModifier} will be constructed specifying a function
+ * {@link LocateFunctionModifier} will be constructed specifying a function
* name of locate and a parameter order of {@link ParameterOrder#DEFAULT}.
*
* @throws Exception
@@ -195,15 +193,15 @@
LANG_FACTORY.createLiteral("abcdefg", String.class) //$NON-NLS-1$
};
// locate / DEFAULT
- helpTestLocate("locate", ParameterOrder.DEFAULT, args, "locate('a', 'abcdefg')"); //$NON-NLS-1$ //$NON-NLS-2$
+ helpTestLocate("locate", false, args, "locate('a', 'abcdefg')"); //$NON-NLS-1$ //$NON-NLS-2$
}
/**
- * Test {@link LOCATEFunctionModifier#modify(IFunction)} to validate a call
+ * Test {@link LocateFunctionModifier#modify(IFunction)} to validate a call
* to LOCATE(search_str, source_str, 1) using constants for all parameters
* returns INSTR(source_str, search_str, 1).
* <p>
- * {@link LOCATEFunctionModifier} will be constructed specifying a function
+ * {@link LocateFunctionModifier} will be constructed specifying a function
* name of INSTR and a parameter order of {@link ParameterOrder#SOURCE_SEARCH_INDEX}.
*
* @throws Exception
@@ -215,15 +213,15 @@
LANG_FACTORY.createLiteral(1, Integer.class)
};
// INSTR / SOURCE_SEARCH_INDEX
- helpTestLocate("INSTR", ParameterOrder.SOURCE_SEARCH_INDEX, args, "INSTR('abcdefg', 'a', 1)"); //$NON-NLS-1$ //$NON-NLS-2$
+ helpTestLocate("INSTR", true, args, "INSTR('abcdefg', 'a', 1)"); //$NON-NLS-1$ //$NON-NLS-2$
}
/**
- * Test {@link LOCATEFunctionModifier#modify(IFunction)} to validate a call
+ * Test {@link LocateFunctionModifier#modify(IFunction)} to validate a call
* to LOCATE(search_str, source_str, 4) using constants for all parameters
* returns LOCATE(search_str, source_str, 5).
* <p>
- * {@link LOCATEFunctionModifier} will be constructed specifying no function
+ * {@link LocateFunctionModifier} will be constructed specifying no function
* name or parameter order.
*
* @throws Exception
@@ -235,15 +233,15 @@
LANG_FACTORY.createLiteral(4, Integer.class)
};
// default / default
- helpTestLocate(null, null, args, "LOCATE('a', 'abcdefg', 4)"); //$NON-NLS-1$
+ helpTestLocate(args, "LOCATE('a', 'abcdefg', 4)"); //$NON-NLS-1$
}
/**
- * Test {@link LOCATEFunctionModifier#modify(IFunction)} to validate a call
+ * Test {@link LocateFunctionModifier#modify(IFunction)} to validate a call
* to LOCATE(search_str, source_str, -5) using constants for all parameters
* returns LOCATE(search_str, source_str, 1).
* <p>
- * {@link LOCATEFunctionModifier} will be constructed specifying no function
+ * {@link LocateFunctionModifier} will be constructed specifying no function
* name or parameter order.
*
* @throws Exception
@@ -255,15 +253,15 @@
LANG_FACTORY.createLiteral(-5, Integer.class)
};
// default / default
- helpTestLocate(null, null, args, "LOCATE('a', 'abcdefg', 1)"); //$NON-NLS-1$
+ helpTestLocate(args, "LOCATE('a', 'abcdefg', 1)"); //$NON-NLS-1$
}
/**
- * Test {@link LOCATEFunctionModifier#modify(IFunction)} to validate a call
+ * Test {@link LocateFunctionModifier#modify(IFunction)} to validate a call
* to LOCATE(search_str, source_str, null) using constants for all parameters
* returns LOCATE(search_str, source_str, NULL).
* <p>
- * {@link LOCATEFunctionModifier} will be constructed specifying no function
+ * {@link LocateFunctionModifier} will be constructed specifying no function
* name or parameter order.
*
* @throws Exception
@@ -275,15 +273,15 @@
LANG_FACTORY.createLiteral(null, Integer.class)
};
// default / default
- helpTestLocate(null, null, args, "LOCATE('a', 'abcdefg', NULL)"); //$NON-NLS-1$
+ helpTestLocate(args, "LOCATE('a', 'abcdefg', NULL)"); //$NON-NLS-1$
}
/**
- * Test {@link LOCATEFunctionModifier#modify(IFunction)} to validate a call
+ * Test {@link LocateFunctionModifier#modify(IFunction)} to validate a call
* to LOCATE(search_str, source_str, e1) using an element for start index
* parameter returns INSTR(source_str, search_str, CASE WHEN e1 < 1 THEN 1 ELSE e1 END).
* <p>
- * {@link LOCATEFunctionModifier} will be constructed specifying a function
+ * {@link LocateFunctionModifier} will be constructed specifying a function
* name of INSTR and a parameter order of {@link ParameterOrder#SOURCE_SEARCH_INDEX}.
*
* @throws Exception
@@ -295,15 +293,15 @@
LANG_FACTORY.createElement("e1", null, null, Integer.class) //$NON-NLS-1$
};
// INSTR / SOURCE_SEARCH_INDEX
- helpTestLocate("INSTR", ParameterOrder.SOURCE_SEARCH_INDEX, args, "INSTR('abcdefg', 'a', CASE WHEN e1 < 1 THEN 1 ELSE e1 END)"); //$NON-NLS-1$ //$NON-NLS-2$
+ helpTestLocate("INSTR", true, args, "INSTR('abcdefg', 'a', CASE WHEN e1 < 1 THEN 1 ELSE e1 END)"); //$NON-NLS-1$ //$NON-NLS-2$
}
/**
- * Test {@link LOCATEFunctionModifier#modify(IFunction)} to validate a call
+ * Test {@link LocateFunctionModifier#modify(IFunction)} to validate a call
* to LOCATE(search_str, source_str, e1) using an element for start index
* parameter returns LOCATE(search_str, source_str, CASE WHEN e1 < 0 THEN 0 ELSE e1 END).
* <p>
- * {@link LOCATEFunctionModifier} will be constructed specifying no function
+ * {@link LocateFunctionModifier} will be constructed specifying no function
* name and no parameter order.
*
* @throws Exception
@@ -315,99 +313,7 @@
LANG_FACTORY.createElement("e1", null, null, Integer.class) //$NON-NLS-1$
};
// default / default
- helpTestLocate(null, null, args, "LOCATE('a', 'abcdefg', CASE WHEN e1 < 1 THEN 1 ELSE e1 END)"); //$NON-NLS-1$
+ helpTestLocate(args, "LOCATE('a', 'abcdefg', CASE WHEN e1 < 1 THEN 1 ELSE e1 END)"); //$NON-NLS-1$
}
-
- /**
- * Test {@link LOCATEFunctionModifier#modify(IFunction)} to validate a call
- * to LOCATE(search_str, source_str, e1) using an element for start index
- * parameter returns LOCATE(search_str, source_str, e1).
- * <p>
- * {@link LOCATEFunctionModifier} will be constructed specifying no function
- * name, no parameter order, and no string index base. The test explicitly
- * overrides {@link LOCATEFunctionModifier#getStartIndexExpression(IExpression)}
- * to produce output that does not use the searched case expression for the
- * element.
- *
- * @throws Exception
- */
- @Test public void testOverrideGetStartIndexExpression() throws Exception {
- final String expectedStr = "LOCATE('a', 'abcdefg', e1)"; //$NON-NLS-1$
-
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral("a", String.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral("abcdefg", String.class), //$NON-NLS-1$
- LANG_FACTORY.createElement("e1", null, null, Integer.class) //$NON-NLS-1$
- };
- IFunction func = LANG_FACTORY.createFunction(SourceSystemFunctions.LOCATE, args, Integer.class);
-
- final Translator trans = new Translator() {
- @Override
- public void initialize(ConnectorEnvironment env)
- throws ConnectorException {
- super.initialize(env);
- registerFunctionModifier(SourceSystemFunctions.LOCATE, new LOCATEFunctionModifier(getLanguageFactory(), null, null) {
- @Override
- protected IExpression getStartIndexExpression(
- IExpression startIndex) {
- return startIndex;
- }
-
- });
- }
- };
-
- trans.initialize(EnvironmentUtility.createEnvironment(new Properties(), false));
-
- IExpression expr = trans.getFunctionModifiers().get(SourceSystemFunctions.LOCATE).modify(func);
- SQLConversionVisitor sqlVisitor = trans.getSQLConversionVisitor();
- sqlVisitor.append(expr);
- assertEquals("Modified function does not match", expectedStr, sqlVisitor.toString()); //$NON-NLS-1$
- }
-
- /**
- * Test {@link LOCATEFunctionModifier#modify(IFunction)} to validate a call
- * to LOCATE(search_str, source_str, 1) using a literal for start index
- * parameter returns LOCATE(search_str, source_str, (1 + 1)).
- * <p>
- * {@link LOCATEFunctionModifier} will be constructed specifying no function
- * name, no parameter order. The test explicitly overrides {@link LOCATEFunctionModifier#getStartIndexExpression(ILiteral)}
- * to produce output that adds <code>1</code> to the literal.
- *
- * @throws Exception
- */
- @Test public void testOverrideGetStartIndexExpression2() throws Exception {
- final String expectedStr = "LOCATE('a', 'abcdefg', (1 + 1))"; //$NON-NLS-1$
-
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral("a", String.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral("abcdefg", String.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral(1, Integer.class)
- };
- IFunction func = LANG_FACTORY.createFunction(SourceSystemFunctions.LOCATE, args, Integer.class);
-
- final Translator trans = new Translator() {
- @Override
- public void initialize(ConnectorEnvironment env)
- throws ConnectorException {
- super.initialize(env);
- registerFunctionModifier(SourceSystemFunctions.LOCATE, new LOCATEFunctionModifier(getLanguageFactory(), null, null) {
- @Override
- protected IExpression getStartIndexExpression(
- ILiteral startIndex) {
- return LANG_FACTORY.createFunction("+", Arrays.asList(startIndex, LANG_FACTORY.createLiteral(1, Integer.class)), Integer.class); //$NON-NLS-1$
- }
-
- });
- }
- };
-
- trans.initialize(EnvironmentUtility.createEnvironment(new Properties(), false));
-
- IExpression expr = trans.getFunctionModifiers().get(SourceSystemFunctions.LOCATE).modify(func);
- SQLConversionVisitor sqlVisitor = trans.getSQLConversionVisitor();
- sqlVisitor.append(expr);
- assertEquals("Modified function does not match", expectedStr, sqlVisitor.toString()); //$NON-NLS-1$
- }
}
Deleted: trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/translator/TestMODFunctionModifier.java
===================================================================
--- trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/translator/TestMODFunctionModifier.java 2009-08-19 19:50:56 UTC (rev 1264)
+++ trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/translator/TestMODFunctionModifier.java 2009-08-19 21:08:00 UTC (rev 1265)
@@ -1,1253 +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.connector.jdbc.translator;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Properties;
-
-import junit.framework.TestCase;
-
-import org.teiid.connector.api.ConnectorEnvironment;
-import org.teiid.connector.api.ConnectorException;
-import org.teiid.connector.api.SourceSystemFunctions;
-import org.teiid.connector.language.IExpression;
-import org.teiid.connector.language.IFunction;
-import org.teiid.connector.language.ILanguageFactory;
-
-import com.metamatrix.cdk.CommandBuilder;
-import com.metamatrix.cdk.api.EnvironmentUtility;
-
-/**
- * Test <code>ModFunctionModifier</code> by invoking its methods with varying
- * parameters to validate it performs as designed and expected.
- */
-public class TestMODFunctionModifier extends TestCase {
-
- private static final ILanguageFactory LANG_FACTORY = CommandBuilder.getLanuageFactory();
-
- /**
- * Constructor for TestModFunctionModifier.
- * @param name
- */
- public TestMODFunctionModifier(String name) {
- super(name);
- }
-
-
- /**
- * Create an expression containing a MOD function using <code>args</code>
- * and pass it to the <code>Translator</code>'s MOD function modifier and
- * compare the resulting expression to <code>expectedStr</code>.
- *
- * @param args An array of <code>IExpression</code>'s to use as the
- * arguments to the MOD() function
- * @param expectedStr A string representing the modified expression
- * @return On success, the modified expression.
- * @throws Exception
- */
- public IExpression helpTestMod(IExpression[] args, String expectedStr) throws Exception {
- return this.helpTestMod(null, null, args, expectedStr);
- }
-
- /**
- * Create an expression containing a MOD function using a function name of
- * <code>modFunctionName</code> which supports types of <code>supportedTypes</code>
- * and uses the arguments <code>args</code> and pass it to the
- * <code>Translator</code>'s MOD function modifier and compare the resulting
- * expression to <code>expectedStr</code>.
- *
- * @param modFunctionName the name to use for the function modifier
- * @param supportedTypes a list of types that the mod function should support
- * @param args an array of <code>IExpression</code>'s to use as the
- * arguments to the MOD() function
- * @param expectedStr A string representing the modified expression
- * @return On success, the modified expression.
- * @throws Exception
- */
- public IExpression helpTestMod(final String modFunctionName, final List<Class<?>> supportedTypes, IExpression[] args, String expectedStr) throws Exception {
- IExpression param1 = null;
- IExpression param2 = null;
-
- if (args.length < 2) {
- param2 = LANG_FACTORY.createLiteral(null, Short.class);
- if (args.length < 1) {
- param1 = LANG_FACTORY.createLiteral(null, Short.class);
- } else {
- param1 = args[0];
- }
- } else {
- param1 = args[0];
- param2 = args[1];
- }
-
- if ( !param1.getType().equals(param2.getType()) ) {
- if (param2.getType().equals(BigDecimal.class)) {
- param1.setType(param2.getType());
- } else if (param1.getType().equals(BigDecimal.class)) {
- param2.setType(param1.getType());
- } else if (param2.getType().equals(BigInteger.class)) {
- param1.setType(param2.getType());
- } else if (param1.getType().equals(BigInteger.class)) {
- param2.setType(param1.getType());
- } else if (param2.getType().equals(Float.class)) {
- param1.setType(param2.getType());
- } else if (param1.getType().equals(Float.class)) {
- param2.setType(param1.getType());
- } else if (param2.getType().equals(Long.class)) {
- param1.setType(param2.getType());
- } else if (param1.getType().equals(Long.class)) {
- param2.setType(param1.getType());
- } else if (param2.getType().equals(Integer.class)) {
- param1.setType(param2.getType());
- } else if (param1.getType().equals(Integer.class)) {
- param2.setType(param1.getType());
- } else if (param2.getType().equals(Short.class)) {
- param1.setType(param2.getType());
- } else if (param1.getType().equals(Short.class)) {
- param2.setType(param1.getType());
- } else {
- throw new IllegalArgumentException("Parameters must be of numeric types"); //$NON-NLS-1$
- }
- }
-
- IFunction func = LANG_FACTORY.createFunction(modFunctionName,
- Arrays.asList(param1, param2), param1.getType());
-
- Translator trans = new Translator() {
- @Override
- public void initialize(ConnectorEnvironment env)
- throws ConnectorException {
- super.initialize(env);
- if (modFunctionName == null) {
- registerFunctionModifier(SourceSystemFunctions.MOD, new MODFunctionModifier(getLanguageFactory()));
- } else {
- registerFunctionModifier(SourceSystemFunctions.MOD, new MODFunctionModifier(getLanguageFactory(), modFunctionName, supportedTypes));
- }
- }
- };
-
- trans.initialize(EnvironmentUtility.createEnvironment(new Properties(), false));
-
- IExpression expr = trans.getFunctionModifiers().get(SourceSystemFunctions.MOD).modify(func);
-
- SQLConversionVisitor sqlVisitor = trans.getSQLConversionVisitor();
- sqlVisitor.append(expr);
-
- assertEquals("Modified function does not match", expectedStr, sqlVisitor.toString()); //$NON-NLS-1$
-
- return expr;
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * MOD(x,y) using {@link Short} constants for both parameters returns MOD(x,y).
- * {@link MODFunctionModifier} will be constructed without specifying a
- * function name or a supported type list.
- *
- * @throws Exception
- */
- public void testTwoShortConst() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new Short((short) 10), Short.class),
- LANG_FACTORY.createLiteral(new Short((short) 6), Short.class)
- };
- // default / default
- helpTestMod(args, "MOD(10, 6)"); //$NON-NLS-1$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * MOD(x,y) using {@link Short} constants for both parameters returns MOD(x,y).
- * {@link MODFunctionModifier} will be constructed with a function name of
- * "MOD" but without a supported type list.
- *
- * @throws Exception
- */
- public void testTwoShortConst2() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new Short((short) 10), Short.class),
- LANG_FACTORY.createLiteral(new Short((short) 6), Short.class)
- };
- // mod / default
- helpTestMod("MOD", null, args, "MOD(10, 6)"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * MOD(x,y) using {@link Short} constants for both parameters returns MOD(x,y).
- * {@link MODFunctionModifier} will be constructed with a function name of
- * "MOD" and a supported type list which contains {@link Short}.
- *
- * @throws Exception
- */
- public void testTwoShortConst3() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new Short((short) 10), Short.class),
- LANG_FACTORY.createLiteral(new Short((short) 6), Short.class)
- };
- // mod / Short
- List<Class<?>> typeList = new ArrayList<Class<?>>(1);
- typeList.add(Short.class);
- helpTestMod("MOD", typeList, args, "MOD(10, 6)"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * MOD(x,y) using {@link Short} constants for both parameters returns
- * (x - (TRUNC((x / y), 0) * y)). {@link MODFunctionModifier} will be
- * constructed with a function name of "MOD" and a supported type list which
- * does not contains {@link Short}.
- *
- * @throws Exception
- */
- public void testTwoShortConst4() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new Short((short) 10), Short.class),
- LANG_FACTORY.createLiteral(new Short((short) 6), Short.class)
- };
- // mod / Integer
- List<Class<?>> typeList = new ArrayList<Class<?>>(1);
- typeList.add(Integer.class);
- helpTestMod("MOD", typeList, args, "(10 - (TRUNC((10 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * x % y using {@link Short} constants for both parameters returns (x % y).
- * {@link MODFunctionModifier} will be constructed with a function name of
- * "%" and no supported type list.
- *
- * @throws Exception
- */
- public void testTwoShortConst5() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new Short((short) 10), Short.class),
- LANG_FACTORY.createLiteral(new Short((short) 6), Short.class)
- };
- // % / default
- helpTestMod("%", null, args, "(10 % 6)"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * x % y using {@link Short} constants for both parameters returns (x % y).
- * {@link MODFunctionModifier} will be constructed with a function name of
- * "%" and a supported type list which contains {@link Short}.
- *
- * @throws Exception
- */
- public void testTwoShortConst6() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new Short((short) 10), Short.class),
- LANG_FACTORY.createLiteral(new Short((short) 6), Short.class)
- };
- // % / Short
- List<Class<?>> typeList = new ArrayList<Class<?>>(1);
- typeList.add(Short.class);
- helpTestMod("%", typeList, args, "(10 % 6)"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * x % y using {@link Short} constants for both parameters returns
- * (10 - (TRUNC((10 / 6), 0) * 6)). {@link MODFunctionModifier} will be
- * constructed with a function name of "%" and a supported type list does not
- * contain {@link Short}.
- *
- * @throws Exception
- */
- public void testTwoShortConst7() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new Short((short) 10), Short.class),
- LANG_FACTORY.createLiteral(new Short((short) 6), Short.class)
- };
- // % / Integer
- List<Class<?>> typeList = new ArrayList<Class<?>>(1);
- typeList.add(Integer.class);
- helpTestMod("%", typeList, args, "(10 - (TRUNC((10 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * MOD(x,y) using {@link Integer} constants for both parameters returns
- * MOD(x,y). {@link MODFunctionModifier} will be constructed without
- * specifying a function name or a supported type list.
- *
- * @throws Exception
- */
- public void testTwoIntConst() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new Integer(10), Integer.class),
- LANG_FACTORY.createLiteral(new Integer(6), Integer.class)
- };
- // default / default
- helpTestMod(args, "MOD(10, 6)"); //$NON-NLS-1$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * MOD(x,y) using {@link Integer} constants for both parameters returns
- * MOD(x,y). {@link MODFunctionModifier} will be constructed with a
- * function name of "MOD" but without a supported type list.
- *
- * @throws Exception
- */
- public void testTwoIntConst2() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new Integer(10), Integer.class),
- LANG_FACTORY.createLiteral(new Integer(6), Integer.class)
- };
- // mod / default
- helpTestMod("MOD", null, args, "MOD(10, 6)"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * MOD(x,y) using {@link Integer} constants for both parameters returns
- * MOD(x,y). {@link MODFunctionModifier} will be constructed with a
- * function name of "MOD" and a supported type list which contains {@link Integer}.
- *
- * @throws Exception
- */
- public void testTwoIntConst3() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new Integer(10), Integer.class),
- LANG_FACTORY.createLiteral(new Integer(6), Integer.class)
- };
- // mod / Short
- List<Class<?>> typeList = new ArrayList<Class<?>>(1);
- typeList.add(Integer.class);
- helpTestMod("MOD", typeList, args, "MOD(10, 6)"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * MOD(x,y) using {@link Integer} constants for both parameters returns
- * (x - (TRUNC((x / y), 0) * y)). {@link MODFunctionModifier} will be
- * constructed with a function name of "MOD" and a supported type list which
- * does not contain {@link Integer}.
- *
- * @throws Exception
- */
- public void testTwoIntConst4() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new Integer(10), Integer.class),
- LANG_FACTORY.createLiteral(new Integer(6), Integer.class)
- };
- // mod / Integer
- List<Class<?>> typeList = new ArrayList<Class<?>>(1);
- typeList.add(Short.class);
- helpTestMod("MOD", typeList, args, "(10 - (TRUNC((10 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * x % y using {@link Integer} constants for both parameters returns (x % y).
- * {@link MODFunctionModifier} will be constructed with a function name of
- * "%" and no supported type list.
- *
- * @throws Exception
- */
- public void testTwoIntConst5() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new Integer(10), Integer.class),
- LANG_FACTORY.createLiteral(new Integer(6), Integer.class)
- };
- // % / default
- helpTestMod("%", null, args, "(10 % 6)"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * x % y using {@link Integer} constants for both parameters returns (x % y).
- * {@link MODFunctionModifier} will be constructed with a function name of
- * "%" and a supported type list which contains {@link Integer}.
- *
- * @throws Exception
- */
- public void testTwoIntConst6() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new Integer(10), Integer.class),
- LANG_FACTORY.createLiteral(new Integer(6), Integer.class)
- };
- // % / Short
- List<Class<?>> typeList = new ArrayList<Class<?>>(1);
- typeList.add(Integer.class);
- helpTestMod("%", typeList, args, "(10 % 6)"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * x % y using {@link Integer} constants for both parameters returns
- * (10 - (TRUNC((10 / 6), 0) * 6)). {@link MODFunctionModifier} will be
- * constructed with a function name of "%" and a supported type list that
- * does not contain {@link Integer}.
- *
- * @throws Exception
- */
- public void testTwoIntConst7() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new Integer(10), Integer.class),
- LANG_FACTORY.createLiteral(new Integer(6), Integer.class)
- };
- // % / Integer
- List<Class<?>> typeList = new ArrayList<Class<?>>(1);
- typeList.add(Short.class);
- helpTestMod("%", typeList, args, "(10 - (TRUNC((10 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * MOD(x,y) using {@link Long} constants for both parameters returns
- * MOD(x,y). {@link MODFunctionModifier} will be constructed without
- * specifying a function name or a supported type list.
- *
- * @throws Exception
- */
- public void testTwoLongConst() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new Long(10), Long.class),
- LANG_FACTORY.createLiteral(new Long(6), Long.class)
- };
- // default / default
- helpTestMod(args, "MOD(10, 6)"); //$NON-NLS-1$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * MOD(x,y) using {@link Long} constants for both parameters returns
- * MOD(x,y). {@link MODFunctionModifier} will be constructed with a
- * function name of "MOD" but without a supported type list.
- *
- * @throws Exception
- */
- public void testTwoLongConst2() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new Long(10), Long.class),
- LANG_FACTORY.createLiteral(new Long(6), Long.class)
- };
- // mod / default
- helpTestMod("MOD", null, args, "MOD(10, 6)"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * MOD(x,y) using {@link Long} constants for both parameters returns
- * MOD(x,y). {@link MODFunctionModifier} will be constructed with a
- * function name of "MOD" and a supported type list which contains {@link Long}.
- *
- * @throws Exception
- */
- public void testTwoLongConst3() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new Long(10), Long.class),
- LANG_FACTORY.createLiteral(new Long(6), Long.class)
- };
- // mod / Long
- List<Class<?>> typeList = new ArrayList<Class<?>>(1);
- typeList.add(Long.class);
- helpTestMod("MOD", typeList, args, "MOD(10, 6)"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * MOD(x,y) using {@link Long} constants for both parameters returns
- * (x - (TRUNC((x / y), 0) * y)). {@link MODFunctionModifier} will be
- * constructed with a function name of "MOD" and a supported type list which
- * does not contain {@link Long}.
- *
- * @throws Exception
- */
- public void testTwoLongConst4() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new Long(10), Long.class),
- LANG_FACTORY.createLiteral(new Long(6), Long.class)
- };
- // mod / Short
- List<Class<?>> typeList = new ArrayList<Class<?>>(1);
- typeList.add(Short.class);
- helpTestMod("MOD", typeList, args, "(10 - (TRUNC((10 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * x % y using {@link Long} constants for both parameters returns (x % y).
- * {@link MODFunctionModifier} will be constructed with a function name of
- * "%" and no supported type list.
- *
- * @throws Exception
- */
- public void testTwoLongConst5() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new Long(10), Long.class),
- LANG_FACTORY.createLiteral(new Long(6), Long.class)
- };
- // % / default
- helpTestMod("%", null, args, "(10 % 6)"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * x % y using {@link Long} constants for both parameters returns (x % y).
- * {@link MODFunctionModifier} will be constructed with a function name of
- * "%" and a supported type list which contains {@link Long}.
- *
- * @throws Exception
- */
- public void testTwoLongConst6() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new Long(10), Long.class),
- LANG_FACTORY.createLiteral(new Long(6), Long.class)
- };
- // % / Long
- List<Class<?>> typeList = new ArrayList<Class<?>>(1);
- typeList.add(Long.class);
- helpTestMod("%", typeList, args, "(10 % 6)"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * x % y using {@link Long} constants for both parameters returns
- * (10 - (TRUNC((10 / 6), 0) * 6)). {@link MODFunctionModifier} will be
- * constructed with a function name of "%" and a supported type list that
- * does not contain {@link Long}.
- *
- * @throws Exception
- */
- public void testTwoLongConst7() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new Long(10), Long.class),
- LANG_FACTORY.createLiteral(new Long(6), Long.class)
- };
- // % / Short
- List<Class<?>> typeList = new ArrayList<Class<?>>(1);
- typeList.add(Short.class);
- helpTestMod("%", typeList, args, "(10 - (TRUNC((10 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * MOD(x,y) using {@link Float} constants for both parameters returns
- * (x - (TRUNC((x / y), 0) * y)). {@link MODFunctionModifier} will be
- * constructed without specifying a function name or a supported type list.
- *
- * @throws Exception
- */
- public void testTwoFloatConst() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new Float(10), Float.class),
- LANG_FACTORY.createLiteral(new Float(6), Float.class)
- };
- // default / default
- helpTestMod(args, "(10.0 - (TRUNC((10.0 / 6.0), 0) * 6.0))"); //$NON-NLS-1$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * MOD(x,y) using {@link Float} constants for both parameters returns
- * (x - (TRUNC((x / y), 0) * y)). {@link MODFunctionModifier} will be
- * constructed with a function name of "MOD" but without a supported type
- * list.
- *
- * @throws Exception
- */
- public void testTwoFloatConst2() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new Float(10), Float.class),
- LANG_FACTORY.createLiteral(new Float(6), Float.class)
- };
- // mod / default
- helpTestMod("MOD", null, args, "(10.0 - (TRUNC((10.0 / 6.0), 0) * 6.0))"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * MOD(x,y) using {@link Float} constants for both parameters returns
- * MOD(x,y). {@link MODFunctionModifier} will be constructed with a
- * function name of "MOD" and a supported type list which contains {@link Float}.
- *
- * @throws Exception
- */
- public void testTwoFloatConst3() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new Float(10), Float.class),
- LANG_FACTORY.createLiteral(new Float(6), Float.class)
- };
- // mod / Float
- List<Class<?>> typeList = new ArrayList<Class<?>>(1);
- typeList.add(Float.class);
- helpTestMod("MOD", typeList, args, "MOD(10.0, 6.0)"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * MOD(x,y) using {@link Float} constants for both parameters returns
- * (x - (TRUNC((x / y), 0) * y)). {@link MODFunctionModifier} will be
- * constructed with a function name of "MOD" and a supported type list which
- * does not contain {@link Float}.
- *
- * @throws Exception
- */
- public void testTwoFloatConst4() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new Float(10), Float.class),
- LANG_FACTORY.createLiteral(new Float(6), Float.class)
- };
- // mod / Short
- List<Class<?>> typeList = new ArrayList<Class<?>>(1);
- typeList.add(Short.class);
- helpTestMod("MOD", typeList, args, "(10.0 - (TRUNC((10.0 / 6.0), 0) * 6.0))"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * x % y using {@link Float} constants for both parameters returns
- * (x - (TRUNC((x / y), 0) * x)). {@link MODFunctionModifier} will be
- * constructed with a function name of "%" and no supported type list.
- *
- * @throws Exception
- */
- public void testTwoFloatConst5() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new Float(10), Float.class),
- LANG_FACTORY.createLiteral(new Float(6), Float.class)
- };
- // % / default
- helpTestMod("%", null, args, "(10.0 - (TRUNC((10.0 / 6.0), 0) * 6.0))"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * x % y using {@link Float} constants for both parameters returns (x % y).
- * {@link MODFunctionModifier} will be constructed with a function name of
- * "%" and a supported type list which contains {@link Float}.
- *
- * @throws Exception
- */
- public void testTwoFloatConst6() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new Float(10), Float.class),
- LANG_FACTORY.createLiteral(new Float(6), Float.class)
- };
- // % / Float
- List<Class<?>> typeList = new ArrayList<Class<?>>(1);
- typeList.add(Float.class);
- helpTestMod("%", typeList, args, "(10.0 % 6.0)"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * x % y using {@link Float} constants for both parameters returns
- * (x - (TRUNC((x / y), 0) * x)). {@link MODFunctionModifier} will be
- * constructed with a function name of "%" and a supported type list that
- * does not contain {@link Float}.
- *
- * @throws Exception
- */
- public void testTwoFloatConst7() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new Float(10), Float.class),
- LANG_FACTORY.createLiteral(new Float(6), Float.class)
- };
- // % / Short
- List<Class<?>> typeList = new ArrayList<Class<?>>(1);
- typeList.add(Short.class);
- helpTestMod("%", typeList, args, "(10.0 - (TRUNC((10.0 / 6.0), 0) * 6.0))"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * MOD(x,y) using {@link BigInteger} constants for both parameters returns
- * (x - (TRUNC((x / y), 0) * y)). {@link MODFunctionModifier} will be
- * constructed without specifying a function name or a supported type list.
- *
- * @throws Exception
- */
- public void testTwoBigIntConst() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new BigInteger("10"), BigInteger.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral(new BigInteger("6"), BigInteger.class) //$NON-NLS-1$
- };
- // default / default
- helpTestMod(args, "(10 - (TRUNC((10 / 6), 0) * 6))"); //$NON-NLS-1$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * MOD(x,y) using {@link BigInteger} constants for both parameters returns
- * (x - (TRUNC((x / y), 0) * y)). {@link MODFunctionModifier} will be
- * constructed with a function name of "MOD" but without a supported type
- * list.
- *
- * @throws Exception
- */
- public void testTwoBigIntConst2() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new BigInteger("10"), BigInteger.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral(new BigInteger("6"), BigInteger.class) //$NON-NLS-1$
- };
- // mod / default
- helpTestMod("MOD", null, args, "(10 - (TRUNC((10 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * MOD(x,y) using {@link BigInteger} constants for both parameters returns
- * MOD(x,y). {@link MODFunctionModifier} will be constructed with a
- * function name of "MOD" and a supported type list which contains {@link BigInteger}.
- *
- * @throws Exception
- */
- public void testTwoBigIntConst3() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new BigInteger("10"), BigInteger.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral(new BigInteger("6"), BigInteger.class) //$NON-NLS-1$
- };
- // mod / BigInteger
- List<Class<?>> typeList = new ArrayList<Class<?>>(1);
- typeList.add(BigInteger.class);
- helpTestMod("MOD", typeList, args, "MOD(10, 6)"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * MOD(x,y) using {@link BigInteger} constants for both parameters returns
- * (x - (TRUNC((x / y), 0) * y)). {@link MODFunctionModifier} will be
- * constructed with a function name of "MOD" and a supported type list which
- * does not contain {@link BigInteger}.
- *
- * @throws Exception
- */
- public void testTwoBigIntConst4() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new BigInteger("10"), BigInteger.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral(new BigInteger("6"), BigInteger.class) //$NON-NLS-1$
- };
- // mod / Short
- List<Class<?>> typeList = new ArrayList<Class<?>>(1);
- typeList.add(Short.class);
- helpTestMod("MOD", typeList, args, "(10 - (TRUNC((10 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * x % y using {@link BigInteger} constants for both parameters returns
- * (x - (TRUNC((x / y), 0) * x)). {@link MODFunctionModifier} will be
- * constructed with a function name of "%" and no supported type list.
- *
- * @throws Exception
- */
- public void testTwoBigIntConst5() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new BigInteger("10"), BigInteger.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral(new BigInteger("6"), BigInteger.class) //$NON-NLS-1$
- };
- // % / default
- helpTestMod("%", null, args, "(10 - (TRUNC((10 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * x % y using {@link BigInteger} constants for both parameters returns
- * (x % y). {@link MODFunctionModifier} will be constructed with a function
- * name of "%" and a supported type list which contains {@link BigInteger}.
- *
- * @throws Exception
- */
- public void testTwoBigIntConst6() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new BigInteger("10"), BigInteger.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral(new BigInteger("6"), BigInteger.class) //$NON-NLS-1$
- };
- // % / BigInteger
- List<Class<?>> typeList = new ArrayList<Class<?>>(1);
- typeList.add(BigInteger.class);
- helpTestMod("%", typeList, args, "(10 % 6)"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * x % y using {@link BigInteger} constants for both parameters returns
- * (x - (TRUNC((x / y), 0) * x)). {@link MODFunctionModifier} will be
- * constructed with a function name of "%" and a supported type list that
- * does not contain {@link BigInteger}.
- *
- * @throws Exception
- */
- public void testTwoBigIntConst7() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new BigInteger("10"), BigInteger.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral(new BigInteger("6"), BigInteger.class) //$NON-NLS-1$
- };
- // % / Short
- List<Class<?>> typeList = new ArrayList<Class<?>>(1);
- typeList.add(Short.class);
- helpTestMod("%", typeList, args, "(10 - (TRUNC((10 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * MOD(x,y) using {@link BigDecimal} constants for both parameters returns
- * (x - (TRUNC((x / y), 0) * y)). {@link MODFunctionModifier} will be
- * constructed without specifying a function name or a supported type list.
- *
- * @throws Exception
- */
- public void testTwoBigDecConst() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new BigDecimal("10"), BigDecimal.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral(new BigDecimal("6"), BigDecimal.class) //$NON-NLS-1$
- };
- // default / default
- helpTestMod(args, "(10 - (TRUNC((10 / 6), 0) * 6))"); //$NON-NLS-1$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * MOD(x,y) using {@link BigDecimal} constants for both parameters returns
- * (x - (TRUNC((x / y), 0) * y)). {@link MODFunctionModifier} will be
- * constructed with a function name of "MOD" but without a supported type
- * list.
- *
- * @throws Exception
- */
- public void testTwoBigDecConst2() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new BigDecimal("10"), BigDecimal.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral(new BigDecimal("6"), BigDecimal.class) //$NON-NLS-1$
- };
- // mod / default
- helpTestMod("MOD", null, args, "(10 - (TRUNC((10 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * MOD(x,y) using {@link BigDecimal} constants for both parameters returns
- * MOD(x,y). {@link MODFunctionModifier} will be constructed with a
- * function name of "MOD" and a supported type list which contains {@link BigDecimal}.
- *
- * @throws Exception
- */
- public void testTwoBigDecConst3() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new BigDecimal("10"), BigDecimal.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral(new BigDecimal("6"), BigDecimal.class) //$NON-NLS-1$
- };
- // mod / BigDecimal
- List<Class<?>> typeList = new ArrayList<Class<?>>(1);
- typeList.add(BigDecimal.class);
- helpTestMod("MOD", typeList, args, "MOD(10, 6)"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * MOD(x,y) using {@link BigDecimal} constants for both parameters returns
- * (x - (TRUNC((x / y), 0) * y)). {@link MODFunctionModifier} will be
- * constructed with a function name of "MOD" and a supported type list which
- * does not contain {@link BigDecimal}.
- *
- * @throws Exception
- */
- public void testTwoBigDecConst4() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new BigDecimal("10"), BigDecimal.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral(new BigDecimal("6"), BigDecimal.class) //$NON-NLS-1$
- };
- // mod / Short
- List<Class<?>> typeList = new ArrayList<Class<?>>(1);
- typeList.add(Short.class);
- helpTestMod("MOD", typeList, args, "(10 - (TRUNC((10 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * x % y using {@link BigDecimal} constants for both parameters returns
- * (x - (TRUNC((x / y), 0) * x)). {@link MODFunctionModifier} will be
- * constructed with a function name of "%" and no supported type list.
- *
- * @throws Exception
- */
- public void testTwoBigDecConst5() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new BigDecimal("10"), BigDecimal.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral(new BigDecimal("6"), BigDecimal.class) //$NON-NLS-1$
- };
- // % / default
- helpTestMod("%", null, args, "(10 - (TRUNC((10 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * x % y using {@link BigDecimal} constants for both parameters returns
- * (x % y). {@link MODFunctionModifier} will be constructed with a function
- * name of "%" and a supported type list which contains {@link BigDecimal}.
- *
- * @throws Exception
- */
- public void testTwoBigDecConst6() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new BigDecimal("10"), BigDecimal.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral(new BigDecimal("6"), BigDecimal.class) //$NON-NLS-1$
- };
- // % / BigDecimal
- List<Class<?>> typeList = new ArrayList<Class<?>>(1);
- typeList.add(BigDecimal.class);
- helpTestMod("%", typeList, args, "(10 % 6)"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * x % y using {@link BigDecimal} constants for both parameters returns
- * (x - (TRUNC((x / y), 0) * x)). {@link MODFunctionModifier} will be
- * constructed with a function name of "%" and a supported type list that
- * does not contain {@link BigDecimal}.
- *
- * @throws Exception
- */
- public void testTwoBigDecConst7() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new BigDecimal("10"), BigDecimal.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral(new BigDecimal("6"), BigDecimal.class) //$NON-NLS-1$
- };
- // % / Short
- List<Class<?>> typeList = new ArrayList<Class<?>>(1);
- typeList.add(Short.class);
- helpTestMod("%", typeList, args, "(10 - (TRUNC((10 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * MOD(e1,y) using a {@link Integer} element and a {@link Integer} constant
- * for parameters returns MOD(e1,y). {@link MODFunctionModifier} will be
- * constructed without specifying a function name or a supported type list.
- *
- * @throws Exception
- */
- public void testOneIntElemOneIntConst() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createElement("e1", null, null, Integer.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral(new Integer(6), Integer.class)
- };
- // default / default
- helpTestMod(args, "MOD(e1, 6)"); //$NON-NLS-1$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * MOD(e1,y) using a {@link Integer} element and a {@link Integer} constant
- * for parameters returns MOD(e1,y). {@link MODFunctionModifier} will be
- * constructed with a function name of "MOD" but without a supported type
- * list.
- *
- * @throws Exception
- */
- public void testOneIntElemOneIntConst2() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createElement("e1", null, null, Integer.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral(new Integer(6), Integer.class)
- };
- // mod / default
- helpTestMod("MOD", null, args, "MOD(e1, 6)"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * MOD(e1,y) using a {@link Integer} element and a {@link Integer} constant
- * for parameters returns MOD(e1,y). {@link MODFunctionModifier} will be
- * constructed with a function name of "MOD" and a supported type list which
- * contains {@link Integer}.
- *
- * @throws Exception
- */
- public void testOneIntElemOneIntConst3() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createElement("e1", null, null, Integer.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral(new Integer(6), Integer.class)
- };
- // mod / Integer
- List<Class<?>> typeList = new ArrayList<Class<?>>(1);
- typeList.add(Integer.class);
- helpTestMod("MOD", typeList, args, "MOD(e1, 6)"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * MOD(e1,y) using a {@link Integer} element and a {@link Integer} constant
- * for parameters returns (e1 - (TRUNC((e1 / y), 0) * y)).
- * {@link MODFunctionModifier} will be constructed with a function name of
- * "MOD" and a supported type list which does not contain {@link Integer}.
- *
- * @throws Exception
- */
- public void testOneIntElemOneIntConst4() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createElement("e1", null, null, Integer.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral(new Integer(6), Integer.class)
- };
- // mod / Short
- List<Class<?>> typeList = new ArrayList<Class<?>>(1);
- typeList.add(Short.class);
- helpTestMod("MOD", typeList, args, "(e1 - (TRUNC((e1 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * e1 % y using a {@link Integer} element and a {@link Integer} constant for
- * parameters returns (e1 % y). {@link MODFunctionModifier} will be
- * constructed with a function name of "%" and no supported type list.
- *
- * @throws Exception
- */
- public void testOneIntElemOneIntConst5() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createElement("e1", null, null, Integer.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral(new Integer(6), Integer.class)
- };
- // % / default
- helpTestMod("%", null, args, "(e1 % 6)"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * e1 % y using a {@link Integer} element and a {@link Integer} constant for
- * parameters returns (e1 % y). {@link MODFunctionModifier} will be
- * constructed with a function name of "%" and a supported type list which
- * contains {@link Integer}.
- *
- * @throws Exception
- */
- public void testOneIntElemOneIntConst6() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createElement("e1", null, null, Integer.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral(new Integer(6), Integer.class)
- };
- // % / Integer
- List<Class<?>> typeList = new ArrayList<Class<?>>(1);
- typeList.add(Integer.class);
- helpTestMod("%", typeList, args, "(e1 % 6)"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * e1 % y using a {@link Integer} element and a {@link Integer} constant for
- * parameters returns (e1 - (TRUNC((e1 / y), 0) * y)).
- * {@link MODFunctionModifier} will be constructed with a function name of
- * "%" and a supported type list that does not contain {@link Integer}.
- *
- * @throws Exception
- */
- public void testOneIntElemOneIntConst7() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createElement("e1", null, null, Integer.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral(new Integer(6), Integer.class)
- };
- // % / Short
- List<Class<?>> typeList = new ArrayList<Class<?>>(1);
- typeList.add(Short.class);
- helpTestMod("%", typeList, args, "(e1 - (TRUNC((e1 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * MOD(e1,y) using a {@link BigDecimal} element and a {@link BigDecimal}
- * constant for parameters returns (e1 - (TRUNC((e1 / y), 0) * y)).
- * {@link MODFunctionModifier} will be constructed without specifying a
- * function name or a supported type list.
- *
- * @throws Exception
- */
- public void testOneBigDecElemOneBigDecConst() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createElement("e1", null, null, BigDecimal.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral(new BigDecimal(6), BigDecimal.class)
- };
- // default / default
- helpTestMod(args, "(e1 - (TRUNC((e1 / 6), 0) * 6))"); //$NON-NLS-1$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * MOD(e1,y) using a {@link BigDecimal} element and a {@link BigDecimal}
- * constant for parameters returns (e1 - (TRUNC((e1 / y), 0) * y)).
- * {@link MODFunctionModifier} will be constructed with a function name of
- * "MOD" but without a supported type list.
- *
- * @throws Exception
- */
- public void testOneBigDecElemOneBigDecConst2() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createElement("e1", null, null, BigDecimal.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral(new BigDecimal(6), BigDecimal.class)
- };
- // mod / default
- helpTestMod("MOD", null, args, "(e1 - (TRUNC((e1 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * MOD(e1,y) using a {@link BigDecimal} element and a {@link BigDecimal}
- * constant for parameters returns MOD(e1,y). {@link MODFunctionModifier}
- * will be constructed with a function name of "MOD" and a supported type
- * list which contains {@link BigDecimal}.
- *
- * @throws Exception
- */
- public void testOneBigDecElemOneBigDecConst3() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createElement("e1", null, null, BigDecimal.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral(new BigDecimal(6), BigDecimal.class)
- };
- // mod / Integer
- List<Class<?>> typeList = new ArrayList<Class<?>>(1);
- typeList.add(BigDecimal.class);
- helpTestMod("MOD", typeList, args, "MOD(e1, 6)"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * MOD(e1,y) using a {@link BigDecimal} element and a {@link BigDecimal}
- * constant for parameters returns (e1 - (TRUNC((e1 / y), 0) * y)).
- * {@link MODFunctionModifier} will be constructed with a function name of
- * "MOD" and a supported type list which does not contain {@link BigDecimal}.
- *
- * @throws Exception
- */
- public void testOneBigDecElemOneBigDecConst4() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createElement("e1", null, null, BigDecimal.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral(new BigDecimal(6), BigDecimal.class)
- };
- // mod / Short
- List<Class<?>> typeList = new ArrayList<Class<?>>(1);
- typeList.add(Short.class);
- helpTestMod("MOD", typeList, args, "(e1 - (TRUNC((e1 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * e1 % y using a {@link BigDecimal} element and a {@link BigDecimal}
- * constant for parameters returns (e1 % y). {@link MODFunctionModifier}
- * will be constructed with a function name of "%" and no supported type
- * list.
- *
- * @throws Exception
- */
- public void testOneBigDecElemOneBigDecConst5() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createElement("e1", null, null, BigDecimal.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral(new BigDecimal(6), BigDecimal.class)
- };
- // % / default
- helpTestMod("%", null, args, "(e1 - (TRUNC((e1 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * e1 % y using a {@link BigDecimal} element and a {@link BigDecimal}
- * constant for parameters returns (e1 % y). {@link MODFunctionModifier}
- * will be constructed with a function name of "%" and a supported type list
- * which contains {@link BigDecimal}.
- *
- * @throws Exception
- */
- public void testOneBigDecElemOneBigDecConst6() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createElement("e1", null, null, BigDecimal.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral(new BigDecimal(6), BigDecimal.class)
- };
- // % / BigDecimal
- List<Class<?>> typeList = new ArrayList<Class<?>>(1);
- typeList.add(BigDecimal.class);
- helpTestMod("%", typeList, args, "(e1 % 6)"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * e1 % y using a {@link BigDecimal} element and a {@link BigDecimal}
- * constant for parameters returns (e1 - (TRUNC((e1 / y), 0) * y)).
- * {@link MODFunctionModifier} will be constructed with a function name of
- * "%" and a supported type list that does not contain {@link BigDecimal}.
- *
- * @throws Exception
- */
- public void testOneBigDecElemOneBigDecConst7() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createElement("e1", null, null, BigDecimal.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral(new BigDecimal(6), BigDecimal.class)
- };
- // % / Short
- List<Class<?>> typeList = new ArrayList<Class<?>>(1);
- typeList.add(Short.class);
- helpTestMod("%", typeList, args, "(e1 - (TRUNC((e1 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * Test {@link MODFunctionModifier#modify(IFunction)} to validate a call to
- * MOD(x,e1) using a {@link Float} literal and a {@link Float} element for
- * parameters returns (x - (floor((x / e1)) * e1)). {@link MODFunctionModifier}
- * will be constructed with a function name of "MOD" and no supported type
- * list. The test explicitly overrides
- * {@link MODFunctionModifier#getQuotientExpression(IExpression)} to produce
- * output that uses the floor(z) function.
- *
- * @throws Exception
- */
- public void testOverrideGetQuotient() throws Exception {
- final Class<?> dataType = Float.class;
- final String modFunctionName = "MOD"; //$NON-NLS-1$
- final String expectedStr = "(1000.23 - (floor((1000.23 / e1)) * e1))"; //$NON-NLS-1$
-
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(new Float(1000.23), dataType),
- LANG_FACTORY.createElement("e1", null, null, dataType), //$NON-NLS-1$
- };
- IFunction func = LANG_FACTORY.createFunction(modFunctionName, args, dataType);
-
- final Translator trans = new Translator() {
- @Override
- public void initialize(ConnectorEnvironment env)
- throws ConnectorException {
- super.initialize(env);
- registerFunctionModifier(SourceSystemFunctions.MOD, new MODFunctionModifier(getLanguageFactory(), modFunctionName, null) {
- @Override
- protected IExpression getQuotientExpression(
- IExpression division) {
- return getLanguageFactory().createFunction("floor", Arrays.asList(division), division.getType()); //$NON-NLS-1$
- }
-
- });
- }
- };
-
- trans.initialize(EnvironmentUtility.createEnvironment(new Properties(), false));
-
- IExpression expr = trans.getFunctionModifiers().get(SourceSystemFunctions.MOD).modify(func);
- SQLConversionVisitor sqlVisitor = trans.getSQLConversionVisitor();
- sqlVisitor.append(expr);
- assertEquals("Modified function does not match", expectedStr, sqlVisitor.toString()); //$NON-NLS-1$
- }
-}
Copied: trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/translator/TestModFunctionModifier.java (from rev 1264, trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/translator/TestMODFunctionModifier.java)
===================================================================
--- trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/translator/TestModFunctionModifier.java (rev 0)
+++ trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/translator/TestModFunctionModifier.java 2009-08-19 21:08:00 UTC (rev 1265)
@@ -0,0 +1,1253 @@
+/*
+ * 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.connector.jdbc.translator;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Properties;
+
+import junit.framework.TestCase;
+
+import org.teiid.connector.api.ConnectorEnvironment;
+import org.teiid.connector.api.ConnectorException;
+import org.teiid.connector.api.SourceSystemFunctions;
+import org.teiid.connector.language.IExpression;
+import org.teiid.connector.language.IFunction;
+import org.teiid.connector.language.ILanguageFactory;
+
+import com.metamatrix.cdk.CommandBuilder;
+import com.metamatrix.cdk.api.EnvironmentUtility;
+
+/**
+ * Test <code>ModFunctionModifier</code> by invoking its methods with varying
+ * parameters to validate it performs as designed and expected.
+ */
+public class TestModFunctionModifier extends TestCase {
+
+ private static final ILanguageFactory LANG_FACTORY = CommandBuilder.getLanuageFactory();
+
+ /**
+ * Constructor for TestModFunctionModifier.
+ * @param name
+ */
+ public TestModFunctionModifier(String name) {
+ super(name);
+ }
+
+
+ /**
+ * Create an expression containing a MOD function using <code>args</code>
+ * and pass it to the <code>Translator</code>'s MOD function modifier and
+ * compare the resulting expression to <code>expectedStr</code>.
+ *
+ * @param args An array of <code>IExpression</code>'s to use as the
+ * arguments to the MOD() function
+ * @param expectedStr A string representing the modified expression
+ * @return On success, the modified expression.
+ * @throws Exception
+ */
+ public IExpression helpTestMod(IExpression[] args, String expectedStr) throws Exception {
+ return this.helpTestMod(null, null, args, expectedStr);
+ }
+
+ /**
+ * Create an expression containing a MOD function using a function name of
+ * <code>modFunctionName</code> which supports types of <code>supportedTypes</code>
+ * and uses the arguments <code>args</code> and pass it to the
+ * <code>Translator</code>'s MOD function modifier and compare the resulting
+ * expression to <code>expectedStr</code>.
+ *
+ * @param modFunctionName the name to use for the function modifier
+ * @param supportedTypes a list of types that the mod function should support
+ * @param args an array of <code>IExpression</code>'s to use as the
+ * arguments to the MOD() function
+ * @param expectedStr A string representing the modified expression
+ * @return On success, the modified expression.
+ * @throws Exception
+ */
+ public IExpression helpTestMod(final String modFunctionName, final List<Class<?>> supportedTypes, IExpression[] args, String expectedStr) throws Exception {
+ IExpression param1 = null;
+ IExpression param2 = null;
+
+ if (args.length < 2) {
+ param2 = LANG_FACTORY.createLiteral(null, Short.class);
+ if (args.length < 1) {
+ param1 = LANG_FACTORY.createLiteral(null, Short.class);
+ } else {
+ param1 = args[0];
+ }
+ } else {
+ param1 = args[0];
+ param2 = args[1];
+ }
+
+ if ( !param1.getType().equals(param2.getType()) ) {
+ if (param2.getType().equals(BigDecimal.class)) {
+ param1.setType(param2.getType());
+ } else if (param1.getType().equals(BigDecimal.class)) {
+ param2.setType(param1.getType());
+ } else if (param2.getType().equals(BigInteger.class)) {
+ param1.setType(param2.getType());
+ } else if (param1.getType().equals(BigInteger.class)) {
+ param2.setType(param1.getType());
+ } else if (param2.getType().equals(Float.class)) {
+ param1.setType(param2.getType());
+ } else if (param1.getType().equals(Float.class)) {
+ param2.setType(param1.getType());
+ } else if (param2.getType().equals(Long.class)) {
+ param1.setType(param2.getType());
+ } else if (param1.getType().equals(Long.class)) {
+ param2.setType(param1.getType());
+ } else if (param2.getType().equals(Integer.class)) {
+ param1.setType(param2.getType());
+ } else if (param1.getType().equals(Integer.class)) {
+ param2.setType(param1.getType());
+ } else if (param2.getType().equals(Short.class)) {
+ param1.setType(param2.getType());
+ } else if (param1.getType().equals(Short.class)) {
+ param2.setType(param1.getType());
+ } else {
+ throw new IllegalArgumentException("Parameters must be of numeric types"); //$NON-NLS-1$
+ }
+ }
+
+ IFunction func = LANG_FACTORY.createFunction(modFunctionName,
+ Arrays.asList(param1, param2), param1.getType());
+
+ Translator trans = new Translator() {
+ @Override
+ public void initialize(ConnectorEnvironment env)
+ throws ConnectorException {
+ super.initialize(env);
+ if (modFunctionName == null) {
+ registerFunctionModifier(SourceSystemFunctions.MOD, new ModFunctionModifier(getLanguageFactory()));
+ } else {
+ registerFunctionModifier(SourceSystemFunctions.MOD, new ModFunctionModifier(getLanguageFactory(), modFunctionName, supportedTypes));
+ }
+ }
+ };
+
+ trans.initialize(EnvironmentUtility.createEnvironment(new Properties(), false));
+
+ IExpression expr = trans.getFunctionModifiers().get(SourceSystemFunctions.MOD).modify(func);
+
+ SQLConversionVisitor sqlVisitor = trans.getSQLConversionVisitor();
+ sqlVisitor.append(expr);
+
+ assertEquals("Modified function does not match", expectedStr, sqlVisitor.toString()); //$NON-NLS-1$
+
+ return expr;
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * MOD(x,y) using {@link Short} constants for both parameters returns MOD(x,y).
+ * {@link ModFunctionModifier} will be constructed without specifying a
+ * function name or a supported type list.
+ *
+ * @throws Exception
+ */
+ public void testTwoShortConst() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new Short((short) 10), Short.class),
+ LANG_FACTORY.createLiteral(new Short((short) 6), Short.class)
+ };
+ // default / default
+ helpTestMod(args, "MOD(10, 6)"); //$NON-NLS-1$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * MOD(x,y) using {@link Short} constants for both parameters returns MOD(x,y).
+ * {@link ModFunctionModifier} will be constructed with a function name of
+ * "MOD" but without a supported type list.
+ *
+ * @throws Exception
+ */
+ public void testTwoShortConst2() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new Short((short) 10), Short.class),
+ LANG_FACTORY.createLiteral(new Short((short) 6), Short.class)
+ };
+ // mod / default
+ helpTestMod("MOD", null, args, "MOD(10, 6)"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * MOD(x,y) using {@link Short} constants for both parameters returns MOD(x,y).
+ * {@link ModFunctionModifier} will be constructed with a function name of
+ * "MOD" and a supported type list which contains {@link Short}.
+ *
+ * @throws Exception
+ */
+ public void testTwoShortConst3() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new Short((short) 10), Short.class),
+ LANG_FACTORY.createLiteral(new Short((short) 6), Short.class)
+ };
+ // mod / Short
+ List<Class<?>> typeList = new ArrayList<Class<?>>(1);
+ typeList.add(Short.class);
+ helpTestMod("MOD", typeList, args, "MOD(10, 6)"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * MOD(x,y) using {@link Short} constants for both parameters returns
+ * (x - (TRUNC((x / y), 0) * y)). {@link ModFunctionModifier} will be
+ * constructed with a function name of "MOD" and a supported type list which
+ * does not contains {@link Short}.
+ *
+ * @throws Exception
+ */
+ public void testTwoShortConst4() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new Short((short) 10), Short.class),
+ LANG_FACTORY.createLiteral(new Short((short) 6), Short.class)
+ };
+ // mod / Integer
+ List<Class<?>> typeList = new ArrayList<Class<?>>(1);
+ typeList.add(Integer.class);
+ helpTestMod("MOD", typeList, args, "(10 - (TRUNC((10 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * x % y using {@link Short} constants for both parameters returns (x % y).
+ * {@link ModFunctionModifier} will be constructed with a function name of
+ * "%" and no supported type list.
+ *
+ * @throws Exception
+ */
+ public void testTwoShortConst5() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new Short((short) 10), Short.class),
+ LANG_FACTORY.createLiteral(new Short((short) 6), Short.class)
+ };
+ // % / default
+ helpTestMod("%", null, args, "(10 % 6)"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * x % y using {@link Short} constants for both parameters returns (x % y).
+ * {@link ModFunctionModifier} will be constructed with a function name of
+ * "%" and a supported type list which contains {@link Short}.
+ *
+ * @throws Exception
+ */
+ public void testTwoShortConst6() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new Short((short) 10), Short.class),
+ LANG_FACTORY.createLiteral(new Short((short) 6), Short.class)
+ };
+ // % / Short
+ List<Class<?>> typeList = new ArrayList<Class<?>>(1);
+ typeList.add(Short.class);
+ helpTestMod("%", typeList, args, "(10 % 6)"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * x % y using {@link Short} constants for both parameters returns
+ * (10 - (TRUNC((10 / 6), 0) * 6)). {@link ModFunctionModifier} will be
+ * constructed with a function name of "%" and a supported type list does not
+ * contain {@link Short}.
+ *
+ * @throws Exception
+ */
+ public void testTwoShortConst7() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new Short((short) 10), Short.class),
+ LANG_FACTORY.createLiteral(new Short((short) 6), Short.class)
+ };
+ // % / Integer
+ List<Class<?>> typeList = new ArrayList<Class<?>>(1);
+ typeList.add(Integer.class);
+ helpTestMod("%", typeList, args, "(10 - (TRUNC((10 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * MOD(x,y) using {@link Integer} constants for both parameters returns
+ * MOD(x,y). {@link ModFunctionModifier} will be constructed without
+ * specifying a function name or a supported type list.
+ *
+ * @throws Exception
+ */
+ public void testTwoIntConst() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new Integer(10), Integer.class),
+ LANG_FACTORY.createLiteral(new Integer(6), Integer.class)
+ };
+ // default / default
+ helpTestMod(args, "MOD(10, 6)"); //$NON-NLS-1$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * MOD(x,y) using {@link Integer} constants for both parameters returns
+ * MOD(x,y). {@link ModFunctionModifier} will be constructed with a
+ * function name of "MOD" but without a supported type list.
+ *
+ * @throws Exception
+ */
+ public void testTwoIntConst2() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new Integer(10), Integer.class),
+ LANG_FACTORY.createLiteral(new Integer(6), Integer.class)
+ };
+ // mod / default
+ helpTestMod("MOD", null, args, "MOD(10, 6)"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * MOD(x,y) using {@link Integer} constants for both parameters returns
+ * MOD(x,y). {@link ModFunctionModifier} will be constructed with a
+ * function name of "MOD" and a supported type list which contains {@link Integer}.
+ *
+ * @throws Exception
+ */
+ public void testTwoIntConst3() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new Integer(10), Integer.class),
+ LANG_FACTORY.createLiteral(new Integer(6), Integer.class)
+ };
+ // mod / Short
+ List<Class<?>> typeList = new ArrayList<Class<?>>(1);
+ typeList.add(Integer.class);
+ helpTestMod("MOD", typeList, args, "MOD(10, 6)"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * MOD(x,y) using {@link Integer} constants for both parameters returns
+ * (x - (TRUNC((x / y), 0) * y)). {@link ModFunctionModifier} will be
+ * constructed with a function name of "MOD" and a supported type list which
+ * does not contain {@link Integer}.
+ *
+ * @throws Exception
+ */
+ public void testTwoIntConst4() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new Integer(10), Integer.class),
+ LANG_FACTORY.createLiteral(new Integer(6), Integer.class)
+ };
+ // mod / Integer
+ List<Class<?>> typeList = new ArrayList<Class<?>>(1);
+ typeList.add(Short.class);
+ helpTestMod("MOD", typeList, args, "(10 - (TRUNC((10 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * x % y using {@link Integer} constants for both parameters returns (x % y).
+ * {@link ModFunctionModifier} will be constructed with a function name of
+ * "%" and no supported type list.
+ *
+ * @throws Exception
+ */
+ public void testTwoIntConst5() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new Integer(10), Integer.class),
+ LANG_FACTORY.createLiteral(new Integer(6), Integer.class)
+ };
+ // % / default
+ helpTestMod("%", null, args, "(10 % 6)"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * x % y using {@link Integer} constants for both parameters returns (x % y).
+ * {@link ModFunctionModifier} will be constructed with a function name of
+ * "%" and a supported type list which contains {@link Integer}.
+ *
+ * @throws Exception
+ */
+ public void testTwoIntConst6() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new Integer(10), Integer.class),
+ LANG_FACTORY.createLiteral(new Integer(6), Integer.class)
+ };
+ // % / Short
+ List<Class<?>> typeList = new ArrayList<Class<?>>(1);
+ typeList.add(Integer.class);
+ helpTestMod("%", typeList, args, "(10 % 6)"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * x % y using {@link Integer} constants for both parameters returns
+ * (10 - (TRUNC((10 / 6), 0) * 6)). {@link ModFunctionModifier} will be
+ * constructed with a function name of "%" and a supported type list that
+ * does not contain {@link Integer}.
+ *
+ * @throws Exception
+ */
+ public void testTwoIntConst7() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new Integer(10), Integer.class),
+ LANG_FACTORY.createLiteral(new Integer(6), Integer.class)
+ };
+ // % / Integer
+ List<Class<?>> typeList = new ArrayList<Class<?>>(1);
+ typeList.add(Short.class);
+ helpTestMod("%", typeList, args, "(10 - (TRUNC((10 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * MOD(x,y) using {@link Long} constants for both parameters returns
+ * MOD(x,y). {@link ModFunctionModifier} will be constructed without
+ * specifying a function name or a supported type list.
+ *
+ * @throws Exception
+ */
+ public void testTwoLongConst() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new Long(10), Long.class),
+ LANG_FACTORY.createLiteral(new Long(6), Long.class)
+ };
+ // default / default
+ helpTestMod(args, "MOD(10, 6)"); //$NON-NLS-1$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * MOD(x,y) using {@link Long} constants for both parameters returns
+ * MOD(x,y). {@link ModFunctionModifier} will be constructed with a
+ * function name of "MOD" but without a supported type list.
+ *
+ * @throws Exception
+ */
+ public void testTwoLongConst2() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new Long(10), Long.class),
+ LANG_FACTORY.createLiteral(new Long(6), Long.class)
+ };
+ // mod / default
+ helpTestMod("MOD", null, args, "MOD(10, 6)"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * MOD(x,y) using {@link Long} constants for both parameters returns
+ * MOD(x,y). {@link ModFunctionModifier} will be constructed with a
+ * function name of "MOD" and a supported type list which contains {@link Long}.
+ *
+ * @throws Exception
+ */
+ public void testTwoLongConst3() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new Long(10), Long.class),
+ LANG_FACTORY.createLiteral(new Long(6), Long.class)
+ };
+ // mod / Long
+ List<Class<?>> typeList = new ArrayList<Class<?>>(1);
+ typeList.add(Long.class);
+ helpTestMod("MOD", typeList, args, "MOD(10, 6)"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * MOD(x,y) using {@link Long} constants for both parameters returns
+ * (x - (TRUNC((x / y), 0) * y)). {@link ModFunctionModifier} will be
+ * constructed with a function name of "MOD" and a supported type list which
+ * does not contain {@link Long}.
+ *
+ * @throws Exception
+ */
+ public void testTwoLongConst4() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new Long(10), Long.class),
+ LANG_FACTORY.createLiteral(new Long(6), Long.class)
+ };
+ // mod / Short
+ List<Class<?>> typeList = new ArrayList<Class<?>>(1);
+ typeList.add(Short.class);
+ helpTestMod("MOD", typeList, args, "(10 - (TRUNC((10 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * x % y using {@link Long} constants for both parameters returns (x % y).
+ * {@link ModFunctionModifier} will be constructed with a function name of
+ * "%" and no supported type list.
+ *
+ * @throws Exception
+ */
+ public void testTwoLongConst5() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new Long(10), Long.class),
+ LANG_FACTORY.createLiteral(new Long(6), Long.class)
+ };
+ // % / default
+ helpTestMod("%", null, args, "(10 % 6)"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * x % y using {@link Long} constants for both parameters returns (x % y).
+ * {@link ModFunctionModifier} will be constructed with a function name of
+ * "%" and a supported type list which contains {@link Long}.
+ *
+ * @throws Exception
+ */
+ public void testTwoLongConst6() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new Long(10), Long.class),
+ LANG_FACTORY.createLiteral(new Long(6), Long.class)
+ };
+ // % / Long
+ List<Class<?>> typeList = new ArrayList<Class<?>>(1);
+ typeList.add(Long.class);
+ helpTestMod("%", typeList, args, "(10 % 6)"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * x % y using {@link Long} constants for both parameters returns
+ * (10 - (TRUNC((10 / 6), 0) * 6)). {@link ModFunctionModifier} will be
+ * constructed with a function name of "%" and a supported type list that
+ * does not contain {@link Long}.
+ *
+ * @throws Exception
+ */
+ public void testTwoLongConst7() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new Long(10), Long.class),
+ LANG_FACTORY.createLiteral(new Long(6), Long.class)
+ };
+ // % / Short
+ List<Class<?>> typeList = new ArrayList<Class<?>>(1);
+ typeList.add(Short.class);
+ helpTestMod("%", typeList, args, "(10 - (TRUNC((10 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * MOD(x,y) using {@link Float} constants for both parameters returns
+ * (x - (TRUNC((x / y), 0) * y)). {@link ModFunctionModifier} will be
+ * constructed without specifying a function name or a supported type list.
+ *
+ * @throws Exception
+ */
+ public void testTwoFloatConst() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new Float(10), Float.class),
+ LANG_FACTORY.createLiteral(new Float(6), Float.class)
+ };
+ // default / default
+ helpTestMod(args, "(10.0 - (TRUNC((10.0 / 6.0), 0) * 6.0))"); //$NON-NLS-1$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * MOD(x,y) using {@link Float} constants for both parameters returns
+ * (x - (TRUNC((x / y), 0) * y)). {@link ModFunctionModifier} will be
+ * constructed with a function name of "MOD" but without a supported type
+ * list.
+ *
+ * @throws Exception
+ */
+ public void testTwoFloatConst2() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new Float(10), Float.class),
+ LANG_FACTORY.createLiteral(new Float(6), Float.class)
+ };
+ // mod / default
+ helpTestMod("MOD", null, args, "(10.0 - (TRUNC((10.0 / 6.0), 0) * 6.0))"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * MOD(x,y) using {@link Float} constants for both parameters returns
+ * MOD(x,y). {@link ModFunctionModifier} will be constructed with a
+ * function name of "MOD" and a supported type list which contains {@link Float}.
+ *
+ * @throws Exception
+ */
+ public void testTwoFloatConst3() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new Float(10), Float.class),
+ LANG_FACTORY.createLiteral(new Float(6), Float.class)
+ };
+ // mod / Float
+ List<Class<?>> typeList = new ArrayList<Class<?>>(1);
+ typeList.add(Float.class);
+ helpTestMod("MOD", typeList, args, "MOD(10.0, 6.0)"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * MOD(x,y) using {@link Float} constants for both parameters returns
+ * (x - (TRUNC((x / y), 0) * y)). {@link ModFunctionModifier} will be
+ * constructed with a function name of "MOD" and a supported type list which
+ * does not contain {@link Float}.
+ *
+ * @throws Exception
+ */
+ public void testTwoFloatConst4() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new Float(10), Float.class),
+ LANG_FACTORY.createLiteral(new Float(6), Float.class)
+ };
+ // mod / Short
+ List<Class<?>> typeList = new ArrayList<Class<?>>(1);
+ typeList.add(Short.class);
+ helpTestMod("MOD", typeList, args, "(10.0 - (TRUNC((10.0 / 6.0), 0) * 6.0))"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * x % y using {@link Float} constants for both parameters returns
+ * (x - (TRUNC((x / y), 0) * x)). {@link ModFunctionModifier} will be
+ * constructed with a function name of "%" and no supported type list.
+ *
+ * @throws Exception
+ */
+ public void testTwoFloatConst5() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new Float(10), Float.class),
+ LANG_FACTORY.createLiteral(new Float(6), Float.class)
+ };
+ // % / default
+ helpTestMod("%", null, args, "(10.0 - (TRUNC((10.0 / 6.0), 0) * 6.0))"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * x % y using {@link Float} constants for both parameters returns (x % y).
+ * {@link ModFunctionModifier} will be constructed with a function name of
+ * "%" and a supported type list which contains {@link Float}.
+ *
+ * @throws Exception
+ */
+ public void testTwoFloatConst6() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new Float(10), Float.class),
+ LANG_FACTORY.createLiteral(new Float(6), Float.class)
+ };
+ // % / Float
+ List<Class<?>> typeList = new ArrayList<Class<?>>(1);
+ typeList.add(Float.class);
+ helpTestMod("%", typeList, args, "(10.0 % 6.0)"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * x % y using {@link Float} constants for both parameters returns
+ * (x - (TRUNC((x / y), 0) * x)). {@link ModFunctionModifier} will be
+ * constructed with a function name of "%" and a supported type list that
+ * does not contain {@link Float}.
+ *
+ * @throws Exception
+ */
+ public void testTwoFloatConst7() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new Float(10), Float.class),
+ LANG_FACTORY.createLiteral(new Float(6), Float.class)
+ };
+ // % / Short
+ List<Class<?>> typeList = new ArrayList<Class<?>>(1);
+ typeList.add(Short.class);
+ helpTestMod("%", typeList, args, "(10.0 - (TRUNC((10.0 / 6.0), 0) * 6.0))"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * MOD(x,y) using {@link BigInteger} constants for both parameters returns
+ * (x - (TRUNC((x / y), 0) * y)). {@link ModFunctionModifier} will be
+ * constructed without specifying a function name or a supported type list.
+ *
+ * @throws Exception
+ */
+ public void testTwoBigIntConst() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new BigInteger("10"), BigInteger.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral(new BigInteger("6"), BigInteger.class) //$NON-NLS-1$
+ };
+ // default / default
+ helpTestMod(args, "(10 - (TRUNC((10 / 6), 0) * 6))"); //$NON-NLS-1$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * MOD(x,y) using {@link BigInteger} constants for both parameters returns
+ * (x - (TRUNC((x / y), 0) * y)). {@link ModFunctionModifier} will be
+ * constructed with a function name of "MOD" but without a supported type
+ * list.
+ *
+ * @throws Exception
+ */
+ public void testTwoBigIntConst2() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new BigInteger("10"), BigInteger.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral(new BigInteger("6"), BigInteger.class) //$NON-NLS-1$
+ };
+ // mod / default
+ helpTestMod("MOD", null, args, "(10 - (TRUNC((10 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * MOD(x,y) using {@link BigInteger} constants for both parameters returns
+ * MOD(x,y). {@link ModFunctionModifier} will be constructed with a
+ * function name of "MOD" and a supported type list which contains {@link BigInteger}.
+ *
+ * @throws Exception
+ */
+ public void testTwoBigIntConst3() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new BigInteger("10"), BigInteger.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral(new BigInteger("6"), BigInteger.class) //$NON-NLS-1$
+ };
+ // mod / BigInteger
+ List<Class<?>> typeList = new ArrayList<Class<?>>(1);
+ typeList.add(BigInteger.class);
+ helpTestMod("MOD", typeList, args, "MOD(10, 6)"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * MOD(x,y) using {@link BigInteger} constants for both parameters returns
+ * (x - (TRUNC((x / y), 0) * y)). {@link ModFunctionModifier} will be
+ * constructed with a function name of "MOD" and a supported type list which
+ * does not contain {@link BigInteger}.
+ *
+ * @throws Exception
+ */
+ public void testTwoBigIntConst4() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new BigInteger("10"), BigInteger.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral(new BigInteger("6"), BigInteger.class) //$NON-NLS-1$
+ };
+ // mod / Short
+ List<Class<?>> typeList = new ArrayList<Class<?>>(1);
+ typeList.add(Short.class);
+ helpTestMod("MOD", typeList, args, "(10 - (TRUNC((10 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * x % y using {@link BigInteger} constants for both parameters returns
+ * (x - (TRUNC((x / y), 0) * x)). {@link ModFunctionModifier} will be
+ * constructed with a function name of "%" and no supported type list.
+ *
+ * @throws Exception
+ */
+ public void testTwoBigIntConst5() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new BigInteger("10"), BigInteger.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral(new BigInteger("6"), BigInteger.class) //$NON-NLS-1$
+ };
+ // % / default
+ helpTestMod("%", null, args, "(10 - (TRUNC((10 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * x % y using {@link BigInteger} constants for both parameters returns
+ * (x % y). {@link ModFunctionModifier} will be constructed with a function
+ * name of "%" and a supported type list which contains {@link BigInteger}.
+ *
+ * @throws Exception
+ */
+ public void testTwoBigIntConst6() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new BigInteger("10"), BigInteger.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral(new BigInteger("6"), BigInteger.class) //$NON-NLS-1$
+ };
+ // % / BigInteger
+ List<Class<?>> typeList = new ArrayList<Class<?>>(1);
+ typeList.add(BigInteger.class);
+ helpTestMod("%", typeList, args, "(10 % 6)"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * x % y using {@link BigInteger} constants for both parameters returns
+ * (x - (TRUNC((x / y), 0) * x)). {@link ModFunctionModifier} will be
+ * constructed with a function name of "%" and a supported type list that
+ * does not contain {@link BigInteger}.
+ *
+ * @throws Exception
+ */
+ public void testTwoBigIntConst7() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new BigInteger("10"), BigInteger.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral(new BigInteger("6"), BigInteger.class) //$NON-NLS-1$
+ };
+ // % / Short
+ List<Class<?>> typeList = new ArrayList<Class<?>>(1);
+ typeList.add(Short.class);
+ helpTestMod("%", typeList, args, "(10 - (TRUNC((10 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * MOD(x,y) using {@link BigDecimal} constants for both parameters returns
+ * (x - (TRUNC((x / y), 0) * y)). {@link ModFunctionModifier} will be
+ * constructed without specifying a function name or a supported type list.
+ *
+ * @throws Exception
+ */
+ public void testTwoBigDecConst() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new BigDecimal("10"), BigDecimal.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral(new BigDecimal("6"), BigDecimal.class) //$NON-NLS-1$
+ };
+ // default / default
+ helpTestMod(args, "(10 - (TRUNC((10 / 6), 0) * 6))"); //$NON-NLS-1$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * MOD(x,y) using {@link BigDecimal} constants for both parameters returns
+ * (x - (TRUNC((x / y), 0) * y)). {@link ModFunctionModifier} will be
+ * constructed with a function name of "MOD" but without a supported type
+ * list.
+ *
+ * @throws Exception
+ */
+ public void testTwoBigDecConst2() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new BigDecimal("10"), BigDecimal.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral(new BigDecimal("6"), BigDecimal.class) //$NON-NLS-1$
+ };
+ // mod / default
+ helpTestMod("MOD", null, args, "(10 - (TRUNC((10 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * MOD(x,y) using {@link BigDecimal} constants for both parameters returns
+ * MOD(x,y). {@link ModFunctionModifier} will be constructed with a
+ * function name of "MOD" and a supported type list which contains {@link BigDecimal}.
+ *
+ * @throws Exception
+ */
+ public void testTwoBigDecConst3() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new BigDecimal("10"), BigDecimal.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral(new BigDecimal("6"), BigDecimal.class) //$NON-NLS-1$
+ };
+ // mod / BigDecimal
+ List<Class<?>> typeList = new ArrayList<Class<?>>(1);
+ typeList.add(BigDecimal.class);
+ helpTestMod("MOD", typeList, args, "MOD(10, 6)"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * MOD(x,y) using {@link BigDecimal} constants for both parameters returns
+ * (x - (TRUNC((x / y), 0) * y)). {@link ModFunctionModifier} will be
+ * constructed with a function name of "MOD" and a supported type list which
+ * does not contain {@link BigDecimal}.
+ *
+ * @throws Exception
+ */
+ public void testTwoBigDecConst4() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new BigDecimal("10"), BigDecimal.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral(new BigDecimal("6"), BigDecimal.class) //$NON-NLS-1$
+ };
+ // mod / Short
+ List<Class<?>> typeList = new ArrayList<Class<?>>(1);
+ typeList.add(Short.class);
+ helpTestMod("MOD", typeList, args, "(10 - (TRUNC((10 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * x % y using {@link BigDecimal} constants for both parameters returns
+ * (x - (TRUNC((x / y), 0) * x)). {@link ModFunctionModifier} will be
+ * constructed with a function name of "%" and no supported type list.
+ *
+ * @throws Exception
+ */
+ public void testTwoBigDecConst5() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new BigDecimal("10"), BigDecimal.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral(new BigDecimal("6"), BigDecimal.class) //$NON-NLS-1$
+ };
+ // % / default
+ helpTestMod("%", null, args, "(10 - (TRUNC((10 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * x % y using {@link BigDecimal} constants for both parameters returns
+ * (x % y). {@link ModFunctionModifier} will be constructed with a function
+ * name of "%" and a supported type list which contains {@link BigDecimal}.
+ *
+ * @throws Exception
+ */
+ public void testTwoBigDecConst6() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new BigDecimal("10"), BigDecimal.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral(new BigDecimal("6"), BigDecimal.class) //$NON-NLS-1$
+ };
+ // % / BigDecimal
+ List<Class<?>> typeList = new ArrayList<Class<?>>(1);
+ typeList.add(BigDecimal.class);
+ helpTestMod("%", typeList, args, "(10 % 6)"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * x % y using {@link BigDecimal} constants for both parameters returns
+ * (x - (TRUNC((x / y), 0) * x)). {@link ModFunctionModifier} will be
+ * constructed with a function name of "%" and a supported type list that
+ * does not contain {@link BigDecimal}.
+ *
+ * @throws Exception
+ */
+ public void testTwoBigDecConst7() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new BigDecimal("10"), BigDecimal.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral(new BigDecimal("6"), BigDecimal.class) //$NON-NLS-1$
+ };
+ // % / Short
+ List<Class<?>> typeList = new ArrayList<Class<?>>(1);
+ typeList.add(Short.class);
+ helpTestMod("%", typeList, args, "(10 - (TRUNC((10 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * MOD(e1,y) using a {@link Integer} element and a {@link Integer} constant
+ * for parameters returns MOD(e1,y). {@link ModFunctionModifier} will be
+ * constructed without specifying a function name or a supported type list.
+ *
+ * @throws Exception
+ */
+ public void testOneIntElemOneIntConst() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createElement("e1", null, null, Integer.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral(new Integer(6), Integer.class)
+ };
+ // default / default
+ helpTestMod(args, "MOD(e1, 6)"); //$NON-NLS-1$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * MOD(e1,y) using a {@link Integer} element and a {@link Integer} constant
+ * for parameters returns MOD(e1,y). {@link ModFunctionModifier} will be
+ * constructed with a function name of "MOD" but without a supported type
+ * list.
+ *
+ * @throws Exception
+ */
+ public void testOneIntElemOneIntConst2() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createElement("e1", null, null, Integer.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral(new Integer(6), Integer.class)
+ };
+ // mod / default
+ helpTestMod("MOD", null, args, "MOD(e1, 6)"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * MOD(e1,y) using a {@link Integer} element and a {@link Integer} constant
+ * for parameters returns MOD(e1,y). {@link ModFunctionModifier} will be
+ * constructed with a function name of "MOD" and a supported type list which
+ * contains {@link Integer}.
+ *
+ * @throws Exception
+ */
+ public void testOneIntElemOneIntConst3() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createElement("e1", null, null, Integer.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral(new Integer(6), Integer.class)
+ };
+ // mod / Integer
+ List<Class<?>> typeList = new ArrayList<Class<?>>(1);
+ typeList.add(Integer.class);
+ helpTestMod("MOD", typeList, args, "MOD(e1, 6)"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * MOD(e1,y) using a {@link Integer} element and a {@link Integer} constant
+ * for parameters returns (e1 - (TRUNC((e1 / y), 0) * y)).
+ * {@link ModFunctionModifier} will be constructed with a function name of
+ * "MOD" and a supported type list which does not contain {@link Integer}.
+ *
+ * @throws Exception
+ */
+ public void testOneIntElemOneIntConst4() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createElement("e1", null, null, Integer.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral(new Integer(6), Integer.class)
+ };
+ // mod / Short
+ List<Class<?>> typeList = new ArrayList<Class<?>>(1);
+ typeList.add(Short.class);
+ helpTestMod("MOD", typeList, args, "(e1 - (TRUNC((e1 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * e1 % y using a {@link Integer} element and a {@link Integer} constant for
+ * parameters returns (e1 % y). {@link ModFunctionModifier} will be
+ * constructed with a function name of "%" and no supported type list.
+ *
+ * @throws Exception
+ */
+ public void testOneIntElemOneIntConst5() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createElement("e1", null, null, Integer.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral(new Integer(6), Integer.class)
+ };
+ // % / default
+ helpTestMod("%", null, args, "(e1 % 6)"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * e1 % y using a {@link Integer} element and a {@link Integer} constant for
+ * parameters returns (e1 % y). {@link ModFunctionModifier} will be
+ * constructed with a function name of "%" and a supported type list which
+ * contains {@link Integer}.
+ *
+ * @throws Exception
+ */
+ public void testOneIntElemOneIntConst6() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createElement("e1", null, null, Integer.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral(new Integer(6), Integer.class)
+ };
+ // % / Integer
+ List<Class<?>> typeList = new ArrayList<Class<?>>(1);
+ typeList.add(Integer.class);
+ helpTestMod("%", typeList, args, "(e1 % 6)"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * e1 % y using a {@link Integer} element and a {@link Integer} constant for
+ * parameters returns (e1 - (TRUNC((e1 / y), 0) * y)).
+ * {@link ModFunctionModifier} will be constructed with a function name of
+ * "%" and a supported type list that does not contain {@link Integer}.
+ *
+ * @throws Exception
+ */
+ public void testOneIntElemOneIntConst7() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createElement("e1", null, null, Integer.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral(new Integer(6), Integer.class)
+ };
+ // % / Short
+ List<Class<?>> typeList = new ArrayList<Class<?>>(1);
+ typeList.add(Short.class);
+ helpTestMod("%", typeList, args, "(e1 - (TRUNC((e1 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * MOD(e1,y) using a {@link BigDecimal} element and a {@link BigDecimal}
+ * constant for parameters returns (e1 - (TRUNC((e1 / y), 0) * y)).
+ * {@link ModFunctionModifier} will be constructed without specifying a
+ * function name or a supported type list.
+ *
+ * @throws Exception
+ */
+ public void testOneBigDecElemOneBigDecConst() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createElement("e1", null, null, BigDecimal.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral(new BigDecimal(6), BigDecimal.class)
+ };
+ // default / default
+ helpTestMod(args, "(e1 - (TRUNC((e1 / 6), 0) * 6))"); //$NON-NLS-1$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * MOD(e1,y) using a {@link BigDecimal} element and a {@link BigDecimal}
+ * constant for parameters returns (e1 - (TRUNC((e1 / y), 0) * y)).
+ * {@link ModFunctionModifier} will be constructed with a function name of
+ * "MOD" but without a supported type list.
+ *
+ * @throws Exception
+ */
+ public void testOneBigDecElemOneBigDecConst2() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createElement("e1", null, null, BigDecimal.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral(new BigDecimal(6), BigDecimal.class)
+ };
+ // mod / default
+ helpTestMod("MOD", null, args, "(e1 - (TRUNC((e1 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * MOD(e1,y) using a {@link BigDecimal} element and a {@link BigDecimal}
+ * constant for parameters returns MOD(e1,y). {@link ModFunctionModifier}
+ * will be constructed with a function name of "MOD" and a supported type
+ * list which contains {@link BigDecimal}.
+ *
+ * @throws Exception
+ */
+ public void testOneBigDecElemOneBigDecConst3() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createElement("e1", null, null, BigDecimal.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral(new BigDecimal(6), BigDecimal.class)
+ };
+ // mod / Integer
+ List<Class<?>> typeList = new ArrayList<Class<?>>(1);
+ typeList.add(BigDecimal.class);
+ helpTestMod("MOD", typeList, args, "MOD(e1, 6)"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * MOD(e1,y) using a {@link BigDecimal} element and a {@link BigDecimal}
+ * constant for parameters returns (e1 - (TRUNC((e1 / y), 0) * y)).
+ * {@link ModFunctionModifier} will be constructed with a function name of
+ * "MOD" and a supported type list which does not contain {@link BigDecimal}.
+ *
+ * @throws Exception
+ */
+ public void testOneBigDecElemOneBigDecConst4() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createElement("e1", null, null, BigDecimal.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral(new BigDecimal(6), BigDecimal.class)
+ };
+ // mod / Short
+ List<Class<?>> typeList = new ArrayList<Class<?>>(1);
+ typeList.add(Short.class);
+ helpTestMod("MOD", typeList, args, "(e1 - (TRUNC((e1 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * e1 % y using a {@link BigDecimal} element and a {@link BigDecimal}
+ * constant for parameters returns (e1 % y). {@link ModFunctionModifier}
+ * will be constructed with a function name of "%" and no supported type
+ * list.
+ *
+ * @throws Exception
+ */
+ public void testOneBigDecElemOneBigDecConst5() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createElement("e1", null, null, BigDecimal.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral(new BigDecimal(6), BigDecimal.class)
+ };
+ // % / default
+ helpTestMod("%", null, args, "(e1 - (TRUNC((e1 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * e1 % y using a {@link BigDecimal} element and a {@link BigDecimal}
+ * constant for parameters returns (e1 % y). {@link ModFunctionModifier}
+ * will be constructed with a function name of "%" and a supported type list
+ * which contains {@link BigDecimal}.
+ *
+ * @throws Exception
+ */
+ public void testOneBigDecElemOneBigDecConst6() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createElement("e1", null, null, BigDecimal.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral(new BigDecimal(6), BigDecimal.class)
+ };
+ // % / BigDecimal
+ List<Class<?>> typeList = new ArrayList<Class<?>>(1);
+ typeList.add(BigDecimal.class);
+ helpTestMod("%", typeList, args, "(e1 % 6)"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * e1 % y using a {@link BigDecimal} element and a {@link BigDecimal}
+ * constant for parameters returns (e1 - (TRUNC((e1 / y), 0) * y)).
+ * {@link ModFunctionModifier} will be constructed with a function name of
+ * "%" and a supported type list that does not contain {@link BigDecimal}.
+ *
+ * @throws Exception
+ */
+ public void testOneBigDecElemOneBigDecConst7() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createElement("e1", null, null, BigDecimal.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral(new BigDecimal(6), BigDecimal.class)
+ };
+ // % / Short
+ List<Class<?>> typeList = new ArrayList<Class<?>>(1);
+ typeList.add(Short.class);
+ helpTestMod("%", typeList, args, "(e1 - (TRUNC((e1 / 6), 0) * 6))"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link ModFunctionModifier#modify(IFunction)} to validate a call to
+ * MOD(x,e1) using a {@link Float} literal and a {@link Float} element for
+ * parameters returns (x - (floor((x / e1)) * e1)). {@link ModFunctionModifier}
+ * will be constructed with a function name of "MOD" and no supported type
+ * list. The test explicitly overrides
+ * {@link ModFunctionModifier#getQuotientExpression(IExpression)} to produce
+ * output that uses the floor(z) function.
+ *
+ * @throws Exception
+ */
+ public void testOverrideGetQuotient() throws Exception {
+ final Class<?> dataType = Float.class;
+ final String modFunctionName = "MOD"; //$NON-NLS-1$
+ final String expectedStr = "(1000.23 - (floor((1000.23 / e1)) * e1))"; //$NON-NLS-1$
+
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral(new Float(1000.23), dataType),
+ LANG_FACTORY.createElement("e1", null, null, dataType), //$NON-NLS-1$
+ };
+ IFunction func = LANG_FACTORY.createFunction(modFunctionName, args, dataType);
+
+ final Translator trans = new Translator() {
+ @Override
+ public void initialize(ConnectorEnvironment env)
+ throws ConnectorException {
+ super.initialize(env);
+ registerFunctionModifier(SourceSystemFunctions.MOD, new ModFunctionModifier(getLanguageFactory(), modFunctionName, null) {
+ @Override
+ protected IExpression getQuotientExpression(
+ IExpression division) {
+ return getLanguageFactory().createFunction("floor", Arrays.asList(division), division.getType()); //$NON-NLS-1$
+ }
+
+ });
+ }
+ };
+
+ trans.initialize(EnvironmentUtility.createEnvironment(new Properties(), false));
+
+ IExpression expr = trans.getFunctionModifiers().get(SourceSystemFunctions.MOD).modify(func);
+ SQLConversionVisitor sqlVisitor = trans.getSQLConversionVisitor();
+ sqlVisitor.append(expr);
+ assertEquals("Modified function does not match", expectedStr, sqlVisitor.toString()); //$NON-NLS-1$
+ }
+}
Property changes on: trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/translator/TestModFunctionModifier.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
16 years, 1 month
teiid SVN: r1264 - in trunk/connectors/connector-jdbc/src: main/java/org/teiid/connector/jdbc/derby and 10 other directories.
by teiid-commits@lists.jboss.org
Author: loleary
Date: 2009-08-19 15:50:56 -0400 (Wed, 19 Aug 2009)
New Revision: 1264
Added:
trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/postgresql/LOCATEFunctionModifier.java
trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/translator/LOCATEFunctionModifier.java
trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/derby/TestDerbySQLTranslator.java
trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/translator/TestLOCATEFunctionModifier.java
Removed:
trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/oracle/LocateFunctionModifier.java
trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/postgresql/LocateFunctionModifier.java
trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/oracle/TestLocateFunctionModifier.java
Modified:
trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/db2/DB2SQLTranslator.java
trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/derby/DerbySQLTranslator.java
trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/mysql/MySQLTranslator.java
trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/oracle/OracleSQLTranslator.java
trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/postgresql/PostgreSQLTranslator.java
trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/db2/TestDB2SqlTranslator.java
trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/mysql/TestMySQLTranslator.java
trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/oracle/TestOracleTranslator.java
trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/postgresql/TestPostgreSQLTranslator.java
Log:
TEIID-754: LOCATE() function isn't being translated correctly by Oracle Connector
Created generic LOCATEFunctionModifier that could be used by all connectors. This ensures the implementation is for string index bases of 1.
To handle the negative value issue the modify method uses a searched case expression for non-literal start indexes and and checks literal to ensure they are not less than 1.
Modified: trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/db2/DB2SQLTranslator.java
===================================================================
--- trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/db2/DB2SQLTranslator.java 2009-08-19 15:20:26 UTC (rev 1263)
+++ trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/db2/DB2SQLTranslator.java 2009-08-19 19:50:56 UTC (rev 1264)
@@ -34,6 +34,7 @@
import org.teiid.connector.api.TypeFacility;
import org.teiid.connector.api.TypeFacility.RUNTIME_TYPES;
import org.teiid.connector.jdbc.translator.AliasModifier;
+import org.teiid.connector.jdbc.translator.LOCATEFunctionModifier;
import org.teiid.connector.jdbc.translator.MODFunctionModifier;
import org.teiid.connector.jdbc.translator.Translator;
import org.teiid.connector.language.ICommand;
@@ -49,8 +50,6 @@
import org.teiid.connector.visitor.framework.HierarchyVisitor;
-/**
- */
public class DB2SQLTranslator extends Translator {
@Override
@@ -60,6 +59,7 @@
registerFunctionModifier(SourceSystemFunctions.CHAR, new AliasModifier("chr")); //$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.DAYOFMONTH, new AliasModifier("day")); //$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.IFNULL, new AliasModifier("coalesce")); //$NON-NLS-1$
+ registerFunctionModifier(SourceSystemFunctions.LOCATE, new LOCATEFunctionModifier(getLanguageFactory(), "LOCATE")); //$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.SUBSTRING, new AliasModifier("substr")); //$NON-NLS-1$
List<Class<?>> supportedModTypes = new ArrayList<Class<?>>(3);
Modified: trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/derby/DerbySQLTranslator.java
===================================================================
--- trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/derby/DerbySQLTranslator.java 2009-08-19 15:20:26 UTC (rev 1263)
+++ trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/derby/DerbySQLTranslator.java 2009-08-19 19:50:56 UTC (rev 1264)
@@ -29,6 +29,7 @@
import org.teiid.connector.jdbc.db2.DB2SQLTranslator;
import org.teiid.connector.jdbc.oracle.LeftOrRightFunctionModifier;
import org.teiid.connector.jdbc.translator.EscapeSyntaxModifier;
+import org.teiid.connector.jdbc.translator.LOCATEFunctionModifier;
@@ -46,6 +47,7 @@
registerFunctionModifier(SourceSystemFunctions.TIMESTAMPADD, new EscapeSyntaxModifier());
registerFunctionModifier(SourceSystemFunctions.TIMESTAMPDIFF, new EscapeSyntaxModifier());
registerFunctionModifier(SourceSystemFunctions.LEFT, new LeftOrRightFunctionModifier(getLanguageFactory()));
+ registerFunctionModifier(SourceSystemFunctions.LOCATE, new LOCATEFunctionModifier(getLanguageFactory(), "LOCATE")); //$NON-NLS-1$
//overrides of db2 functions
registerFunctionModifier(SourceSystemFunctions.CONCAT, new EscapeSyntaxModifier());
Modified: trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/mysql/MySQLTranslator.java
===================================================================
--- trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/mysql/MySQLTranslator.java 2009-08-19 15:20:26 UTC (rev 1263)
+++ trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/mysql/MySQLTranslator.java 2009-08-19 19:50:56 UTC (rev 1264)
@@ -33,6 +33,7 @@
import org.teiid.connector.api.ConnectorEnvironment;
import org.teiid.connector.api.ConnectorException;
import org.teiid.connector.api.SourceSystemFunctions;
+import org.teiid.connector.jdbc.translator.LOCATEFunctionModifier;
import org.teiid.connector.jdbc.translator.Translator;
@@ -50,6 +51,7 @@
registerFunctionModifier(SourceSystemFunctions.BITNOT, new BitFunctionModifier("~", getLanguageFactory())); //$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.BITOR, new BitFunctionModifier("|", getLanguageFactory())); //$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.BITXOR, new BitFunctionModifier("^", getLanguageFactory())); //$NON-NLS-1$
+ registerFunctionModifier(SourceSystemFunctions.LOCATE, new LOCATEFunctionModifier(getLanguageFactory(), "LOCATE")); //$NON-NLS-1$
}
@Override
Deleted: trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/oracle/LocateFunctionModifier.java
===================================================================
--- trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/oracle/LocateFunctionModifier.java 2009-08-19 15:20:26 UTC (rev 1263)
+++ trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/oracle/LocateFunctionModifier.java 2009-08-19 19:50:56 UTC (rev 1264)
@@ -1,79 +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.connector.jdbc.oracle;
-
-import java.util.Arrays;
-import java.util.List;
-
-import org.teiid.connector.jdbc.translator.BasicFunctionModifier;
-import org.teiid.connector.jdbc.translator.FunctionModifier;
-import org.teiid.connector.language.IExpression;
-import org.teiid.connector.language.IFunction;
-import org.teiid.connector.language.ILanguageFactory;
-import org.teiid.connector.language.ILiteral;
-
-
-/**
- * Modify the locate function to use the Oracle instr function.
- *
- * locate(sub, str) -> instr(str, sub)
- *
- * locate(sub, str, start) -> instr(str, sub, start+1)
- */
-public class LocateFunctionModifier extends BasicFunctionModifier implements FunctionModifier {
-
- private ILanguageFactory langFactory;
-
- public LocateFunctionModifier(ILanguageFactory langFactory) {
- this.langFactory = langFactory;
- }
-
- /*
- * @see com.metamatrix.connector.jdbc.extension.FunctionModifier#modify(com.metamatrix.data.language.IFunction)
- */
- public IExpression modify(IFunction function) {
- function.setName("instr"); //$NON-NLS-1$
- List<IExpression> args = function.getParameters();
- IExpression expr = args.get(0);
- args.set(0, args.get(1));
- args.set(1, expr);
- if(args.size() == 3) {
- if(args.get(2) instanceof ILiteral) {
- ILiteral indexConst = (ILiteral)args.get(2);
- if(indexConst.getValue() != null) {
- // Just modify the constant
- Integer index = (Integer) indexConst.getValue();
- args.set(2, langFactory.createLiteral(new Integer(index.intValue()+1), Integer.class));
- }
- } else {
- // Make plus function since this involves an element or function
- IFunction plusFunction = langFactory.createFunction("+", //$NON-NLS-1$
- Arrays.asList( args.get(2), langFactory.createLiteral(new Integer(1), Integer.class) ),
- Integer.class);
- args.set(2, plusFunction);
- }
- }
- return function;
- }
-
-}
Modified: trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/oracle/OracleSQLTranslator.java
===================================================================
--- trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/oracle/OracleSQLTranslator.java 2009-08-19 15:20:26 UTC (rev 1263)
+++ trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/oracle/OracleSQLTranslator.java 2009-08-19 19:50:56 UTC (rev 1264)
@@ -42,7 +42,9 @@
import org.teiid.connector.jdbc.JDBCPlugin;
import org.teiid.connector.jdbc.translator.AliasModifier;
import org.teiid.connector.jdbc.translator.ExtractFunctionModifier;
+import org.teiid.connector.jdbc.translator.LOCATEFunctionModifier;
import org.teiid.connector.jdbc.translator.Translator;
+import org.teiid.connector.jdbc.translator.LOCATEFunctionModifier.ParameterOrder;
import org.teiid.connector.language.ICommand;
import org.teiid.connector.language.IElement;
import org.teiid.connector.language.IFunction;
@@ -96,7 +98,7 @@
registerFunctionModifier(SourceSystemFunctions.QUARTER, new DayWeekQuarterFunctionModifier(getLanguageFactory(), "Q"));//$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.DAYOFWEEK, new DayWeekQuarterFunctionModifier(getLanguageFactory(), "D"));//$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.DAYOFYEAR, new DayWeekQuarterFunctionModifier(getLanguageFactory(), "DDD"));//$NON-NLS-1$
- registerFunctionModifier(SourceSystemFunctions.LOCATE, new LocateFunctionModifier(getLanguageFactory()));
+ registerFunctionModifier(SourceSystemFunctions.LOCATE, new LOCATEFunctionModifier(getLanguageFactory(), "INSTR", ParameterOrder.SOURCE_SEARCH_INDEX)); //$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.SUBSTRING, new AliasModifier("substr"));//$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.LEFT, new LeftOrRightFunctionModifier(getLanguageFactory()));
registerFunctionModifier(SourceSystemFunctions.RIGHT, new LeftOrRightFunctionModifier(getLanguageFactory()));
Added: trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/postgresql/LOCATEFunctionModifier.java
===================================================================
--- trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/postgresql/LOCATEFunctionModifier.java (rev 0)
+++ trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/postgresql/LOCATEFunctionModifier.java 2009-08-19 19:50:56 UTC (rev 1264)
@@ -0,0 +1,55 @@
+/*
+ * 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.connector.jdbc.postgresql;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.teiid.connector.api.TypeFacility;
+import org.teiid.connector.language.IExpression;
+import org.teiid.connector.language.IFunction;
+import org.teiid.connector.language.ILanguageFactory;
+
+public class LOCATEFunctionModifier extends org.teiid.connector.jdbc.translator.LOCATEFunctionModifier {
+
+ public LOCATEFunctionModifier(ILanguageFactory factory) {
+ super(factory);
+ }
+
+ @Override
+ public List<?> translate(IFunction function) {
+ List<Object> parts = new ArrayList<Object>();
+ List<IExpression> params = function.getParameters();
+ parts.add("position("); //$NON-NLS-1$
+ parts.add(params.get(0));
+ parts.add(" in "); //$NON-NLS-1$
+ if (params.size() == 3) {
+ parts.add(this.getLanguageFactory().createFunction("substr", params.subList(1, 3), TypeFacility.RUNTIME_TYPES.STRING)); //$NON-NLS-1$
+ } else {
+ parts.add(params.get(1));
+ }
+ parts.add(")"); //$NON-NLS-1$
+ return parts;
+ }
+
+}
Property changes on: trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/postgresql/LOCATEFunctionModifier.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Deleted: trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/postgresql/LocateFunctionModifier.java
===================================================================
--- trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/postgresql/LocateFunctionModifier.java 2009-08-19 15:20:26 UTC (rev 1263)
+++ trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/postgresql/LocateFunctionModifier.java 2009-08-19 19:50:56 UTC (rev 1264)
@@ -1,58 +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.connector.jdbc.postgresql;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.teiid.connector.api.TypeFacility;
-import org.teiid.connector.jdbc.translator.BasicFunctionModifier;
-import org.teiid.connector.language.IExpression;
-import org.teiid.connector.language.IFunction;
-import org.teiid.connector.language.ILanguageFactory;
-
-public class LocateFunctionModifier extends BasicFunctionModifier {
-
- private ILanguageFactory factory;
-
- public LocateFunctionModifier(ILanguageFactory factory) {
- this.factory = factory;
- }
-
- @Override
- public List<?> translate(IFunction function) {
- List<Object> parts = new ArrayList<Object>();
- List<IExpression> params = function.getParameters();
- parts.add("position("); //$NON-NLS-1$
- parts.add(params.get(0));
- parts.add(" in "); //$NON-NLS-1$
- if (params.size() == 3) {
- parts.add(factory.createFunction("substr", params.subList(1, 3), TypeFacility.RUNTIME_TYPES.STRING)); //$NON-NLS-1$
- } else {
- parts.add(params.get(1));
- }
- parts.add(")"); //$NON-NLS-1$
- return parts;
- }
-
-}
Modified: trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/postgresql/PostgreSQLTranslator.java
===================================================================
--- trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/postgresql/PostgreSQLTranslator.java 2009-08-19 15:20:26 UTC (rev 1263)
+++ trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/postgresql/PostgreSQLTranslator.java 2009-08-19 19:50:56 UTC (rev 1264)
@@ -95,7 +95,7 @@
registerFunctionModifier(SourceSystemFunctions.IFNULL, new AliasModifier("coalesce")); //$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.CONVERT, new PostgreSQLConvertModifier(getLanguageFactory()));
- registerFunctionModifier(SourceSystemFunctions.LOCATE, new LocateFunctionModifier(getLanguageFactory()));
+ registerFunctionModifier(SourceSystemFunctions.LOCATE, new LOCATEFunctionModifier(getLanguageFactory()));
}
@Override
Added: trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/translator/LOCATEFunctionModifier.java
===================================================================
--- trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/translator/LOCATEFunctionModifier.java (rev 0)
+++ trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/translator/LOCATEFunctionModifier.java 2009-08-19 19:50:56 UTC (rev 1264)
@@ -0,0 +1,323 @@
+/*
+ * 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.connector.jdbc.translator;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.teiid.connector.jdbc.translator.BasicFunctionModifier;
+import org.teiid.connector.jdbc.translator.FunctionModifier;
+import org.teiid.connector.language.ICompareCriteria;
+import org.teiid.connector.language.IExpression;
+import org.teiid.connector.language.IFunction;
+import org.teiid.connector.language.ILanguageFactory;
+import org.teiid.connector.language.ILiteral;
+import org.teiid.connector.language.ICompareCriteria.Operator;
+
+
+/**
+ * A modifier class that can be used to translate the scalar function
+ * <code>locate(search_string, source_string)</code> and
+ * <code>locate(search_string, source_string, start_index)</code> to a function
+ * or expression that can be used at the data source.
+ * <p>
+ * If the default implementation is used, a function name of LOCATE will be used
+ * for the function name.
+ * <p>
+ * If the default implementation is used, the expression will not be modified if:
+ * <li><code>locate(search_string, source_string)</code> is used</li>
+ * <li><code>locate(search_string, source_string, start_index)</code> is used
+ * and <code>start_index</code> is a literal integer greater then 0</li>
+ * <li>the default function parameter order is used or unspecified</li>
+ * <p>
+ * If the default implementation is used, the expression will be modified if:
+ * <li><code>locate(search_string, source_string, start_index)</code> is used
+ * and <code>start_index</code> is a literal integer less then 1</li>
+ * <li><code>locate(search_string, source_string, start_index)</code> is used
+ * and <code>start_index</code> is not a literal integer</li>
+ * <li>the function parameter order is something other than the default</li>
+ * <p>
+ * If the default implementation is used and the expression is modified, it is
+ * modified to ensure that any literal integer value less than 1 is made equal
+ * to 1 and any non literal value is wrapped by a searched case expression
+ * to ensure that a value of less then 1 will be equal to 1 and the parameter
+ * order matches that of what the data source expects.
+ * <p>
+ * For example:
+ * <li><code>locate('a', 'abcdef')</code> --> <code>LOCATE('a', 'abcdef')</code></li>
+ * <li><code>locate('a', 'abcdef', 2)</code> --> <code>LOCATE('a', 'abcdef', 2)</code></li>
+ * <li><code>locate('a', 'abcdef', 0)</code> --> <code>LOCATE('a', 'abcdef', 1)</code></li>
+ * <li><code>locate('a', 'abcdef', intCol)</code> --> <code>LOCATE('a', 'abcdef', CASE WHEN intCol < 1 THEN 1 ELSE intCol END)</code></li>
+ *
+ * @since 6.2
+ */
+public class LOCATEFunctionModifier extends BasicFunctionModifier implements FunctionModifier {
+
+ /**
+ * An <code>enum</code> that defines the parameter orders that can be used
+ * with <code>LOCATEFunctionModifier</code>
+ *
+ */
+ public static enum ParameterOrder {
+ /**
+ * Indicates that the parameter order should be consistent with the
+ * built-in system function <code>LOCATE(searchStr, sourceStr, startIndex)</code>.
+ */
+ DEFAULT,
+
+ /**
+ * Indicates that the parameter order should be changed from the default
+ * built-in system function <code>LOCATE(searchStr, sourceStr, startIndex)</code>
+ * to <code>LOCATE(sourceStr, searchStr, startIndex)</code>.
+ */
+ SOURCE_SEARCH_INDEX,
+
+ /**
+ * Indicates that the parameter order should be changed from the default
+ * built-in system function <code>LOCATE(searchStr, sourceStr, startIndex)</code>
+ * to <code>LOCATE(startIndex, sourceStr, searchStr)</code>.
+ */
+ INDEX_SOURCE_SEARCH
+
+ }
+
+ private ILanguageFactory langFactory;
+ private String functionName = "LOCATE"; //$NON-NLS-1$
+ private ParameterOrder parameterOrder = ParameterOrder.DEFAULT;
+ private final Integer systemStringIndexBase = 1;
+
+ /**
+ * Constructs a {@link BasicFunctionModifier} object that can be used to
+ * translate the scalar function LOCATE() to a source specific scalar
+ * function or expression.
+ * <p>
+ * This constructor invokes {@link #LOCATEFunctionModifier(ILanguageFactory, String, ParameterOrder)}
+ * passing it <code>langFactory</code>, <code>null</code>, <code>null</code>.
+ *
+ * @param langFactory the language factory associated with translation
+ */
+ public LOCATEFunctionModifier(ILanguageFactory langFactory) {
+ this(langFactory, null, null);
+ }
+
+ /**
+ * Constructs a {@link BasicFunctionModifier} object that can be used to
+ * translate the scalar function LOCATE() to a source specific scalar
+ * function or expression.
+ * <p>
+ * This constructor invokes {@link #LOCATEFunctionModifier(ILanguageFactory, String, ParameterOrder)}
+ * passing it <code>langFactory</code>, <code>functionName</code>,
+ * <code>null</code>.
+ *
+ * @param langFactory the language factory associated with translation
+ * @param functionName the function name or alias to be used instead of LOCATE
+ */
+ public LOCATEFunctionModifier(ILanguageFactory langFactory, final String functionName) {
+ this(langFactory, functionName, null);
+ }
+
+ /**
+ * Constructs a {@link BasicFunctionModifier} object that can be used to
+ * translate the scalar function LOCATE() to a source specific scalar
+ * function or expression.
+ * <p>
+ * <code>functionName</code> should represent the default function name or
+ * alias used by the data source. If this value is <code>null</code> a
+ * default value will be used.
+ * <p>
+ * <code>paramOrder</code> should represent how the data source's version of
+ * the LOCATE() function expects its parameters. This value can be any
+ * supported value offered by {@link ParameterOrder}. If this value is
+ * <code>null</code> a default value will be used.
+ * <p>
+ *
+ * @param langFactory the language factory associated with translation
+ * @param functionName the function name or alias to be used instead of
+ * LOCATE, or <code>null</code> if the default should be used
+ * @param paramOrder the order in which parameters should be translated, or
+ * <code>null</code> if the default should be used
+ */
+ public LOCATEFunctionModifier(ILanguageFactory langFactory, final String functionName, final ParameterOrder paramOrder) {
+ if (functionName != null) this.functionName = functionName;
+ if (paramOrder != null) this.parameterOrder = paramOrder;
+ this.langFactory = langFactory;
+ }
+
+ /**
+ * Returns a version of <code>function</code> suitable for executing at the
+ * data source.
+ * <p>
+ * First, a default function name or the value specified during construction
+ * of <code>MODFunctionModifier</code> is set on <code>function</code>.
+ * <p>
+ * If <code>function</code> represents <code>LOCATE(searchStr, sourceStr, startIndex)</code>
+ * and <code>startIndex</code> is a literal value, it is translated for
+ * consistency between the built-in system function
+ * <code>LOCATE(searchStr, sourceStr, startIndex)</code> and the sources
+ * implementation. This is done by calling {@link #getStartIndexExpression(ILiteral)}
+ * and passing it the literal <code>startIndex</code> value.
+ * <p>
+ * If <code>function</code> represents <code>LOCATE(searchStr, sourceStr, startIndex)</code>
+ * and <code>startIndex</code> is not a literal value, it is translated for
+ * consistency between the built-in system function
+ * <code>LOCATE(searchStr, sourceStr, startIndex)</code> and the sources
+ * implementation. This is done by calling {@link #getStartIndexExpression(IExpression)}
+ * and passing it the non-literal <code>startIndex</code> value.
+ * <p>
+ * Finally, <code>function</code>'s parameters may be rearranged depending
+ * on the value specified by {@link ParameterOrder} during construction of
+ * <code>MODFunctionModifier</code>.
+ * <p>
+ * The translated <code>function</code> is then returned.
+ * <p>
+ * For example:
+ * <ul>
+ * <code>locate('a', 'abcdefg') ---> LOCATE('a', 'abcdefg')</code><br />
+ * <code>locate('a', 'abcdefg', 1) ---> LOCATE('a', 'abcdefg', 1)</code><br />
+ * <code>locate('a', 'abcdefg', 1) ---> INSTR('abcdefg', 'a', 1)</code><br />
+ * <code>locate('a', 'abcdefg', -5) ---> INSTR('abcdefg', 'a', 1)</code><br />
+ * <code>locate('a', 'abcdefg', 1) ---> FINDSTR('a', 'abcdefg', 1)</code><br />
+ * <code>locate('a', 'abcdefg', myCol) ---> LOCATE('a', 'abcdefg', CASE WHEN myCol < 1 THEN 1 ELSE myCol END)</code>
+ * </ul>
+ *
+ * @param function the LOCATE function that may need to be modified
+ */
+ public IExpression modify(IFunction function) {
+ function.setName(this.functionName);
+ List<IExpression> args = function.getParameters();
+ IExpression searchStr = args.get(0);
+ IExpression sourceStr = args.get(1);
+ IExpression startIndex = (args.size() > 2 ? args.get(2) : null);
+
+ // if startIndex was given then we may need to do additional work
+ if (startIndex != null) {
+ if (startIndex instanceof ILiteral) {
+ startIndex = this.getStartIndexExpression((ILiteral)startIndex);
+ } else {
+ startIndex = this.getStartIndexExpression((IExpression)startIndex);
+ }
+ }
+ switch (this.parameterOrder) {
+ case SOURCE_SEARCH_INDEX:
+ args.set(0, sourceStr);
+ args.set(1, searchStr);
+ if (startIndex != null) args.set(2, startIndex);
+ break;
+ case INDEX_SOURCE_SEARCH:
+ if (startIndex != null) args.set(0, startIndex);
+ args.set(1, sourceStr);
+ args.set(2, searchStr);
+ break;
+ case DEFAULT:
+ args.set(0, searchStr);
+ args.set(1, sourceStr);
+ if (startIndex != null) args.set(2, startIndex);
+ break;
+ }
+ return function;
+ }
+
+ /**
+ * Return an expression that represents <code>startIndex</code> rewritten to
+ * be consistent with the built-in system function's
+ * <code>LOCATE(searchStr, sourceStr, startIndex)</code> <code>startIndex</code>
+ * parameter.
+ * <p>
+ * <code>startIndex</code> represents the unmodified parameter as passed to
+ * the <code>LOCATE(searchStr, sourceStr, startIndex)</code> function. The
+ * returned value will represent a normalized version of the expression that
+ * is consistent to the built-in system function. For example, a value for
+ * <code>startIndex</code> should not be less than <code>1</code>.
+ * <p>
+ * If this method is not overriden, the result will be:
+ * <p>
+ * <ul>If <code>startIndex</code> is <code>null</code>, <code>startIndex</code></ul>
+ * <ul>If <code>startIndex</code> is not <code>null</code> and its value is
+ * less than <code>1</code>, <code>1</code></ul>
+ *
+ * @param startIndex an expression representing the <code>startIndex</code>
+ * parameter used in <code>LOCATE(searchStr, sourceStr, startIndex)</code>
+ * @return an expression that represents a normalized <code>startIndex</code>
+ */
+ protected IExpression getStartIndexExpression(ILiteral startIndex) {
+ if (startIndex.getValue() != null) {
+ if ((Integer)startIndex.getValue() < this.getSystemStringIndexBase()) {
+ startIndex.setValue(this.getSystemStringIndexBase());
+ }
+ }
+ return startIndex;
+ }
+
+ /**
+ * Return an expression that represents <code>startIndex</code> rewritten to
+ * be consistent with the built-in system function's
+ * <code>LOCATE(searchStr, sourceStr, startIndex)</code> <code>startIndex</code>
+ * parameter.
+ * <p>
+ * <code>startIndex</code> represents the unmodified parameter as passed to
+ * the <code>LOCATE(searchStr, sourceStr, startIndex)</code> function. The
+ * returned value will represent a normalized version of the expression that
+ * is consistent to the built-in system function. For example, a value for
+ * <code>startIndex</code> should not be less than <code>1</code>.
+ * <p>
+ * If this method is not overriden, the result will be:
+ * <p>
+ * <ul><code>CASE WHEN <startIndex> < 1; THEN 1; ELSE <startIndex> END</code></ul>
+ * <p>
+ * For the default searched case expression to work, the source must support
+ * searched case.
+ *
+ * @param startIndex an expression representing the <code>startIndex</code>
+ * parameter used in <code>LOCATE(searchStr, sourceStr, startIndex)</code>
+ * @return an expression that represents a normalized <code>startIndex</code>
+ */
+ protected IExpression getStartIndexExpression(IExpression startIndex) {
+ ICompareCriteria[] whenExpr = {langFactory.createCompareCriteria(
+ Operator.LT,
+ startIndex,
+ langFactory.createLiteral(this.getSystemStringIndexBase(), Integer.class)
+ )};
+ ILiteral[] thenExpr = {langFactory.createLiteral(this.getSystemStringIndexBase(), Integer.class)};
+ return langFactory.createSearchedCaseExpression(Arrays.asList(whenExpr), Arrays.asList(thenExpr), startIndex, Integer.class);
+ }
+
+ /**
+ * Get the string index base used by built-in system functions. The value
+ * represents what is considered the first character of a string.
+ *
+ * @return the data source's string index base
+ */
+ protected Integer getSystemStringIndexBase() {
+ return this.systemStringIndexBase;
+ }
+
+ /**
+ * Get the instance of {@link ILanguageFactory} set during construction.
+ *
+ * @return the <code>ILanguageFactory</code> instance
+ */
+ protected ILanguageFactory getLanguageFactory() {
+ return this.langFactory;
+ }
+
+}
Property changes on: trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/translator/LOCATEFunctionModifier.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/db2/TestDB2SqlTranslator.java
===================================================================
--- trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/db2/TestDB2SqlTranslator.java 2009-08-19 15:20:26 UTC (rev 1263)
+++ trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/db2/TestDB2SqlTranslator.java 2009-08-19 19:50:56 UTC (rev 1264)
@@ -30,6 +30,7 @@
import org.junit.Test;
import org.teiid.connector.api.ConnectorException;
import org.teiid.connector.api.ExecutionContext;
+import org.teiid.connector.jdbc.MetadataFactory;
import org.teiid.connector.jdbc.translator.TranslatedCommand;
import org.teiid.connector.language.ICommand;
@@ -117,5 +118,123 @@
output);
}
+ /**
+ * Test the translator's ability to rewrite the LOCATE() function in a form
+ * suitable for the data source.
+ * <p>
+ * <code>SELECT locate(INTNUM, 'chimp', 1) FROM BQT1.SMALLA</code>
+ *
+ * @throws Exception
+ */
+ @Test public void testLocate() throws Exception {
+ String input = "SELECT locate(INTNUM, 'chimp', 1) FROM BQT1.SMALLA"; //$NON-NLS-1$
+ String output = "SELECT LOCATE(char(SmallA.IntNum), 'chimp', 1) FROM SmallA"; //$NON-NLS-1$
+ MetadataFactory.helpTestVisitor(MetadataFactory.BQT_VDB,
+ input, output,
+ TRANSLATOR);
+ }
+
+ /**
+ * Test the translator's ability to rewrite the LOCATE() function in a form
+ * suitable for the data source.
+ * <p>
+ * <code>SELECT locate(STRINGNUM, 'chimp') FROM BQT1.SMALLA</code>
+ *
+ * @throws Exception
+ */
+ @Test public void testLocate2() throws Exception {
+ String input = "SELECT locate(STRINGNUM, 'chimp') FROM BQT1.SMALLA"; //$NON-NLS-1$
+ String output = "SELECT LOCATE(SmallA.StringNum, 'chimp') FROM SmallA"; //$NON-NLS-1$
+
+ MetadataFactory.helpTestVisitor(MetadataFactory.BQT_VDB,
+ input, output,
+ TRANSLATOR);
+ }
+
+ /**
+ * Test the translator's ability to rewrite the LOCATE() function in a form
+ * suitable for the data source.
+ * <p>
+ * <code>SELECT locate(INTNUM, '234567890', 1) FROM BQT1.SMALLA WHERE INTKEY = 26</code>
+ *
+ * @throws Exception
+ */
+ @Test public void testLocate3() throws Exception {
+ String input = "SELECT locate(INTNUM, '234567890', 1) FROM BQT1.SMALLA WHERE INTKEY = 26"; //$NON-NLS-1$
+ String output = "SELECT LOCATE(char(SmallA.IntNum), '234567890', 1) FROM SmallA WHERE SmallA.IntKey = 26"; //$NON-NLS-1$
+
+ MetadataFactory.helpTestVisitor(MetadataFactory.BQT_VDB,
+ input, output,
+ TRANSLATOR);
+ }
+
+ /**
+ * Test the translator's ability to rewrite the LOCATE() function in a form
+ * suitable for the data source.
+ * <p>
+ * <code>SELECT locate('c', 'chimp', 1) FROM BQT1.SMALLA</code>
+ *
+ * @throws Exception
+ */
+ @Test public void testLocate4() throws Exception {
+ String input = "SELECT locate('c', 'chimp', 1) FROM BQT1.SMALLA"; //$NON-NLS-1$
+ String output = "SELECT 1 FROM SmallA"; //$NON-NLS-1$
+
+ MetadataFactory.helpTestVisitor(MetadataFactory.BQT_VDB,
+ input, output,
+ TRANSLATOR);
+ }
+
+ /**
+ * Test the translator's ability to rewrite the LOCATE() function in a form
+ * suitable for the data source.
+ * <p>
+ * <code>SELECT locate(STRINGNUM, 'chimp', -5) FROM BQT1.SMALLA</code>
+ *
+ * @throws Exception
+ */
+ @Test public void testLocate5() throws Exception {
+ String input = "SELECT locate(STRINGNUM, 'chimp', -5) FROM BQT1.SMALLA"; //$NON-NLS-1$
+ String output = "SELECT LOCATE(SmallA.StringNum, 'chimp', 1) FROM SmallA"; //$NON-NLS-1$
+
+ MetadataFactory.helpTestVisitor(MetadataFactory.BQT_VDB,
+ input, output,
+ TRANSLATOR);
+ }
+
+ /**
+ * Test the translator's ability to rewrite the LOCATE() function in a form
+ * suitable for the data source.
+ * <p>
+ * <code>SELECT locate(STRINGNUM, 'chimp', INTNUM) FROM BQT1.SMALLA</code>
+ *
+ * @throws Exception
+ */
+ @Test public void testLocate6() throws Exception {
+ String input = "SELECT locate(STRINGNUM, 'chimp', INTNUM) FROM BQT1.SMALLA"; //$NON-NLS-1$
+ String output = "SELECT LOCATE(SmallA.StringNum, 'chimp', CASE WHEN SmallA.IntNum < 1 THEN 1 ELSE SmallA.IntNum END) FROM SmallA"; //$NON-NLS-1$
+
+ MetadataFactory.helpTestVisitor(MetadataFactory.BQT_VDB,
+ input, output,
+ TRANSLATOR);
+ }
+
+ /**
+ * Test the translator's ability to rewrite the LOCATE() function in a form
+ * suitable for the data source.
+ * <p>
+ * <code>SELECT locate(STRINGNUM, 'chimp', LOCATE(STRINGNUM, 'chimp') + 1) FROM BQT1.SMALLA</code>
+ *
+ * @throws Exception
+ */
+ @Test public void testLocate7() throws Exception {
+ String input = "SELECT locate(STRINGNUM, 'chimp', LOCATE(STRINGNUM, 'chimp') + 1) FROM BQT1.SMALLA"; //$NON-NLS-1$
+ String output = "SELECT LOCATE(SmallA.StringNum, 'chimp', CASE WHEN (LOCATE(SmallA.StringNum, 'chimp') + 1) < 1 THEN 1 ELSE (LOCATE(SmallA.StringNum, 'chimp') + 1) END) FROM SmallA"; //$NON-NLS-1$
+
+ MetadataFactory.helpTestVisitor(MetadataFactory.BQT_VDB,
+ input, output,
+ TRANSLATOR);
+ }
+
}
Added: trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/derby/TestDerbySQLTranslator.java
===================================================================
--- trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/derby/TestDerbySQLTranslator.java (rev 0)
+++ trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/derby/TestDerbySQLTranslator.java 2009-08-19 19:50:56 UTC (rev 1264)
@@ -0,0 +1,261 @@
+/*
+ * 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.connector.jdbc.derby;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Properties;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.teiid.connector.api.ConnectorException;
+import org.teiid.connector.api.ExecutionContext;
+import org.teiid.connector.jdbc.MetadataFactory;
+import org.teiid.connector.jdbc.translator.TranslatedCommand;
+import org.teiid.connector.language.ICommand;
+
+import com.metamatrix.cdk.api.EnvironmentUtility;
+import com.metamatrix.cdk.api.TranslationUtility;
+import com.metamatrix.cdk.unittest.FakeTranslationFactory;
+import com.metamatrix.core.util.UnitTestUtil;
+
+/**
+ */
+public class TestDerbySQLTranslator {
+
+ private static DerbySQLTranslator TRANSLATOR;
+
+ @BeforeClass
+ public static void setUp() throws ConnectorException {
+ TRANSLATOR = new DerbySQLTranslator();
+ TRANSLATOR.initialize(EnvironmentUtility.createEnvironment(new Properties(), false));
+ }
+
+ public String getTestVDB() {
+ return UnitTestUtil.getTestDataPath() + "/PartsSupplier.vdb"; //$NON-NLS-1$
+ }
+
+ public void helpTestVisitor(TranslationUtility util, String input, String expectedOutput) throws ConnectorException {
+ // Convert from sql to objects
+ ICommand obj = util.parseCommand(input);
+
+ ExecutionContext context = EnvironmentUtility.createSecurityContext("user"); //$NON-NLS-1$
+
+ TranslatedCommand tc = new TranslatedCommand(context, TRANSLATOR);
+ tc.translateCommand(obj);
+
+ assertEquals("Did not get correct sql", expectedOutput, tc.getSql()); //$NON-NLS-1$
+ }
+
+ @Test
+ public void testRowLimit() throws Exception {
+ String input = "select intkey from bqt1.smalla limit 100"; //$NON-NLS-1$
+ String output = "SELECT SmallA.IntKey FROM SmallA FETCH FIRST 100 ROWS ONLY"; //$NON-NLS-1$
+
+ helpTestVisitor(FakeTranslationFactory.getInstance().getBQTTranslationUtility(),
+ input,
+ output);
+ }
+
+ @Test
+ public void testCrossJoin() throws Exception{
+ String input = "SELECT bqt1.smalla.stringkey FROM bqt1.smalla cross join bqt1.smallb"; //$NON-NLS-1$
+ String output = "SELECT SmallA.StringKey FROM SmallA INNER JOIN SmallB ON 1 = 1"; //$NON-NLS-1$
+
+ helpTestVisitor(FakeTranslationFactory.getInstance().getBQTTranslationUtility(),
+ input,
+ output);
+ }
+
+ @Test
+ public void testConcat_useLiteral() throws Exception {
+ String input = "select concat(stringnum,'_xx') from BQT1.Smalla"; //$NON-NLS-1$
+ String output = "SELECT {fn concat(SmallA.StringNum, '_xx')} FROM SmallA"; //$NON-NLS-1$
+
+ helpTestVisitor(FakeTranslationFactory.getInstance().getBQTTranslationUtility(),
+ input,
+ output);
+
+ }
+
+ @Test
+ public void testConcat() throws Exception {
+ String input = "select concat(stringnum, stringnum) from BQT1.Smalla"; //$NON-NLS-1$
+ String output = "SELECT {fn concat(SmallA.StringNum, SmallA.StringNum)} FROM SmallA"; //$NON-NLS-1$
+
+ helpTestVisitor(FakeTranslationFactory.getInstance().getBQTTranslationUtility(),
+ input,
+ output);
+ }
+
+ @Test
+ public void testConcat2_useLiteral() throws Exception {
+ String input = "select concat2(stringnum,'_xx') from BQT1.Smalla"; //$NON-NLS-1$
+ String output = "SELECT {fn concat(coalesce(SmallA.StringNum, ''), '_xx')} FROM SmallA"; //$NON-NLS-1$
+
+ helpTestVisitor(FakeTranslationFactory.getInstance().getBQTTranslationUtility(),
+ input,
+ output);
+
+ }
+
+ @Test
+ public void testConcat2() throws Exception {
+ String input = "select concat2(stringnum, stringnum) from BQT1.Smalla"; //$NON-NLS-1$
+ String output = "SELECT CASE WHEN SmallA.StringNum IS NULL THEN NULL ELSE {fn concat(coalesce(SmallA.StringNum, ''), coalesce(SmallA.StringNum, ''))} END FROM SmallA"; //$NON-NLS-1$
+
+ helpTestVisitor(FakeTranslationFactory.getInstance().getBQTTranslationUtility(),
+ input,
+ output);
+ }
+
+ @Test
+ public void testSelectNullLiteral() throws Exception {
+ String input = "select null + 1 as x, null || 'a' from BQT1.Smalla"; //$NON-NLS-1$
+ String output = "SELECT CAST(NULL AS INTEGER) AS x, CAST(NULL AS CHAR) FROM SmallA"; //$NON-NLS-1$
+
+ helpTestVisitor(FakeTranslationFactory.getInstance().getBQTTranslationUtility(),
+ input,
+ output);
+ }
+
+ /**
+ * Test the translator's ability to rewrite the LOCATE() function in a form
+ * suitable for the data source.
+ * <p>
+ * <code>SELECT locate(INTNUM, 'chimp', 1) FROM BQT1.SMALLA</code>
+ *
+ * @throws Exception
+ */
+ @Test public void testLocate() throws Exception {
+ String input = "SELECT locate(INTNUM, 'chimp', 1) FROM BQT1.SMALLA"; //$NON-NLS-1$
+ String output = "SELECT LOCATE(char(SmallA.IntNum), 'chimp', 1) FROM SmallA"; //$NON-NLS-1$
+
+ MetadataFactory.helpTestVisitor(MetadataFactory.BQT_VDB,
+ input, output,
+ TRANSLATOR);
+ }
+
+ /**
+ * Test the translator's ability to rewrite the LOCATE() function in a form
+ * suitable for the data source.
+ * <p>
+ * <code>SELECT locate(STRINGNUM, 'chimp') FROM BQT1.SMALLA</code>
+ *
+ * @throws Exception
+ */
+ @Test public void testLocate2() throws Exception {
+ String input = "SELECT locate(STRINGNUM, 'chimp') FROM BQT1.SMALLA"; //$NON-NLS-1$
+ String output = "SELECT LOCATE(SmallA.StringNum, 'chimp') FROM SmallA"; //$NON-NLS-1$
+
+ MetadataFactory.helpTestVisitor(MetadataFactory.BQT_VDB,
+ input, output,
+ TRANSLATOR);
+ }
+
+ /**
+ * Test the translator's ability to rewrite the LOCATE() function in a form
+ * suitable for the data source.
+ * <p>
+ * <code>SELECT locate(INTNUM, '234567890', 1) FROM BQT1.SMALLA WHERE INTKEY = 26</code>
+ *
+ * @throws Exception
+ */
+ @Test public void testLocate3() throws Exception {
+ String input = "SELECT locate(INTNUM, '234567890', 1) FROM BQT1.SMALLA WHERE INTKEY = 26"; //$NON-NLS-1$
+ String output = "SELECT LOCATE(char(SmallA.IntNum), '234567890', 1) FROM SmallA WHERE SmallA.IntKey = 26"; //$NON-NLS-1$
+
+ MetadataFactory.helpTestVisitor(MetadataFactory.BQT_VDB,
+ input, output,
+ TRANSLATOR);
+ }
+
+ /**
+ * Test the translator's ability to rewrite the LOCATE() function in a form
+ * suitable for the data source.
+ * <p>
+ * <code>SELECT locate('c', 'chimp', 1) FROM BQT1.SMALLA</code>
+ *
+ * @throws Exception
+ */
+ @Test public void testLocate4() throws Exception {
+ String input = "SELECT locate('c', 'chimp', 1) FROM BQT1.SMALLA"; //$NON-NLS-1$
+ String output = "SELECT 1 FROM SmallA"; //$NON-NLS-1$
+
+ MetadataFactory.helpTestVisitor(MetadataFactory.BQT_VDB,
+ input, output,
+ TRANSLATOR);
+ }
+
+ /**
+ * Test the translator's ability to rewrite the LOCATE() function in a form
+ * suitable for the data source.
+ * <p>
+ * <code>SELECT locate(STRINGNUM, 'chimp', -5) FROM BQT1.SMALLA</code>
+ *
+ * @throws Exception
+ */
+ @Test public void testLocate5() throws Exception {
+ String input = "SELECT locate(STRINGNUM, 'chimp', -5) FROM BQT1.SMALLA"; //$NON-NLS-1$
+ String output = "SELECT LOCATE(SmallA.StringNum, 'chimp', 1) FROM SmallA"; //$NON-NLS-1$
+
+ MetadataFactory.helpTestVisitor(MetadataFactory.BQT_VDB,
+ input, output,
+ TRANSLATOR);
+ }
+
+ /**
+ * Test the translator's ability to rewrite the LOCATE() function in a form
+ * suitable for the data source.
+ * <p>
+ * <code>SELECT locate(STRINGNUM, 'chimp', INTNUM) FROM BQT1.SMALLA</code>
+ *
+ * @throws Exception
+ */
+ @Test public void testLocate6() throws Exception {
+ String input = "SELECT locate(STRINGNUM, 'chimp', INTNUM) FROM BQT1.SMALLA"; //$NON-NLS-1$
+ String output = "SELECT LOCATE(SmallA.StringNum, 'chimp', CASE WHEN SmallA.IntNum < 1 THEN 1 ELSE SmallA.IntNum END) FROM SmallA"; //$NON-NLS-1$
+
+ MetadataFactory.helpTestVisitor(MetadataFactory.BQT_VDB,
+ input, output,
+ TRANSLATOR);
+ }
+
+ /**
+ * Test the translator's ability to rewrite the LOCATE() function in a form
+ * suitable for the data source.
+ * <p>
+ * <code>SELECT locate(STRINGNUM, 'chimp', LOCATE(STRINGNUM, 'chimp') + 1) FROM BQT1.SMALLA</code>
+ *
+ * @throws Exception
+ */
+ @Test public void testLocate7() throws Exception {
+ String input = "SELECT locate(STRINGNUM, 'chimp', LOCATE(STRINGNUM, 'chimp') + 1) FROM BQT1.SMALLA"; //$NON-NLS-1$
+ String output = "SELECT LOCATE(SmallA.StringNum, 'chimp', CASE WHEN (LOCATE(SmallA.StringNum, 'chimp') + 1) < 1 THEN 1 ELSE (LOCATE(SmallA.StringNum, 'chimp') + 1) END) FROM SmallA"; //$NON-NLS-1$
+
+ MetadataFactory.helpTestVisitor(MetadataFactory.BQT_VDB,
+ input, output,
+ TRANSLATOR);
+ }
+
+}
Property changes on: trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/derby/TestDerbySQLTranslator.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/mysql/TestMySQLTranslator.java
===================================================================
--- trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/mysql/TestMySQLTranslator.java 2009-08-19 15:20:26 UTC (rev 1263)
+++ trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/mysql/TestMySQLTranslator.java 2009-08-19 19:50:56 UTC (rev 1264)
@@ -50,7 +50,7 @@
return MetadataFactory.BQT_VDB;
}
- @Test public void testRewriteConversion1() throws Exception {
+ @Test public void testConversion1() throws Exception {
String input = "SELECT char(convert(PART_WEIGHT, integer) + 100) FROM PARTS"; //$NON-NLS-1$
String output = "SELECT char((convert(PARTS.PART_WEIGHT, SIGNED INTEGER) + 100)) FROM PARTS"; //$NON-NLS-1$
@@ -59,7 +59,7 @@
output, TRANSLATOR);
}
- @Test public void testRewriteConversion2() throws Exception {
+ @Test public void testConversion2() throws Exception {
String input = "SELECT convert(PART_WEIGHT, long) FROM PARTS"; //$NON-NLS-1$
String output = "SELECT convert(PARTS.PART_WEIGHT, SIGNED) FROM PARTS"; //$NON-NLS-1$
@@ -68,7 +68,7 @@
output, TRANSLATOR);
}
- @Test public void testRewriteConversion3() throws Exception {
+ @Test public void testConversion3() throws Exception {
String input = "SELECT convert(convert(PART_WEIGHT, long), string) FROM PARTS"; //$NON-NLS-1$
String output = "SELECT convert(convert(PARTS.PART_WEIGHT, SIGNED), CHAR) FROM PARTS"; //$NON-NLS-1$
@@ -77,7 +77,7 @@
output, TRANSLATOR);
}
- @Test public void testRewriteConversion4() throws Exception {
+ @Test public void testConversion4() throws Exception {
String input = "SELECT convert(convert(PART_WEIGHT, date), string) FROM PARTS"; //$NON-NLS-1$
String output = "SELECT date_format(DATE(PARTS.PART_WEIGHT), '%Y-%m-%d') FROM PARTS"; //$NON-NLS-1$
@@ -85,7 +85,7 @@
input,
output, TRANSLATOR);
}
- @Test public void testRewriteConversion5() throws Exception {
+ @Test public void testConversion5() throws Exception {
String input = "SELECT convert(convert(PART_WEIGHT, time), string) FROM PARTS"; //$NON-NLS-1$
String output = "SELECT date_format(TIME(PARTS.PART_WEIGHT), '%H:%i:%S') FROM PARTS"; //$NON-NLS-1$
@@ -93,7 +93,7 @@
input,
output, TRANSLATOR);
}
- @Test public void testRewriteConversion6() throws Exception {
+ @Test public void testConversion6() throws Exception {
String input = "SELECT convert(convert(PART_WEIGHT, timestamp), string) FROM PARTS"; //$NON-NLS-1$
String output = "SELECT date_format(TIMESTAMP(PARTS.PART_WEIGHT), '%Y-%m-%d %H:%i:%S.%f') FROM PARTS"; //$NON-NLS-1$
@@ -101,7 +101,7 @@
input,
output, TRANSLATOR);
}
- @Test public void testRewriteConversion8() throws Exception {
+ @Test public void testConversion8() throws Exception {
String input = "SELECT ifnull(PART_WEIGHT, 'otherString') FROM PARTS"; //$NON-NLS-1$
String output = "SELECT ifnull(PARTS.PART_WEIGHT, 'otherString') FROM PARTS"; //$NON-NLS-1$
@@ -109,7 +109,7 @@
input,
output, TRANSLATOR);
}
- @Test public void testRewriteConversion7() throws Exception {
+ @Test public void testConversion7() throws Exception {
String input = "SELECT convert(convert(PART_WEIGHT, integer), string) FROM PARTS"; //$NON-NLS-1$
String output = "SELECT convert(convert(PARTS.PART_WEIGHT, SIGNED INTEGER), CHAR) FROM PARTS"; //$NON-NLS-1$
@@ -117,7 +117,7 @@
input,
output, TRANSLATOR);
}
- @Test public void testRewriteInsert() throws Exception {
+ @Test public void testInsert() throws Exception {
String input = "SELECT insert(PART_WEIGHT, 1, 5, 'chimp') FROM PARTS"; //$NON-NLS-1$
String output = "SELECT insert(PARTS.PART_WEIGHT, 1, 5, 'chimp') FROM PARTS"; //$NON-NLS-1$
@@ -125,15 +125,127 @@
input,
output, TRANSLATOR);
}
- @Test public void testRewriteLocate() throws Exception {
- String input = "SELECT locate(PART_WEIGHT, 'chimp', 1) FROM PARTS"; //$NON-NLS-1$
- String output = "SELECT locate(PARTS.PART_WEIGHT, 'chimp', 1) FROM PARTS"; //$NON-NLS-1$
- MetadataFactory.helpTestVisitor(getTestVDB(),
- input,
- output, TRANSLATOR);
+ /**
+ * Test the translator's ability to rewrite the LOCATE() function in a form
+ * suitable for the data source.
+ * <p>
+ * <code>SELECT locate(INTNUM, 'chimp', 1) FROM BQT1.SMALLA</code>
+ *
+ * @throws Exception
+ */
+ @Test public void testLocate() throws Exception {
+ String input = "SELECT locate(INTNUM, 'chimp', 1) FROM BQT1.SMALLA"; //$NON-NLS-1$
+ String output = "SELECT LOCATE(convert(SmallA.IntNum, CHAR), 'chimp', 1) FROM SmallA"; //$NON-NLS-1$
+
+ MetadataFactory.helpTestVisitor(MetadataFactory.BQT_VDB,
+ input, output,
+ TRANSLATOR);
+ }
+
+ /**
+ * Test the translator's ability to rewrite the LOCATE() function in a form
+ * suitable for the data source.
+ * <p>
+ * <code>SELECT locate(STRINGNUM, 'chimp') FROM BQT1.SMALLA</code>
+ *
+ * @throws Exception
+ */
+ @Test public void testLocate2() throws Exception {
+ String input = "SELECT locate(STRINGNUM, 'chimp') FROM BQT1.SMALLA"; //$NON-NLS-1$
+ String output = "SELECT LOCATE(SmallA.StringNum, 'chimp') FROM SmallA"; //$NON-NLS-1$
+
+ MetadataFactory.helpTestVisitor(MetadataFactory.BQT_VDB,
+ input, output,
+ TRANSLATOR);
+ }
+
+ /**
+ * Test the translator's ability to rewrite the LOCATE() function in a form
+ * suitable for the data source.
+ * <p>
+ * <code>SELECT locate(INTNUM, '234567890', 1) FROM BQT1.SMALLA WHERE INTKEY = 26</code>
+ *
+ * @throws Exception
+ */
+ @Test public void testLocate3() throws Exception {
+ String input = "SELECT locate(INTNUM, '234567890', 1) FROM BQT1.SMALLA WHERE INTKEY = 26"; //$NON-NLS-1$
+ String output = "SELECT LOCATE(convert(SmallA.IntNum, CHAR), '234567890', 1) FROM SmallA WHERE SmallA.IntKey = 26"; //$NON-NLS-1$
+
+ MetadataFactory.helpTestVisitor(MetadataFactory.BQT_VDB,
+ input, output,
+ TRANSLATOR);
+ }
+
+ /**
+ * Test the translator's ability to rewrite the LOCATE() function in a form
+ * suitable for the data source.
+ * <p>
+ * <code>SELECT locate('c', 'chimp', 1) FROM BQT1.SMALLA</code>
+ *
+ * @throws Exception
+ */
+ @Test public void testLocate4() throws Exception {
+ String input = "SELECT locate('c', 'chimp', 1) FROM BQT1.SMALLA"; //$NON-NLS-1$
+ String output = "SELECT 1 FROM SmallA"; //$NON-NLS-1$
+
+ MetadataFactory.helpTestVisitor(MetadataFactory.BQT_VDB,
+ input, output,
+ TRANSLATOR);
+ }
+
+ /**
+ * Test the translator's ability to rewrite the LOCATE() function in a form
+ * suitable for the data source.
+ * <p>
+ * <code>SELECT locate(STRINGNUM, 'chimp', -5) FROM BQT1.SMALLA</code>
+ *
+ * @throws Exception
+ */
+ @Test public void testLocate5() throws Exception {
+ String input = "SELECT locate(STRINGNUM, 'chimp', -5) FROM BQT1.SMALLA"; //$NON-NLS-1$
+ String output = "SELECT LOCATE(SmallA.StringNum, 'chimp', 1) FROM SmallA"; //$NON-NLS-1$
+
+ MetadataFactory.helpTestVisitor(MetadataFactory.BQT_VDB,
+ input, output,
+ TRANSLATOR);
}
- @Test public void testRewriteSubstring1() throws Exception {
+
+ /**
+ * Test the translator's ability to rewrite the LOCATE() function in a form
+ * suitable for the data source.
+ * <p>
+ * <code>SELECT locate(STRINGNUM, 'chimp', INTNUM) FROM BQT1.SMALLA</code>
+ *
+ * @throws Exception
+ */
+ @Test public void testLocate6() throws Exception {
+ String input = "SELECT locate(STRINGNUM, 'chimp', INTNUM) FROM BQT1.SMALLA"; //$NON-NLS-1$
+ String output = "SELECT LOCATE(SmallA.StringNum, 'chimp', CASE WHEN SmallA.IntNum < 1 THEN 1 ELSE SmallA.IntNum END) FROM SmallA"; //$NON-NLS-1$
+
+ MetadataFactory.helpTestVisitor(MetadataFactory.BQT_VDB,
+ input, output,
+ TRANSLATOR);
+ }
+
+ /**
+ * Test the translator's ability to rewrite the LOCATE() function in a form
+ * suitable for the data source.
+ * <p>
+ * <code>SELECT locate(STRINGNUM, 'chimp', LOCATE(STRINGNUM, 'chimp') + 1) FROM BQT1.SMALLA</code>
+ *
+ * @throws Exception
+ */
+ @Test public void testLocate7() throws Exception {
+ String input = "SELECT locate(STRINGNUM, 'chimp', LOCATE(STRINGNUM, 'chimp') + 1) FROM BQT1.SMALLA"; //$NON-NLS-1$
+ String output = "SELECT LOCATE(SmallA.StringNum, 'chimp', CASE WHEN (LOCATE(SmallA.StringNum, 'chimp') + 1) < 1 THEN 1 ELSE (LOCATE(SmallA.StringNum, 'chimp') + 1) END) FROM SmallA"; //$NON-NLS-1$
+
+ MetadataFactory.helpTestVisitor(MetadataFactory.BQT_VDB,
+ input, output,
+ TRANSLATOR);
+ }
+
+ @Test public void testSubstring1() throws Exception {
String input = "SELECT substring(PART_WEIGHT, 1) FROM PARTS"; //$NON-NLS-1$
String output = "SELECT substring(PARTS.PART_WEIGHT, 1) FROM PARTS"; //$NON-NLS-1$
@@ -141,7 +253,7 @@
input,
output, TRANSLATOR);
}
- @Test public void testRewriteSubstring2() throws Exception {
+ @Test public void testSubstring2() throws Exception {
String input = "SELECT substring(PART_WEIGHT, 1, 5) FROM PARTS"; //$NON-NLS-1$
String output = "SELECT substring(PARTS.PART_WEIGHT, 1, 5) FROM PARTS"; //$NON-NLS-1$
@@ -149,7 +261,7 @@
input,
output, TRANSLATOR);
}
- @Test public void testRewriteUnionWithOrderBy() throws Exception {
+ @Test public void testUnionWithOrderBy() throws Exception {
String input = "SELECT PART_ID FROM PARTS UNION SELECT PART_ID FROM PARTS ORDER BY PART_ID"; //$NON-NLS-1$
String output = "(SELECT PARTS.PART_ID FROM PARTS) UNION (SELECT PARTS.PART_ID FROM PARTS) ORDER BY PART_ID"; //$NON-NLS-1$
Deleted: trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/oracle/TestLocateFunctionModifier.java
===================================================================
--- trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/oracle/TestLocateFunctionModifier.java 2009-08-19 15:20:26 UTC (rev 1263)
+++ trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/oracle/TestLocateFunctionModifier.java 2009-08-19 19:50:56 UTC (rev 1264)
@@ -1,108 +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.connector.jdbc.oracle;
-
-import java.util.Arrays;
-import java.util.Properties;
-
-import org.teiid.connector.jdbc.oracle.LocateFunctionModifier;
-import org.teiid.connector.jdbc.oracle.OracleSQLTranslator;
-import org.teiid.connector.jdbc.translator.SQLConversionVisitor;
-import org.teiid.connector.language.IExpression;
-import org.teiid.connector.language.IFunction;
-import org.teiid.connector.language.ILanguageFactory;
-
-import junit.framework.TestCase;
-
-import com.metamatrix.cdk.CommandBuilder;
-import com.metamatrix.cdk.api.EnvironmentUtility;
-
-/**
- */
-public class TestLocateFunctionModifier extends TestCase {
-
- private static final ILanguageFactory LANG_FACTORY = CommandBuilder.getLanuageFactory();
-
- /**
- * Constructor for TestLocateFunctionModifier.
- * @param name
- */
- public TestLocateFunctionModifier(String name) {
- super(name);
- }
-
- public IExpression helpTestMod(IExpression[] args, String expectedStr) throws Exception {
- IFunction func = LANG_FACTORY.createFunction("hour", //$NON-NLS-1$
- Arrays.asList(args),
- Integer.class);
-
- LocateFunctionModifier mod = new LocateFunctionModifier(LANG_FACTORY);
- IExpression expr = mod.modify(func);
-
- OracleSQLTranslator trans = new OracleSQLTranslator();
- trans.initialize(EnvironmentUtility.createEnvironment(new Properties(), false));
-
- SQLConversionVisitor sqlVisitor = trans.getSQLConversionVisitor();
- sqlVisitor.append(expr);
-
- assertEquals(expectedStr, sqlVisitor.toString());
-
- return expr;
- }
-
- public void testTwoArgs() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(".", String.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral("a.b.c", String.class) //$NON-NLS-1$
- };
- helpTestMod(args, "instr('a.b.c', '.')"); //$NON-NLS-1$
- }
-
- public void testThreeArgsWithConstant() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(".", String.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral("a.b.c", String.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral(new Integer(2), Integer.class)
- };
- helpTestMod(args, "instr('a.b.c', '.', 3)"); //$NON-NLS-1$
- }
-
- public void testThreeArgsWithElement() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(".", String.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral("a.b.c", String.class), //$NON-NLS-1$
- LANG_FACTORY.createElement("e1", null, null, Integer.class) //$NON-NLS-1$
- };
- helpTestMod(args, "instr('a.b.c', '.', (e1 + 1))"); //$NON-NLS-1$
- }
-
- public void testThreeArgsWithNull() throws Exception {
- IExpression[] args = new IExpression[] {
- LANG_FACTORY.createLiteral(".", String.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral("a.b.c", String.class), //$NON-NLS-1$
- LANG_FACTORY.createLiteral(null, Integer.class)
- };
- helpTestMod(args, "instr('a.b.c', '.', NULL)"); //$NON-NLS-1$
- }
-
-}
Modified: trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/oracle/TestOracleTranslator.java
===================================================================
--- trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/oracle/TestOracleTranslator.java 2009-08-19 15:20:26 UTC (rev 1263)
+++ trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/oracle/TestOracleTranslator.java 2009-08-19 19:50:56 UTC (rev 1264)
@@ -28,7 +28,6 @@
import org.junit.AfterClass;
import org.junit.BeforeClass;
-import org.junit.Ignore;
import org.junit.Test;
import org.teiid.connector.api.ConnectorException;
import org.teiid.connector.jdbc.MetadataFactory;
@@ -183,34 +182,66 @@
input, output,
TRANSLATOR);
}
- @Ignore("TEIID-754: Fix Oracle translator so fromPosition of LOCATE function is used as is")
+
+ /**
+ * Test the translator's ability to rewrite the LOCATE() function in a form
+ * suitable for the data source.
+ * <p>
+ * <code>SELECT locate(INTNUM, 'chimp', 1) FROM BQT1.SMALLA</code>
+ *
+ * @throws Exception
+ */
@Test public void testLocate() throws Exception {
- // TODO TEIID-754: Fix Oracle translator so fromPosition of LOCATE function is used as is
String input = "SELECT locate(INTNUM, 'chimp', 1) FROM BQT1.SMALLA"; //$NON-NLS-1$
- String output = "SELECT instr('chimp', to_char(SmallA.IntNum), 1) FROM SmallA"; //$NON-NLS-1$
+ String output = "SELECT INSTR('chimp', to_char(SmallA.IntNum), 1) FROM SmallA"; //$NON-NLS-1$
MetadataFactory.helpTestVisitor(MetadataFactory.BQT_VDB,
input, output,
TRANSLATOR);
}
+
+ /**
+ * Test the translator's ability to rewrite the LOCATE() function in a form
+ * suitable for the data source.
+ * <p>
+ * <code>SELECT locate(STRINGNUM, 'chimp') FROM BQT1.SMALLA</code>
+ *
+ * @throws Exception
+ */
@Test public void testLocate2() throws Exception {
String input = "SELECT locate(STRINGNUM, 'chimp') FROM BQT1.SMALLA"; //$NON-NLS-1$
- String output = "SELECT instr('chimp', SmallA.StringNum) FROM SmallA"; //$NON-NLS-1$
+ String output = "SELECT INSTR('chimp', SmallA.StringNum) FROM SmallA"; //$NON-NLS-1$
MetadataFactory.helpTestVisitor(MetadataFactory.BQT_VDB,
input, output,
TRANSLATOR);
}
- @Ignore("TEIID-754: Fix Oracle translator so fromPosition of LOCATE function is used as is")
+
+ /**
+ * Test the translator's ability to rewrite the LOCATE() function in a form
+ * suitable for the data source.
+ * <p>
+ * <code>SELECT locate(INTNUM, '234567890', 1) FROM BQT1.SMALLA WHERE INTKEY = 26</code>
+ *
+ * @throws Exception
+ */
@Test public void testLocate3() throws Exception {
- // TODO TEIID-754: Fix Oracle translator so fromPosition of LOCATE function is used as is
String input = "SELECT locate(INTNUM, '234567890', 1) FROM BQT1.SMALLA WHERE INTKEY = 26"; //$NON-NLS-1$
- String output = "SELECT instr('234567890', to_char(SmallA.IntNum), 1) FROM SmallA WHERE SmallA.IntKey = 26"; //$NON-NLS-1$
+ String output = "SELECT INSTR('234567890', to_char(SmallA.IntNum), 1) FROM SmallA WHERE SmallA.IntKey = 26"; //$NON-NLS-1$
MetadataFactory.helpTestVisitor(MetadataFactory.BQT_VDB,
input, output,
TRANSLATOR);
}
+
+ /**
+ * Test the translator's ability to rewrite the LOCATE() function in a form
+ * suitable for the data source.
+ * <p>
+ * <code>SELECT locate('c', 'chimp', 1) FROM BQT1.SMALLA</code>
+ *
+ * @throws Exception
+ */
@Test public void testLocate4() throws Exception {
String input = "SELECT locate('c', 'chimp', 1) FROM BQT1.SMALLA"; //$NON-NLS-1$
String output = "SELECT 1 FROM SmallA"; //$NON-NLS-1$
@@ -219,16 +250,58 @@
input, output,
TRANSLATOR);
}
- @Ignore("TEIID-754: Fix Oracle translator so fromPosition of LOCATE function is 1 if a value of < 1 is given")
+
+ /**
+ * Test the translator's ability to rewrite the LOCATE() function in a form
+ * suitable for the data source.
+ * <p>
+ * <code>SELECT locate(STRINGNUM, 'chimp', -5) FROM BQT1.SMALLA</code>
+ *
+ * @throws Exception
+ */
@Test public void testLocate5() throws Exception {
- // TODO TEIID-754: Fix Oracle translator so fromPosition of LOCATE function is 1 if a value of < 1 is given
String input = "SELECT locate(STRINGNUM, 'chimp', -5) FROM BQT1.SMALLA"; //$NON-NLS-1$
- String output = "SELECT instr('chimp', SmallA.StringNum, 1) FROM SmallA"; //$NON-NLS-1$
+ String output = "SELECT INSTR('chimp', SmallA.StringNum, 1) FROM SmallA"; //$NON-NLS-1$
MetadataFactory.helpTestVisitor(MetadataFactory.BQT_VDB,
input, output,
TRANSLATOR);
}
+
+ /**
+ * Test the translator's ability to rewrite the LOCATE() function in a form
+ * suitable for the data source.
+ * <p>
+ * <code>SELECT locate(STRINGNUM, 'chimp', INTNUM) FROM BQT1.SMALLA</code>
+ *
+ * @throws Exception
+ */
+ @Test public void testLocate6() throws Exception {
+ String input = "SELECT locate(STRINGNUM, 'chimp', INTNUM) FROM BQT1.SMALLA"; //$NON-NLS-1$
+ String output = "SELECT INSTR('chimp', SmallA.StringNum, CASE WHEN SmallA.IntNum < 1 THEN 1 ELSE SmallA.IntNum END) FROM SmallA"; //$NON-NLS-1$
+
+ MetadataFactory.helpTestVisitor(MetadataFactory.BQT_VDB,
+ input, output,
+ TRANSLATOR);
+ }
+
+ /**
+ * Test the translator's ability to rewrite the LOCATE() function in a form
+ * suitable for the data source.
+ * <p>
+ * <code>SELECT locate(STRINGNUM, 'chimp', LOCATE(STRINGNUM, 'chimp') + 1) FROM BQT1.SMALLA</code>
+ *
+ * @throws Exception
+ */
+ @Test public void testLocate7() throws Exception {
+ String input = "SELECT locate(STRINGNUM, 'chimp', LOCATE(STRINGNUM, 'chimp') + 1) FROM BQT1.SMALLA"; //$NON-NLS-1$
+ String output = "SELECT INSTR('chimp', SmallA.StringNum, CASE WHEN (INSTR('chimp', SmallA.StringNum) + 1) < 1 THEN 1 ELSE (INSTR('chimp', SmallA.StringNum) + 1) END) FROM SmallA"; //$NON-NLS-1$
+
+ MetadataFactory.helpTestVisitor(MetadataFactory.BQT_VDB,
+ input, output,
+ TRANSLATOR);
+ }
+
@Test public void testSubstring1() throws Exception {
String input = "SELECT substring(StringNum, 1) FROM BQT1.SMALLA"; //$NON-NLS-1$
String output = "SELECT substr(SmallA.StringNum, 1) FROM SmallA"; //$NON-NLS-1$
Modified: trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/postgresql/TestPostgreSQLTranslator.java
===================================================================
--- trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/postgresql/TestPostgreSQLTranslator.java 2009-08-19 15:20:26 UTC (rev 1263)
+++ trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/postgresql/TestPostgreSQLTranslator.java 2009-08-19 19:50:56 UTC (rev 1264)
@@ -52,7 +52,7 @@
MetadataFactory.helpTestVisitor(vdb, input, expectedOutput, TRANSLATOR);
}
- @Test public void testRewriteConversion1() throws Exception {
+ @Test public void testConversion1() throws Exception {
String input = "SELECT char(convert(PART_WEIGHT, integer) + 100) FROM PARTS"; //$NON-NLS-1$
String output = "SELECT chr((cast(PARTS.PART_WEIGHT AS integer) + 100)) FROM PARTS"; //$NON-NLS-1$
@@ -61,7 +61,7 @@
output);
}
- @Test public void testRewriteConversion2() throws Exception {
+ @Test public void testConversion2() throws Exception {
String input = "SELECT convert(PART_WEIGHT, long) FROM PARTS"; //$NON-NLS-1$
String output = "SELECT cast(PARTS.PART_WEIGHT AS bigint) FROM PARTS"; //$NON-NLS-1$
@@ -70,7 +70,7 @@
output);
}
- @Test public void testRewriteConversion3() throws Exception {
+ @Test public void testConversion3() throws Exception {
String input = "SELECT convert(PART_WEIGHT, short) FROM PARTS"; //$NON-NLS-1$
String output = "SELECT cast(PARTS.PART_WEIGHT AS smallint) FROM PARTS"; //$NON-NLS-1$
@@ -79,7 +79,7 @@
output);
}
- @Test public void testRewriteConversion4() throws Exception {
+ @Test public void testConversion4() throws Exception {
String input = "SELECT convert(PART_WEIGHT, float) FROM PARTS"; //$NON-NLS-1$
String output = "SELECT cast(PARTS.PART_WEIGHT AS real) FROM PARTS"; //$NON-NLS-1$
@@ -87,7 +87,7 @@
input,
output);
}
- @Test public void testRewriteConversion5() throws Exception {
+ @Test public void testConversion5() throws Exception {
String input = "SELECT convert(PART_WEIGHT, double) FROM PARTS"; //$NON-NLS-1$
String output = "SELECT cast(PARTS.PART_WEIGHT AS float8) FROM PARTS"; //$NON-NLS-1$
@@ -95,7 +95,7 @@
input,
output);
}
- @Test public void testRewriteConversion6() throws Exception {
+ @Test public void testConversion6() throws Exception {
String input = "SELECT convert(PART_WEIGHT, biginteger) FROM PARTS"; //$NON-NLS-1$
String output = "SELECT cast(PARTS.PART_WEIGHT AS numeric) FROM PARTS"; //$NON-NLS-1$
@@ -103,7 +103,7 @@
input,
output);
}
- @Test public void testRewriteConversion7() throws Exception {
+ @Test public void testConversion7() throws Exception {
String input = "SELECT convert(PART_WEIGHT, bigdecimal) FROM PARTS"; //$NON-NLS-1$
String output = "SELECT cast(PARTS.PART_WEIGHT AS decimal) FROM PARTS"; //$NON-NLS-1$
@@ -111,7 +111,7 @@
input,
output);
}
- @Test public void testRewriteConversion8() throws Exception {
+ @Test public void testConversion8() throws Exception {
String input = "SELECT convert(PART_WEIGHT, boolean) FROM PARTS"; //$NON-NLS-1$
String output = "SELECT cast(PARTS.PART_WEIGHT AS boolean) FROM PARTS"; //$NON-NLS-1$
@@ -119,7 +119,7 @@
input,
output);
}
- @Test public void testRewriteConversion9() throws Exception {
+ @Test public void testConversion9() throws Exception {
String input = "SELECT convert(PART_WEIGHT, date) FROM PARTS"; //$NON-NLS-1$
String output = "SELECT to_date(PARTS.PART_WEIGHT, 'YYYY-MM-DD') FROM PARTS"; //$NON-NLS-1$
@@ -127,7 +127,7 @@
input,
output);
}
- @Test public void testRewriteConversion10() throws Exception {
+ @Test public void testConversion10() throws Exception {
String input = "SELECT convert(PART_WEIGHT, time) FROM PARTS"; //$NON-NLS-1$
String output = "SELECT to_timestamp(('1970-01-01 ' || PARTS.PART_WEIGHT), 'YYYY-MM-DD HH24:MI:SS') FROM PARTS"; //$NON-NLS-1$
@@ -135,7 +135,7 @@
input,
output);
}
- @Test public void testRewriteConversion11() throws Exception {
+ @Test public void testConversion11() throws Exception {
String input = "SELECT convert(PART_WEIGHT, timestamp) FROM PARTS"; //$NON-NLS-1$
String output = "SELECT to_timestamp(PARTS.PART_WEIGHT, 'YYYY-MM-DD HH24:MI:SS.UF') FROM PARTS"; //$NON-NLS-1$
@@ -143,7 +143,7 @@
input,
output);
}
- @Test public void testRewriteConversion12() throws Exception {
+ @Test public void testConversion12() throws Exception {
String input = "SELECT convert(convert(PART_WEIGHT, time), string) FROM PARTS"; //$NON-NLS-1$
String output = "SELECT to_char(to_timestamp(('1970-01-01 ' || PARTS.PART_WEIGHT), 'YYYY-MM-DD HH24:MI:SS'), 'HH24:MI:SS') FROM PARTS"; //$NON-NLS-1$
@@ -151,7 +151,7 @@
input,
output);
}
- @Test public void testRewriteConversion13() throws Exception {
+ @Test public void testConversion13() throws Exception {
String input = "SELECT convert(convert(PART_WEIGHT, timestamp), string) FROM PARTS"; //$NON-NLS-1$
String output = "SELECT to_char(to_timestamp(PARTS.PART_WEIGHT, 'YYYY-MM-DD HH24:MI:SS.UF'), 'YYYY-MM-DD HH24:MI:SS.US') FROM PARTS"; //$NON-NLS-1$
@@ -159,7 +159,7 @@
input,
output);
}
- @Test public void testRewriteConversion14() throws Exception {
+ @Test public void testConversion14() throws Exception {
String input = "SELECT convert(convert(PART_WEIGHT, date), string) FROM PARTS"; //$NON-NLS-1$
String output = "SELECT to_char(to_date(PARTS.PART_WEIGHT, 'YYYY-MM-DD'), 'YYYY-MM-DD') FROM PARTS"; //$NON-NLS-1$
@@ -167,7 +167,7 @@
input,
output);
}
- @Test public void testRewriteConversion15() throws Exception {
+ @Test public void testConversion15() throws Exception {
String input = "SELECT convert(convert(PART_WEIGHT, timestamp), date) FROM PARTS"; //$NON-NLS-1$
String output = "SELECT cast(to_timestamp(PARTS.PART_WEIGHT, 'YYYY-MM-DD HH24:MI:SS.UF') AS date) FROM PARTS"; //$NON-NLS-1$
@@ -175,7 +175,7 @@
input,
output);
}
- @Test public void testRewriteConversion16() throws Exception {
+ @Test public void testConversion16() throws Exception {
String input = "SELECT convert(convert(PART_WEIGHT, timestamp), time) FROM PARTS"; //$NON-NLS-1$
String output = "SELECT cast(to_timestamp(PARTS.PART_WEIGHT, 'YYYY-MM-DD HH24:MI:SS.UF') AS time) FROM PARTS"; //$NON-NLS-1$
@@ -183,7 +183,7 @@
input,
output);
}
- @Test public void testRewriteConversion17() throws Exception {
+ @Test public void testConversion17() throws Exception {
String input = "SELECT convert(convert(PART_WEIGHT, time), timestamp) FROM PARTS"; //$NON-NLS-1$
String output = "SELECT to_timestamp(to_char(to_timestamp(('1970-01-01 ' || PARTS.PART_WEIGHT), 'YYYY-MM-DD HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS') FROM PARTS"; //$NON-NLS-1$
@@ -191,7 +191,7 @@
input,
output);
}
- @Test public void testRewriteConversion18() throws Exception {
+ @Test public void testConversion18() throws Exception {
String input = "SELECT convert(convert(PART_WEIGHT, date), timestamp) FROM PARTS"; //$NON-NLS-1$
String output = "SELECT to_timestamp(to_char(to_date(PARTS.PART_WEIGHT, 'YYYY-MM-DD'), 'YYYY-MM-DD HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS') FROM PARTS"; //$NON-NLS-1$
@@ -199,7 +199,7 @@
input,
output);
}
- @Test public void testRewriteConversion19() throws Exception {
+ @Test public void testConversion19() throws Exception {
String input = "SELECT convert(convert(PART_WEIGHT, boolean), string) FROM PARTS"; //$NON-NLS-1$
String output = "SELECT CASE WHEN cast(PARTS.PART_WEIGHT AS boolean) = TRUE THEN '1' ELSE '0' END FROM PARTS"; //$NON-NLS-1$
@@ -208,7 +208,7 @@
output);
}
- @Test public void testRewriteLog() throws Exception {
+ @Test public void testLog() throws Exception {
String input = "SELECT log(convert(PART_WEIGHT, double)) FROM PARTS"; //$NON-NLS-1$
String output = "SELECT ln(cast(PARTS.PART_WEIGHT AS float8)) FROM PARTS"; //$NON-NLS-1$
@@ -223,7 +223,7 @@
output);
}
- @Test public void testRewriteLeft() throws Exception {
+ @Test public void testLeft() throws Exception {
String input = "SELECT left(PART_WEIGHT, 2) FROM PARTS"; //$NON-NLS-1$
String output = "SELECT SUBSTR(PARTS.PART_WEIGHT, 1, 2) FROM PARTS"; //$NON-NLS-1$
@@ -231,7 +231,7 @@
input,
output);
}
- @Test public void testRewriteRight() throws Exception {
+ @Test public void testRight() throws Exception {
String input = "SELECT right(PART_WEIGHT, 2) FROM PARTS"; //$NON-NLS-1$
String output = "SELECT SUBSTR(PARTS.PART_WEIGHT, (-1 * 2)) FROM PARTS"; //$NON-NLS-1$
@@ -394,13 +394,123 @@
output);
}
+ /**
+ * Test the translator's ability to rewrite the LOCATE() function in a form
+ * suitable for the data source.
+ * <p>
+ * <code>SELECT locate(INTNUM, 'chimp', 1) FROM BQT1.SMALLA</code>
+ *
+ * @throws Exception
+ */
@Test public void testLocate() throws Exception {
- String input = "select locate('a', stringkey), locate('b', stringkey, 2) from bqt1.smalla"; //$NON-NLS-1$
- String output = "SELECT position('a' in SmallA.StringKey), position('b' in substr(SmallA.StringKey, 2)) FROM SmallA"; //$NON-NLS-1$
-
- helpTestVisitor(getTestBQTVDB(),
- input,
- output);
+ String input = "SELECT locate(INTNUM, 'chimp', 1) FROM BQT1.SMALLA"; //$NON-NLS-1$
+ String output = "SELECT position(cast(SmallA.IntNum AS varchar) in substr('chimp', 1)) FROM SmallA"; //$NON-NLS-1$
+
+ MetadataFactory.helpTestVisitor(MetadataFactory.BQT_VDB,
+ input, output,
+ TRANSLATOR);
}
+
+ /**
+ * Test the translator's ability to rewrite the LOCATE() function in a form
+ * suitable for the data source.
+ * <p>
+ * <code>SELECT locate(STRINGNUM, 'chimp') FROM BQT1.SMALLA</code>
+ *
+ * @throws Exception
+ */
+ @Test public void testLocate2() throws Exception {
+ String input = "SELECT locate(STRINGNUM, 'chimp') FROM BQT1.SMALLA"; //$NON-NLS-1$
+ String output = "SELECT position(SmallA.StringNum in 'chimp') FROM SmallA"; //$NON-NLS-1$
+
+ MetadataFactory.helpTestVisitor(MetadataFactory.BQT_VDB,
+ input, output,
+ TRANSLATOR);
+ }
+
+ /**
+ * Test the translator's ability to rewrite the LOCATE() function in a form
+ * suitable for the data source.
+ * <p>
+ * <code>SELECT locate(INTNUM, '234567890', 1) FROM BQT1.SMALLA WHERE INTKEY = 26</code>
+ *
+ * @throws Exception
+ */
+ @Test public void testLocate3() throws Exception {
+ String input = "SELECT locate(INTNUM, '234567890', 1) FROM BQT1.SMALLA WHERE INTKEY = 26"; //$NON-NLS-1$
+ String output = "SELECT position(cast(SmallA.IntNum AS varchar) in substr('234567890', 1)) FROM SmallA WHERE SmallA.IntKey = 26"; //$NON-NLS-1$
+
+ MetadataFactory.helpTestVisitor(MetadataFactory.BQT_VDB,
+ input, output,
+ TRANSLATOR);
+ }
+
+ /**
+ * Test the translator's ability to rewrite the LOCATE() function in a form
+ * suitable for the data source.
+ * <p>
+ * <code>SELECT locate('c', 'chimp', 1) FROM BQT1.SMALLA</code>
+ *
+ * @throws Exception
+ */
+ @Test public void testLocate4() throws Exception {
+ String input = "SELECT locate('c', 'chimp', 1) FROM BQT1.SMALLA"; //$NON-NLS-1$
+ String output = "SELECT 1 FROM SmallA"; //$NON-NLS-1$
+
+ MetadataFactory.helpTestVisitor(MetadataFactory.BQT_VDB,
+ input, output,
+ TRANSLATOR);
+ }
+
+ /**
+ * Test the translator's ability to rewrite the LOCATE() function in a form
+ * suitable for the data source.
+ * <p>
+ * <code>SELECT locate(STRINGNUM, 'chimp', -5) FROM BQT1.SMALLA</code>
+ *
+ * @throws Exception
+ */
+ @Test public void testLocate5() throws Exception {
+ String input = "SELECT locate(STRINGNUM, 'chimp', -5) FROM BQT1.SMALLA"; //$NON-NLS-1$
+ String output = "SELECT position(SmallA.StringNum in substr('chimp', 1)) FROM SmallA"; //$NON-NLS-1$
+
+ MetadataFactory.helpTestVisitor(MetadataFactory.BQT_VDB,
+ input, output,
+ TRANSLATOR);
+ }
+
+ /**
+ * Test the translator's ability to rewrite the LOCATE() function in a form
+ * suitable for the data source.
+ * <p>
+ * <code>SELECT locate(STRINGNUM, 'chimp', INTNUM) FROM BQT1.SMALLA</code>
+ *
+ * @throws Exception
+ */
+ @Test public void testLocate6() throws Exception {
+ String input = "SELECT locate(STRINGNUM, 'chimp', INTNUM) FROM BQT1.SMALLA"; //$NON-NLS-1$
+ String output = "SELECT position(SmallA.StringNum in substr('chimp', CASE WHEN SmallA.IntNum < 1 THEN 1 ELSE SmallA.IntNum END)) FROM SmallA"; //$NON-NLS-1$
+
+ MetadataFactory.helpTestVisitor(MetadataFactory.BQT_VDB,
+ input, output,
+ TRANSLATOR);
+ }
+
+ /**
+ * Test the translator's ability to rewrite the LOCATE() function in a form
+ * suitable for the data source.
+ * <p>
+ * <code>SELECT locate(STRINGNUM, 'chimp', LOCATE(STRINGNUM, 'chimp') + 1) FROM BQT1.SMALLA</code>
+ *
+ * @throws Exception
+ */
+ @Test public void testLocate7() throws Exception {
+ String input = "SELECT locate(STRINGNUM, 'chimp', LOCATE(STRINGNUM, 'chimp') + 1) FROM BQT1.SMALLA"; //$NON-NLS-1$
+ String output = "SELECT position(SmallA.StringNum in substr('chimp', CASE WHEN (position(SmallA.StringNum in 'chimp') + 1) < 1 THEN 1 ELSE (position(SmallA.StringNum in 'chimp') + 1) END)) FROM SmallA"; //$NON-NLS-1$
+
+ MetadataFactory.helpTestVisitor(MetadataFactory.BQT_VDB,
+ input, output,
+ TRANSLATOR);
+ }
}
Added: trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/translator/TestLOCATEFunctionModifier.java
===================================================================
--- trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/translator/TestLOCATEFunctionModifier.java (rev 0)
+++ trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/translator/TestLOCATEFunctionModifier.java 2009-08-19 19:50:56 UTC (rev 1264)
@@ -0,0 +1,413 @@
+/*
+ * 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.connector.jdbc.translator;
+
+import static org.junit.Assert.*;
+
+import java.util.Arrays;
+import java.util.Properties;
+
+import org.junit.Test;
+import org.teiid.connector.api.ConnectorEnvironment;
+import org.teiid.connector.api.ConnectorException;
+import org.teiid.connector.api.SourceSystemFunctions;
+import org.teiid.connector.jdbc.translator.LOCATEFunctionModifier.ParameterOrder;
+import org.teiid.connector.language.IExpression;
+import org.teiid.connector.language.IFunction;
+import org.teiid.connector.language.ILanguageFactory;
+import org.teiid.connector.language.ILiteral;
+
+import com.metamatrix.cdk.CommandBuilder;
+import com.metamatrix.cdk.api.EnvironmentUtility;
+
+/**
+ * Test <code>LOCATEFunctionModifier</code> by invoking its methods with varying
+ * parameters to validate it performs as designed and expected.
+ */
+public class TestLOCATEFunctionModifier {
+
+ private static final ILanguageFactory LANG_FACTORY = CommandBuilder.getLanuageFactory();
+
+ /**
+ * Create an expression containing a LOCATE function using <code>args</code>
+ * and pass it to the <code>Translator</code>'s LOCATE function modifier and
+ * compare the resulting expression to <code>expectedStr</code>.
+ *
+ * @param args An array of <code>IExpression</code>'s to use as the
+ * arguments to the LOCATE() function
+ * @param expectedStr A string representing the modified expression
+ * @return On success, the modified expression.
+ * @throws Exception
+ */
+ public IExpression helpTestLocate(IExpression[] args, String expectedStr) throws Exception {
+ return this.helpTestLocate(null, null, args, expectedStr);
+ }
+
+ /**
+ * Create an expression containing a LOCATE function using a function name of
+ * <code>locateFunctionName</code> with the parameter order of
+ * <code>parameterOrder</code> and a string index base of
+ * <code>stringIndexBase</code> and uses the arguments <code>args</code> and
+ * pass it to the <code>Translator</code>'s LOCATE function modifier and
+ * compare the resulting expression to <code>expectedStr</code>.
+ *
+ * @param locateFunctionName the name to use for the function modifier
+ * @param parameterOrder an <code>enum</code> value as defined by
+ * {@link ParameterOrder} which represents the parameter order to use
+ * for the modified LOCATE() function
+ * @param stringIndexBase the string index that represents the first character of a string
+ * @param args an array of <code>IExpression</code>'s to use as the
+ * arguments to the LOCATE() function
+ * @param expectedStr A string representing the modified expression
+ * @return On success, the modified expression.
+ * @throws Exception
+ */
+ public IExpression helpTestLocate(final String locateFunctionName, final ParameterOrder parameterOrder, IExpression[] args, String expectedStr) throws Exception {
+ IExpression param1 = null;
+ IExpression param2 = null;
+ IExpression param3 = null;
+
+ if (args.length > 0 ) param1 = args[0];
+ if (args.length > 1 ) param2 = args[1];
+ if (args.length > 2 ) param3 = args[2];
+
+ IFunction func = null;
+
+ if (param3 != null) {
+ func = LANG_FACTORY.createFunction(SourceSystemFunctions.LOCATE,
+ Arrays.asList(param1, param2, param3), Integer.class);
+ } else {
+ func = LANG_FACTORY.createFunction(SourceSystemFunctions.LOCATE,
+ Arrays.asList(param1, param2), Integer.class);
+ }
+
+ Translator trans = new Translator() {
+ @Override
+ public void initialize(ConnectorEnvironment env)
+ throws ConnectorException {
+ super.initialize(env);
+ registerFunctionModifier(SourceSystemFunctions.LOCATE, new LOCATEFunctionModifier(getLanguageFactory(), locateFunctionName, parameterOrder));
+ }
+ };
+
+ trans.initialize(EnvironmentUtility.createEnvironment(new Properties(), false));
+
+ IExpression expr = trans.getFunctionModifiers().get(SourceSystemFunctions.LOCATE).modify(func);
+
+ SQLConversionVisitor sqlVisitor = trans.getSQLConversionVisitor();
+ sqlVisitor.append(expr);
+
+ assertEquals("Modified function does not match", expectedStr, sqlVisitor.toString()); //$NON-NLS-1$
+
+ return expr;
+ }
+
+ /**
+ * Test {@link LOCATEFunctionModifier#modify(IFunction)} to validate a call
+ * to LOCATE(search_str, source_str) using constants for both parameters
+ * returns LOCATE(search_str, source_str).
+ * <p>
+ * {@link LOCATEFunctionModifier} will be constructed without specifying a
+ * function name or parameter order.
+ *
+ * @throws Exception
+ */
+ @Test public void testModifySimple() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral("a", String.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral("abcdefg", String.class) //$NON-NLS-1$
+ };
+ // default / default
+ helpTestLocate(args, "LOCATE('a', 'abcdefg')"); //$NON-NLS-1$
+ }
+
+ /**
+ * Test {@link LOCATEFunctionModifier#modify(IFunction)} to validate a call
+ * to LOCATE(search_str, source_str) using constants for both parameters
+ * returns locate(search_str, source_str).
+ * <p>
+ * {@link LOCATEFunctionModifier} will be constructed specifying a function
+ * name of locate but no parameter order.
+ *
+ * @throws Exception
+ */
+ @Test public void testModifySimple2() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral("a", String.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral("abcdefg", String.class) //$NON-NLS-1$
+ };
+ // locate / default
+ helpTestLocate("locate", null, args, "locate('a', 'abcdefg')"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link LOCATEFunctionModifier#modify(IFunction)} to validate a call
+ * to LOCATE(search_str, source_str) using constants for both parameters
+ * returns INSTR(source_str, search_str).
+ * <p>
+ * {@link LOCATEFunctionModifier} will be constructed specifying a function
+ * name of INSTR and a parameter order of {@link ParameterOrder#SOURCE_SEARCH_INDEX}.
+ *
+ * @throws Exception
+ */
+ @Test public void testModifySimple3() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral("a", String.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral("abcdefg", String.class) //$NON-NLS-1$
+ };
+ // INSTR / SOURCE_SEARCH_INDEX
+ helpTestLocate("INSTR", ParameterOrder.SOURCE_SEARCH_INDEX, args, "INSTR('abcdefg', 'a')"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link LOCATEFunctionModifier#modify(IFunction)} to validate a call
+ * to LOCATE(search_str, source_str) using constants for both parameters
+ * returns locate(search_str, source_str).
+ * <p>
+ * {@link LOCATEFunctionModifier} will be constructed specifying a function
+ * name of locate and a parameter order of {@link ParameterOrder#DEFAULT}.
+ *
+ * @throws Exception
+ */
+ @Test public void testModifySimple4() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral("a", String.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral("abcdefg", String.class) //$NON-NLS-1$
+ };
+ // locate / DEFAULT
+ helpTestLocate("locate", ParameterOrder.DEFAULT, args, "locate('a', 'abcdefg')"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link LOCATEFunctionModifier#modify(IFunction)} to validate a call
+ * to LOCATE(search_str, source_str, 1) using constants for all parameters
+ * returns INSTR(source_str, search_str, 1).
+ * <p>
+ * {@link LOCATEFunctionModifier} will be constructed specifying a function
+ * name of INSTR and a parameter order of {@link ParameterOrder#SOURCE_SEARCH_INDEX}.
+ *
+ * @throws Exception
+ */
+ @Test public void testModifyWithStartIndex() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral("a", String.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral("abcdefg", String.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral(1, Integer.class)
+ };
+ // INSTR / SOURCE_SEARCH_INDEX
+ helpTestLocate("INSTR", ParameterOrder.SOURCE_SEARCH_INDEX, args, "INSTR('abcdefg', 'a', 1)"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link LOCATEFunctionModifier#modify(IFunction)} to validate a call
+ * to LOCATE(search_str, source_str, 4) using constants for all parameters
+ * returns LOCATE(search_str, source_str, 5).
+ * <p>
+ * {@link LOCATEFunctionModifier} will be constructed specifying no function
+ * name or parameter order.
+ *
+ * @throws Exception
+ */
+ @Test public void testModifyWithStartIndex2() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral("a", String.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral("abcdefg", String.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral(4, Integer.class)
+ };
+ // default / default
+ helpTestLocate(null, null, args, "LOCATE('a', 'abcdefg', 4)"); //$NON-NLS-1$
+ }
+
+ /**
+ * Test {@link LOCATEFunctionModifier#modify(IFunction)} to validate a call
+ * to LOCATE(search_str, source_str, -5) using constants for all parameters
+ * returns LOCATE(search_str, source_str, 1).
+ * <p>
+ * {@link LOCATEFunctionModifier} will be constructed specifying no function
+ * name or parameter order.
+ *
+ * @throws Exception
+ */
+ @Test public void testModifyWithStartIndex3() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral("a", String.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral("abcdefg", String.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral(-5, Integer.class)
+ };
+ // default / default
+ helpTestLocate(null, null, args, "LOCATE('a', 'abcdefg', 1)"); //$NON-NLS-1$
+ }
+
+ /**
+ * Test {@link LOCATEFunctionModifier#modify(IFunction)} to validate a call
+ * to LOCATE(search_str, source_str, null) using constants for all parameters
+ * returns LOCATE(search_str, source_str, NULL).
+ * <p>
+ * {@link LOCATEFunctionModifier} will be constructed specifying no function
+ * name or parameter order.
+ *
+ * @throws Exception
+ */
+ @Test public void testModifyWithStartIndex4() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral("a", String.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral("abcdefg", String.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral(null, Integer.class)
+ };
+ // default / default
+ helpTestLocate(null, null, args, "LOCATE('a', 'abcdefg', NULL)"); //$NON-NLS-1$
+ }
+
+ /**
+ * Test {@link LOCATEFunctionModifier#modify(IFunction)} to validate a call
+ * to LOCATE(search_str, source_str, e1) using an element for start index
+ * parameter returns INSTR(source_str, search_str, CASE WHEN e1 < 1 THEN 1 ELSE e1 END).
+ * <p>
+ * {@link LOCATEFunctionModifier} will be constructed specifying a function
+ * name of INSTR and a parameter order of {@link ParameterOrder#SOURCE_SEARCH_INDEX}.
+ *
+ * @throws Exception
+ */
+ @Test public void testModifyWithElementStartIndex() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral("a", String.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral("abcdefg", String.class), //$NON-NLS-1$
+ LANG_FACTORY.createElement("e1", null, null, Integer.class) //$NON-NLS-1$
+ };
+ // INSTR / SOURCE_SEARCH_INDEX
+ helpTestLocate("INSTR", ParameterOrder.SOURCE_SEARCH_INDEX, args, "INSTR('abcdefg', 'a', CASE WHEN e1 < 1 THEN 1 ELSE e1 END)"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test {@link LOCATEFunctionModifier#modify(IFunction)} to validate a call
+ * to LOCATE(search_str, source_str, e1) using an element for start index
+ * parameter returns LOCATE(search_str, source_str, CASE WHEN e1 < 0 THEN 0 ELSE e1 END).
+ * <p>
+ * {@link LOCATEFunctionModifier} will be constructed specifying no function
+ * name and no parameter order.
+ *
+ * @throws Exception
+ */
+ @Test public void testModifyWithElementStartIndex2() throws Exception {
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral("a", String.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral("abcdefg", String.class), //$NON-NLS-1$
+ LANG_FACTORY.createElement("e1", null, null, Integer.class) //$NON-NLS-1$
+ };
+ // default / default
+ helpTestLocate(null, null, args, "LOCATE('a', 'abcdefg', CASE WHEN e1 < 1 THEN 1 ELSE e1 END)"); //$NON-NLS-1$
+ }
+
+ /**
+ * Test {@link LOCATEFunctionModifier#modify(IFunction)} to validate a call
+ * to LOCATE(search_str, source_str, e1) using an element for start index
+ * parameter returns LOCATE(search_str, source_str, e1).
+ * <p>
+ * {@link LOCATEFunctionModifier} will be constructed specifying no function
+ * name, no parameter order, and no string index base. The test explicitly
+ * overrides {@link LOCATEFunctionModifier#getStartIndexExpression(IExpression)}
+ * to produce output that does not use the searched case expression for the
+ * element.
+ *
+ * @throws Exception
+ */
+ @Test public void testOverrideGetStartIndexExpression() throws Exception {
+ final String expectedStr = "LOCATE('a', 'abcdefg', e1)"; //$NON-NLS-1$
+
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral("a", String.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral("abcdefg", String.class), //$NON-NLS-1$
+ LANG_FACTORY.createElement("e1", null, null, Integer.class) //$NON-NLS-1$
+ };
+ IFunction func = LANG_FACTORY.createFunction(SourceSystemFunctions.LOCATE, args, Integer.class);
+
+ final Translator trans = new Translator() {
+ @Override
+ public void initialize(ConnectorEnvironment env)
+ throws ConnectorException {
+ super.initialize(env);
+ registerFunctionModifier(SourceSystemFunctions.LOCATE, new LOCATEFunctionModifier(getLanguageFactory(), null, null) {
+ @Override
+ protected IExpression getStartIndexExpression(
+ IExpression startIndex) {
+ return startIndex;
+ }
+
+ });
+ }
+ };
+
+ trans.initialize(EnvironmentUtility.createEnvironment(new Properties(), false));
+
+ IExpression expr = trans.getFunctionModifiers().get(SourceSystemFunctions.LOCATE).modify(func);
+ SQLConversionVisitor sqlVisitor = trans.getSQLConversionVisitor();
+ sqlVisitor.append(expr);
+ assertEquals("Modified function does not match", expectedStr, sqlVisitor.toString()); //$NON-NLS-1$
+ }
+
+ /**
+ * Test {@link LOCATEFunctionModifier#modify(IFunction)} to validate a call
+ * to LOCATE(search_str, source_str, 1) using a literal for start index
+ * parameter returns LOCATE(search_str, source_str, (1 + 1)).
+ * <p>
+ * {@link LOCATEFunctionModifier} will be constructed specifying no function
+ * name, no parameter order. The test explicitly overrides {@link LOCATEFunctionModifier#getStartIndexExpression(ILiteral)}
+ * to produce output that adds <code>1</code> to the literal.
+ *
+ * @throws Exception
+ */
+ @Test public void testOverrideGetStartIndexExpression2() throws Exception {
+ final String expectedStr = "LOCATE('a', 'abcdefg', (1 + 1))"; //$NON-NLS-1$
+
+ IExpression[] args = new IExpression[] {
+ LANG_FACTORY.createLiteral("a", String.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral("abcdefg", String.class), //$NON-NLS-1$
+ LANG_FACTORY.createLiteral(1, Integer.class)
+ };
+ IFunction func = LANG_FACTORY.createFunction(SourceSystemFunctions.LOCATE, args, Integer.class);
+
+ final Translator trans = new Translator() {
+ @Override
+ public void initialize(ConnectorEnvironment env)
+ throws ConnectorException {
+ super.initialize(env);
+ registerFunctionModifier(SourceSystemFunctions.LOCATE, new LOCATEFunctionModifier(getLanguageFactory(), null, null) {
+ @Override
+ protected IExpression getStartIndexExpression(
+ ILiteral startIndex) {
+ return LANG_FACTORY.createFunction("+", Arrays.asList(startIndex, LANG_FACTORY.createLiteral(1, Integer.class)), Integer.class); //$NON-NLS-1$
+ }
+
+ });
+ }
+ };
+
+ trans.initialize(EnvironmentUtility.createEnvironment(new Properties(), false));
+
+ IExpression expr = trans.getFunctionModifiers().get(SourceSystemFunctions.LOCATE).modify(func);
+ SQLConversionVisitor sqlVisitor = trans.getSQLConversionVisitor();
+ sqlVisitor.append(expr);
+ assertEquals("Modified function does not match", expectedStr, sqlVisitor.toString()); //$NON-NLS-1$
+ }
+
+}
Property changes on: trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/translator/TestLOCATEFunctionModifier.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
16 years, 1 month
teiid SVN: r1263 - trunk/client/src/main/java/com/metamatrix/common/comm/platform/client.
by teiid-commits@lists.jboss.org
Author: rareddy
Date: 2009-08-19 11:20:26 -0400 (Wed, 19 Aug 2009)
New Revision: 1263
Modified:
trunk/client/src/main/java/com/metamatrix/common/comm/platform/client/ServerAdminFactory.java
Log:
TEIID-793: making the call to connection at the time "getAdmin" is called, such that any identy assertion is done during scope of the "getAdmin" call.
Modified: trunk/client/src/main/java/com/metamatrix/common/comm/platform/client/ServerAdminFactory.java
===================================================================
--- trunk/client/src/main/java/com/metamatrix/common/comm/platform/client/ServerAdminFactory.java 2009-08-18 19:37:24 UTC (rev 1262)
+++ trunk/client/src/main/java/com/metamatrix/common/comm/platform/client/ServerAdminFactory.java 2009-08-19 15:20:26 UTC (rev 1263)
@@ -60,8 +60,9 @@
private Properties p;
private boolean closed;
- public ReconnectingProxy(Properties p) {
+ public ReconnectingProxy(Properties p) throws ConnectionException, CommunicationException {
this.p = p;
+ this.registry = serverConnectionFactory.createConnection(p);
}
private synchronized Admin getTarget() throws AdminComponentException, CommunicationException {
@@ -214,14 +215,20 @@
return createAdmin(p);
}
- public Admin createAdmin(Properties p) {
+ public Admin createAdmin(Properties p) throws AdminException {
p = PropertiesUtils.clone(p);
p.remove(MMURL.JDBC.VDB_NAME);
p.remove(MMURL.JDBC.VDB_VERSION);
p.setProperty(MMURL.CONNECTION.AUTO_FAILOVER, Boolean.TRUE.toString());
- Admin serverAdmin = (Admin)Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[] { Admin.class }, new ReconnectingProxy(p));
- return serverAdmin;
+ try {
+ Admin serverAdmin = (Admin)Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[] { Admin.class }, new ReconnectingProxy(p));
+ return serverAdmin;
+ } catch (ConnectionException e) {
+ throw new AdminComponentException(e.getMessage());
+ } catch (CommunicationException e) {
+ throw new AdminComponentException(e.getMessage());
+ }
}
}
16 years, 1 month
teiid SVN: r1262 - in trunk/connectors/connector-jdbc/src: main/resources/org/teiid/connector/jdbc and 1 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2009-08-18 15:37:24 -0400 (Tue, 18 Aug 2009)
New Revision: 1262
Modified:
trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/oracle/OracleSQLTranslator.java
trunk/connectors/connector-jdbc/src/main/resources/org/teiid/connector/jdbc/i18n.properties
trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/oracle/TestOracleTranslator.java
Log:
TEIID-787 after consulting with John Doyle, removing special spatial logic from the oracle connector
Modified: trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/oracle/OracleSQLTranslator.java
===================================================================
--- trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/oracle/OracleSQLTranslator.java 2009-08-18 16:09:14 UTC (rev 1261)
+++ trunk/connectors/connector-jdbc/src/main/java/org/teiid/connector/jdbc/oracle/OracleSQLTranslator.java 2009-08-18 19:37:24 UTC (rev 1262)
@@ -39,13 +39,11 @@
import org.teiid.connector.api.ConnectorException;
import org.teiid.connector.api.ExecutionContext;
import org.teiid.connector.api.SourceSystemFunctions;
-import org.teiid.connector.api.TypeFacility;
import org.teiid.connector.jdbc.JDBCPlugin;
import org.teiid.connector.jdbc.translator.AliasModifier;
import org.teiid.connector.jdbc.translator.ExtractFunctionModifier;
import org.teiid.connector.jdbc.translator.Translator;
import org.teiid.connector.language.ICommand;
-import org.teiid.connector.language.ICriteria;
import org.teiid.connector.language.IElement;
import org.teiid.connector.language.IFunction;
import org.teiid.connector.language.IGroup;
@@ -54,16 +52,12 @@
import org.teiid.connector.language.ILimit;
import org.teiid.connector.language.IQuery;
import org.teiid.connector.language.IQueryCommand;
-import org.teiid.connector.language.ISelect;
import org.teiid.connector.language.ISelectSymbol;
import org.teiid.connector.language.ISetQuery.Operation;
import org.teiid.connector.metadata.runtime.Element;
import org.teiid.connector.visitor.util.CollectorVisitor;
import org.teiid.connector.visitor.util.SQLReservedWords;
-
-/**
- */
public class OracleSQLTranslator extends Translator {
/*
@@ -115,37 +109,6 @@
@Override
public ICommand modifyCommand(ICommand command, ExecutionContext context) throws ConnectorException {
- if (command instanceof IQuery) {
- IQuery query = (IQuery)command;
-
- ISelect select = ((IQuery)command).getSelect();
- List<ISelectSymbol> symbols = select.getSelectSymbols();
-
- Collection<IFunction> functions = CollectorVisitor.collectObjects(IFunction.class, select);
- for (IFunction function : functions) {
- if (function.getName().equalsIgnoreCase("SDO_NN_DISTANCE")) {//$NON-NLS-1$
- ICriteria criteria = query.getWhere();
- if(criteria == null || criteria.toString().indexOf("SDO_NN") == -1){ //$NON-NLS-1$
- throw(new ConnectorException(
- JDBCPlugin.Util.getString("OracleSpatialSQLTranslator.SDO_NN_DEPENDENCY_ERROR"))); //$NON-NLS-1$
- }
- break;
- }
- }
-
- for (int i = 0; i < symbols.size(); i++) {
- ISelectSymbol symbol = symbols.get(i);
- if (symbol.getExpression().getType().equals(Object.class)) {
- String outName = symbol.getOutputName();
- int lIndx = outName.lastIndexOf("."); //$NON-NLS-1$
- symbol.setOutputName(outName.substring(lIndx + 1));
- symbol.setExpression(getLanguageFactory().createLiteral(null, TypeFacility.RUNTIME_TYPES.OBJECT));
- symbol.setAlias(true);
- }
- }
- return query;
- }
-
if (!(command instanceof IInsert)) {
return command;
}
@@ -294,16 +257,13 @@
// query.
// Right now, we look through all functions passed in the query
// (returned as a collection)
- // Then we check if any of those functions contain the strings 'sdo' and
- // 'relate'
+ // Then we check if any of those functions are sdo_relate
// If so, the ORDERED hint is added, if not, it isn't
Collection<IFunction> col = CollectorVisitor.collectObjects(IFunction.class, command);
for (IFunction func : col) {
- String funcName = func.getName().toUpperCase();
- int indx1 = funcName.indexOf("SDO"); //$NON-NLS-1$
- int indx2 = funcName.indexOf("RELATE"); //$NON-NLS-1$
- if (indx1 >= 0 && indx2 > indx1)
+ if (func.getName().equalsIgnoreCase(RELATE)) {
return comment + "/*+ ORDERED */ "; //$NON-NLS-1$
+ }
}
}
return comment;
Modified: trunk/connectors/connector-jdbc/src/main/resources/org/teiid/connector/jdbc/i18n.properties
===================================================================
--- trunk/connectors/connector-jdbc/src/main/resources/org/teiid/connector/jdbc/i18n.properties 2009-08-18 16:09:14 UTC (rev 1261)
+++ trunk/connectors/connector-jdbc/src/main/resources/org/teiid/connector/jdbc/i18n.properties 2009-08-18 19:37:24 UTC (rev 1262)
@@ -73,5 +73,3 @@
BasicResultsTranslator.Couldn__t_parse_property=Could not parse property: {0}
JDBCMetadataProcessor.cannot_find_primary=Cannot find primary key table {0}
-
-OracleSpatialSQLTranslator.SDO_NN_DEPENDENCY_ERROR=The SDO_NN_DISTANCE operator can only be used in conjunction with the SDO_NN operator.
Modified: trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/oracle/TestOracleTranslator.java
===================================================================
--- trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/oracle/TestOracleTranslator.java 2009-08-18 16:09:14 UTC (rev 1261)
+++ trunk/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/oracle/TestOracleTranslator.java 2009-08-18 19:37:24 UTC (rev 1262)
@@ -116,7 +116,7 @@
output, TRANSLATOR);
}
- @Test public void testRewriteConversion1() throws Exception {
+ @Test public void testConversion1() throws Exception {
String input = "SELECT char(convert(STRINGNUM, integer) + 100) FROM BQT1.SMALLA"; //$NON-NLS-1$
String output = "SELECT chr((to_number(SmallA.StringNum) + 100)) FROM SmallA"; //$NON-NLS-1$
@@ -125,7 +125,7 @@
TRANSLATOR);
}
- @Test public void testRewriteConversion2() throws Exception {
+ @Test public void testConversion2() throws Exception {
String input = "SELECT convert(STRINGNUM, long) FROM BQT1.SMALLA"; //$NON-NLS-1$
String output = "SELECT to_number(SmallA.StringNum) FROM SmallA"; //$NON-NLS-1$
@@ -134,7 +134,7 @@
TRANSLATOR);
}
- @Test public void testRewriteConversion3() throws Exception {
+ @Test public void testConversion3() throws Exception {
String input = "SELECT convert(convert(STRINGNUM, long), string) FROM BQT1.SMALLA"; //$NON-NLS-1$
String output = "SELECT to_char(to_number(SmallA.StringNum)) FROM SmallA"; //$NON-NLS-1$
@@ -143,7 +143,7 @@
TRANSLATOR);
}
- @Test public void testRewriteConversion4() throws Exception {
+ @Test public void testConversion4() throws Exception {
String input = "SELECT convert(convert(TIMESTAMPVALUE, date), string) FROM BQT1.SMALLA"; //$NON-NLS-1$
String output = "SELECT to_char(trunc(SmallA.TimestampValue), 'YYYY-MM-DD') FROM SmallA"; //$NON-NLS-1$
@@ -151,7 +151,7 @@
input, output,
TRANSLATOR);
}
- @Test public void testRewriteConversion5() throws Exception {
+ @Test public void testConversion5() throws Exception {
String input = "SELECT convert(convert(TIMESTAMPVALUE, time), string) FROM BQT1.SMALLA"; //$NON-NLS-1$
String output = "SELECT to_char(to_date(('1970-01-01 ' || to_char(SmallA.TimestampValue, 'HH24:MI:SS')), 'YYYY-MM-DD HH24:MI:SS'), 'HH24:MI:SS') FROM SmallA"; //$NON-NLS-1$
@@ -159,7 +159,7 @@
input, output,
TRANSLATOR);
}
- @Test public void testRewriteConversion6() throws Exception {
+ @Test public void testConversion6() throws Exception {
String input = "SELECT convert(convert(TIMEVALUE, timestamp), string) FROM BQT1.SMALLA"; //$NON-NLS-1$
String output = "SELECT to_char(cast(SmallA.TimeValue AS timestamp), 'YYYY-MM-DD HH24:MI:SS.FF') FROM SmallA"; //$NON-NLS-1$
@@ -167,7 +167,7 @@
input, output,
TRANSLATOR);
}
- @Test public void testRewriteConversion8() throws Exception {
+ @Test public void testConversion8() throws Exception {
String input = "SELECT nvl(INTNUM, 'otherString') FROM BQT1.SMALLA"; //$NON-NLS-1$
String output = "SELECT nvl(to_char(SmallA.IntNum), 'otherString') FROM SmallA"; //$NON-NLS-1$
@@ -175,7 +175,7 @@
input, output,
TRANSLATOR);
}
- @Test public void testRewriteConversion7() throws Exception {
+ @Test public void testConversion7() throws Exception {
String input = "SELECT convert(convert(STRINGNUM, integer), string) FROM BQT1.SMALLA"; //$NON-NLS-1$
String output = "SELECT to_char(to_number(SmallA.StringNum)) FROM SmallA"; //$NON-NLS-1$
@@ -184,7 +184,7 @@
TRANSLATOR);
}
@Ignore("TEIID-754: Fix Oracle translator so fromPosition of LOCATE function is used as is")
- @Test public void testRewriteLocate() throws Exception {
+ @Test public void testLocate() throws Exception {
// TODO TEIID-754: Fix Oracle translator so fromPosition of LOCATE function is used as is
String input = "SELECT locate(INTNUM, 'chimp', 1) FROM BQT1.SMALLA"; //$NON-NLS-1$
String output = "SELECT instr('chimp', to_char(SmallA.IntNum), 1) FROM SmallA"; //$NON-NLS-1$
@@ -193,7 +193,7 @@
input, output,
TRANSLATOR);
}
- @Test public void testRewriteLocate2() throws Exception {
+ @Test public void testLocate2() throws Exception {
String input = "SELECT locate(STRINGNUM, 'chimp') FROM BQT1.SMALLA"; //$NON-NLS-1$
String output = "SELECT instr('chimp', SmallA.StringNum) FROM SmallA"; //$NON-NLS-1$
@@ -202,7 +202,7 @@
TRANSLATOR);
}
@Ignore("TEIID-754: Fix Oracle translator so fromPosition of LOCATE function is used as is")
- @Test public void testRewriteLocate3() throws Exception {
+ @Test public void testLocate3() throws Exception {
// TODO TEIID-754: Fix Oracle translator so fromPosition of LOCATE function is used as is
String input = "SELECT locate(INTNUM, '234567890', 1) FROM BQT1.SMALLA WHERE INTKEY = 26"; //$NON-NLS-1$
String output = "SELECT instr('234567890', to_char(SmallA.IntNum), 1) FROM SmallA WHERE SmallA.IntKey = 26"; //$NON-NLS-1$
@@ -211,7 +211,7 @@
input, output,
TRANSLATOR);
}
- @Test public void testRewriteLocate4() throws Exception {
+ @Test public void testLocate4() throws Exception {
String input = "SELECT locate('c', 'chimp', 1) FROM BQT1.SMALLA"; //$NON-NLS-1$
String output = "SELECT 1 FROM SmallA"; //$NON-NLS-1$
@@ -220,7 +220,7 @@
TRANSLATOR);
}
@Ignore("TEIID-754: Fix Oracle translator so fromPosition of LOCATE function is 1 if a value of < 1 is given")
- @Test public void testRewriteLocate5() throws Exception {
+ @Test public void testLocate5() throws Exception {
// TODO TEIID-754: Fix Oracle translator so fromPosition of LOCATE function is 1 if a value of < 1 is given
String input = "SELECT locate(STRINGNUM, 'chimp', -5) FROM BQT1.SMALLA"; //$NON-NLS-1$
String output = "SELECT instr('chimp', SmallA.StringNum, 1) FROM SmallA"; //$NON-NLS-1$
@@ -229,7 +229,7 @@
input, output,
TRANSLATOR);
}
- @Test public void testRewriteSubstring1() throws Exception {
+ @Test public void testSubstring1() throws Exception {
String input = "SELECT substring(StringNum, 1) FROM BQT1.SMALLA"; //$NON-NLS-1$
String output = "SELECT substr(SmallA.StringNum, 1) FROM SmallA"; //$NON-NLS-1$
@@ -237,7 +237,7 @@
input, output,
TRANSLATOR);
}
- @Test public void testRewriteSubstring2() throws Exception {
+ @Test public void testSubstring2() throws Exception {
String input = "SELECT substring(StringNum, 1, 1) FROM BQT1.SMALLA"; //$NON-NLS-1$
String output = "SELECT substr(SmallA.StringNum, 1, 1) FROM SmallA"; //$NON-NLS-1$
@@ -245,7 +245,7 @@
input, output,
TRANSLATOR);
}
- @Test public void testRewriteUnionWithOrderBy() throws Exception {
+ @Test public void testUnionWithOrderBy() throws Exception {
String input = "SELECT IntKey FROM BQT1.SMALLA UNION SELECT IntKey FROM BQT1.SMALLB ORDER BY IntKey"; //$NON-NLS-1$
String output = "SELECT SmallA.IntKey FROM SmallA UNION SELECT SmallB.IntKey FROM SmallB ORDER BY IntKey NULLS FIRST"; //$NON-NLS-1$
@@ -317,7 +317,7 @@
*
* @throws Exception
*/
- @Test public void testRewrite_sdo_relate() throws Exception {
+ @Test public void test_sdo_relate() throws Exception {
String input = "SELECT a.INTKEY FROM BQT1.SMALLA A, BQT1.SMALLB B WHERE sdo_relate(A.OBJECTVALUE, b.OBJECTVALUE, 'mask=ANYINTERACT') = true"; //$NON-NLS-1$
String output = "SELECT /*+ ORDERED */ A.IntKey FROM SmallA A, SmallB B WHERE sdo_relate(A.ObjectValue, B.ObjectValue, 'mask=ANYINTERACT') = 'true'"; //$NON-NLS-1$
@@ -333,7 +333,7 @@
*
* @throws Exception
*/
- @Test public void testRewrite_sdo_within_distance() throws Exception {
+ @Test public void test_sdo_within_distance() throws Exception {
String input = "SELECT INTKEY FROM BQT1.SMALLA WHERE sdo_within_distance(OBJECTVALUE, 'SDO_GEOMETRY(2001, 8307, MDSYS.SDO_POINT_TYPE(90.0, -45.0, NULL), NULL, NULL)', 'DISTANCE=25.0 UNIT=NAUT_MILE') = true"; //$NON-NLS-1$
String output = "SELECT SmallA.IntKey FROM SmallA WHERE sdo_within_distance(SmallA.ObjectValue, SDO_GEOMETRY(2001, 8307, MDSYS.SDO_POINT_TYPE(90.0, -45.0, NULL), NULL, NULL), 'DISTANCE=25.0 UNIT=NAUT_MILE') = 'true'"; //$NON-NLS-1$
@@ -349,7 +349,7 @@
*
* @throws Exception
*/
- @Test public void testRewrite_sdo_within_distance2() throws Exception {
+ @Test public void test_sdo_within_distance2() throws Exception {
String input = "SELECT INTKEY FROM BQT1.SMALLA WHERE sdo_within_distance('SDO_GEOMETRY(2001, 8307, MDSYS.SDO_POINT_TYPE(90.0, -45.0, NULL), NULL, NULL)', OBJECTVALUE, 'DISTANCE=25.0 UNIT=NAUT_MILE') = true"; //$NON-NLS-1$
String output = "SELECT SmallA.IntKey FROM SmallA WHERE sdo_within_distance(SDO_GEOMETRY(2001, 8307, MDSYS.SDO_POINT_TYPE(90.0, -45.0, NULL), NULL, NULL), SmallA.ObjectValue, 'DISTANCE=25.0 UNIT=NAUT_MILE') = 'true'"; //$NON-NLS-1$
@@ -365,9 +365,9 @@
*
* @throws Exception
*/
- @Test public void testRewrite_sdo_within_distance3() throws Exception {
+ @Test public void test_sdo_within_distance3() throws Exception {
String input = "SELECT INTKEY FROM BQT1.SMALLA WHERE sdo_within_distance(STRINGKEY, 'SDO_GEOMETRY(2001, 8307, MDSYS.SDO_POINT_TYPE(90.0, -45.0, NULL), NULL, NULL)', 'DISTANCE=25.0 UNIT=NAUT_MILE') = true"; //$NON-NLS-1$
- // using ? for bind value as rewriter marks the criteria as bindEligible
+ // using ? for bind value as r marks the criteria as bindEligible
// due to literal of type Object appearing in left side of criteria.
// The literal Object is a result of the sdo_within_distance function
// signature being sdo_within_distance(string, object, string) : string
@@ -386,9 +386,9 @@
*
* @throws Exception
*/
- @Test public void testRewrite_sdo_within_distance4() throws Exception {
+ @Test public void test_sdo_within_distance4() throws Exception {
String input = "SELECT INTKEY FROM BQT1.SMALLA WHERE sdo_within_distance('SDO_GEOMETRY(2001, 8307, MDSYS.SDO_POINT_TYPE(90.0, -45.0, NULL), NULL, NULL)', 'SDO_GEOMETRY(2001, 8307, MDSYS.SDO_POINT_TYPE(90.0, -45.0, NULL), NULL, NULL)', 'DISTANCE=25.0 UNIT=NAUT_MILE') = true"; //$NON-NLS-1$
- // using ? for bind value as rewriter marks the criteria as bindEligible
+ // using ? for bind value as r marks the criteria as bindEligible
// due to literal of type Object appearing in left side of criteria.
// The literal Object is a result of the sdo_within_distance function
// signature being sdo_within_distance(string, object, string) : string
@@ -407,7 +407,7 @@
*
* @throws Exception
*/
- @Test public void testRewrite_sdo_within_distance5() throws Exception {
+ @Test public void test_sdo_within_distance5() throws Exception {
String input = "SELECT a.INTKEY FROM BQT1.SMALLA A, BQT1.SMALLB B WHERE sdo_within_distance(a.OBJECTVALUE, b.OBJECTVALUE, 'DISTANCE=25.0 UNIT=NAUT_MILE') = true"; //$NON-NLS-1$
String output = "SELECT A.IntKey FROM SmallA A, SmallB B WHERE sdo_within_distance(A.ObjectValue, B.ObjectValue, 'DISTANCE=25.0 UNIT=NAUT_MILE') = 'true'"; //$NON-NLS-1$
16 years, 1 month
teiid SVN: r1261 - in trunk/build: kit-runtime/deploy and 1 other directory.
by teiid-commits@lists.jboss.org
Author: rareddy
Date: 2009-08-18 12:09:14 -0400 (Tue, 18 Aug 2009)
New Revision: 1261
Modified:
trunk/build/kit-adminshell/adminshell.sh
trunk/build/kit-runtime/deploy/admin-roles.properties
Log:
minor spelling corrections
Modified: trunk/build/kit-adminshell/adminshell.sh
===================================================================
--- trunk/build/kit-adminshell/adminshell.sh 2009-08-18 16:05:21 UTC (rev 1260)
+++ trunk/build/kit-adminshell/adminshell.sh 2009-08-18 16:09:14 UTC (rev 1261)
@@ -68,15 +68,15 @@
JAVA_OPTS="$JAVA_OPTS -Djava.util.logging.config.file=log.properties"
# Print the env settings
-echo "========================================================================="
+echo "======================================================================"
echo ""
-echo " Teiid AdminSehll Bootstrap Environment"
+echo " Teiid AdminShell Bootstrap Environment"
echo ""
-echo " TEIID_HOME = $TEIID_HOME"
-echo " CLASSPATH = $TEIID_CLASSPATH"
-echo " JAVA = $JAVA"
+echo " TEIID_HOME = $TEIID_HOME"
+echo " CLASSPATH = $TEIID_CLASSPATH"
+echo " JAVA = $JAVA"
echo ""
-echo "========================================================================="
+echo "======================================================================"
echo ""
$JAVA $JAVA_OPTS -cp $TEIID_CLASSPATH -Xmx256m org.teiid.AdminShell $*
\ No newline at end of file
Modified: trunk/build/kit-runtime/deploy/admin-roles.properties
===================================================================
--- trunk/build/kit-runtime/deploy/admin-roles.properties 2009-08-18 16:05:21 UTC (rev 1260)
+++ trunk/build/kit-runtime/deploy/admin-roles.properties 2009-08-18 16:09:14 UTC (rev 1261)
@@ -3,8 +3,8 @@
# function calls into the system. The following format needs to be used
# define the permissions
-# role1 = groupA, groupB
-# role2 = groupB, groupC
+# role1 = groupA,groupB
+# role2 = groupB,groupC
# for group names check your membership provider configuration.
16 years, 1 month
teiid SVN: r1260 - trunk/test-integration/src/test/java/com/metamatrix/server/integration.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2009-08-18 12:05:21 -0400 (Tue, 18 Aug 2009)
New Revision: 1260
Modified:
trunk/test-integration/src/test/java/com/metamatrix/server/integration/TestAdminApi.java
Log:
TEIID-791 adding a test of getProcesses
Modified: trunk/test-integration/src/test/java/com/metamatrix/server/integration/TestAdminApi.java
===================================================================
--- trunk/test-integration/src/test/java/com/metamatrix/server/integration/TestAdminApi.java 2009-08-18 16:04:21 UTC (rev 1259)
+++ trunk/test-integration/src/test/java/com/metamatrix/server/integration/TestAdminApi.java 2009-08-18 16:05:21 UTC (rev 1260)
@@ -1,3 +1,25 @@
+/*
+ * 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 com.metamatrix.server.integration;
import java.sql.Connection;
16 years, 1 month
teiid SVN: r1259 - trunk/test-integration/src/test/java/com/metamatrix/server/integration.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2009-08-18 12:04:21 -0400 (Tue, 18 Aug 2009)
New Revision: 1259
Added:
trunk/test-integration/src/test/java/com/metamatrix/server/integration/TestAdminApi.java
Log:
TEIID-791 adding a test of getProcesses
Added: trunk/test-integration/src/test/java/com/metamatrix/server/integration/TestAdminApi.java
===================================================================
--- trunk/test-integration/src/test/java/com/metamatrix/server/integration/TestAdminApi.java (rev 0)
+++ trunk/test-integration/src/test/java/com/metamatrix/server/integration/TestAdminApi.java 2009-08-18 16:04:21 UTC (rev 1259)
@@ -0,0 +1,29 @@
+package com.metamatrix.server.integration;
+
+import java.sql.Connection;
+import java.util.Collection;
+
+import org.junit.Test;
+import org.teiid.adminapi.Admin;
+import org.teiid.adminapi.ProcessObject;
+
+import static org.junit.Assert.*;
+
+import com.metamatrix.core.util.UnitTestUtil;
+import com.metamatrix.jdbc.MMConnection;
+import com.metamatrix.jdbc.api.AbstractMMQueryTestCase;
+
+public class TestAdminApi extends AbstractMMQueryTestCase {
+
+ private static final String DQP_PROP_FILE = UnitTestUtil.getTestDataPath() + "/authcheck/bqt.properties;"; //$NON-NLS-1$
+ private static final String VDB = "bqt"; //$NON-NLS-1$
+
+ @Test public void testGetProcess() throws Exception {
+ Connection conn = getConnection(VDB, DQP_PROP_FILE, "user=admin;password=teiid;"); //$NON-NLS-1$
+ Admin admin = ((MMConnection)conn).getAdminAPI();
+ Collection<ProcessObject> processes = admin.getProcesses("*"); //$NON-NLS-1$
+ assertEquals(1, processes.size());
+ assertNotNull(processes.iterator().next().getInetAddress());
+ }
+
+}
Property changes on: trunk/test-integration/src/test/java/com/metamatrix/server/integration/TestAdminApi.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
16 years, 1 month
teiid SVN: r1258 - trunk/runtime/src/main/java/com/metamatrix/jdbc.
by teiid-commits@lists.jboss.org
Author: rareddy
Date: 2009-08-18 11:43:14 -0400 (Tue, 18 Aug 2009)
New Revision: 1258
Modified:
trunk/runtime/src/main/java/com/metamatrix/jdbc/EmbeddedConnectionFactoryImpl.java
Log:
TEIID-791
Modified: trunk/runtime/src/main/java/com/metamatrix/jdbc/EmbeddedConnectionFactoryImpl.java
===================================================================
--- trunk/runtime/src/main/java/com/metamatrix/jdbc/EmbeddedConnectionFactoryImpl.java 2009-08-18 15:08:24 UTC (rev 1257)
+++ trunk/runtime/src/main/java/com/metamatrix/jdbc/EmbeddedConnectionFactoryImpl.java 2009-08-18 15:43:14 UTC (rev 1258)
@@ -379,7 +379,7 @@
Properties props = getProperties();
- String hostName = ((InetAddress)props.get(DQPEmbeddedProperties.HOST_ADDRESS)).getHostName();
+ String hostName = getAddress().getHostName();
String processName = props.getProperty(DQPEmbeddedProperties.PROCESSNAME);
String[] identifierParts = new String[] {hostName, processName};
@@ -389,7 +389,7 @@
process.setEnabled(true);
process.setCreated(new Date(getStartTime()));
- process.setInetAddress((InetAddress)props.get(DQPEmbeddedProperties.HOST_ADDRESS));
+ process.setInetAddress(getAddress());
process.setFreeMemory(rt.freeMemory());
process.setTotalMemory(rt.totalMemory());
process.setProperties(PropertiesUtils.clone(props));
16 years, 1 month