teiid SVN: r2905 - in trunk/engine/src: test/java/org/teiid/query/metadata and 1 other directory.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-02-14 15:12:15 -0500 (Mon, 14 Feb 2011)
New Revision: 2905
Modified:
trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java
trunk/engine/src/test/java/org/teiid/query/metadata/TestTransformationMetadata.java
Log:
TEIID-1467 fix for procedure visibility issue
Modified: trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java 2011-02-14 01:30:06 UTC (rev 2904)
+++ trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java 2011-02-14 20:12:15 UTC (rev 2905)
@@ -352,7 +352,7 @@
for (StoredProcedureInfo storedProcedureInfo : results) {
Schema schema = (Schema)storedProcedureInfo.getModelID();
- if(vdbMetaData == null || vdbMetaData.isVisible(schema.getName())){
+ if(fullyQualifiedProcedureName.equalsIgnoreCase(storedProcedureInfo.getProcedureCallableName()) || vdbMetaData == null || vdbMetaData.isVisible(schema.getName())){
if (result != null) {
throw new QueryMetadataException(QueryPlugin.Util.getString("ambiguous_procedure", fullyQualifiedProcedureName)); //$NON-NLS-1$
}
@@ -743,6 +743,10 @@
return vdbMetaData.getVersion();
}
+ public VDBMetaData getVdbMetaData() {
+ return vdbMetaData;
+ }
+
/**
* @see org.teiid.query.metadata.QueryMetadataInterface#getXMLTempGroups(java.lang.Object)
*/
Modified: trunk/engine/src/test/java/org/teiid/query/metadata/TestTransformationMetadata.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/metadata/TestTransformationMetadata.java 2011-02-14 01:30:06 UTC (rev 2904)
+++ trunk/engine/src/test/java/org/teiid/query/metadata/TestTransformationMetadata.java 2011-02-14 20:12:15 UTC (rev 2905)
@@ -61,6 +61,16 @@
assertEquals("Procedure 'y' is ambiguous, use the fully qualified name instead", e.getMessage()); //$NON-NLS-1$
}
}
+
+ @Test public void testProcVisibility() throws Exception {
+ TransformationMetadata tm = exampleTransformationMetadata();
+ VDBMetaData vdb = tm.getVdbMetaData();
+ vdb.getModel("x").setVisible(false);
+ StoredProcedureInfo spi = tm.getStoredProcedureInfoForProcedure("y"); //$NON-NLS-1$
+ assertEquals("x1.y", spi.getProcedureCallableName());
+ spi = tm.getStoredProcedureInfoForProcedure("x.y"); //$NON-NLS-1$
+ assertEquals("x.y", spi.getProcedureCallableName());
+ }
private TransformationMetadata exampleTransformationMetadata()
throws TranslatorException {
13 years, 10 months
teiid SVN: r2904 - in trunk: common-core/src/main/java/org/teiid/core/util and 5 other directories.
by teiid-commits@lists.jboss.org
Author: rareddy
Date: 2011-02-13 20:30:06 -0500 (Sun, 13 Feb 2011)
New Revision: 2904
Modified:
trunk/build/kits/jboss-container/deploy/teiid/teiid-jboss-beans.xml
trunk/common-core/src/main/java/org/teiid/core/util/ObjectConverterUtil.java
trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPConfiguration.java
trunk/jboss-integration/src/main/java/org/teiid/jboss/deployers/RuntimeEngineDeployer.java
trunk/runtime/src/main/java/org/teiid/odbc/ODBCClientRemote.java
trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemote.java
trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemoteImpl.java
trunk/runtime/src/main/java/org/teiid/transport/ODBCSocketListener.java
trunk/runtime/src/main/java/org/teiid/transport/PgBackendProtocol.java
trunk/runtime/src/main/java/org/teiid/transport/PgFrontendProtocol.java
trunk/runtime/src/main/resources/org/teiid/runtime/i18n.properties
Log:
TEIID-1163: Adding lob support for ODBC using postges 'bytea' data type. This data type does not support streaming.
Modified: trunk/build/kits/jboss-container/deploy/teiid/teiid-jboss-beans.xml
===================================================================
--- trunk/build/kits/jboss-container/deploy/teiid/teiid-jboss-beans.xml 2011-02-10 19:56:37 UTC (rev 2903)
+++ trunk/build/kits/jboss-container/deploy/teiid/teiid-jboss-beans.xml 2011-02-14 01:30:06 UTC (rev 2904)
@@ -110,6 +110,8 @@
<property name="maxSourceRows">-1</property>
<!-- Indicates if an exception should be thrown if the specified value for Maximum Source Rows is exceeded; only up to the maximum rows will be consumed. -->
<property name="exceptionOnMaxSourceRows">true</property>
+ <!-- Maximum size of lob allowed through ODBC connection in bytes (default 5MB) -->
+ <property name="maxODBCLobSizeAllowed">5242880</property>
</bean>
<!-- JDBC Socket connection properties (SSL see below) -->
Modified: trunk/common-core/src/main/java/org/teiid/core/util/ObjectConverterUtil.java
===================================================================
--- trunk/common-core/src/main/java/org/teiid/core/util/ObjectConverterUtil.java 2011-02-10 19:56:37 UTC (rev 2903)
+++ trunk/common-core/src/main/java/org/teiid/core/util/ObjectConverterUtil.java 2011-02-14 01:30:06 UTC (rev 2904)
@@ -90,16 +90,32 @@
* @throws IOException if a problem occurred reading the stream.
*/
public static byte[] convertToByteArray(final InputStream is, int length) throws IOException {
+ return convertToByteArray(is, length, true);
+ }
+
+ public static byte[] convertToByteArray(final InputStream is, int length, boolean close) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
- write(out, is, length);
- return out.toByteArray();
+ write(out, is, length, close);
+ out.close();
+ return out.toByteArray();
}
+
+ public static int write(final OutputStream out, final InputStream is, byte[] l_buffer, int length) throws IOException {
+ return write(out, is, l_buffer, length, true);
+ }
- public static int write(final OutputStream out, final InputStream is, byte[] l_buffer, int length) throws IOException {
+ public static int write(final OutputStream out, final InputStream is, byte[] l_buffer, int length, boolean close) throws IOException {
int writen = 0;
try {
int l_nbytes = 0; // Number of bytes read
- while ((l_nbytes = is.read(l_buffer)) != -1) {
+ int readLength = length;
+ if (length == -1) {
+ readLength = l_buffer.length;
+ }
+ else {
+ readLength = Math.min(length, l_buffer.length);
+ }
+ while ((l_nbytes = is.read(l_buffer, 0, readLength)) != -1) {
if (length != -1 && writen > length - l_nbytes) {
out.write(l_buffer, 0, writen + l_nbytes - length);
break;
@@ -109,16 +125,22 @@
}
return writen;
} finally {
- try {
- is.close();
- } finally {
- out.close();
+ if (close) {
+ try {
+ is.close();
+ } finally {
+ out.close();
+ }
}
}
}
+
+ public static int write(final OutputStream out, final InputStream is, int length) throws IOException {
+ return write(out, is, length, true);
+ }
- public static void write(final OutputStream out, final InputStream is, int length) throws IOException {
- write(out, is, new byte[DEFAULT_READING_SIZE], length); // buffer holding bytes to be transferred
+ public static int write(final OutputStream out, final InputStream is, int length, boolean close) throws IOException {
+ return write(out, is, new byte[DEFAULT_READING_SIZE], length, close); // buffer holding bytes to be transferred
}
public static void write(final Writer out, final Reader is, int length) throws IOException {
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPConfiguration.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPConfiguration.java 2011-02-10 19:56:37 UTC (rev 2903)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPConfiguration.java 2011-02-14 01:30:06 UTC (rev 2904)
@@ -51,6 +51,7 @@
private int maxSourceRows = -1;
private int maxActivePlans = DEFAULT_MAX_ACTIVE_PLANS;
private CacheConfiguration resultsetCacheConfig;
+ private int maxODBCLobSizeAllowed = 5*1024*1024; // 5 MB
@ManagementProperty(description="Max active plans (default 20). Increase this value, and max threads, on highly concurrent systems - but ensure that the underlying pools can handle the increased load without timeouts.")
public int getMaxActivePlans() {
@@ -185,4 +186,13 @@
public void setMaxSourceRows(int maxSourceRows) {
this.maxSourceRows = maxSourceRows;
}
+
+ @ManagementProperty(description="Maximum Lob Size allowed over ODBC (default 5MB)")
+ public int getMaxODBCLobSizeAllowed() {
+ return this.maxODBCLobSizeAllowed;
+ }
+
+ public void setMaxODBCLobSizeAllowed(int lobSize) {
+ this.maxODBCLobSizeAllowed = lobSize;
+ }
}
Modified: trunk/jboss-integration/src/main/java/org/teiid/jboss/deployers/RuntimeEngineDeployer.java
===================================================================
--- trunk/jboss-integration/src/main/java/org/teiid/jboss/deployers/RuntimeEngineDeployer.java 2011-02-10 19:56:37 UTC (rev 2903)
+++ trunk/jboss-integration/src/main/java/org/teiid/jboss/deployers/RuntimeEngineDeployer.java 2011-02-14 01:30:06 UTC (rev 2904)
@@ -192,7 +192,7 @@
if (this.odbcSocketConfiguration.getEnabled()) {
this.vdbRepository.odbcEnabled();
- this.odbcSocket = new ODBCSocketListener(this.odbcSocketConfiguration, this.dqpCore.getBufferManager(), offset);
+ this.odbcSocket = new ODBCSocketListener(this.odbcSocketConfiguration, this.dqpCore.getBufferManager(), offset, getMaxODBCLobSizeAllowed());
LogManager.logInfo(LogConstants.CTX_RUNTIME, IntegrationPlugin.Util.getString("odbc_enabled","Teiid ODBC - SSL=", (this.odbcSocketConfiguration.getSSLConfiguration().isSslEnabled()?"ON":"OFF")+" Host = "+this.odbcSocketConfiguration.getHostAddress().getHostName()+" Port = "+(this.odbcSocketConfiguration.getPortNumber()+offset))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
} else {
LogManager.logInfo(LogConstants.CTX_RUNTIME, IntegrationPlugin.Util.getString("odbc_not_enabled")); //$NON-NLS-1$
Modified: trunk/runtime/src/main/java/org/teiid/odbc/ODBCClientRemote.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/odbc/ODBCClientRemote.java 2011-02-10 19:56:37 UTC (rev 2903)
+++ trunk/runtime/src/main/java/org/teiid/odbc/ODBCClientRemote.java 2011-02-14 01:30:06 UTC (rev 2904)
@@ -79,6 +79,12 @@
void flush();
+ // FunctionCallResponse (B)
+ void functionCallResponse(byte[] data);
+ void functionCallResponse(int data);
+
+ void sslDenied();
+
// unimplemented backend messages
// AuthenticationKerberosV5 (B)
@@ -95,8 +101,6 @@
// CopyInResponse (B)
// CopyOutResponse (B)
- // FunctionCallResponse (B)
-
// NoticeResponse (B)
// NotificationResponse (B)
Modified: trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemote.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemote.java 2011-02-10 19:56:37 UTC (rev 2903)
+++ trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemote.java 2011-02-14 01:30:06 UTC (rev 2904)
@@ -56,13 +56,14 @@
void flush();
+ void functionCall(int oid);
+
+ void sslRequest();
+
// unimplemented frontend messages
// CopyData (F & B)
// CopyDone (F & B)
// CopyFail (F)
- // Flush (F)
- // FunctionCall (F)
- // SSLRequest (F)
}
Modified: trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemoteImpl.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemoteImpl.java 2011-02-10 19:56:37 UTC (rev 2903)
+++ trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemoteImpl.java 2011-02-14 01:30:06 UTC (rev 2904)
@@ -571,7 +571,18 @@
public void flush() {
this.client.flush();
}
-
+
+ @Override
+ public void functionCall(int oid) {
+ this.client.errorOccurred(RuntimePlugin.Util.getString("lo_not_supported")); //$NON-NLS-1$
+ sync();
+ }
+
+ @Override
+ public void sslRequest() {
+ this.client.sslDenied();
+ }
+
/**
* Represents a PostgreSQL Prepared object.
*/
Modified: trunk/runtime/src/main/java/org/teiid/transport/ODBCSocketListener.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/transport/ODBCSocketListener.java 2011-02-10 19:56:37 UTC (rev 2903)
+++ trunk/runtime/src/main/java/org/teiid/transport/ODBCSocketListener.java 2011-02-14 01:30:06 UTC (rev 2904)
@@ -32,10 +32,12 @@
public class ODBCSocketListener extends SocketListener {
private ODBCServerRemote.AuthenticationType authType = ODBCServerRemote.AuthenticationType.CLEARTEXT;
+ private int maxLobSize;
- public ODBCSocketListener(SocketConfiguration config, StorageManager storageManager, int portOffset) {
+ public ODBCSocketListener(SocketConfiguration config, StorageManager storageManager, int portOffset, int maxLobSize) {
//the clientserviceregistry isn't actually used by ODBC
super(config, new ClientServiceRegistryImpl(ClientServiceRegistry.Type.ODBC), storageManager, portOffset);
+ this.maxLobSize = maxLobSize;
}
@Override
@@ -49,7 +51,7 @@
pipeline.addLast("ssl", new SslHandler(engine)); //$NON-NLS-1$
}
pipeline.addLast("odbcFrontendProtocol", new PgFrontendProtocol(1 << 20)); //$NON-NLS-1$
- pipeline.addLast("odbcBackendProtocol", new PgBackendProtocol()); //$NON-NLS-1$
+ pipeline.addLast("odbcBackendProtocol", new PgBackendProtocol(maxLobSize)); //$NON-NLS-1$
pipeline.addLast("handler", this); //$NON-NLS-1$
return pipeline;
}
Modified: trunk/runtime/src/main/java/org/teiid/transport/PgBackendProtocol.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/transport/PgBackendProtocol.java 2011-02-10 19:56:37 UTC (rev 2903)
+++ trunk/runtime/src/main/java/org/teiid/transport/PgBackendProtocol.java 2011-02-14 01:30:06 UTC (rev 2904)
@@ -27,10 +27,13 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.charset.Charset;
+import java.sql.Blob;
+import java.sql.Clob;
import java.sql.ParameterMetaData;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
+import java.sql.SQLXML;
import java.sql.Types;
import java.util.Properties;
@@ -41,6 +44,8 @@
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.MessageEvent;
+import org.teiid.core.util.ObjectConverterUtil;
+import org.teiid.core.util.ReaderInputStream;
import org.teiid.core.util.ReflectionHelper;
import org.teiid.jdbc.TeiidSQLException;
import org.teiid.logging.LogConstants;
@@ -64,15 +69,16 @@
private static final int PG_TYPE_INT2 = 21;
private static final int PG_TYPE_INT4 = 23;
private static final int PG_TYPE_TEXT = 25;
- private static final int PG_TYPE_OID = 26;
+ //private static final int PG_TYPE_OID = 26;
private static final int PG_TYPE_FLOAT4 = 700;
private static final int PG_TYPE_FLOAT8 = 701;
private static final int PG_TYPE_UNKNOWN = 705;
- private static final int PG_TYPE_TEXTARRAY = 1009;
+ //private static final int PG_TYPE_TEXTARRAY = 1009;
private static final int PG_TYPE_DATE = 1082;
private static final int PG_TYPE_TIME = 1083;
private static final int PG_TYPE_TIMESTAMP_NO_TMZONE = 1114;
private static final int PG_TYPE_NUMERIC = 1700;
+ //private static final int PG_TYPE_LO = 14939;
private DataOutputStream dataOut;
private ByteArrayOutputStream outBuffer;
@@ -82,7 +88,12 @@
private ReflectionHelper clientProxy = new ReflectionHelper(ODBCClientRemote.class);
private ChannelHandlerContext ctx;
private MessageEvent message;
+ private int maxLobSize = (2*1024*1024); // 2 MB
+ public PgBackendProtocol(int maxLobSize) {
+ this.maxLobSize = maxLobSize;
+ }
+
@Override
public void handleDownstream(ChannelHandlerContext ctx, ChannelEvent evt) throws Exception {
if (!(evt instanceof MessageEvent)) {
@@ -210,7 +221,7 @@
if (paramType != null && paramType[i] != 0) {
type = paramType[i];
} else {
- type = PG_TYPE_VARCHAR;
+ type = convertType(meta.getParameterType(i+1));
}
writeInt(type);
}
@@ -244,8 +255,13 @@
ResultSetMetaData meta = rs.getMetaData();
sendRowDescription(meta);
}
+ int columns = rs.getMetaData().getColumnCount();
+ int[] types = new int[columns];
+ for(int i = 0; i < columns; i++) {
+ types[i] = rs.getMetaData().getColumnType(i+1);
+ }
while (rs.next()) {
- sendDataRow(rs);
+ sendDataRow(rs, columns, types);
}
sendCommandComplete(sql, 0);
} catch (SQLException e) {
@@ -331,27 +347,81 @@
sendMessage();
}
- private void sendDataRow(ResultSet rs) throws SQLException, IOException {
- int columns = rs.getMetaData().getColumnCount();
- String[] values = new String[columns];
- for (int i = 0; i < columns; i++) {
- values[i] = rs.getString(i + 1);
- }
+ private void sendDataRow(ResultSet rs, int columns, int[] types) throws SQLException, IOException {
startMessage('D');
writeShort(columns);
- for (String s : values) {
- if (s == null) {
+ for (int i = 0; i < columns; i++) {
+ byte[] bytes = getContent(rs, types[i], i+1);
+ if (bytes == null) {
writeInt(-1);
} else {
- // TODO write Binary data
- byte[] d2 = s.getBytes(this.encoding);
- writeInt(d2.length);
- write(d2);
+ writeInt(bytes.length);
+ write(bytes);
}
}
sendMessage();
}
+ private byte[] getContent(ResultSet rs, int type, int column) throws SQLException, TeiidSQLException, IOException {
+ byte[] bytes = null;
+ switch (type) {
+ case Types.BOOLEAN:
+ case Types.VARCHAR:
+ case Types.CHAR:
+ case Types.SMALLINT:
+ case Types.INTEGER:
+ case Types.BIGINT:
+ case Types.NUMERIC:
+ case Types.DECIMAL:
+ case Types.FLOAT:
+ case Types.REAL:
+ case Types.DOUBLE:
+ case Types.TIME:
+ case Types.DATE:
+ case Types.TIMESTAMP:
+ String value = rs.getString(column);
+ if (value != null) {
+ bytes = value.getBytes(this.encoding);
+ }
+ break;
+
+ case Types.LONGVARCHAR:
+ case Types.CLOB:
+ Clob clob = rs.getClob(column);
+ if (clob != null) {
+ bytes = ObjectConverterUtil.convertToByteArray(new ReaderInputStream(clob.getCharacterStream(), this.encoding), this.maxLobSize);
+ }
+ break;
+
+ case Types.SQLXML:
+ SQLXML xml = rs.getSQLXML(column);
+ if (xml != null) {
+ bytes = ObjectConverterUtil.convertToByteArray(new ReaderInputStream(xml.getCharacterStream(), this.encoding), this.maxLobSize);
+ }
+ break;
+
+ case Types.BINARY:
+ case Types.VARBINARY:
+ case Types.LONGVARBINARY:
+ case Types.BLOB:
+ Blob blob = rs.getBlob(column);
+ if (blob != null) {
+ bytes = toHex(ObjectConverterUtil.convertToByteArray(blob.getBinaryStream(), this.maxLobSize));
+ }
+ break;
+ default:
+ throw new TeiidSQLException("unknown datatype failed to convert");
+ }
+ return bytes;
+ }
+
+ @Override
+ public void sslDenied() {
+ ChannelBuffer buffer = ChannelBuffers.directBuffer(1);
+ buffer.writeByte('N');
+ Channels.write(this.ctx, this.message.getFuture(), buffer, this.message.getRemoteAddress());
+ }
+
private void sendErrorResponse(Throwable t) throws IOException {
trace(t.getMessage());
SQLException e = TeiidSQLException.create(t);
@@ -496,6 +566,35 @@
writeString(value);
sendMessage();
}
+
+ @Override
+ public void functionCallResponse(byte[] data) {
+ try {
+ startMessage('V');
+ if (data == null) {
+ writeInt(-1);
+ }
+ else {
+ writeInt(data.length);
+ write(data);
+ }
+ sendMessage();
+ } catch (IOException e) {
+ terminate(e);
+ }
+ }
+
+ @Override
+ public void functionCallResponse(int data) {
+ try {
+ startMessage('V');
+ writeInt(4);
+ writeInt(data);
+ sendMessage();
+ } catch (IOException e) {
+ terminate(e);
+ }
+ }
private void writeString(String s) throws IOException {
write(s.getBytes(this.encoding));
@@ -543,26 +642,30 @@
LogManager.logTrace(LogConstants.CTX_ODBC, msg);
}
+ /**
+ * Types.ARRAY is not supported
+ */
private static int convertType(final int type) {
switch (type) {
case Types.BOOLEAN:
- return PG_TYPE_BOOL;
+ return PG_TYPE_BOOL;
case Types.VARCHAR:
- return PG_TYPE_VARCHAR;
- case Types.CLOB:
- return PG_TYPE_TEXT;
+ return PG_TYPE_VARCHAR;
case Types.CHAR:
- return PG_TYPE_BPCHAR;
+ return PG_TYPE_BPCHAR;
+ case Types.TINYINT:
case Types.SMALLINT:
- return PG_TYPE_INT2;
+ return PG_TYPE_INT2;
case Types.INTEGER:
- return PG_TYPE_INT4;
+ return PG_TYPE_INT4;
case Types.BIGINT:
- return PG_TYPE_INT8;
+ return PG_TYPE_INT8;
+ case Types.NUMERIC:
case Types.DECIMAL:
- return PG_TYPE_NUMERIC;
+ return PG_TYPE_NUMERIC;
+ case Types.FLOAT:
case Types.REAL:
- return PG_TYPE_FLOAT4;
+ return PG_TYPE_FLOAT4;
case Types.DOUBLE:
return PG_TYPE_FLOAT8;
case Types.TIME:
@@ -571,14 +674,44 @@
return PG_TYPE_DATE;
case Types.TIMESTAMP:
return PG_TYPE_TIMESTAMP_NO_TMZONE;
- case Types.VARBINARY:
- return PG_TYPE_BYTEA;
- case Types.BLOB:
- return PG_TYPE_OID;
- case Types.ARRAY:
- return PG_TYPE_TEXTARRAY;
+
+ case Types.BLOB:
+ case Types.BINARY:
+ case Types.VARBINARY:
+ case Types.LONGVARBINARY:
+ return PG_TYPE_BYTEA;
+
+ case Types.LONGVARCHAR:
+ case Types.CLOB:
+ return PG_TYPE_TEXT;
+
+ case Types.SQLXML:
+ return PG_TYPE_TEXT;
+
default:
return PG_TYPE_UNKNOWN;
}
}
+
+ private static final byte[] hexChars = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e','f' };
+
+ /**
+ * When sending the byteA content to client convert into Hex before sending the content.
+ * @param b
+ * @return
+ * @throws IOException
+ */
+ static byte[] toHex(byte[] b) throws IOException {
+ byte[] hexbytes = PgFrontendProtocol.createByteArray((2 * b.length)+2);
+ hexbytes[0] = '\\';
+ hexbytes[1] = 'x';
+
+ for (int i = 0; i < b.length; i++) {
+ int index = (i*2)+2;
+ int v = b[i] & 0xff;
+ hexbytes[index] = hexChars[v >> 4];
+ hexbytes[index+1] = hexChars[v & 0xf];
+ }
+ return hexbytes;
+ }
}
Modified: trunk/runtime/src/main/java/org/teiid/transport/PgFrontendProtocol.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/transport/PgFrontendProtocol.java 2011-02-10 19:56:37 UTC (rev 2903)
+++ trunk/runtime/src/main/java/org/teiid/transport/PgFrontendProtocol.java 2011-02-14 01:30:06 UTC (rev 2904)
@@ -47,6 +47,15 @@
@SuppressWarnings("nls")
public class PgFrontendProtocol extends FrameDecoder {
+ private static final int LO_CREAT = 957;
+ private static final int LO_OPEN = 952;
+ private static final int LO_CLOSE = 953;
+ private static final int LO_READ = 954;
+ private static final int LO_WRITE = 955;
+ private static final int LO_LSEEK = 956;
+ private static final int LO_TELL = 958;
+ private static final int LO_UNLINK = 964;
+
private int maxObjectSize;
private Byte messageType;
private Integer dataLength;
@@ -148,7 +157,9 @@
case 'C':
return buildClose(data);
case 'H':
- return buildFlush();
+ return buildFlush();
+ case 'F':
+ return buildFunctionCall(data);
default:
return buildError();
}
@@ -179,6 +190,13 @@
int version = data.readInt();
props.setProperty("version", Integer.toString(version));
+ // SSL Request
+ if (version == 80877103) {
+ this.initialized = false;
+ this.odbcProxy.sslRequest();
+ return message;
+ }
+
trace("StartupMessage");
trace(" version " + version + " (" + (version >> 16) + "." + (version & 0xff) + ")");
@@ -235,7 +253,7 @@
}
int paramCount = data.readShort();
- Object[] params = new String[paramCount];
+ Object[] params = new Object[paramCount];
for (int i = 0; i < paramCount; i++) {
int paramLen = data.readInt();
byte[] paramdata = createByteArray(paramLen);
@@ -299,7 +317,7 @@
return message;
}
- private byte[] createByteArray(int length) throws StreamCorruptedException{
+ static byte[] createByteArray(int length) throws StreamCorruptedException{
try {
return new byte[length];
} catch(OutOfMemoryError e) {
@@ -322,6 +340,66 @@
return message;
}
+ /**
+ * LO functions are always binary, so I am ignoring the formats, return types. The below is not used
+ * leaving for future if ever LO is revisited
+ */
+ @SuppressWarnings("unused")
+ private Object buildFunctionCall(NullTerminatedStringDataInputStream data) throws IOException {
+ int funcID = data.readInt();
+
+ // read data types of arguments
+ int formatCount = data.readShort();
+ int[] formatTypes = new int[formatCount];
+ for (int i = 0; i< formatCount; i++) {
+ formatTypes[i] = data.readShort();
+ }
+
+ // arguments
+ data.readShort(); // ignore the param count; we know them by functions supported.
+ int oid = readInt(data);
+ switch(funcID) {
+ case LO_CREAT:
+ break;
+ case LO_OPEN:
+ int mode = readInt(data);
+ break;
+ case LO_CLOSE:
+ break;
+ case LO_READ:
+ int length = readInt(data);
+ break;
+ case LO_WRITE:
+ byte[] contents = readByteArray(data);
+ break;
+ case LO_LSEEK:
+ int offset = readInt(data);
+ int where = readInt(data);
+ break;
+ case LO_TELL:
+ break;
+ case LO_UNLINK:
+ break;
+ }
+ this.odbcProxy.functionCall(oid);
+ return message;
+ }
+
+ private int readInt(NullTerminatedStringDataInputStream data) throws IOException {
+ data.readInt(); // ignore this this is length always 4
+ return data.readInt();
+ }
+
+ private byte[] readByteArray(NullTerminatedStringDataInputStream data) throws IOException {
+ int length = data.readInt();
+ if (length == -1 || length == 0) {
+ return null;
+ }
+ byte[] content = createByteArray(length);
+ data.read(content, 0, length);
+ return content;
+ }
+
static class NullTerminatedStringDataInputStream extends DataInputStream{
private String encoding;
Modified: trunk/runtime/src/main/resources/org/teiid/runtime/i18n.properties
===================================================================
--- trunk/runtime/src/main/resources/org/teiid/runtime/i18n.properties 2011-02-10 19:56:37 UTC (rev 2903)
+++ trunk/runtime/src/main/resources/org/teiid/runtime/i18n.properties 2011-02-14 01:30:06 UTC (rev 2904)
@@ -87,3 +87,4 @@
error_closing_stmt=Error closing portal statement {0}
model_metadata_loading=VDB "{0}" - "{1}" model metadata is currently being loaded. Start Time: {2}
ambigious_name=Ambiguous VDB name specified. Only single occurrence of the "." is allowed in the VDB name. Also, when version based vdb name is specified, then a separate "version" connection option is not allowed:{0}.{1}
+lo_not_supported=LO functions are not supported
\ No newline at end of file
13 years, 10 months
teiid SVN: r2903 - in trunk: api/src/main/java/org/teiid/translator and 21 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-02-10 14:56:37 -0500 (Thu, 10 Feb 2011)
New Revision: 2903
Added:
trunk/engine/src/main/java/org/teiid/query/processor/relational/ArrayTableNode.java
trunk/engine/src/main/java/org/teiid/query/sql/lang/ArrayTable.java
trunk/engine/src/test/java/org/teiid/query/processor/TestArrayTable.java
Removed:
trunk/engine/src/main/resources/org/teiid/query/execution/
Modified:
trunk/api/src/main/java/org/teiid/language/SQLConstants.java
trunk/api/src/main/java/org/teiid/translator/SourceSystemFunctions.java
trunk/build/kits/jboss-container/teiid-releasenotes.html
trunk/client/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java
trunk/connectors/translator-olap/src/main/java/org/teiid/translator/olap/OlapExecutionFactory.java
trunk/connectors/translator-olap/src/main/java/org/teiid/translator/olap/OlapQueryExecution.java
trunk/documentation/reference/src/main/docbook/en-US/content/grammar.xml
trunk/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml
trunk/documentation/reference/src/main/docbook/en-US/content/sql_support.xml
trunk/documentation/reference/src/main/docbook/en-US/content/translators.xml
trunk/engine/src/main/java/org/teiid/dqp/internal/process/PreparedStatementRequest.java
trunk/engine/src/main/java/org/teiid/query/function/FunctionMethods.java
trunk/engine/src/main/java/org/teiid/query/function/source/SystemSource.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.java
trunk/engine/src/main/java/org/teiid/query/resolver/command/SimpleQueryResolver.java
trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java
trunk/engine/src/main/java/org/teiid/query/sql/lang/TableFunctionReference.java
trunk/engine/src/main/java/org/teiid/query/sql/lang/TextTable.java
trunk/engine/src/main/java/org/teiid/query/sql/lang/XMLTable.java
trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java
trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java
trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
trunk/engine/src/main/resources/org/teiid/query/i18n.properties
trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java
trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java
trunk/hibernate-dialect/src/main/java/org/teiid/dialect/TeiidDialect.java
Log:
TEIID-1011 TEIID-247 refining the mondrian/olap support to use a more efficient array based processing and adding system functions to handle array values
Modified: trunk/api/src/main/java/org/teiid/language/SQLConstants.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/SQLConstants.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/api/src/main/java/org/teiid/language/SQLConstants.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -103,6 +103,8 @@
public static final String ENCODING = "ENCODING"; //$NON-NLS-1$
public static final String TEXTAGG = "TEXTAGG"; //$NON-NLS-1$
+
+ public static final String ARRAYTABLE = "ARRAYTABLE"; //$NON-NLS-1$
}
public interface Reserved {
Modified: trunk/api/src/main/java/org/teiid/translator/SourceSystemFunctions.java
===================================================================
--- trunk/api/src/main/java/org/teiid/translator/SourceSystemFunctions.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/api/src/main/java/org/teiid/translator/SourceSystemFunctions.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -133,6 +133,8 @@
public static final String IFNULL = "ifnull"; //$NON-NLS-1$
public static final String COALESCE = "coalesce"; //$NON-NLS-1$
public static final String NULLIF = "nullif"; //$NON-NLS-1$
+ public static final String ARRAY_GET = "array_get"; //$NON-NLS-1$
+ public static final String ARRAY_LENGTH = "array_length"; //$NON-NLS-1$
//conversion functions
public static final String CONVERT = "convert"; //$NON-NLS-1$
Modified: trunk/build/kits/jboss-container/teiid-releasenotes.html
===================================================================
--- trunk/build/kits/jboss-container/teiid-releasenotes.html 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/build/kits/jboss-container/teiid-releasenotes.html 2011-02-10 19:56:37 UTC (rev 2903)
@@ -29,7 +29,13 @@
<LI><B>Virtual procedure out params</B> - virtual procedures can now have RETURN/OUT/INOUT parameters to return values.
<LI><B>OLAP</B> - OLAP translator is now part of Teiid kit using OLAP4J
<LI><B>Multi-source procedures</B> - multi-source handling was expanded to cover stored procedure execution. See the Reference for more.
- <LI><B>UUID function</B> - was added to generate type 4 UUIDs and the Hibernate dialect was updated to support the GUIDGenerator.
+ <LI><B>Function Support</B> - additional system functions were made available.
+ <UL>
+ <LI><B>uuid</B> was added to generate type 4 UUIDs and the Hibernate dialect was updated to support the GUIDGenerator.
+ <LI><B>array_get</B> was added to extract values from java.sql.Array or java array values.
+ <LI><B>array_length</B> was added to get the length of java.sql.Array or java array values.
+ </UL>
+ <LI><B>ARRAYTABLE</B> - the ARRAYTABLE table function was added to simplify array value extraction into a tabular format.
</UL>
<h2><a name="Compatibility">Compatibility Issues</a></h2>
Modified: trunk/client/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/client/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -89,7 +89,7 @@
"PARSETIMESTAMP, QUARTER, SECOND, TIMESTAMPADD, TIMESTAMPDIFF, WEEK, YEAR"; //$NON-NLS-1$
// constant value giving the names of system functions supported
final static String SYSTEM_FUNCTIONS =
- "CAST, COALESCE, CONVERT, DECODESTRING, DECODEINTEGER, IFNULL, NULLIF, NVL, LOOKUP"; //$NON-NLS-1$
+ "CAST, COALESCE, CONVERT, DECODESTRING, DECODEINTEGER, IFNULL, NULLIF, NVL, LOOKUP, UUID, UNESCAPE, ARRAY_GET, ARRAY_LENGTH"; //$NON-NLS-1$
// constant value giving max length of a catalog name
private final static int MAX_CATALOG_NAME_LENGTH = 255;
// constant value giving max length of a procedure name
Modified: trunk/connectors/translator-olap/src/main/java/org/teiid/translator/olap/OlapExecutionFactory.java
===================================================================
--- trunk/connectors/translator-olap/src/main/java/org/teiid/translator/olap/OlapExecutionFactory.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/connectors/translator-olap/src/main/java/org/teiid/translator/olap/OlapExecutionFactory.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -57,8 +57,7 @@
ProcedureParameter param = metadataFactory.addProcedureParameter("request", TypeFacility.RUNTIME_NAMES.STRING, Type.In, p); //$NON-NLS-1$
param.setAnnotation("The MDX query to execute"); //$NON-NLS-1$
param.setNullType(NullType.Nullable);
-
- metadataFactory.addProcedureParameter("result", TypeFacility.RUNTIME_NAMES.XML, Type.ReturnValue, p); //$NON-NLS-1$
+ metadataFactory.addProcedureResultSetColumn("tuple", TypeFacility.RUNTIME_NAMES.OBJECT, p); //$NON-NLS-1$
}
@Override
Modified: trunk/connectors/translator-olap/src/main/java/org/teiid/translator/olap/OlapQueryExecution.java
===================================================================
--- trunk/connectors/translator-olap/src/main/java/org/teiid/translator/olap/OlapQueryExecution.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/connectors/translator-olap/src/main/java/org/teiid/translator/olap/OlapQueryExecution.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -21,16 +21,11 @@
*/
package org.teiid.translator.olap;
-import java.io.IOException;
-import java.io.Reader;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import java.util.ListIterator;
-import javax.xml.transform.Source;
-import javax.xml.transform.stream.StreamSource;
-
import org.olap4j.Axis;
import org.olap4j.Cell;
import org.olap4j.CellSet;
@@ -48,6 +43,9 @@
import org.teiid.translator.ProcedureExecution;
import org.teiid.translator.TranslatorException;
+/**
+ * Executes the given MDX and packs the results into an array
+ */
public class OlapQueryExecution implements ProcedureExecution {
protected Command command;
@@ -55,8 +53,10 @@
protected ExecutionContext context;
protected OlapExecutionFactory executionFactory;
private OlapStatement stmt;
- private Source returnValue;
-
+ private CellSet cellSet;
+ private CellSetAxis cols;
+ private int colWidth;
+ private ListIterator<Position> iterator;
public OlapQueryExecution(Command command, OlapConnection connection, ExecutionContext context, OlapExecutionFactory executionFactory) {
this.command = command;
@@ -71,12 +71,13 @@
Call procedure = (Call) this.command;
List<Argument> arguments = procedure.getArguments();
String mdxQuery = (String) arguments.get(0).getArgumentValue().getValue();
- OlapStatement stmt = this.connection.createStatement();
+ stmt = this.connection.createStatement();
- CellSet cellSet = stmt.executeOlapQuery(mdxQuery);
- this.returnValue = new StreamSource(new MdxResultsReader(cellSet));
-
-
+ cellSet = stmt.executeOlapQuery(mdxQuery);
+ CellSetAxis rows = this.cellSet.getAxes().get(Axis.ROWS.axisOrdinal());
+ iterator = rows.iterator();
+ cols = cellSet.getAxes().get(Axis.COLUMNS.axisOrdinal());
+ colWidth = rows.getAxisMetaData().getHierarchies().size() + this.cols.getPositions().size();
} catch (SQLException e) {
throw new TranslatorException(e);
}
@@ -85,8 +86,9 @@
@Override
public void cancel() throws TranslatorException {
try {
- if (this.stmt != null) {
- this.stmt.cancel();
+ OlapStatement olapStatement = this.stmt;
+ if (olapStatement != null) {
+ olapStatement.cancel();
}
} catch (SQLException e) {
throw new TranslatorException(e);
@@ -94,7 +96,7 @@
}
@Override
- public synchronized void close() {
+ public void close() {
try {
if (this.stmt != null) {
this.stmt.close();
@@ -107,100 +109,30 @@
@Override
public List<?> next() throws TranslatorException {
- return null;
+ if (!iterator.hasNext()) {
+ return null;
+ }
+ Position nextRow = iterator.next();
+ Object[] result = new Object[colWidth];
+ int i = 0;
+ // add in rows axis
+ List<Member> members = nextRow.getMembers();
+ for (Member member:members) {
+ String columnName = member.getHierarchy().getName();
+ result[i++] = columnName;
+ }
+
+ // add col axis
+ for (Position colPos : cols) {
+ Cell cell = cellSet.getCell(colPos, nextRow);
+ result[i++] = cell.getValue();
+ }
+ return Arrays.asList(result);
}
@Override
public List<?> getOutputParameterValues() throws TranslatorException {
- return Arrays.asList(this.returnValue);
+ return null;
}
- static class MdxResultsReader extends Reader {
- private CellSet cellSet;
- private ListIterator<Position> rows;
- private Position nextRow;
- private boolean closed = false;
- private char[] buffer;
- private int index = 0;
-
- public MdxResultsReader(CellSet cellSet) {
- this.cellSet = cellSet;
- CellSetAxis rowAxis = cellSet.getAxes().get(Axis.ROWS.axisOrdinal());
- this.rows = rowAxis.iterator();
- if (this.rows.hasNext()) {
- this.nextRow = this.rows.next();
- this.buffer = "<resultset>".toCharArray(); //$NON-NLS-1$
- }
- }
-
- private String readNextRow() {
- if (this.nextRow == null) {
- return null;
- }
-
- StringBuilder sb = new StringBuilder();
- CellSetAxis cols = cellSet.getAxes().get(Axis.COLUMNS.axisOrdinal());
- sb.append("<row>"); //$NON-NLS-1$
-
- // add in rows axis
- List<Member> members = nextRow.getMembers();
- for (Member member:members) {
- String columnName = member.getHierarchy().getName();
- columnName = columnName.replace(' ', '_');
- sb.append('<').append(columnName).append('>');
- sb.append(member.getName());
- sb.append("</").append(columnName).append('>'); //$NON-NLS-1$
- }
-
- // add col axis
- for (Position colPos : cols) {
- Cell cell = cellSet.getCell(colPos, nextRow);
- String columnName = colPos.getMembers().get(0).getName();
- columnName = columnName.replace(' ', '_');
- sb.append('<').append(columnName).append('>');
- sb.append(cell.getValue());
- sb.append("</").append(columnName).append('>'); //$NON-NLS-1$
- }
- sb.append("</row>");//$NON-NLS-1$
-
- // advance the cursor to next row.
- if (this.rows.hasNext()) {
- this.nextRow = this.rows.next();
- }
- else {
- this.nextRow = null;
- }
- return sb.toString();
- }
-
- @Override
- public void close() throws IOException {
- }
-
- @Override
- public int read(char[] cbuf, int off, int len) throws IOException {
- int availble = this.buffer.length - this.index;
- if (availble == 0) {
- String next = readNextRow();
- if (next == null) {
- if (!this.closed) {
- this.buffer = "</resultset>".toCharArray();//$NON-NLS-1$
- this.closed = true;
- }
- else {
- return -1;
- }
- }
- else {
- this.buffer = next.toCharArray();
- }
- this.index = 0;
- availble = this.buffer.length;
- }
- len = (availble > len) ? len : availble;
- System.arraycopy(this.buffer, this.index, cbuf, off, len);
- this.index = this.index + len;
- return len;
- }
- }
}
Modified: trunk/documentation/reference/src/main/docbook/en-US/content/grammar.xml
===================================================================
--- trunk/documentation/reference/src/main/docbook/en-US/content/grammar.xml 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/documentation/reference/src/main/docbook/en-US/content/grammar.xml 2011-02-10 19:56:37 UTC (rev 2903)
@@ -508,7 +508,7 @@
<row>
<entry align="right" valign="top"><para><anchor id="prod39" xreflabel="createElementsWithTypes"/>createElementsWithTypes</para></entry>
<entry align="left" valign="top"><para>::=
-<link linkend="prod2">id</link> <link linkend="prod35">dataType</link> ( <COMMA> <link linkend="prod2">id</link> <link linkend="prod35">dataType</link> )*</para></entry></row>
+<link linkend="prod2">id</link> <link linkend="prod19">dataTypeString</link> ( <COMMA> <link linkend="prod2">id</link> <link linkend="prod19">dataTypeString</link> )*</para></entry></row>
<row>
<entry align="right" valign="top"><para><anchor id="prod6" xreflabel="callableStatement"/>callableStatement</para></entry>
<entry align="left" valign="top"><para>::=
@@ -628,9 +628,9 @@
<row>
<entry align="right" valign="top"><para><anchor id="prod69" xreflabel="tablePrimary"/>tablePrimary</para></entry>
<entry align="left" valign="top"><para>::=
-( <link linkend="prod72">textTable</link> | <link linkend="prod73">xmlTable</link> | <link linkend="prod74">unaryFromClause</link> | <link linkend="prod75">subqueryFromClause</link> | ( <LPAREN> <link linkend="prod68">joinedTable</link> <RPAREN> ) ) ( ( <MAKEDEP> ) | ( <MAKENOTDEP> ) )?</para></entry></row>
+( <link linkend="prod72">textTable</link> | <link linkend="prod73">arrayTable</link> | <link linkend="prod74">xmlTable</link> | <link linkend="prod75">unaryFromClause</link> | <link linkend="prod76">subqueryFromClause</link> | ( <LPAREN> <link linkend="prod68">joinedTable</link> <RPAREN> ) ) ( ( <MAKEDEP> ) | ( <MAKENOTDEP> ) )?</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod76" xreflabel="xmlSerialize"/>xmlSerialize</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod77" xreflabel="xmlSerialize"/>xmlSerialize</para></entry>
<entry align="left" valign="top"><para>::=
<XMLSERIALIZE> <LPAREN> ( <link linkend="prod18">nonReserved</link> )? <link linkend="prod21">expression</link> ( <AS> ( <STRING> | <VARCHAR> | <CLOB> ) )? <RPAREN></para></entry></row>
<row>
@@ -638,35 +638,39 @@
<entry align="left" valign="top"><para>::=
<ID></para></entry></row>
<row>
+<entry align="right" valign="top"><para><anchor id="prod73" xreflabel="arrayTable"/>arrayTable</para></entry>
+<entry align="left" valign="top"><para>::=
+<ID> <LPAREN> <link linkend="prod21">expression</link> <link linkend="prod18">nonReserved</link> <link linkend="prod39">createElementsWithTypes</link> <RPAREN> ( <AS> )? <link linkend="prod2">id</link></para></entry></row>
+<row>
<entry align="right" valign="top"><para><anchor id="prod72" xreflabel="textTable"/>textTable</para></entry>
<entry align="left" valign="top"><para>::=
-<ID> <LPAREN> <link linkend="prod21">expression</link> <link linkend="prod18">nonReserved</link> <link linkend="prod77">textColumn</link> ( <COMMA> <link linkend="prod77">textColumn</link> )* ( <ID> <link linkend="prod65">charVal</link> )? ( ( <ESCAPE> <link linkend="prod65">charVal</link> ) | ( <ID> <link linkend="prod65">charVal</link> ) )? ( <ID> ( <link linkend="prod78">intVal</link> )? )? ( <ID> <link linkend="prod78">intVal</link> )? <RPAREN> ( <AS> )? <link linkend="prod2">id</link></para></entry></row>
+<ID> <LPAREN> <link linkend="prod21">expression</link> <link linkend="prod18">nonReserved</link> <link linkend="prod78">textColumn</link> ( <COMMA> <link linkend="prod78">textColumn</link> )* ( <ID> <link linkend="prod65">charVal</link> )? ( ( <ESCAPE> <link linkend="prod65">charVal</link> ) | ( <ID> <link linkend="prod65">charVal</link> ) )? ( <ID> ( <link linkend="prod79">intVal</link> )? )? ( <ID> <link linkend="prod79">intVal</link> )? <RPAREN> ( <AS> )? <link linkend="prod2">id</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod77" xreflabel="textColumn"/>textColumn</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod78" xreflabel="textColumn"/>textColumn</para></entry>
<entry align="left" valign="top"><para>::=
-<link linkend="prod2">id</link> <link linkend="prod35">dataType</link> ( <ID> <link linkend="prod78">intVal</link> )?</para></entry></row>
+<link linkend="prod2">id</link> <link linkend="prod35">dataType</link> ( <ID> <link linkend="prod79">intVal</link> )?</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod79" xreflabel="xmlQuery"/>xmlQuery</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod80" xreflabel="xmlQuery"/>xmlQuery</para></entry>
<entry align="left" valign="top"><para>::=
-<XMLQUERY> <LPAREN> ( <link linkend="prod80">xmlNamespaces</link> <COMMA> )? <link linkend="prod1">stringVal</link> ( <ID> <link linkend="prod62">derivedColumn</link> ( <COMMA> <link linkend="prod62">derivedColumn</link> )* )? ( ( <NULL> | <link linkend="prod18">nonReserved</link> ) <ON> <link linkend="prod18">nonReserved</link> )? <RPAREN></para></entry></row>
+<XMLQUERY> <LPAREN> ( <link linkend="prod81">xmlNamespaces</link> <COMMA> )? <link linkend="prod1">stringVal</link> ( <ID> <link linkend="prod62">derivedColumn</link> ( <COMMA> <link linkend="prod62">derivedColumn</link> )* )? ( ( <NULL> | <link linkend="prod18">nonReserved</link> ) <ON> <link linkend="prod18">nonReserved</link> )? <RPAREN></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod73" xreflabel="xmlTable"/>xmlTable</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod74" xreflabel="xmlTable"/>xmlTable</para></entry>
<entry align="left" valign="top"><para>::=
-<XMLTABLE> <LPAREN> ( <link linkend="prod80">xmlNamespaces</link> <COMMA> )? <link linkend="prod1">stringVal</link> ( <ID> <link linkend="prod62">derivedColumn</link> ( <COMMA> <link linkend="prod62">derivedColumn</link> )* )? ( <ID> <link linkend="prod81">xmlColumn</link> ( <COMMA> <link linkend="prod81">xmlColumn</link> )* )? <RPAREN> ( <AS> )? <link linkend="prod2">id</link></para></entry></row>
+<XMLTABLE> <LPAREN> ( <link linkend="prod81">xmlNamespaces</link> <COMMA> )? <link linkend="prod1">stringVal</link> ( <ID> <link linkend="prod62">derivedColumn</link> ( <COMMA> <link linkend="prod62">derivedColumn</link> )* )? ( <ID> <link linkend="prod82">xmlColumn</link> ( <COMMA> <link linkend="prod82">xmlColumn</link> )* )? <RPAREN> ( <AS> )? <link linkend="prod2">id</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod81" xreflabel="xmlColumn"/>xmlColumn</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod82" xreflabel="xmlColumn"/>xmlColumn</para></entry>
<entry align="left" valign="top"><para>::=
<link linkend="prod2">id</link> ( ( <FOR> <link linkend="prod18">nonReserved</link> ) | ( <link linkend="prod35">dataType</link> ( <DEFAULT_KEYWORD> <link linkend="prod21">expression</link> )? ( <link linkend="prod18">nonReserved</link> <link linkend="prod1">stringVal</link> )? ) )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod78" xreflabel="intVal"/>intVal</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod79" xreflabel="intVal"/>intVal</para></entry>
<entry align="left" valign="top"><para>::=
<INTEGERVAL></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod75" xreflabel="subqueryFromClause"/>subqueryFromClause</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod76" xreflabel="subqueryFromClause"/>subqueryFromClause</para></entry>
<entry align="left" valign="top"><para>::=
( <TABLE> )? <LPAREN> ( <link linkend="prod10">queryExpression</link> | <link linkend="prod11">storedProcedure</link> ) <RPAREN> ( <AS> )? <link linkend="prod2">id</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod74" xreflabel="unaryFromClause"/>unaryFromClause</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod75" xreflabel="unaryFromClause"/>unaryFromClause</para></entry>
<entry align="left" valign="top"><para>::=
( <ID> ( ( <AS> )? <link linkend="prod2">id</link> )? )</para></entry></row>
<row>
@@ -676,69 +680,69 @@
<row>
<entry align="right" valign="top"><para><anchor id="prod32" xreflabel="criteria"/>criteria</para></entry>
<entry align="left" valign="top"><para>::=
-<link linkend="prod82">compoundCritOr</link></para></entry></row>
+<link linkend="prod83">compoundCritOr</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod82" xreflabel="compoundCritOr"/>compoundCritOr</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod83" xreflabel="compoundCritOr"/>compoundCritOr</para></entry>
<entry align="left" valign="top"><para>::=
-<link linkend="prod83">compoundCritAnd</link> ( <OR> <link linkend="prod83">compoundCritAnd</link> )*</para></entry></row>
+<link linkend="prod84">compoundCritAnd</link> ( <OR> <link linkend="prod84">compoundCritAnd</link> )*</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod83" xreflabel="compoundCritAnd"/>compoundCritAnd</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod84" xreflabel="compoundCritAnd"/>compoundCritAnd</para></entry>
<entry align="left" valign="top"><para>::=
-<link linkend="prod84">notCrit</link> ( <AND> <link linkend="prod84">notCrit</link> )*</para></entry></row>
+<link linkend="prod85">notCrit</link> ( <AND> <link linkend="prod85">notCrit</link> )*</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod84" xreflabel="notCrit"/>notCrit</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod85" xreflabel="notCrit"/>notCrit</para></entry>
<entry align="left" valign="top"><para>::=
-( <NOT> )? <link linkend="prod85">booleanPrimary</link></para></entry></row>
+( <NOT> )? <link linkend="prod86">booleanPrimary</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod85" xreflabel="booleanPrimary"/>booleanPrimary</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod86" xreflabel="booleanPrimary"/>booleanPrimary</para></entry>
<entry align="left" valign="top"><para>::=
-( <link linkend="prod38">translateCriteria</link> | ( <link linkend="prod86">commonValueExpression</link> ( ( <link linkend="prod87">betweenCrit</link> | <link linkend="prod88">matchCrit</link> | <link linkend="prod89">setCrit</link> | <link linkend="prod90">isNullCrit</link> | <link linkend="prod91">subqueryCompareCriteria</link> | <link linkend="prod92">compareCrit</link> ) )? ) | <link linkend="prod93">existsCriteria</link> | <link linkend="prod34">hasCriteria</link> )</para></entry></row>
+( <link linkend="prod38">translateCriteria</link> | ( <link linkend="prod87">commonValueExpression</link> ( ( <link linkend="prod88">betweenCrit</link> | <link linkend="prod89">matchCrit</link> | <link linkend="prod90">setCrit</link> | <link linkend="prod91">isNullCrit</link> | <link linkend="prod92">subqueryCompareCriteria</link> | <link linkend="prod93">compareCrit</link> ) )? ) | <link linkend="prod94">existsCriteria</link> | <link linkend="prod34">hasCriteria</link> )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod94" xreflabel="operator"/>operator</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod95" xreflabel="operator"/>operator</para></entry>
<entry align="left" valign="top"><para>::=
( <EQ> | <NE> | <NE2> | <LT> | <LE> | <GT> | <GE> )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod92" xreflabel="compareCrit"/>compareCrit</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod93" xreflabel="compareCrit"/>compareCrit</para></entry>
<entry align="left" valign="top"><para>::=
-<link linkend="prod94">operator</link> <link linkend="prod86">commonValueExpression</link></para></entry></row>
+<link linkend="prod95">operator</link> <link linkend="prod87">commonValueExpression</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod95" xreflabel="subquery"/>subquery</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod96" xreflabel="subquery"/>subquery</para></entry>
<entry align="left" valign="top"><para>::=
<LPAREN> ( <link linkend="prod10">queryExpression</link> | ( <link linkend="prod11">storedProcedure</link> ) ) <RPAREN></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod91" xreflabel="subqueryCompareCriteria"/>subqueryCompareCriteria</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod92" xreflabel="subqueryCompareCriteria"/>subqueryCompareCriteria</para></entry>
<entry align="left" valign="top"><para>::=
-<link linkend="prod94">operator</link> ( <ANY> | <SOME> | <ALL> ) <link linkend="prod95">subquery</link></para></entry></row>
+<link linkend="prod95">operator</link> ( <ANY> | <SOME> | <ALL> ) <link linkend="prod96">subquery</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod88" xreflabel="matchCrit"/>matchCrit</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod89" xreflabel="matchCrit"/>matchCrit</para></entry>
<entry align="left" valign="top"><para>::=
-( <NOT> )? <LIKE> <link linkend="prod86">commonValueExpression</link> ( <ESCAPE> <link linkend="prod65">charVal</link> | ( <LBRACE> <ESCAPE> <link linkend="prod65">charVal</link> <RBRACE> ) )?</para></entry></row>
+( <NOT> )? <LIKE> <link linkend="prod87">commonValueExpression</link> ( <ESCAPE> <link linkend="prod65">charVal</link> | ( <LBRACE> <ESCAPE> <link linkend="prod65">charVal</link> <RBRACE> ) )?</para></entry></row>
<row>
<entry align="right" valign="top"><para><anchor id="prod65" xreflabel="charVal"/>charVal</para></entry>
<entry align="left" valign="top"><para>::=
<link linkend="prod1">stringVal</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod87" xreflabel="betweenCrit"/>betweenCrit</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod88" xreflabel="betweenCrit"/>betweenCrit</para></entry>
<entry align="left" valign="top"><para>::=
-( <NOT> )? <BETWEEN> <link linkend="prod86">commonValueExpression</link> <AND> <link linkend="prod86">commonValueExpression</link></para></entry></row>
+( <NOT> )? <BETWEEN> <link linkend="prod87">commonValueExpression</link> <AND> <link linkend="prod87">commonValueExpression</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod90" xreflabel="isNullCrit"/>isNullCrit</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod91" xreflabel="isNullCrit"/>isNullCrit</para></entry>
<entry align="left" valign="top"><para>::=
<IS> ( <NOT> )? <NULL></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod89" xreflabel="setCrit"/>setCrit</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod90" xreflabel="setCrit"/>setCrit</para></entry>
<entry align="left" valign="top"><para>::=
-( <NOT> )? <IN> ( ( <link linkend="prod95">subquery</link> ) | ( <LPAREN> <link linkend="prod86">commonValueExpression</link> ( <COMMA> <link linkend="prod86">commonValueExpression</link> )* <RPAREN> ) )</para></entry></row>
+( <NOT> )? <IN> ( ( <link linkend="prod96">subquery</link> ) | ( <LPAREN> <link linkend="prod87">commonValueExpression</link> ( <COMMA> <link linkend="prod87">commonValueExpression</link> )* <RPAREN> ) )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod93" xreflabel="existsCriteria"/>existsCriteria</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod94" xreflabel="existsCriteria"/>existsCriteria</para></entry>
<entry align="left" valign="top"><para>::=
-<EXISTS> <link linkend="prod95">subquery</link></para></entry></row>
+<EXISTS> <link linkend="prod96">subquery</link></para></entry></row>
<row>
<entry align="right" valign="top"><para><anchor id="prod57" xreflabel="groupBy"/>groupBy</para></entry>
<entry align="left" valign="top"><para>::=
-<GROUP> <BY> ( <link linkend="prod96">groupByItem</link> ( <COMMA> <link linkend="prod96">groupByItem</link> )* )</para></entry></row>
+<GROUP> <BY> ( <link linkend="prod97">groupByItem</link> ( <COMMA> <link linkend="prod97">groupByItem</link> )* )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod96" xreflabel="groupByItem"/>groupByItem</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod97" xreflabel="groupByItem"/>groupByItem</para></entry>
<entry align="left" valign="top"><para>::=
<link linkend="prod21">expression</link></para></entry></row>
<row>
@@ -748,13 +752,13 @@
<row>
<entry align="right" valign="top"><para><anchor id="prod50" xreflabel="orderby"/>orderby</para></entry>
<entry align="left" valign="top"><para>::=
-<ORDER> <BY> <link linkend="prod97">sortSpecification</link> ( <COMMA> <link linkend="prod97">sortSpecification</link> )*</para></entry></row>
+<ORDER> <BY> <link linkend="prod98">sortSpecification</link> ( <COMMA> <link linkend="prod98">sortSpecification</link> )*</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod97" xreflabel="sortSpecification"/>sortSpecification</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod98" xreflabel="sortSpecification"/>sortSpecification</para></entry>
<entry align="left" valign="top"><para>::=
-<link linkend="prod98">sortKey</link> ( <ASC> | <DESC> )? ( <link linkend="prod18">nonReserved</link> <link linkend="prod18">nonReserved</link> )?</para></entry></row>
+<link linkend="prod99">sortKey</link> ( <ASC> | <DESC> )? ( <link linkend="prod18">nonReserved</link> <link linkend="prod18">nonReserved</link> )?</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod98" xreflabel="sortKey"/>sortKey</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod99" xreflabel="sortKey"/>sortKey</para></entry>
<entry align="left" valign="top"><para>::=
<link linkend="prod21">expression</link></para></entry></row>
<row>
@@ -770,71 +774,71 @@
<entry align="left" valign="top"><para>::=
<link linkend="prod32">criteria</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod86" xreflabel="commonValueExpression"/>commonValueExpression</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod87" xreflabel="commonValueExpression"/>commonValueExpression</para></entry>
<entry align="left" valign="top"><para>::=
-( <link linkend="prod99">plusExpression</link> ( <CONCAT_OP> <link linkend="prod99">plusExpression</link> )* )</para></entry></row>
+( <link linkend="prod100">plusExpression</link> ( <CONCAT_OP> <link linkend="prod100">plusExpression</link> )* )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod99" xreflabel="plusExpression"/>plusExpression</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod100" xreflabel="plusExpression"/>plusExpression</para></entry>
<entry align="left" valign="top"><para>::=
-( <link linkend="prod100">timesExpression</link> ( <link linkend="prod101">plusOperator</link> <link linkend="prod100">timesExpression</link> )* )</para></entry></row>
+( <link linkend="prod101">timesExpression</link> ( <link linkend="prod102">plusOperator</link> <link linkend="prod101">timesExpression</link> )* )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod101" xreflabel="plusOperator"/>plusOperator</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod102" xreflabel="plusOperator"/>plusOperator</para></entry>
<entry align="left" valign="top"><para>::=
( <PLUS> | <MINUS> )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod100" xreflabel="timesExpression"/>timesExpression</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod101" xreflabel="timesExpression"/>timesExpression</para></entry>
<entry align="left" valign="top"><para>::=
-( <link linkend="prod102">valueExpressionPrimary</link> ( <link linkend="prod103">timesOperator</link> <link linkend="prod102">valueExpressionPrimary</link> )* )</para></entry></row>
+( <link linkend="prod103">valueExpressionPrimary</link> ( <link linkend="prod104">timesOperator</link> <link linkend="prod103">valueExpressionPrimary</link> )* )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod103" xreflabel="timesOperator"/>timesOperator</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod104" xreflabel="timesOperator"/>timesOperator</para></entry>
<entry align="left" valign="top"><para>::=
( <STAR> | <SLASH> )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod102" xreflabel="valueExpressionPrimary"/>valueExpressionPrimary</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod103" xreflabel="valueExpressionPrimary"/>valueExpressionPrimary</para></entry>
<entry align="left" valign="top"><para>::=
-( <QMARK> | <link linkend="prod104">literal</link> | ( <LBRACE> <link linkend="prod18">nonReserved</link> <link linkend="prod105">function</link> <RBRACE> ) | ( <link linkend="prod64">textAgg</link> ) | ( <link linkend="prod66">aggregateSymbol</link> ) | ( <link linkend="prod66">aggregateSymbol</link> ) | ( <link linkend="prod66">aggregateSymbol</link> ) | ( <link linkend="prod63">xmlAgg</link> ) | ( <link linkend="prod105">function</link> ) | ( <ID> ) | <link linkend="prod95">subquery</link> | ( <LPAREN> <link linkend="prod21">expression</link> <RPAREN> ) | <link linkend="prod106">searchedCaseExpression</link> | <link linkend="prod107">caseExpression</link> )</para></entry></row>
+( <QMARK> | <link linkend="prod105">literal</link> | ( <LBRACE> <link linkend="prod18">nonReserved</link> <link linkend="prod106">function</link> <RBRACE> ) | ( <link linkend="prod64">textAgg</link> ) | ( <link linkend="prod66">aggregateSymbol</link> ) | ( <link linkend="prod66">aggregateSymbol</link> ) | ( <link linkend="prod66">aggregateSymbol</link> ) | ( <link linkend="prod63">xmlAgg</link> ) | ( <link linkend="prod106">function</link> ) | ( <ID> ) | <link linkend="prod96">subquery</link> | ( <LPAREN> <link linkend="prod21">expression</link> <RPAREN> ) | <link linkend="prod107">searchedCaseExpression</link> | <link linkend="prod108">caseExpression</link> )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod107" xreflabel="caseExpression"/>caseExpression</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod108" xreflabel="caseExpression"/>caseExpression</para></entry>
<entry align="left" valign="top"><para>::=
<CASE> <link linkend="prod21">expression</link> ( <WHEN> <link linkend="prod21">expression</link> <THEN> <link linkend="prod21">expression</link> )+ ( <ELSE> <link linkend="prod21">expression</link> )? <END></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod106" xreflabel="searchedCaseExpression"/>searchedCaseExpression</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod107" xreflabel="searchedCaseExpression"/>searchedCaseExpression</para></entry>
<entry align="left" valign="top"><para>::=
<CASE> ( <WHEN> <link linkend="prod32">criteria</link> <THEN> <link linkend="prod21">expression</link> )+ ( <ELSE> <link linkend="prod21">expression</link> )? <END></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod105" xreflabel="function"/>function</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod106" xreflabel="function"/>function</para></entry>
<entry align="left" valign="top"><para>::=
-( ( <CONVERT> <LPAREN> <link linkend="prod21">expression</link> <COMMA> <link linkend="prod35">dataType</link> <RPAREN> ) | ( <CAST> <LPAREN> <link linkend="prod21">expression</link> <AS> <link linkend="prod35">dataType</link> <RPAREN> ) | ( <link linkend="prod18">nonReserved</link> <LPAREN> <link linkend="prod21">expression</link> <COMMA> <link linkend="prod108">stringConstant</link> <RPAREN> ) | ( <link linkend="prod18">nonReserved</link> <LPAREN> <link linkend="prod109">intervalType</link> <COMMA> <link linkend="prod21">expression</link> <COMMA> <link linkend="prod21">expression</link> <RPAREN> ) | <link linkend="prod110">queryString</link> | ( ( <LEFT> | <RIGHT> | <CHAR> | <USER> | <YEAR> | <MONTH> | <HOUR> | <MINUTE> | <SECOND> | <XMLCONCAT> | <XMLCOMMENT> ) <LPAREN> ( <link linkend="prod21">expression</link> !
( <COMMA> <link linkend="prod21">expression</link> )* )? <RPAREN> ) | ( ( <INSERT> ) <LPAREN> ( <link linkend="prod21">expression</link> ( <COMMA> <link linkend="prod21">expression</link> )* )? <RPAREN> ) | ( ( <TRANSLATE> ) <LPAREN> ( <link linkend="prod21">expression</link> ( <COMMA> <link linkend="prod21">expression</link> )* )? <RPAREN> ) | <link linkend="prod111">xmlParse</link> | <link linkend="prod112">xmlElement</link> | ( <XMLPI> <LPAREN> ( <ID> <link linkend="prod113">idExpression</link> | <link linkend="prod113">idExpression</link> ) ( <COMMA> <link linkend="prod21">expression</link> )? <RPAREN> ) | <link linkend="prod114">xmlForest</link> | <link linkend="prod76">xmlSerialize</link> | <link linkend="prod79">xmlQuery</link> | ( <link linkend="prod2">id</link> <LPAREN> ( <link linkend="prod21">expression</link> ( <COMMA> <link linkend="prod21">expression</link> )*!
)? <RPAREN> ) )</para></entry></row>
+( ( <CONVERT> <LPAREN> <link linkend="prod21">expression</link> <COMMA> <link linkend="prod35">dataType</link> <RPAREN> ) | ( <CAST> <LPAREN> <link linkend="prod21">expression</link> <AS> <link linkend="prod35">dataType</link> <RPAREN> ) | ( <link linkend="prod18">nonReserved</link> <LPAREN> <link linkend="prod21">expression</link> <COMMA> <link linkend="prod109">stringConstant</link> <RPAREN> ) | ( <link linkend="prod18">nonReserved</link> <LPAREN> <link linkend="prod110">intervalType</link> <COMMA> <link linkend="prod21">expression</link> <COMMA> <link linkend="prod21">expression</link> <RPAREN> ) | <link linkend="prod111">queryString</link> | ( ( <LEFT> | <RIGHT> | <CHAR> | <USER> | <YEAR> | <MONTH> | <HOUR> | <MINUTE> | <SECOND> | <XMLCONCAT> | <XMLCOMMENT> ) <LPAREN> ( <link linkend="prod21">expression</link> !
( <COMMA> <link linkend="prod21">expression</link> )* )? <RPAREN> ) | ( ( <INSERT> ) <LPAREN> ( <link linkend="prod21">expression</link> ( <COMMA> <link linkend="prod21">expression</link> )* )? <RPAREN> ) | ( ( <TRANSLATE> ) <LPAREN> ( <link linkend="prod21">expression</link> ( <COMMA> <link linkend="prod21">expression</link> )* )? <RPAREN> ) | <link linkend="prod112">xmlParse</link> | <link linkend="prod113">xmlElement</link> | ( <XMLPI> <LPAREN> ( <ID> <link linkend="prod114">idExpression</link> | <link linkend="prod114">idExpression</link> ) ( <COMMA> <link linkend="prod21">expression</link> )? <RPAREN> ) | <link linkend="prod115">xmlForest</link> | <link linkend="prod77">xmlSerialize</link> | <link linkend="prod80">xmlQuery</link> | ( <link linkend="prod2">id</link> <LPAREN> ( <link linkend="prod21">expression</link> ( <COMMA> <link linkend="prod21">expression</link> )*!
)? <RPAREN> ) )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod108" xreflabel="stringConstant"/>stringConstant</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod109" xreflabel="stringConstant"/>stringConstant</para></entry>
<entry align="left" valign="top"><para>::=
<link linkend="prod1">stringVal</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod111" xreflabel="xmlParse"/>xmlParse</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod112" xreflabel="xmlParse"/>xmlParse</para></entry>
<entry align="left" valign="top"><para>::=
<XMLPARSE> <LPAREN> <link linkend="prod18">nonReserved</link> <link linkend="prod21">expression</link> ( <link linkend="prod18">nonReserved</link> )? <RPAREN></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod110" xreflabel="queryString"/>queryString</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod111" xreflabel="queryString"/>queryString</para></entry>
<entry align="left" valign="top"><para>::=
<link linkend="prod18">nonReserved</link> <LPAREN> <link linkend="prod21">expression</link> ( <COMMA> <link linkend="prod62">derivedColumn</link> )* <RPAREN></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod112" xreflabel="xmlElement"/>xmlElement</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod113" xreflabel="xmlElement"/>xmlElement</para></entry>
<entry align="left" valign="top"><para>::=
-<XMLELEMENT> <LPAREN> ( <ID> <link linkend="prod2">id</link> | <link linkend="prod2">id</link> ) ( <COMMA> <link linkend="prod80">xmlNamespaces</link> )? ( <COMMA> <link linkend="prod115">xmlAttributes</link> )? ( <COMMA> <link linkend="prod21">expression</link> )* <RPAREN></para></entry></row>
+<XMLELEMENT> <LPAREN> ( <ID> <link linkend="prod2">id</link> | <link linkend="prod2">id</link> ) ( <COMMA> <link linkend="prod81">xmlNamespaces</link> )? ( <COMMA> <link linkend="prod116">xmlAttributes</link> )? ( <COMMA> <link linkend="prod21">expression</link> )* <RPAREN></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod115" xreflabel="xmlAttributes"/>xmlAttributes</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod116" xreflabel="xmlAttributes"/>xmlAttributes</para></entry>
<entry align="left" valign="top"><para>::=
<XMLATTRIBUTES> <LPAREN> <link linkend="prod62">derivedColumn</link> ( <COMMA> <link linkend="prod62">derivedColumn</link> )* <RPAREN></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod114" xreflabel="xmlForest"/>xmlForest</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod115" xreflabel="xmlForest"/>xmlForest</para></entry>
<entry align="left" valign="top"><para>::=
-<XMLFOREST> <LPAREN> ( <link linkend="prod80">xmlNamespaces</link> <COMMA> )? <link linkend="prod62">derivedColumn</link> ( <COMMA> <link linkend="prod62">derivedColumn</link> )* <RPAREN></para></entry></row>
+<XMLFOREST> <LPAREN> ( <link linkend="prod81">xmlNamespaces</link> <COMMA> )? <link linkend="prod62">derivedColumn</link> ( <COMMA> <link linkend="prod62">derivedColumn</link> )* <RPAREN></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod80" xreflabel="xmlNamespaces"/>xmlNamespaces</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod81" xreflabel="xmlNamespaces"/>xmlNamespaces</para></entry>
<entry align="left" valign="top"><para>::=
-<XMLNAMESPACES> <LPAREN> <link linkend="prod116">namespaceItem</link> ( <COMMA> <link linkend="prod116">namespaceItem</link> )* <RPAREN></para></entry></row>
+<XMLNAMESPACES> <LPAREN> <link linkend="prod117">namespaceItem</link> ( <COMMA> <link linkend="prod117">namespaceItem</link> )* <RPAREN></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod116" xreflabel="namespaceItem"/>namespaceItem</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod117" xreflabel="namespaceItem"/>namespaceItem</para></entry>
<entry align="left" valign="top"><para>::=
( <link linkend="prod1">stringVal</link> <AS> <link linkend="prod2">id</link> )</para></entry></row>
<row>
@@ -846,7 +850,7 @@
<entry align="left" valign="top"><para>::=
( <DEFAULT_KEYWORD> <link linkend="prod1">stringVal</link> )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod113" xreflabel="idExpression"/>idExpression</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod114" xreflabel="idExpression"/>idExpression</para></entry>
<entry align="left" valign="top"><para>::=
<link linkend="prod2">id</link></para></entry></row>
<row>
@@ -858,11 +862,11 @@
<entry align="left" valign="top"><para>::=
<link linkend="prod19">dataTypeString</link></para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod109" xreflabel="intervalType"/>intervalType</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod110" xreflabel="intervalType"/>intervalType</para></entry>
<entry align="left" valign="top"><para>::=
( <link linkend="prod18">nonReserved</link> )</para></entry></row>
<row>
-<entry align="right" valign="top"><para><anchor id="prod104" xreflabel="literal"/>literal</para></entry>
+<entry align="right" valign="top"><para><anchor id="prod105" xreflabel="literal"/>literal</para></entry>
<entry align="left" valign="top"><para>::=
( <link linkend="prod1">stringVal</link> | <INTEGERVAL> | <FLOATVAL> | <FALSE> | <TRUE> | <UNKNOWN> | <NULL> | ( ( <BOOLEANTYPE> | <TIMESTAMPTYPE> | <DATETYPE> | <TIMETYPE> ) <link linkend="prod1">stringVal</link> <RBRACE> ) )</para></entry></row>
</tbody>
Modified: trunk/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml
===================================================================
--- trunk/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml 2011-02-10 19:56:37 UTC (rev 2903)
@@ -42,7 +42,7 @@
</entry>
<entry>
<para>x in {integer, long, float, double, biginteger,
- bigdecimal}, return type is same as x <footnote>The precision and scale of non-bigdecimal arithmetic function functions results matches that of Java. The results of bigdecimal operations match Java, except for division, which uses a preferred scale of max(16, dividend.scale + divisor.precision + 1), which then has trailing zeros removed by setting the scale to max(dividend.scale, normalized scale)</footnote></para>
+ bigdecimal}, return type is same as x <footnote><para>The precision and scale of non-bigdecimal arithmetic function functions results matches that of Java. The results of bigdecimal operations match Java, except for division, which uses a preferred scale of max(16, dividend.scale + divisor.precision + 1), which then has trailing zeros removed by setting the scale to max(dividend.scale, normalized scale)</para></footnote></para>
</entry>
</row>
<row>
@@ -2077,7 +2077,21 @@
<section>
<title>Miscellaneous Functions</title>
<para>Other functions.</para>
+ <section id="array_get">
+ <title>array_get</title>
+ <para>Retuns the object value at a given array index.</para>
+ <para><synopsis>array_get(array, index)</synopsis></para>
+ <para>array is the object type, index must be an integer, and the return type is object.</para>
+ <para>1-based indexing is used. The actual array value should be a java.sql.Array or java array type. An exception will be thrown if the array value is the wrong type of the index is out of bounds.</para>
+ </section>
<section>
+ <title>array_length</title>
+ <para>Returns the length for a given array</para>
+ <para><synopsis>array_length(array)</synopsis></para>
+ <para>array is the object type, and the return type is integer.</para>
+ <para>The actual array value should be a java.sql.Array or java array type. An exception will be thrown if the array value is the wrong type.</para>
+ </section>
+ <section>
<title>uuid</title>
<para>Retuns a universally unique identifier.</para>
<para><synopsis>uuid()</synopsis></para>
Modified: trunk/documentation/reference/src/main/docbook/en-US/content/sql_support.xml
===================================================================
--- trunk/documentation/reference/src/main/docbook/en-US/content/sql_support.xml 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/documentation/reference/src/main/docbook/en-US/content/sql_support.xml 2011-02-10 19:56:37 UTC (rev 2903)
@@ -799,6 +799,7 @@
<listitem><para>FROM table1 left outer join <link linkend="optional_join">/*+ optional */</link> table2 ON join-criteria</para></listitem>
<listitem><para>FROM <link linkend="texttable">TEXTTABLE...</link></para></listitem>
<listitem><para>FROM <link linkend="xmltable">XMLTABLE...</link></para></listitem>
+ <listitem><para>FROM <link linkend="arraytable">ARRAYTABLE...</link></para></listitem>
</itemizedlist>
<note>
<title>DEP Hints</title>
@@ -966,6 +967,41 @@
</itemizedlist>
</section>
</section>
+ <section id="arraytable">
+ <title>ARRAYTABLE</title>
+ <para>The ARRAYTABLE funciton processes an array input to produce tabular ouptut.
+ The function itself defines what columns it projects.
+ The ARRAYTABLE function is implicitly a nested table and may be correlated to preceeding FROM clause entries.
+ </para>
+ <para>
+ Usage:
+ <synopsis label="Usage">ARRAYTABLE(expression COLUMNS <COLUMN>, ...) AS name</synopsis>
+ <synopsis label="Usage">COLUMN := name datatype</synopsis>
+ </para>
+ <itemizedlist>
+ <para>Parameters</para>
+ <listitem>
+ <para>expression - the array to process, which should be a java.sql.Array or java array value.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <itemizedlist>
+ <para>Syntax Rules:
+ </para>
+ <listitem>
+ <para>The columns names must be not contain duplicates.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <itemizedlist>
+ <para>Examples</para>
+ <listitem>
+ <para>As a nested table: <programlisting>select x.* from (call source.invokeMDX('some query')) r, arraytable(r.tuple COLUMNS first string, second bigdecimal) x</programlisting>
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>ARRAYTABLE is effectively a shortcut for using the <xref linkend="array_get"/> function in a nested table. For example "ARRAYGET(val COLUMNS col1 string, col2 integer) AS X" is the same as "TABLE(SELECT cast(array_get(val, 1) AS string) AS col1, cast(array_get(val, 2) AS integer) AS col2) AS X".</para>
+ </section>
<section id="where_clause">
<title>WHERE Clause</title>
<para>
Modified: trunk/documentation/reference/src/main/docbook/en-US/content/translators.xml
===================================================================
--- trunk/documentation/reference/src/main/docbook/en-US/content/translators.xml 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/documentation/reference/src/main/docbook/en-US/content/translators.xml 2011-02-10 19:56:37 UTC (rev 2903)
@@ -1019,16 +1019,14 @@
<title>OLAP Translator</title>
<para>
The OLAP Services translator, known by the type name <emphasis>olap</emphasis>,
- exposes stored procedures for calling analysis sevices backed by a OLAP server using MDX query lanaguage. Given the MDX
- query, this translator executes the query and returns the results in XML format.
- It will commonly be used with the <link linkend="xmltable">XMLTABLE</link> table functions to use XML formated data.
+ exposes stored procedures for calling analysis sevices backed by a OLAP server using MDX query lanaguage.
+ This translator exposes a stored procedure, invokeMDX, that returns a result set containing tuple array values for a given MDX query.
+ invokeMDX will commonly be used with the <link linkend="arraytable">ARRAYTABLE</link> table function to extract the results.
</para>
<para>
Since the Cube metadata exposed by the OLAP servers and relational database metadata are so different, there is no single
- way to map the metadata from one to other. It is best that OLAP system be queried using its own native MDX language
- through Teiid abstraction layers than introducing a custom Teiid based MDX like extensions for querying. To build MDX
- queries dynamically use Teiid's abstraction layer define your target schema in relational terms and use Teiid's procedural
- langaugage to build a query.
+ way to map the metadata from one to other. It is best to query OLAP system using its own native MDX language
+ through. MDX queries my be defined statically or built dynamically in Teiid's abstraction layers.
</para>
<section>
@@ -1040,32 +1038,17 @@
<section>
<title>InvokeMDX Procedure</title>
<para>
- <methodname>invokeMdx</methodname> returns the XML contents of results in tabular form.
+ <methodname>invokeMdx</methodname> returns a resultset of the tuples as array values.
</para>
- <programlisting>Procedure invokeMdx(mdx in STRING) returns SQLXML</programlisting>
+ <programlisting>Procedure invokeMdx(mdx in STRING) returns resultset (tuple object)</programlisting>
<para>
- mdx parameter indicates the query in its original form that is to be executed on the OLAP server.
+ The mdx parameter is a MDX query to be executed on the OLAP server.
</para>
<para>
- The results of the query will be returned in SQLXML form that in the format as shown below.
- <programlisting role="XML" language="XML"><![CDATA[
- <?xml version="1.0" encoding="UTF-8"?>
- <resultset>
- <row>
- <Promotion_Media>All Media</Promotion_Media>
- <Product>All Products</Product>
- <Unit_Sales>266773.0</Unit_Sales>
- <Store_Cost>225627.2336</Store_Cost>
- <Store_Sales>565238.13</Store_Sales>
- </row>
- </resultset>
- ]]></programlisting>
- From the above XML result, the first two columns in the row were the members from the row axis and the
- last three columns are the measures from the cube from column axis. Currently the resultset only supports
- 2 dimentional cube.
+ The results of the query will be returned such that each row on the row axis will be packed into an array value that will first contain each hierarcy member name on the row axis then each measure value from the column axis.
</para>
-
+ <note><para>Currently the resultset only supports 2 dimentional cube.</para></note>
<para>
This translator requires a data source to be configured to the OLAP cube using OLAP4J JDBC driver. Two sample
-ds.xml files provided for accessing OLAP servers in teiid-examples section. One is Mondrian specific, when Mondrian server is deloyed
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/PreparedStatementRequest.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/PreparedStatementRequest.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/PreparedStatementRequest.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -100,7 +100,7 @@
if (!proc.isCallableStatement()) {
return;
}
- List values = requestMsg.getParameterValues();
+ List<?> values = requestMsg.getParameterValues();
List<SPParameter> spParams = proc.getParameters();
proc.clearParameters();
int inParameterCount = values.size();
Modified: trunk/engine/src/main/java/org/teiid/query/function/FunctionMethods.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/FunctionMethods.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/engine/src/main/java/org/teiid/query/function/FunctionMethods.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -25,12 +25,14 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
+import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.nio.charset.Charset;
import java.sql.Blob;
import java.sql.Clob;
+import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.DateFormat;
@@ -1380,4 +1382,28 @@
return UUID.randomUUID().toString();
}
+ public static Object array_get(Object array, int index) throws FunctionExecutionException, SQLException {
+ try {
+ if (array.getClass().isArray()) {
+ return Array.get(array, index - 1);
+ }
+ if (array instanceof java.sql.Array) {
+ return Array.get(((java.sql.Array)array).getArray(index, 1), 0);
+ }
+ } catch (ArrayIndexOutOfBoundsException e) {
+ throw new FunctionExecutionException(QueryPlugin.Util.getString("FunctionMethods.array_index", index)); //$NON-NLS-1$
+ }
+ throw new FunctionExecutionException(QueryPlugin.Util.getString("FunctionMethods.not_array_value", array.getClass())); //$NON-NLS-1$
+ }
+
+ public static int array_length(Object array) throws FunctionExecutionException, SQLException {
+ if (array.getClass().isArray()) {
+ return Array.getLength(array);
+ }
+ if (array instanceof java.sql.Array) {
+ return Array.getLength(((java.sql.Array)array).getArray());
+ }
+ throw new FunctionExecutionException(QueryPlugin.Util.getString("FunctionMethods.not_array_value", array.getClass())); //$NON-NLS-1$
+ }
+
}
Modified: trunk/engine/src/main/java/org/teiid/query/function/source/SystemSource.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/source/SystemSource.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/engine/src/main/java/org/teiid/query/function/source/SystemSource.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -194,14 +194,30 @@
addUnescape();
addUuidFunction();
+ addArrayGet();
+ addArrayLength();
}
- private void addUnescape() {
+ private void addArrayLength() {
+ functions.add(new FunctionMethod(SourceSystemFunctions.ARRAY_LENGTH, QueryPlugin.Util.getString("SystemSource.array_length_desc"), MISCELLANEOUS, PushDown.CAN_PUSHDOWN, FUNCTION_CLASS, SourceSystemFunctions.ARRAY_LENGTH, //$NON-NLS-1$
+ new FunctionParameter[] {
+ new FunctionParameter("array", DataTypeManager.DefaultDataTypes.OBJECT, QueryPlugin.Util.getString("SystemSource.array_param1"))}, //$NON-NLS-1$ //$NON-NLS-2$
+ new FunctionParameter("result", DataTypeManager.DefaultDataTypes.INTEGER, QueryPlugin.Util.getString("SystemSource.array_length_result")), false, Determinism.DETERMINISTIC ) ); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ private void addArrayGet() {
+ functions.add(new FunctionMethod(SourceSystemFunctions.ARRAY_GET, QueryPlugin.Util.getString("SystemSource.array_get_desc"), MISCELLANEOUS, PushDown.CAN_PUSHDOWN, FUNCTION_CLASS, SourceSystemFunctions.ARRAY_GET, //$NON-NLS-1$
+ new FunctionParameter[] {
+ new FunctionParameter("array", DataTypeManager.DefaultDataTypes.OBJECT, QueryPlugin.Util.getString("SystemSource.array_param1")), //$NON-NLS-1$ //$NON-NLS-2$
+ new FunctionParameter("index", DataTypeManager.DefaultDataTypes.INTEGER, QueryPlugin.Util.getString("SystemSource.array_get_param2"))}, //$NON-NLS-1$ //$NON-NLS-2$
+ new FunctionParameter("result", DataTypeManager.DefaultDataTypes.OBJECT, QueryPlugin.Util.getString("SystemSource.array_get_result")), false, Determinism.DETERMINISTIC ) ); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ private void addUnescape() {
functions.add(new FunctionMethod(SourceSystemFunctions.UNESCAPE, QueryPlugin.Util.getString("SystemSource.unescape_desc"), STRING, PushDown.CANNOT_PUSHDOWN, FUNCTION_CLASS, SourceSystemFunctions.UNESCAPE, //$NON-NLS-1$
new FunctionParameter[] {
new FunctionParameter("string", DataTypeManager.DefaultDataTypes.STRING, QueryPlugin.Util.getString("SystemSource.unescape_param1"))}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, QueryPlugin.Util.getString("SystemSource.unescape_result")), false, Determinism.DETERMINISTIC ) ); //$NON-NLS-1$ //$NON-NLS-2$
-
}
private void addSecurityFunctions() {
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -24,7 +24,6 @@
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -50,6 +49,7 @@
import org.teiid.query.optimizer.relational.rules.FrameUtil;
import org.teiid.query.processor.ProcessorPlan;
import org.teiid.query.processor.relational.AccessNode;
+import org.teiid.query.processor.relational.ArrayTableNode;
import org.teiid.query.processor.relational.DependentAccessNode;
import org.teiid.query.processor.relational.DependentProcedureAccessNode;
import org.teiid.query.processor.relational.DependentProcedureExecutionNode;
@@ -76,6 +76,7 @@
import org.teiid.query.processor.relational.MergeJoinStrategy.SortOption;
import org.teiid.query.processor.relational.SortUtility.Mode;
import org.teiid.query.resolver.util.ResolverUtil;
+import org.teiid.query.sql.lang.ArrayTable;
import org.teiid.query.sql.lang.Command;
import org.teiid.query.sql.lang.Criteria;
import org.teiid.query.sql.lang.Insert;
@@ -408,6 +409,14 @@
processNode = ttn;
break;
}
+ if (source instanceof ArrayTable) {
+ ArrayTableNode atn = new ArrayTableNode(getID());
+ ArrayTable at = (ArrayTable)source;
+ updateGroupName(node, at);
+ atn.setTable(at);
+ processNode = atn;
+ break;
+ }
return null;
case NodeConstants.Types.SET_OP:
Operation setOp = (Operation) node.getProperty(NodeConstants.Info.SET_OPERATION);
Added: trunk/engine/src/main/java/org/teiid/query/processor/relational/ArrayTableNode.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/relational/ArrayTableNode.java (rev 0)
+++ trunk/engine/src/main/java/org/teiid/query/processor/relational/ArrayTableNode.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -0,0 +1,123 @@
+/*
+ * 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.query.processor.relational;
+
+import java.lang.reflect.Array;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Map;
+
+import org.teiid.api.exception.query.FunctionExecutionException;
+import org.teiid.common.buffer.BlockedException;
+import org.teiid.common.buffer.BufferManager;
+import org.teiid.common.buffer.TupleBatch;
+import org.teiid.core.TeiidComponentException;
+import org.teiid.core.TeiidProcessingException;
+import org.teiid.core.types.DataTypeManager;
+import org.teiid.core.types.TransformationException;
+import org.teiid.query.QueryPlugin;
+import org.teiid.query.processor.ProcessorDataManager;
+import org.teiid.query.sql.lang.ArrayTable;
+import org.teiid.query.sql.lang.TableFunctionReference.ProjectedColumn;
+import org.teiid.query.util.CommandContext;
+
+/**
+ * Handles array table processing.
+ */
+public class ArrayTableNode extends SubqueryAwareRelationalNode {
+
+ private ArrayTable table;
+
+ //initialized state
+ private int[] projectionIndexes;
+
+ public ArrayTableNode(int nodeID) {
+ super(nodeID);
+ }
+
+ @Override
+ public void initialize(CommandContext context, BufferManager bufferManager,
+ ProcessorDataManager dataMgr) {
+ super.initialize(context, bufferManager, dataMgr);
+ if (projectionIndexes != null) {
+ return;
+ }
+ Map elementMap = createLookupMap(table.getProjectedSymbols());
+ this.projectionIndexes = getProjectionIndexes(elementMap, getElements());
+ }
+
+ @Override
+ public void closeDirect() {
+ super.closeDirect();
+ reset();
+ }
+
+ public void setTable(ArrayTable table) {
+ this.table = table;
+ }
+
+ @Override
+ public ArrayTableNode clone() {
+ ArrayTableNode clone = new ArrayTableNode(getID());
+ this.copy(this, clone);
+ clone.setTable(table);
+ return clone;
+ }
+
+ @Override
+ protected TupleBatch nextBatchDirect() throws BlockedException,
+ TeiidComponentException, TeiidProcessingException {
+ ArrayList<Object> tuple = new ArrayList<Object>(projectionIndexes.length);
+
+ Object array = getEvaluator(Collections.emptyMap()).evaluate(table.getArrayValue(), null);
+
+ if (!array.getClass().isArray()) {
+ if (array instanceof java.sql.Array) {
+ try {
+ array = ((java.sql.Array)array).getArray();
+ } catch (SQLException e) {
+ throw new TeiidProcessingException(e);
+ }
+ } else {
+ throw new FunctionExecutionException(QueryPlugin.Util.getString("FunctionMethods.not_array_value", array.getClass())); //$NON-NLS-1$
+ }
+ }
+
+ for (int output : projectionIndexes) {
+ ProjectedColumn col = table.getColumns().get(output);
+ try {
+ Object val = Array.get(array, output);
+ tuple.add(DataTypeManager.transformValue(val, table.getColumns().get(output).getSymbol().getType()));
+ } catch (TransformationException e) {
+ throw new TeiidProcessingException(e, QueryPlugin.Util.getString("ArrayTableNode.conversion_error", col.getName())); //$NON-NLS-1$
+ } catch (ArrayIndexOutOfBoundsException e) {
+ throw new FunctionExecutionException(QueryPlugin.Util.getString("FunctionMethods.array_index", output + 1)); //$NON-NLS-1$
+ }
+ }
+ addBatchRow(tuple);
+ terminateBatches();
+ return pullBatch();
+ }
+
+}
Property changes on: trunk/engine/src/main/java/org/teiid/query/processor/relational/ArrayTableNode.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: trunk/engine/src/main/java/org/teiid/query/resolver/command/SimpleQueryResolver.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/resolver/command/SimpleQueryResolver.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/engine/src/main/java/org/teiid/query/resolver/command/SimpleQueryResolver.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -52,6 +52,7 @@
import org.teiid.query.resolver.util.ResolverUtil;
import org.teiid.query.resolver.util.ResolverVisitor;
import org.teiid.query.sql.LanguageObject;
+import org.teiid.query.sql.lang.ArrayTable;
import org.teiid.query.sql.lang.Command;
import org.teiid.query.sql.lang.ExistsCriteria;
import org.teiid.query.sql.lang.From;
@@ -345,6 +346,13 @@
}
@Override
+ public void visit(ArrayTable obj) {
+ LinkedHashSet<GroupSymbol> saved = preTableFunctionReference(obj);
+ visitNode(obj.getArrayValue());
+ postTableFunctionReference(obj, saved);
+ }
+
+ @Override
public void visit(XMLTable obj) {
LinkedHashSet<GroupSymbol> saved = preTableFunctionReference(obj);
visitNodes(obj.getPassing());
Modified: trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -76,6 +76,7 @@
import org.teiid.query.sql.ProcedureReservedWords;
import org.teiid.query.sql.LanguageObject.Util;
import org.teiid.query.sql.lang.AbstractSetCriteria;
+import org.teiid.query.sql.lang.ArrayTable;
import org.teiid.query.sql.lang.BatchedUpdateCommand;
import org.teiid.query.sql.lang.BetweenCriteria;
import org.teiid.query.sql.lang.Command;
@@ -1039,6 +1040,9 @@
XMLTable xt = (XMLTable)clause;
xt.rewriteDefaultColumn();
rewriteExpressions(clause);
+ } else if (clause instanceof ArrayTable) {
+ ArrayTable at = (ArrayTable)clause;
+ at.setArrayValue(rewriteExpressionDirect(at.getArrayValue()));
}
return clause;
}
Modified: trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -139,4 +139,5 @@
public void visit(ExpressionCriteria obj) {}
public void visit(WithQueryCommand obj) {}
public void visit(TriggerAction obj) {}
+ public void visit(ArrayTable obj) {}
}
Added: trunk/engine/src/main/java/org/teiid/query/sql/lang/ArrayTable.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/lang/ArrayTable.java (rev 0)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/ArrayTable.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -0,0 +1,85 @@
+/*
+ * 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.query.sql.lang;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.teiid.core.util.EquivalenceUtil;
+import org.teiid.query.sql.LanguageVisitor;
+import org.teiid.query.sql.symbol.Expression;
+
+/**
+ * Represents the ArrayTable table function.
+ */
+public class ArrayTable extends TableFunctionReference {
+
+ private Expression arrayValue;
+ private List<ProjectedColumn> columns = new ArrayList<ProjectedColumn>();
+
+ public List<ProjectedColumn> getColumns() {
+ return columns;
+ }
+
+ public void setColumns(List<ProjectedColumn> columns) {
+ this.columns = columns;
+ }
+
+ public Expression getArrayValue() {
+ return arrayValue;
+ }
+
+ public void setArrayValue(Expression arrayValue) {
+ this.arrayValue = arrayValue;
+ }
+
+ @Override
+ public void acceptVisitor(LanguageVisitor visitor) {
+ visitor.visit(this);
+ }
+
+ @Override
+ public ArrayTable clone() {
+ ArrayTable clone = new ArrayTable();
+ this.copy(clone);
+ clone.setArrayValue((Expression)this.arrayValue.clone());
+ for (ProjectedColumn column : columns) {
+ clone.getColumns().add(column.copyTo(new ProjectedColumn()));
+ }
+ return clone;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!super.equals(obj) || !(obj instanceof ArrayTable)) {
+ return false;
+ }
+ ArrayTable other = (ArrayTable)obj;
+ return this.columns.equals(other.columns)
+ && EquivalenceUtil.areEqual(arrayValue, other.arrayValue);
+ }
+
+}
Property changes on: trunk/engine/src/main/java/org/teiid/query/sql/lang/ArrayTable.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: trunk/engine/src/main/java/org/teiid/query/sql/lang/TableFunctionReference.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/lang/TableFunctionReference.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/TableFunctionReference.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -80,10 +80,11 @@
return symbol.hashCode();
}
- public void copy(ProjectedColumn copy) {
+ public ProjectedColumn copyTo(ProjectedColumn copy) {
copy.name = this.name;
copy.type = this.type;
copy.symbol = (ElementSymbol)this.symbol.clone();
+ return copy;
}
}
Modified: trunk/engine/src/main/java/org/teiid/query/sql/lang/TextTable.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/lang/TextTable.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/TextTable.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -70,7 +70,7 @@
public TextColumn clone() {
TextColumn clone = new TextColumn();
clone.width = this.width;
- this.copy(clone);
+ this.copyTo(clone);
return clone;
}
}
Modified: trunk/engine/src/main/java/org/teiid/query/sql/lang/XMLTable.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/lang/XMLTable.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/XMLTable.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -90,7 +90,7 @@
@Override
public XMLColumn clone() {
XMLColumn clone = new XMLColumn();
- super.copy(clone);
+ super.copyTo(clone);
clone.ordinal = this.ordinal;
clone.path = this.path;
if (this.defaultExpression != null) {
Modified: trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -26,6 +26,7 @@
import org.teiid.query.sql.LanguageObject;
import org.teiid.query.sql.LanguageVisitor;
+import org.teiid.query.sql.lang.ArrayTable;
import org.teiid.query.sql.lang.BatchedUpdateCommand;
import org.teiid.query.sql.lang.BetweenCriteria;
import org.teiid.query.sql.lang.CompareCriteria;
@@ -658,6 +659,14 @@
postVisitVisitor(obj);
}
+ @Override
+ public void visit(ArrayTable obj) {
+ preVisitVisitor(obj);
+ visitNode(obj.getArrayValue());
+ visitNode(obj.getGroupSymbol());
+ postVisitVisitor(obj);
+ }
+
public static void doVisit(LanguageObject object, LanguageVisitor visitor, boolean order) {
doVisit(object, visitor, order, false);
}
Modified: trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -38,6 +38,7 @@
import org.teiid.metadata.BaseColumn.NullType;
import org.teiid.query.sql.LanguageObject;
import org.teiid.query.sql.LanguageVisitor;
+import org.teiid.query.sql.lang.ArrayTable;
import org.teiid.query.sql.lang.AtomicCriteria;
import org.teiid.query.sql.lang.BetweenCriteria;
import org.teiid.query.sql.lang.CacheHint;
@@ -83,6 +84,7 @@
import org.teiid.query.sql.lang.Update;
import org.teiid.query.sql.lang.WithQueryCommand;
import org.teiid.query.sql.lang.XMLTable;
+import org.teiid.query.sql.lang.TableFunctionReference.ProjectedColumn;
import org.teiid.query.sql.lang.TextTable.TextColumn;
import org.teiid.query.sql.lang.XMLTable.XMLColumn;
import org.teiid.query.sql.proc.AssignmentStatement;
@@ -1905,7 +1907,32 @@
addTabs(0);
visitNode(obj.getBlock());
}
+
+ @Override
+ public void visit(ArrayTable obj) {
+ append("ARRAYTABLE("); //$NON-NLS-1$
+ visitNode(obj.getArrayValue());
+ append(SPACE);
+ append(NonReserved.COLUMNS);
+ for (Iterator<ProjectedColumn> cols = obj.getColumns().iterator(); cols.hasNext();) {
+ ProjectedColumn col = cols.next();
+ append(SPACE);
+ outputDisplayName(col.getName());
+ append(SPACE);
+ append(col.getType());
+ if (cols.hasNext()) {
+ append(","); //$NON-NLS-1$
+ }
+ }
+
+ append(")");//$NON-NLS-1$
+ append(SPACE);
+ append(AS);
+ append(SPACE);
+ outputDisplayName(obj.getName());
+ }
+
public static String escapeSinglePart( String part ) {
if (isReservedWord(part)) {
return ID_ESCAPE_CHAR + part + ID_ESCAPE_CHAR;
Modified: trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
===================================================================
--- trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj 2011-02-10 19:56:37 UTC (rev 2903)
@@ -1092,7 +1092,7 @@
GroupSymbol group = null;
int updateCount = 0;
Token updateToken = null;
- List elements = null;
+ List<TableFunctionReference.ProjectedColumn> elements = null;
SetClauseList using = null;
DynamicCommand dcStmt = new DynamicCommand();
SetClauseList setClauseList = null;
@@ -1114,7 +1114,11 @@
]
{
dcStmt.setIntoGroup(group);
- dcStmt.setAsColumns(elements);
+ List<ElementSymbol> symbols = new ArrayList(elements.size());
+ for (TableFunctionReference.ProjectedColumn col : elements) {
+ symbols.add(col.getSymbol());
+ }
+ dcStmt.setAsColumns(symbols);
dcStmt.setAsClauseSet(true);
}
]
@@ -1174,27 +1178,25 @@
* Create elements with datatypes
* @throws ParseException if parsing failed
*/
-List createElementsWithTypes(ParseInfo info) :
+List<TableFunctionReference.ProjectedColumn> createElementsWithTypes(ParseInfo info) :
{
String element = null;
- Constant type = null;
- List elements = new ArrayList();
+ String type = null;
+ List<TableFunctionReference.ProjectedColumn> elements = new ArrayList<TableFunctionReference.ProjectedColumn>();
}
{
element = id()
- type = dataType()
+ type = dataTypeString()
{
- ElementSymbol symbol = new ElementSymbol(validateElementName(element));
- symbol.setType(DataTypeManager.getDataTypeClass(type.getValue().toString()));
+ TableFunctionReference.ProjectedColumn symbol = new TableFunctionReference.ProjectedColumn(validateElementName(element), type);
elements.add(symbol);
}
(LOOKAHEAD(2) <COMMA>
element = id()
- type = dataType()
+ type = dataTypeString()
{
- symbol = new ElementSymbol(validateElementName(element));
- symbol.setType(DataTypeManager.getDataTypeClass(type.getValue().toString()));
- elements.add(symbol);
+ symbol = new TableFunctionReference.ProjectedColumn(validateElementName(element), type);
+ elements.add(symbol);
}
)*
{
@@ -2087,6 +2089,8 @@
{
( LOOKAHEAD(<ID> <LPAREN>, { "texttable".equalsIgnoreCase(getToken(1).image) }) clause = textTable(info)
|
+ LOOKAHEAD(<ID> <LPAREN>, { "arraytable".equalsIgnoreCase(getToken(1).image) }) clause = arrayTable(info)
+ |
clause = xmlTable(info)
|
clause = unaryFromClause(info)
@@ -2150,6 +2154,27 @@
}
}
+ArrayTable arrayTable(ParseInfo info) :
+{
+ Expression array = null;
+ List<TableFunctionReference.ProjectedColumn> columns;
+ String aliasID = null;
+}
+{
+ <ID> <LPAREN> array = expression(info)
+ nonReserved("COLUMNS")
+ columns = createElementsWithTypes(info)
+ <RPAREN>
+ [<AS>] aliasID=id()
+ {
+ ArrayTable result = new ArrayTable();
+ result.setArrayValue(array);
+ result.setColumns(columns);
+ result.setName(validateAlias(aliasID));
+ return result;
+ }
+}
+
TextTable textTable(ParseInfo info) :
{
Expression file = null;
Modified: trunk/engine/src/main/resources/org/teiid/query/i18n.properties
===================================================================
--- trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2011-02-10 19:56:37 UTC (rev 2903)
@@ -269,6 +269,12 @@
SQLParser.Invalid_short_name=Invalid simple identifier format: [{0}]
SQLParser.Invalid_char={0} value must be a single character: [{1}].
SQLParser.expected_non_reserved=Expected non-reserved word {0}, but was {1}.
+SystemSource.array_length_desc=Get the length of the given array value
+SystemSource.array_param1=Array
+SystemSource.array_length_result=The array length
+SystemSource.array_get_desc=Get the object value at the given array index
+SystemSource.array_get_param2=Array index
+SystemSource.array_get_result=The object value
SystemSource.Add_desc=Converts escape sequences in the given string to their actual characters.
SystemSource.unescape_param1=String to be unescaped
SystemSource.unescape_result=Unescaped string
@@ -786,9 +792,9 @@
FileStoreageManager.not_a_directory={0} is not a valid storage manager directory.
FileStoreageManager.space_exhausted=Max buffer space of {0} bytes has been exceed. The current operation will be aborted.
-TextTableNode.no_value=No value found for column \"{0}\" in the row ending on text line {1} in {2}.
-TextTableNode.conversion_error=Could not convert value for column \"{0}\" in the row ending on text line {1} in {2}.
-TextTableNode.header_missing=HEADER entry missing for column name \"{0}\" in {1}.
+TextTableNode.no_value=No value found for column {0} in the row ending on text line {1} in {2}.
+TextTableNode.conversion_error=Could not convert value for column {0} in the row ending on text line {1} in {2}.
+TextTableNode.header_missing=HEADER entry missing for column name {0} in {1}.
TextTableNode.unclosed=Text parse error: Unclosed qualifier at end of text in {0}.
TextTableNode.character_not_allowed=Text parse error: Non-whitespace character found between the qualifier and the delimiter in text line {0} in {1}.
TextTableNode.unknown_escape=Text parse error: Unknown escape sequence \\{0} in text line {1} in {2}.
@@ -895,4 +901,8 @@
Translate.error=Cannot translate criteria "{0}", it is not matched by selector "{1}"
-MultiSource.out_procedure=The multisource plan must execute a procedure returning parameter values exactly 1: {0}
\ No newline at end of file
+MultiSource.out_procedure=The multisource plan must execute a procedure returning parameter values exactly 1: {0}
+
+FunctionMethods.not_array_value=Expected a java.sql.Array, or java array type, but got: {0}
+FunctionMethods.array_index=Array index out of range: {0}
+ArrayTableNode.conversion_error=Could not convert value for column: {0}
\ No newline at end of file
Modified: trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -33,7 +33,6 @@
import java.sql.Timestamp;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Iterator;
import java.util.Properties;
import java.util.TimeZone;
@@ -90,9 +89,9 @@
// ################################## TEST HELPERS ################################
- private FunctionDescriptor helpCreateDescriptor(String name, Class[] types) {
+ private FunctionDescriptor helpCreateDescriptor(String name, Class<?>[] types) {
final String fname = name;
- final Class[] ftypes = types;
+ final Class<?>[] ftypes = types;
return new FunctionDescriptor() {
public String getName() {
return fname;
@@ -100,10 +99,10 @@
public PushDown getPushdown() {
return PushDown.CAN_PUSHDOWN;
}
- public Class[] getTypes() {
+ public Class<?>[] getTypes() {
return ftypes;
}
- public Class getReturnType() {
+ public Class<?> getReturnType() {
return null;
}
@@ -132,19 +131,19 @@
};
}
- private void helpFindFunction(String fname, Class[] types, FunctionDescriptor expected) {
+ private void helpFindFunction(String fname, Class<?>[] types, FunctionDescriptor expected) {
FunctionDescriptor actual = library.findFunction(fname, types);
assertEquals("Function names do not match: ", expected.getName().toLowerCase(), actual.getName().toLowerCase()); //$NON-NLS-1$
assertEquals("Arg lengths do not match: ", expected.getTypes().length, actual.getTypes().length); //$NON-NLS-1$
}
- private void helpFindFunctionFail(String fname, Class[] types) {
+ private void helpFindFunctionFail(String fname, Class<?>[] types) {
FunctionDescriptor actual = library.findFunction(fname, types);
assertNull("Function was found but should not have been: " + actual, actual); //$NON-NLS-1$
}
- private void helpFindConversions(String fname, Class[] types, FunctionDescriptor[] expected) {
+ private void helpFindConversions(String fname, Class<?>[] types, FunctionDescriptor[] expected) {
FunctionDescriptor[] actual = library.determineNecessaryConversions(fname, null, types, false);
@@ -190,17 +189,17 @@
}
}
- private void helpInvokeMethod(String fname, Class[] types, Object[] inputs, CommandContext context, Object expectedOutput) throws FunctionExecutionException {
+ private void helpInvokeMethod(String fname, Class<?>[] types, Object[] inputs, CommandContext context, Object expectedOutput) throws FunctionExecutionException {
Object actualOutput = helpInvokeMethod(fname, types, inputs, context);
assertEquals("Actual function output not equal to expected: ", expectedOutput, actualOutput); //$NON-NLS-1$
}
- private Object helpInvokeMethod(String fname, Class[] types,
+ private Object helpInvokeMethod(String fname, Class<?>[] types,
Object[] inputs, CommandContext context)
throws FunctionExecutionException {
if (types == null) {
// Build type signature
- types = new Class[inputs.length];
+ types = new Class<?>[inputs.length];
for(int i=0; i<inputs.length; i++) {
types[i] = DataTypeManager.determineDataTypeClass(inputs[i]);
}
@@ -241,167 +240,167 @@
// ################################## ACTUAL TESTS ################################
@Test public void testFindFunction1() {
- helpFindFunction("convert", new Class[] { T_INTEGER, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { T_INTEGER, T_STRING }) );
+ helpFindFunction("convert", new Class<?>[] { T_INTEGER, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { T_INTEGER, T_STRING }) );
}
@Test public void testFindFunction2() {
- helpFindFunction("cast", new Class[] { T_INTEGER, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor(FunctionLibrary.CAST, new Class[] { T_INTEGER, T_STRING }) );
+ helpFindFunction("cast", new Class<?>[] { T_INTEGER, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor(FunctionLibrary.CAST, new Class<?>[] { T_INTEGER, T_STRING }) );
}
@Test public void testFindFunction3() {
- helpFindFunction("curdate", new Class[0], //$NON-NLS-1$
- helpCreateDescriptor("curdate", new Class[0])); //$NON-NLS-1$
+ helpFindFunction("curdate", new Class<?>[0], //$NON-NLS-1$
+ helpCreateDescriptor("curdate", new Class<?>[0])); //$NON-NLS-1$
}
@Test public void testFindFunction4() {
- helpFindFunctionFail("curdate", new Class[] { T_INTEGER }); //$NON-NLS-1$
+ helpFindFunctionFail("curdate", new Class<?>[] { T_INTEGER }); //$NON-NLS-1$
}
@Test public void testFindFunction5() {
- helpFindFunction("+", new Class[] { T_INTEGER, T_INTEGER }, //$NON-NLS-1$
- helpCreateDescriptor("+", new Class[] { T_INTEGER, T_INTEGER }) ); //$NON-NLS-1$
+ helpFindFunction("+", new Class<?>[] { T_INTEGER, T_INTEGER }, //$NON-NLS-1$
+ helpCreateDescriptor("+", new Class<?>[] { T_INTEGER, T_INTEGER }) ); //$NON-NLS-1$
}
@Test public void testFindFunction6() {
- helpFindFunctionFail("+", new Class[] {T_INTEGER, T_FLOAT}); //$NON-NLS-1$
+ helpFindFunctionFail("+", new Class<?>[] {T_INTEGER, T_FLOAT}); //$NON-NLS-1$
}
@Test public void testFindFunction7() {
- helpFindFunctionFail("+", new Class[] {T_INTEGER, T_FLOAT, T_INTEGER}); //$NON-NLS-1$
+ helpFindFunctionFail("+", new Class<?>[] {T_INTEGER, T_FLOAT, T_INTEGER}); //$NON-NLS-1$
}
@Test public void testFindFunction8() {
- helpFindFunctionFail("+", new Class[] {T_INTEGER}); //$NON-NLS-1$
+ helpFindFunctionFail("+", new Class<?>[] {T_INTEGER}); //$NON-NLS-1$
}
@Test public void testFindFunction9() {
- helpFindFunctionFail("+", new Class[] {T_INTEGER, T_NULL }); //$NON-NLS-1$
+ helpFindFunctionFail("+", new Class<?>[] {T_INTEGER, T_NULL }); //$NON-NLS-1$
}
@Test public void testFindFunction10() {
- helpFindFunction("substring", new Class[] { T_STRING, T_INTEGER, T_INTEGER }, //$NON-NLS-1$
- helpCreateDescriptor("substring", new Class[] { T_STRING, T_INTEGER, T_INTEGER }) ); //$NON-NLS-1$
+ helpFindFunction("substring", new Class<?>[] { T_STRING, T_INTEGER, T_INTEGER }, //$NON-NLS-1$
+ helpCreateDescriptor("substring", new Class<?>[] { T_STRING, T_INTEGER, T_INTEGER }) ); //$NON-NLS-1$
}
@Test public void testFindFunction11() {
- helpFindFunction("substring", new Class[] { T_STRING, T_INTEGER }, //$NON-NLS-1$
- helpCreateDescriptor("substring", new Class[] { T_STRING, T_INTEGER }) ); //$NON-NLS-1$
+ helpFindFunction("substring", new Class<?>[] { T_STRING, T_INTEGER }, //$NON-NLS-1$
+ helpCreateDescriptor("substring", new Class<?>[] { T_STRING, T_INTEGER }) ); //$NON-NLS-1$
}
@Test public void testFindFunction12() {
- helpFindFunction("context", new Class[] { T_STRING, T_INTEGER }, //$NON-NLS-1$
- helpCreateDescriptor("context", new Class[] { T_STRING, T_INTEGER }) ); //$NON-NLS-1$
+ helpFindFunction("context", new Class<?>[] { T_STRING, T_INTEGER }, //$NON-NLS-1$
+ helpCreateDescriptor("context", new Class<?>[] { T_STRING, T_INTEGER }) ); //$NON-NLS-1$
}
@Test public void testFindFunction12a() {
- helpFindFunction("rowlimit", new Class[] { T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("rowlimit", new Class[] { T_STRING }) ); //$NON-NLS-1$
+ helpFindFunction("rowlimit", new Class<?>[] { T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("rowlimit", new Class<?>[] { T_STRING }) ); //$NON-NLS-1$
}
@Test public void testFindFunction12b() {
- helpFindFunction("rowlimitexception", new Class[] { T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("rowlimitexception", new Class[] { T_STRING }) ); //$NON-NLS-1$
+ helpFindFunction("rowlimitexception", new Class<?>[] { T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("rowlimitexception", new Class<?>[] { T_STRING }) ); //$NON-NLS-1$
}
@Test public void testFind0ArgConversion1() {
helpFindConversions(
- "curdate", new Class[] {}, //$NON-NLS-1$
+ "curdate", new Class<?>[] {}, //$NON-NLS-1$
new FunctionDescriptor[0] );
}
@Test public void testFind0ArgConversion2() {
helpFindConversions(
- "curdate", new Class[] { T_INTEGER }, //$NON-NLS-1$
+ "curdate", new Class<?>[] { T_INTEGER }, //$NON-NLS-1$
null );
}
@Test public void testFind1ArgConversion1() {
helpFindConversions(
- "length", new Class[] { T_STRING }, //$NON-NLS-1$
+ "length", new Class<?>[] { T_STRING }, //$NON-NLS-1$
new FunctionDescriptor[1] );
}
@Test public void testFind1ArgConversion2() {
helpFindConversions(
- "length", new Class[] { T_INTEGER }, //$NON-NLS-1$
+ "length", new Class<?>[] { T_INTEGER }, //$NON-NLS-1$
new FunctionDescriptor[] {
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { T_INTEGER, T_STRING })
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { T_INTEGER, T_STRING })
} );
}
@Test public void testFind1ArgConversion3() {
helpFindConversions(
- "length", new Class[] { DataTypeManager.DefaultDataClasses.TIMESTAMP }, //$NON-NLS-1$
+ "length", new Class<?>[] { DataTypeManager.DefaultDataClasses.TIMESTAMP }, //$NON-NLS-1$
new FunctionDescriptor[] {
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { DataTypeManager.DefaultDataClasses.TIMESTAMP, T_STRING })
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { DataTypeManager.DefaultDataClasses.TIMESTAMP, T_STRING })
} );
}
@Test public void testFind2ArgConversion1() {
helpFindConversions(
- "+", new Class[] { T_INTEGER, T_INTEGER }, //$NON-NLS-1$
+ "+", new Class<?>[] { T_INTEGER, T_INTEGER }, //$NON-NLS-1$
new FunctionDescriptor[2] );
}
@Test public void testFind2ArgConversion2() {
helpFindConversions(
- "+", new Class[] { T_INTEGER, T_FLOAT }, //$NON-NLS-1$
+ "+", new Class<?>[] { T_INTEGER, T_FLOAT }, //$NON-NLS-1$
new FunctionDescriptor[] {
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { T_INTEGER, T_STRING }),
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { T_FLOAT, T_STRING }) } );
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { T_INTEGER, T_STRING }),
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { T_FLOAT, T_STRING }) } );
}
@Test public void testFind2ArgConversion3() {
helpFindConversions(
- "+", new Class[] { T_FLOAT, T_INTEGER }, //$NON-NLS-1$
+ "+", new Class<?>[] { T_FLOAT, T_INTEGER }, //$NON-NLS-1$
new FunctionDescriptor[] {
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { T_FLOAT, T_STRING }),
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { T_INTEGER, T_STRING }) } );
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { T_FLOAT, T_STRING }),
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { T_INTEGER, T_STRING }) } );
}
@Test public void testFind2ArgConversion4() {
helpFindConversions(
- "+", new Class[] { T_STRING, T_FLOAT }, //$NON-NLS-1$
+ "+", new Class<?>[] { T_STRING, T_FLOAT }, //$NON-NLS-1$
null );
}
@Test public void testFind2ArgConversion5() {
helpFindConversions(
- "+", new Class[] { T_NULL, T_NULL }, //$NON-NLS-1$
+ "+", new Class<?>[] { T_NULL, T_NULL }, //$NON-NLS-1$
new FunctionDescriptor[] {
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { T_NULL, T_STRING }),
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { T_NULL, T_STRING }) } );
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { T_NULL, T_STRING }),
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { T_NULL, T_STRING }) } );
}
@Test public void testFind2ArgConversion6() {
helpFindConversions(
- "+", new Class[] { T_NULL, T_INTEGER }, //$NON-NLS-1$
+ "+", new Class<?>[] { T_NULL, T_INTEGER }, //$NON-NLS-1$
new FunctionDescriptor[] {
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { T_NULL, T_STRING }),
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { T_NULL, T_STRING }),
null } );
}
@Test public void testFind2ArgConversion7() {
helpFindConversions(
- "+", new Class[] { T_INTEGER, T_NULL }, //$NON-NLS-1$
+ "+", new Class<?>[] { T_INTEGER, T_NULL }, //$NON-NLS-1$
new FunctionDescriptor[] {
null,
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { T_NULL, T_STRING }) } );
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { T_NULL, T_STRING }) } );
}
@Test public void testFind3ArgConversion1() {
helpFindConversions(
- "substring", new Class[] { T_STRING, T_INTEGER, T_INTEGER }, //$NON-NLS-1$
+ "substring", new Class<?>[] { T_STRING, T_INTEGER, T_INTEGER }, //$NON-NLS-1$
new FunctionDescriptor[3] );
}
@Test public void testFind3ArgConversion2() {
helpFindConversions(
- "substring", new Class[] { T_INTEGER, T_INTEGER, T_INTEGER }, //$NON-NLS-1$
+ "substring", new Class<?>[] { T_INTEGER, T_INTEGER, T_INTEGER }, //$NON-NLS-1$
new FunctionDescriptor[] {
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { T_INTEGER, T_STRING }),
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { T_INTEGER, T_STRING }),
null,
null
} );
@@ -409,45 +408,45 @@
@Test public void testFind3ArgConversion3() {
helpFindConversions(
- "substring", new Class[] { T_INTEGER, T_INTEGER, DataTypeManager.DefaultDataClasses.SHORT }, //$NON-NLS-1$
+ "substring", new Class<?>[] { T_INTEGER, T_INTEGER, DataTypeManager.DefaultDataClasses.SHORT }, //$NON-NLS-1$
new FunctionDescriptor[] {
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { T_INTEGER, T_STRING }),
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { T_INTEGER, T_STRING }),
null,
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { DataTypeManager.DefaultDataClasses.SHORT, T_STRING })
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { DataTypeManager.DefaultDataClasses.SHORT, T_STRING })
} );
}
@Test public void testFind3ArgConversion4() {
helpFindConversions(
- "substring", new Class[] { T_STRING, T_INTEGER, DataTypeManager.DefaultDataClasses.TIMESTAMP }, //$NON-NLS-1$
+ "substring", new Class<?>[] { T_STRING, T_INTEGER, DataTypeManager.DefaultDataClasses.TIMESTAMP }, //$NON-NLS-1$
null );
}
@Test public void testFind3ArgConversion5() {
helpFindConversions(
- "substring", new Class[] { T_STRING, DataTypeManager.DefaultDataClasses.SHORT, DataTypeManager.DefaultDataClasses.SHORT }, //$NON-NLS-1$
+ "substring", new Class<?>[] { T_STRING, DataTypeManager.DefaultDataClasses.SHORT, DataTypeManager.DefaultDataClasses.SHORT }, //$NON-NLS-1$
new FunctionDescriptor[] {
null,
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { DataTypeManager.DefaultDataClasses.SHORT, T_STRING }),
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { DataTypeManager.DefaultDataClasses.SHORT, T_STRING })
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { DataTypeManager.DefaultDataClasses.SHORT, T_STRING }),
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { DataTypeManager.DefaultDataClasses.SHORT, T_STRING })
} );
}
@Test public void testFind3ArgConversion6() {
helpFindConversions(
- "substring", new Class[] { T_INTEGER, DataTypeManager.DefaultDataClasses.SHORT, DataTypeManager.DefaultDataClasses.SHORT }, //$NON-NLS-1$
+ "substring", new Class<?>[] { T_INTEGER, DataTypeManager.DefaultDataClasses.SHORT, DataTypeManager.DefaultDataClasses.SHORT }, //$NON-NLS-1$
new FunctionDescriptor[] {
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { DataTypeManager.DefaultDataClasses.INTEGER, T_STRING }),
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { DataTypeManager.DefaultDataClasses.SHORT, T_STRING }),
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { DataTypeManager.DefaultDataClasses.SHORT, T_STRING })
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { DataTypeManager.DefaultDataClasses.INTEGER, T_STRING }),
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { DataTypeManager.DefaultDataClasses.SHORT, T_STRING }),
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { DataTypeManager.DefaultDataClasses.SHORT, T_STRING })
} );
}
@Test public void testFind3ArgConversion7() {
helpFindConversions(
- "substring", new Class[] { T_NULL, T_INTEGER, T_INTEGER }, //$NON-NLS-1$
+ "substring", new Class<?>[] { T_NULL, T_INTEGER, T_INTEGER }, //$NON-NLS-1$
new FunctionDescriptor[] {
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { T_NULL, T_STRING }),
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { T_NULL, T_STRING }),
null,
null }
);
@@ -455,36 +454,32 @@
@Test public void testFind3ArgConversion8() {
helpFindConversions(
- "substring", new Class[] { T_NULL, T_NULL, T_INTEGER }, //$NON-NLS-1$
+ "substring", new Class<?>[] { T_NULL, T_NULL, T_INTEGER }, //$NON-NLS-1$
new FunctionDescriptor[] {
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { T_NULL, T_STRING }),
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { T_NULL, T_STRING }),
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { T_NULL, T_STRING }),
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { T_NULL, T_STRING }),
null }
);
}
@Test public void testFind3ArgConversion9() {
helpFindConversions(
- "substring", new Class[] { T_NULL, T_NULL, T_NULL }, //$NON-NLS-1$
+ "substring", new Class<?>[] { T_NULL, T_NULL, T_NULL }, //$NON-NLS-1$
new FunctionDescriptor[] {
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { T_NULL, T_STRING }),
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { T_NULL, T_STRING }),
- helpCreateDescriptor(FunctionLibrary.CONVERT, new Class[] { T_NULL, T_STRING }) }
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { T_NULL, T_STRING }),
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { T_NULL, T_STRING }),
+ helpCreateDescriptor(FunctionLibrary.CONVERT, new Class<?>[] { T_NULL, T_STRING }) }
);
}
// Walk through all functions by metadata
@Test public void testEnumerateForms() {
- Collection categories = library.getFunctionCategories();
- Iterator catIter = categories.iterator();
- while(catIter.hasNext()) {
- String category = (String) catIter.next();
+ Collection<String> categories = library.getFunctionCategories();
+ for (String category : categories) {
//System.out.println("Category: " + category);
- Collection functions = library.getFunctionForms(category);
- Iterator functionIter = functions.iterator();
- while(functionIter.hasNext()) {
- FunctionForm form = (FunctionForm) functionIter.next();
+ Collection<FunctionForm> functions = library.getFunctionForms(category);
+ for (FunctionForm form : functions) {
//System.out.println("\tFunction: " + form.getDisplayString());
// Lookup this form
@@ -739,38 +734,38 @@
}
@Test public void testFindFunction13() {
- helpFindFunction("formatTime", new Class[] { T_TIME, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("formatTime", new Class[] { T_TIME, T_STRING }) ); //$NON-NLS-1$
+ helpFindFunction("formatTime", new Class<?>[] { T_TIME, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("formatTime", new Class<?>[] { T_TIME, T_STRING }) ); //$NON-NLS-1$
}
@Test public void testFindFunction14() {
- helpFindFunction("formatDate", new Class[] { T_DATE, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("formatDate", new Class[] { T_DATE, T_STRING }) ); //$NON-NLS-1$
+ helpFindFunction("formatDate", new Class<?>[] { T_DATE, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("formatDate", new Class<?>[] { T_DATE, T_STRING }) ); //$NON-NLS-1$
}
@Test public void testFindFunction15() {
- helpFindFunction("formatTimestamp", new Class[] { T_TIMESTAMP, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("formatTimestamp", new Class[] { T_TIMESTAMP, T_STRING }) ); //$NON-NLS-1$
+ helpFindFunction("formatTimestamp", new Class<?>[] { T_TIMESTAMP, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("formatTimestamp", new Class<?>[] { T_TIMESTAMP, T_STRING }) ); //$NON-NLS-1$
}
@Test public void testFindFunction16() {
- helpFindFunction("parseTime", new Class[] { T_STRING, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("parseTime", new Class[] { T_STRING, T_STRING }) ); //$NON-NLS-1$
+ helpFindFunction("parseTime", new Class<?>[] { T_STRING, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("parseTime", new Class<?>[] { T_STRING, T_STRING }) ); //$NON-NLS-1$
}
@Test public void testFindFunction17() {
- helpFindFunction("parseDate", new Class[] { T_STRING, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("parseDate", new Class[] { T_STRING, T_STRING }) ); //$NON-NLS-1$
+ helpFindFunction("parseDate", new Class<?>[] { T_STRING, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("parseDate", new Class<?>[] { T_STRING, T_STRING }) ); //$NON-NLS-1$
}
@Test public void testFindFunction18() {
- helpFindFunction("parseTimestamp", new Class[] { T_STRING, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("parseTimestamp", new Class[] { T_STRING, T_STRING }) ); //$NON-NLS-1$
+ helpFindFunction("parseTimestamp", new Class<?>[] { T_STRING, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("parseTimestamp", new Class<?>[] { T_STRING, T_STRING }) ); //$NON-NLS-1$
}
@Test public void testFindFunction19() {
- helpFindFunction("env", new Class[] {T_STRING}, //$NON-NLS-1$
- helpCreateDescriptor("env", new Class[] {T_STRING})); //$NON-NLS-1$
+ helpFindFunction("env", new Class<?>[] {T_STRING}, //$NON-NLS-1$
+ helpCreateDescriptor("env", new Class<?>[] {T_STRING})); //$NON-NLS-1$
}
@Test public void testInvokeFormatTimestamp1() {
@@ -798,62 +793,62 @@
}
@Test public void testFindFormatInteger() {
- helpFindFunction("formatInteger", new Class[] { T_INTEGER, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("formatInteger", new Class[] { T_INTEGER, T_STRING}) ); //$NON-NLS-1$
+ helpFindFunction("formatInteger", new Class<?>[] { T_INTEGER, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("formatInteger", new Class<?>[] { T_INTEGER, T_STRING}) ); //$NON-NLS-1$
}
@Test public void testFindFormatFloat() {
- helpFindFunction("formatFloat", new Class[] { T_FLOAT, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("formatFloat", new Class[] { T_FLOAT, T_STRING}) ); //$NON-NLS-1$
+ helpFindFunction("formatFloat", new Class<?>[] { T_FLOAT, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("formatFloat", new Class<?>[] { T_FLOAT, T_STRING}) ); //$NON-NLS-1$
}
@Test public void testFindFormatDouble() {
- helpFindFunction("formatDouble", new Class[] { T_DOUBLE, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("formatDouble", new Class[] { T_DOUBLE, T_STRING}) ); //$NON-NLS-1$
+ helpFindFunction("formatDouble", new Class<?>[] { T_DOUBLE, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("formatDouble", new Class<?>[] { T_DOUBLE, T_STRING}) ); //$NON-NLS-1$
}
@Test public void testFindFormatLong() {
- helpFindFunction("formatLong", new Class[] { T_LONG, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("formatLong", new Class[] { T_LONG, T_STRING}) ); //$NON-NLS-1$
+ helpFindFunction("formatLong", new Class<?>[] { T_LONG, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("formatLong", new Class<?>[] { T_LONG, T_STRING}) ); //$NON-NLS-1$
}
@Test public void testFindFormatBigInteger() {
- helpFindFunction("formatBigInteger", new Class[] { T_BIG_INTEGER, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("formatBigInteger", new Class[] { T_BIG_INTEGER, T_STRING}) ); //$NON-NLS-1$
+ helpFindFunction("formatBigInteger", new Class<?>[] { T_BIG_INTEGER, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("formatBigInteger", new Class<?>[] { T_BIG_INTEGER, T_STRING}) ); //$NON-NLS-1$
}
@Test public void testFindFormatBigDecimal() {
- helpFindFunction("formatBigDecimal", new Class[] { T_BIG_DECIMAL, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("formatBigDecimal", new Class[] { T_BIG_DECIMAL, T_STRING}) ); //$NON-NLS-1$
+ helpFindFunction("formatBigDecimal", new Class<?>[] { T_BIG_DECIMAL, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("formatBigDecimal", new Class<?>[] { T_BIG_DECIMAL, T_STRING}) ); //$NON-NLS-1$
}
@Test public void testFindParseInteger() {
- helpFindFunction("parseInteger", new Class[] { T_STRING, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("parseInteger", new Class[] { T_STRING, T_STRING}) ); //$NON-NLS-1$
+ helpFindFunction("parseInteger", new Class<?>[] { T_STRING, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("parseInteger", new Class<?>[] { T_STRING, T_STRING}) ); //$NON-NLS-1$
}
@Test public void testFindParseLong() {
- helpFindFunction("parseLong", new Class[] { T_STRING, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("parseLong", new Class[] { T_STRING, T_STRING}) ); //$NON-NLS-1$
+ helpFindFunction("parseLong", new Class<?>[] { T_STRING, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("parseLong", new Class<?>[] { T_STRING, T_STRING}) ); //$NON-NLS-1$
}
@Test public void testFindParseDouble() {
- helpFindFunction("parseDouble", new Class[] { T_STRING, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("parseDouble", new Class[] { T_STRING, T_STRING}) ); //$NON-NLS-1$
+ helpFindFunction("parseDouble", new Class<?>[] { T_STRING, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("parseDouble", new Class<?>[] { T_STRING, T_STRING}) ); //$NON-NLS-1$
}
@Test public void testFindParseFloat() {
- helpFindFunction("parseFloat", new Class[] { T_STRING, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("parseFloat", new Class[] { T_STRING, T_STRING}) ); //$NON-NLS-1$
+ helpFindFunction("parseFloat", new Class<?>[] { T_STRING, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("parseFloat", new Class<?>[] { T_STRING, T_STRING}) ); //$NON-NLS-1$
}
@Test public void testFindParseBigInteger() {
- helpFindFunction("parseBigInteger", new Class[] { T_STRING, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("parseBigInteger", new Class[] { T_STRING, T_STRING}) ); //$NON-NLS-1$
+ helpFindFunction("parseBigInteger", new Class<?>[] { T_STRING, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("parseBigInteger", new Class<?>[] { T_STRING, T_STRING}) ); //$NON-NLS-1$
}
@Test public void testFindParseBigDecimal() {
- helpFindFunction("parseBigDecimal", new Class[] { T_STRING, T_STRING }, //$NON-NLS-1$
- helpCreateDescriptor("parseBigDecimal", new Class[] { T_STRING, T_STRING}) ); //$NON-NLS-1$
+ helpFindFunction("parseBigDecimal", new Class<?>[] { T_STRING, T_STRING }, //$NON-NLS-1$
+ helpCreateDescriptor("parseBigDecimal", new Class<?>[] { T_STRING, T_STRING}) ); //$NON-NLS-1$
}
@Test public void testInvokeParseInteger() {
@@ -1195,13 +1190,13 @@
@Test public void testInvokeRand() throws Exception {
helpInvokeMethod("rand", new Object[] {new Integer(100)}, new Double(0.7220096548596434)); //$NON-NLS-1$
// this does not actually fail but returns a result
- assertNotNull(helpInvokeMethod("rand", new Class[] {Integer.class}, new Object[] {null}, null)); //$NON-NLS-1$
+ assertNotNull(helpInvokeMethod("rand", new Class<?>[] {Integer.class}, new Object[] {null}, null)); //$NON-NLS-1$
}
@Test public void testInvokeUser() throws Exception {
CommandContext c = new CommandContext();
c.setUserName("foodude"); //$NON-NLS-1$
- helpInvokeMethod("user", new Class[] {}, new Object[] {}, c, "foodude"); //$NON-NLS-1$ //$NON-NLS-2$
+ helpInvokeMethod("user", new Class<?>[] {}, new Object[] {}, c, "foodude"); //$NON-NLS-1$ //$NON-NLS-2$
}
@Test public void testInvokeEnv() throws Exception {
@@ -1209,26 +1204,26 @@
Properties props = new Properties();
props.setProperty("env_test", "env_value"); //$NON-NLS-1$ //$NON-NLS-2$
c.setEnvironmentProperties(props);
- helpInvokeMethod("env", new Class[] {String.class}, new Object[] {"env_test"}, c, "env_value"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- helpInvokeMethod("env", new Class[] {String.class}, new Object[] {null}, c, null); //$NON-NLS-1$
+ helpInvokeMethod("env", new Class<?>[] {String.class}, new Object[] {"env_test"}, c, "env_value"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ helpInvokeMethod("env", new Class<?>[] {String.class}, new Object[] {null}, c, null); //$NON-NLS-1$
}
@Test public void testInvokeCommandPayload() throws Exception {
CommandContext c = new CommandContext();
c.setCommandPayload("payload_too heavy"); //$NON-NLS-1$
- helpInvokeMethod("commandpayload", new Class[] {}, new Object[] {}, c, "payload_too heavy"); //$NON-NLS-1$ //$NON-NLS-2$
- helpInvokeMethod("commandpayload", new Class[] {String.class}, new Object[] {null}, c, null); //$NON-NLS-1$
+ helpInvokeMethod("commandpayload", new Class<?>[] {}, new Object[] {}, c, "payload_too heavy"); //$NON-NLS-1$ //$NON-NLS-2$
+ helpInvokeMethod("commandpayload", new Class<?>[] {String.class}, new Object[] {null}, c, null); //$NON-NLS-1$
Properties props = new Properties();
props.setProperty("payload", "payload_too heavy"); //$NON-NLS-1$ //$NON-NLS-2$
c.setCommandPayload(props);
- helpInvokeMethod("commandpayload", new Class[] {String.class}, new Object[] {"payload"}, c, "payload_too heavy"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ helpInvokeMethod("commandpayload", new Class<?>[] {String.class}, new Object[] {"payload"}, c, "payload_too heavy"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
@Test public void testNullDependent() {
- FunctionDescriptor actual = library.findFunction("concat2", new Class[] {String.class, String.class}); //$NON-NLS-1$
+ FunctionDescriptor actual = library.findFunction("concat2", new Class<?>[] {String.class, String.class}); //$NON-NLS-1$
assertTrue(actual.isNullDependent());
- actual = library.findFunction("concat", new Class[] {String.class, String.class}); //$NON-NLS-1$
+ actual = library.findFunction("concat", new Class<?>[] {String.class, String.class}); //$NON-NLS-1$
assertFalse(actual.isNullDependent());
}
@@ -1331,17 +1326,17 @@
}
@Test public void testInvokeNull() throws Exception {
- helpInvokeMethod(SourceSystemFunctions.LTRIM, new Class[] {DataTypeManager.DefaultDataClasses.STRING}, new Object[] { null }, null, null);
+ helpInvokeMethod(SourceSystemFunctions.LTRIM, new Class<?>[] {DataTypeManager.DefaultDataClasses.STRING}, new Object[] { null }, null, null);
}
@Test public void testInvokeNull1() throws Exception {
- helpInvokeMethod(SourceSystemFunctions.CONCAT, new Class[] {DataTypeManager.DefaultDataClasses.STRING, DataTypeManager.DefaultDataClasses.STRING}, new Object[] { null, String.valueOf(1) }, null, null);
+ helpInvokeMethod(SourceSystemFunctions.CONCAT, new Class<?>[] {DataTypeManager.DefaultDataClasses.STRING, DataTypeManager.DefaultDataClasses.STRING}, new Object[] { null, String.valueOf(1) }, null, null);
}
@Test public void testInvokeXslTransform() throws Exception {
CommandContext c = new CommandContext();
c.setBufferManager(BufferManagerFactory.getStandaloneBufferManager());
- ClobType result = (ClobType)helpInvokeMethod("xsltransform", new Class[] {DataTypeManager.DefaultDataClasses.XML, DataTypeManager.DefaultDataClasses.XML},
+ ClobType result = (ClobType)helpInvokeMethod("xsltransform", new Class<?>[] {DataTypeManager.DefaultDataClasses.XML, DataTypeManager.DefaultDataClasses.XML},
new Object[] {DataTypeManager.transformValue("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Catalogs xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><Catalog><Items><Item ItemID=\"001\"><Name>Lamp</Name><Quantity>5</Quantity></Item></Items></Catalog></Catalogs>", DataTypeManager.DefaultDataClasses.XML),
DataTypeManager.transformValue("<?xml version=\"1.0\" encoding=\"UTF-8\"?><xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\"><xsl:template match=\"@*|node()\"><xsl:copy><xsl:apply-templates select=\"@*|node()\"/></xsl:copy></xsl:template><xsl:template match=\"Quantity\"/></xsl:stylesheet>", DataTypeManager.DefaultDataClasses.XML)}, c);
@@ -1352,7 +1347,7 @@
@Test public void testInvokeXmlConcat() throws Exception {
CommandContext c = new CommandContext();
c.setBufferManager(BufferManagerFactory.getStandaloneBufferManager());
- XMLType result = (XMLType)helpInvokeMethod("xmlconcat", new Class[] {DataTypeManager.DefaultDataClasses.XML, DataTypeManager.DefaultDataClasses.XML},
+ XMLType result = (XMLType)helpInvokeMethod("xmlconcat", new Class<?>[] {DataTypeManager.DefaultDataClasses.XML, DataTypeManager.DefaultDataClasses.XML},
new Object[] {DataTypeManager.transformValue("<bar/>", DataTypeManager.DefaultDataClasses.XML), DataTypeManager.transformValue("<Catalogs xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><Catalog><Items><Item ItemID=\"001\"><Name>Lamp</Name><Quantity>5</Quantity></Item></Items></Catalog></Catalogs>", DataTypeManager.DefaultDataClasses.XML)}, c);
String xml = ObjectConverterUtil.convertToString(result.getCharacterStream());
@@ -1362,7 +1357,7 @@
@Test public void testInvokeXmlComment() throws Exception {
CommandContext c = new CommandContext();
c.setBufferManager(BufferManagerFactory.getStandaloneBufferManager());
- XMLType result = (XMLType)helpInvokeMethod("xmlcomment", new Class[] {DataTypeManager.DefaultDataClasses.STRING},
+ XMLType result = (XMLType)helpInvokeMethod("xmlcomment", new Class<?>[] {DataTypeManager.DefaultDataClasses.STRING},
new Object[] {"comment"}, c);
String xml = ObjectConverterUtil.convertToString(result.getCharacterStream());
@@ -1370,43 +1365,47 @@
}
@Test public void testToChars() throws Exception {
- Clob result = (Clob)helpInvokeMethod("to_chars", new Class[] {DefaultDataClasses.BLOB, DefaultDataClasses.STRING}, new Object[] { new BlobType(new SerialBlob("hello world".getBytes("ASCII"))), "ASCII" }, null); //$NON-NLS-1$
+ Clob result = (Clob)helpInvokeMethod("to_chars", new Class<?>[] {DefaultDataClasses.BLOB, DefaultDataClasses.STRING}, new Object[] { new BlobType(new SerialBlob("hello world".getBytes("ASCII"))), "ASCII" }, null); //$NON-NLS-1$
String string = result.getSubString(1, (int)result.length());
assertEquals("hello world", string);
}
@Test public void testToBytes() throws Exception {
- Blob result = (Blob)helpInvokeMethod("to_bytes", new Class[] {DefaultDataClasses.CLOB, DefaultDataClasses.STRING}, new Object[] { new ClobType(new SerialClob("hello world".toCharArray())), "UTF32" }, null); //$NON-NLS-1$
+ Blob result = (Blob)helpInvokeMethod("to_bytes", new Class<?>[] {DefaultDataClasses.CLOB, DefaultDataClasses.STRING}, new Object[] { new ClobType(new SerialClob("hello world".toCharArray())), "UTF32" }, null); //$NON-NLS-1$
assertEquals(44, result.length()); //4 bytes / char
}
@Test public void testToChars1() throws Exception {
- Clob result = (Clob)helpInvokeMethod("to_chars", new Class[] {DefaultDataClasses.BLOB, DefaultDataClasses.STRING}, new Object[] { new BlobType(new SerialBlob("hello world".getBytes("ASCII"))), "BASE64" }, null); //$NON-NLS-1$
+ Clob result = (Clob)helpInvokeMethod("to_chars", new Class<?>[] {DefaultDataClasses.BLOB, DefaultDataClasses.STRING}, new Object[] { new BlobType(new SerialBlob("hello world".getBytes("ASCII"))), "BASE64" }, null); //$NON-NLS-1$
String string = result.getSubString(1, (int)result.length());
assertEquals("hello world", new String(Base64.decode(string), "ASCII"));
}
@Test public void testToChars2() throws Exception {
- Clob result = (Clob)helpInvokeMethod("to_chars", new Class[] {DefaultDataClasses.BLOB, DefaultDataClasses.STRING}, new Object[] { new BlobType(new SerialBlob("hello world".getBytes("ASCII"))), "HEX" }, null); //$NON-NLS-1$
+ Clob result = (Clob)helpInvokeMethod("to_chars", new Class<?>[] {DefaultDataClasses.BLOB, DefaultDataClasses.STRING}, new Object[] { new BlobType(new SerialBlob("hello world".getBytes("ASCII"))), "HEX" }, null); //$NON-NLS-1$
String string = result.getSubString(1, (int)result.length());
assertEquals("68656C6C6F20776F726C64", string);
}
@Test public void testToBytes2() throws Exception {
- Blob result = (Blob)helpInvokeMethod("to_bytes", new Class[] {DefaultDataClasses.CLOB, DefaultDataClasses.STRING}, new Object[] { new ClobType(new SerialClob("68656C6C6F20776F726C64".toCharArray())), "HEX" }, null); //$NON-NLS-1$
+ Blob result = (Blob)helpInvokeMethod("to_bytes", new Class<?>[] {DefaultDataClasses.CLOB, DefaultDataClasses.STRING}, new Object[] { new ClobType(new SerialClob("68656C6C6F20776F726C64".toCharArray())), "HEX" }, null); //$NON-NLS-1$
assertEquals("hello world", new String(ObjectConverterUtil.convertToCharArray(result.getBinaryStream(), -1, "ASCII")));
}
@Test(expected=FunctionExecutionException.class) public void testToBytes3() throws Exception {
- helpInvokeMethod("to_bytes", new Class[] {DefaultDataClasses.CLOB, DefaultDataClasses.STRING}, new Object[] { new ClobType(new SerialClob("a".toCharArray())), "BASE64" }, null); //$NON-NLS-1$
+ helpInvokeMethod("to_bytes", new Class<?>[] {DefaultDataClasses.CLOB, DefaultDataClasses.STRING}, new Object[] { new ClobType(new SerialClob("a".toCharArray())), "BASE64" }, null); //$NON-NLS-1$
}
- @Test() public void testunescape() throws Exception {
- assertEquals("\r\t", helpInvokeMethod("unescape", new Class[] {DefaultDataClasses.STRING}, new Object[] { "\r\\\t" }, null)); //$NON-NLS-1$
+ @Test() public void testUnescape() throws Exception {
+ assertEquals("\r\t", helpInvokeMethod("unescape", new Class<?>[] {DefaultDataClasses.STRING}, new Object[] { "\r\\\t" }, null)); //$NON-NLS-1$
}
@Test() public void testUuid() throws Exception {
- assertNotNull(helpInvokeMethod("uuid", new Class[] {}, new Object[] {}, null)); //$NON-NLS-1$
+ assertNotNull(helpInvokeMethod("uuid", new Class<?>[] {}, new Object[] {}, null)); //$NON-NLS-1$
}
+ @Test() public void testArrayGet() throws Exception {
+ assertEquals(1, helpInvokeMethod("array_get", new Class<?>[] {DefaultDataClasses.OBJECT, DefaultDataClasses.INTEGER}, new Object[] {new Object[] {1}, 1}, null)); //$NON-NLS-1$
+ }
+
}
Modified: trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -43,6 +43,7 @@
import org.teiid.language.SQLConstants.NonReserved;
import org.teiid.language.SQLConstants.Reserved;
import org.teiid.language.SortSpecification.NullOrdering;
+import org.teiid.query.sql.lang.ArrayTable;
import org.teiid.query.sql.lang.BetweenCriteria;
import org.teiid.query.sql.lang.Command;
import org.teiid.query.sql.lang.CompareCriteria;
@@ -78,6 +79,7 @@
import org.teiid.query.sql.lang.SubqueryCompareCriteria;
import org.teiid.query.sql.lang.SubqueryFromClause;
import org.teiid.query.sql.lang.SubquerySetCriteria;
+import org.teiid.query.sql.lang.TableFunctionReference;
import org.teiid.query.sql.lang.TextTable;
import org.teiid.query.sql.lang.UnaryFromClause;
import org.teiid.query.sql.lang.Update;
@@ -6857,5 +6859,20 @@
query.setFrom(from);
helpTest("TABLE X", "SELECT * FROM X", query);
}
+
+ @Test public void testArrayTable() throws Exception {
+ String sql = "SELECT * from arraytable(null columns x string, y date) as x"; //$NON-NLS-1$
+ Query query = new Query();
+ query.setSelect(new Select(Arrays.asList(new AllSymbol())));
+ ArrayTable tt = new ArrayTable();
+ tt.setArrayValue(new Constant(null, DataTypeManager.DefaultDataClasses.OBJECT));
+ List<TableFunctionReference.ProjectedColumn> columns = new ArrayList<TableFunctionReference.ProjectedColumn>();
+ columns.add(new TableFunctionReference.ProjectedColumn("x", "string"));
+ columns.add(new TableFunctionReference.ProjectedColumn("y", "date"));
+ tt.setColumns(columns);
+ tt.setName("x");
+ query.setFrom(new From(Arrays.asList(tt)));
+ helpTest(sql, "SELECT * FROM ARRAYTABLE(null COLUMNS x string, y date) AS x", query);
+ }
}
Added: trunk/engine/src/test/java/org/teiid/query/processor/TestArrayTable.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestArrayTable.java (rev 0)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestArrayTable.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -0,0 +1,83 @@
+/*
+ * 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.query.processor;
+
+import static org.teiid.query.processor.TestProcessor.*;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.Test;
+import org.teiid.core.TeiidProcessingException;
+import org.teiid.query.unittest.RealMetadataFactory;
+
+@SuppressWarnings({"unchecked", "nls"})
+public class TestArrayTable {
+
+ @Test public void testCorrelatedTextTable() throws Exception {
+ String sql = "select x.* from bqt1.smalla, arraytable(objectvalue COLUMNS x string, y integer) x"; //$NON-NLS-1$
+
+ List[] expected = new List[] {
+ Arrays.asList("a", 1),
+ Arrays.asList("b", 3),
+ };
+
+ process(sql, expected);
+ }
+
+ @Test public void testCorrelatedTextTable1() throws Exception {
+ String sql = "select z from bqt1.smalla, arraytable(objectvalue COLUMNS x string, y integer, z long) x"; //$NON-NLS-1$
+
+ List[] expected = new List[] {
+ Arrays.asList(Long.valueOf(2)),
+ Arrays.asList(Long.valueOf(6)),
+ };
+
+ process(sql, expected);
+ }
+
+ @Test(expected=TeiidProcessingException.class) public void testCorrelatedTextTable2() throws Exception {
+ String sql = "select y from bqt1.smalla, arraytable(objectvalue COLUMNS y integer) x"; //$NON-NLS-1$
+
+ List[] expected = new List[] {};
+
+ process(sql, expected);
+ }
+
+ @Test(expected=TeiidProcessingException.class) public void testCorrelatedTextTable3() throws Exception {
+ String sql = "select x.* from bqt1.smalla, arraytable(objectvalue COLUMNS x string, y integer, z integer, aa object) x"; //$NON-NLS-1$
+
+ List[] expected = new List[] {};
+
+ process(sql, expected);
+ }
+
+ public static void process(String sql, List[] expectedResults) throws Exception {
+ HardcodedDataManager dataManager = new HardcodedDataManager();
+ dataManager.addData("SELECT bqt1.smalla.objectvalue FROM bqt1.smalla", new List[] {Collections.singletonList(new Object[] {"a", 1, 2}), Collections.singletonList(new Object[] {"b", 3, 6})} );
+ ProcessorPlan plan = helpGetPlan(helpParse(sql), RealMetadataFactory.exampleBQTCached());
+ helpProcess(plan, createCommandContext(), dataManager, expectedResults);
+ }
+
+}
Property changes on: trunk/engine/src/test/java/org/teiid/query/processor/TestArrayTable.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: trunk/hibernate-dialect/src/main/java/org/teiid/dialect/TeiidDialect.java
===================================================================
--- trunk/hibernate-dialect/src/main/java/org/teiid/dialect/TeiidDialect.java 2011-02-08 16:08:30 UTC (rev 2902)
+++ trunk/hibernate-dialect/src/main/java/org/teiid/dialect/TeiidDialect.java 2011-02-10 19:56:37 UTC (rev 2903)
@@ -146,6 +146,9 @@
registerFunction("uuid", new StandardSQLFunction("uuid", Hibernate.STRING)); //$NON-NLS-1$ //$NON-NLS-2$
registerFunction("unescape", new StandardSQLFunction("unescape", Hibernate.STRING)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ registerFunction("array_get", new StandardSQLFunction("uuid", Hibernate.OBJECT)); //$NON-NLS-1$ //$NON-NLS-2$
+ registerFunction("array_length", new StandardSQLFunction("unescape", Hibernate.INTEGER)); //$NON-NLS-1$ //$NON-NLS-2$
}
public boolean dropConstraints() {
13 years, 10 months
teiid SVN: r2902 - trunk/common-core/src/main/java/org/teiid/core/types.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-02-08 11:08:30 -0500 (Tue, 08 Feb 2011)
New Revision: 2902
Modified:
trunk/common-core/src/main/java/org/teiid/core/types/JDBCSQLTypeInfo.java
Log:
TEIIDDES-836 longvarchar should be imported as clob
Modified: trunk/common-core/src/main/java/org/teiid/core/types/JDBCSQLTypeInfo.java
===================================================================
--- trunk/common-core/src/main/java/org/teiid/core/types/JDBCSQLTypeInfo.java 2011-02-08 16:00:47 UTC (rev 2901)
+++ trunk/common-core/src/main/java/org/teiid/core/types/JDBCSQLTypeInfo.java 2011-02-08 16:08:30 UTC (rev 2902)
@@ -89,7 +89,7 @@
private static Map<String, String> CLASSNAME_TO_NAME = new HashMap<String, String>();
static {
- addTypeMapping(STRING, STRING_CLASS, Types.VARCHAR, Types.CHAR);
+ addTypeMapping(STRING, STRING_CLASS, Types.VARCHAR, Types.CHAR, Types.NVARCHAR, Types.NCHAR);
addTypeMapping(CHAR, CHAR_CLASS, Types.CHAR, false);
addTypeMapping(BOOLEAN, BOOLEAN_CLASS, Types.BIT, Types.BOOLEAN);
addTypeMapping(TIME, TIME_CLASS, Types.TIME);
@@ -104,16 +104,12 @@
addTypeMapping(SHORT, SHORT_CLASS, Types.SMALLINT);
addTypeMapping(LONG, LONG_CLASS, Types.BIGINT);
addTypeMapping(OBJECT, OBJECT_CLASS, Types.JAVA_OBJECT);
- addTypeMapping(CLOB, CLOB_CLASS, Types.CLOB, Types.LONGVARCHAR);
+ addTypeMapping(CLOB, CLOB_CLASS, Types.CLOB, Types.LONGVARCHAR, Types.LONGNVARCHAR, Types.NCLOB);
addTypeMapping(BLOB, BLOB_CLASS, Types.BLOB, Types.BINARY, Types.VARBINARY, Types.LONGVARBINARY);
addTypeMapping(NULL, null, Types.NULL);
addTypeMapping(XML, XML_CLASS, Types.SQLXML);
- TYPE_TO_NAME_MAP.put(Types.NVARCHAR, STRING);
- TYPE_TO_NAME_MAP.put(Types.LONGNVARCHAR, STRING);
- TYPE_TO_NAME_MAP.put(Types.NCHAR, CHAR);
- TYPE_TO_NAME_MAP.put(Types.NCLOB, CLOB);
}
private static void addTypeMapping(String typeName, String javaClass, int sqlType, int ... secondaryTypes) {
13 years, 10 months
teiid SVN: r2901 - trunk/common-core/src/main/java/org/teiid/core/types.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-02-08 11:00:47 -0500 (Tue, 08 Feb 2011)
New Revision: 2901
Modified:
trunk/common-core/src/main/java/org/teiid/core/types/JDBCSQLTypeInfo.java
Log:
TEIIDDES-836 longvarchar should be imported as clob
Modified: trunk/common-core/src/main/java/org/teiid/core/types/JDBCSQLTypeInfo.java
===================================================================
--- trunk/common-core/src/main/java/org/teiid/core/types/JDBCSQLTypeInfo.java 2011-02-07 19:38:21 UTC (rev 2900)
+++ trunk/common-core/src/main/java/org/teiid/core/types/JDBCSQLTypeInfo.java 2011-02-08 16:00:47 UTC (rev 2901)
@@ -89,7 +89,7 @@
private static Map<String, String> CLASSNAME_TO_NAME = new HashMap<String, String>();
static {
- addTypeMapping(STRING, STRING_CLASS, Types.VARCHAR, Types.LONGVARCHAR, Types.CHAR);
+ addTypeMapping(STRING, STRING_CLASS, Types.VARCHAR, Types.CHAR);
addTypeMapping(CHAR, CHAR_CLASS, Types.CHAR, false);
addTypeMapping(BOOLEAN, BOOLEAN_CLASS, Types.BIT, Types.BOOLEAN);
addTypeMapping(TIME, TIME_CLASS, Types.TIME);
@@ -104,7 +104,7 @@
addTypeMapping(SHORT, SHORT_CLASS, Types.SMALLINT);
addTypeMapping(LONG, LONG_CLASS, Types.BIGINT);
addTypeMapping(OBJECT, OBJECT_CLASS, Types.JAVA_OBJECT);
- addTypeMapping(CLOB, CLOB_CLASS, Types.CLOB);
+ addTypeMapping(CLOB, CLOB_CLASS, Types.CLOB, Types.LONGVARCHAR);
addTypeMapping(BLOB, BLOB_CLASS, Types.BLOB, Types.BINARY, Types.VARBINARY, Types.LONGVARBINARY);
addTypeMapping(NULL, null, Types.NULL);
13 years, 10 months
teiid SVN: r2900 - tags.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-02-07 14:38:21 -0500 (Mon, 07 Feb 2011)
New Revision: 2900
Added:
tags/teiid-parent-7.1.1.GA/
Log:
adding 7.1.1.GA tag
Copied: tags/teiid-parent-7.1.1.GA (from rev 2899, branches/7.1.x)
13 years, 10 months
teiid SVN: r2899 - in branches/7.1.x: adminshell and 35 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-02-07 14:35:34 -0500 (Mon, 07 Feb 2011)
New Revision: 2899
Modified:
branches/7.1.x/adminshell/pom.xml
branches/7.1.x/api/pom.xml
branches/7.1.x/build/pom.xml
branches/7.1.x/cache-jbosscache/pom.xml
branches/7.1.x/client/pom.xml
branches/7.1.x/common-core/pom.xml
branches/7.1.x/connectors/connector-file/pom.xml
branches/7.1.x/connectors/connector-ldap/pom.xml
branches/7.1.x/connectors/connector-salesforce/pom.xml
branches/7.1.x/connectors/connector-ws/pom.xml
branches/7.1.x/connectors/pom.xml
branches/7.1.x/connectors/salesforce-api/pom.xml
branches/7.1.x/connectors/sandbox/pom.xml
branches/7.1.x/connectors/sandbox/translator-yahoo/pom.xml
branches/7.1.x/connectors/translator-file/pom.xml
branches/7.1.x/connectors/translator-jdbc/pom.xml
branches/7.1.x/connectors/translator-ldap/pom.xml
branches/7.1.x/connectors/translator-loopback/pom.xml
branches/7.1.x/connectors/translator-salesforce/pom.xml
branches/7.1.x/connectors/translator-ws/pom.xml
branches/7.1.x/console/pom.xml
branches/7.1.x/documentation/admin-guide/pom.xml
branches/7.1.x/documentation/caching-guide/pom.xml
branches/7.1.x/documentation/client-developers-guide/pom.xml
branches/7.1.x/documentation/developer-guide/pom.xml
branches/7.1.x/documentation/pom.xml
branches/7.1.x/documentation/quick-start-example/pom.xml
branches/7.1.x/documentation/reference/pom.xml
branches/7.1.x/engine/pom.xml
branches/7.1.x/hibernate-dialect/pom.xml
branches/7.1.x/jboss-integration/pom.xml
branches/7.1.x/metadata/pom.xml
branches/7.1.x/pom.xml
branches/7.1.x/runtime/pom.xml
branches/7.1.x/test-integration/common/pom.xml
branches/7.1.x/test-integration/db/pom.xml
branches/7.1.x/test-integration/pom.xml
Log:
updating to GA version
Modified: branches/7.1.x/adminshell/pom.xml
===================================================================
--- branches/7.1.x/adminshell/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/adminshell/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>teiid-parent</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>teiid-adminshell</artifactId>
Modified: branches/7.1.x/api/pom.xml
===================================================================
--- branches/7.1.x/api/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/api/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>teiid-parent</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>teiid-api</artifactId>
Modified: branches/7.1.x/build/pom.xml
===================================================================
--- branches/7.1.x/build/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/build/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -2,7 +2,7 @@
<parent>
<artifactId>teiid-parent</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>teiid</artifactId>
Modified: branches/7.1.x/cache-jbosscache/pom.xml
===================================================================
--- branches/7.1.x/cache-jbosscache/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/cache-jbosscache/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>teiid-parent</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>teiid-cache-jbosscache</artifactId>
Modified: branches/7.1.x/client/pom.xml
===================================================================
--- branches/7.1.x/client/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/client/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>teiid-parent</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>teiid-client</artifactId>
Modified: branches/7.1.x/common-core/pom.xml
===================================================================
--- branches/7.1.x/common-core/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/common-core/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>teiid-parent</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>teiid-common-core</artifactId>
Modified: branches/7.1.x/connectors/connector-file/pom.xml
===================================================================
--- branches/7.1.x/connectors/connector-file/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/connectors/connector-file/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>connectors</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>connector-file</artifactId>
Modified: branches/7.1.x/connectors/connector-ldap/pom.xml
===================================================================
--- branches/7.1.x/connectors/connector-ldap/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/connectors/connector-ldap/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -2,7 +2,7 @@
<parent>
<artifactId>connectors</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>connector-ldap</artifactId>
Modified: branches/7.1.x/connectors/connector-salesforce/pom.xml
===================================================================
--- branches/7.1.x/connectors/connector-salesforce/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/connectors/connector-salesforce/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>connectors</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>connector-salesforce</artifactId>
Modified: branches/7.1.x/connectors/connector-ws/pom.xml
===================================================================
--- branches/7.1.x/connectors/connector-ws/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/connectors/connector-ws/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>connectors</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>connector-ws</artifactId>
Modified: branches/7.1.x/connectors/pom.xml
===================================================================
--- branches/7.1.x/connectors/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/connectors/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>teiid-parent</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.jboss.teiid</groupId>
Modified: branches/7.1.x/connectors/salesforce-api/pom.xml
===================================================================
--- branches/7.1.x/connectors/salesforce-api/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/connectors/salesforce-api/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -2,7 +2,7 @@
<parent>
<artifactId>connectors</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>salesforce-api</artifactId>
Modified: branches/7.1.x/connectors/sandbox/pom.xml
===================================================================
--- branches/7.1.x/connectors/sandbox/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/connectors/sandbox/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>connectors</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.jboss.teiid.connectors</groupId>
Modified: branches/7.1.x/connectors/sandbox/translator-yahoo/pom.xml
===================================================================
--- branches/7.1.x/connectors/sandbox/translator-yahoo/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/connectors/sandbox/translator-yahoo/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>sandbox</artifactId>
<groupId>org.jboss.teiid.connectors</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>translator-yahoo</artifactId>
Modified: branches/7.1.x/connectors/translator-file/pom.xml
===================================================================
--- branches/7.1.x/connectors/translator-file/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/connectors/translator-file/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>connectors</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>translator-file</artifactId>
Modified: branches/7.1.x/connectors/translator-jdbc/pom.xml
===================================================================
--- branches/7.1.x/connectors/translator-jdbc/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/connectors/translator-jdbc/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>connectors</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>translator-jdbc</artifactId>
Modified: branches/7.1.x/connectors/translator-ldap/pom.xml
===================================================================
--- branches/7.1.x/connectors/translator-ldap/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/connectors/translator-ldap/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -2,7 +2,7 @@
<parent>
<artifactId>connectors</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>translator-ldap</artifactId>
Modified: branches/7.1.x/connectors/translator-loopback/pom.xml
===================================================================
--- branches/7.1.x/connectors/translator-loopback/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/connectors/translator-loopback/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>connectors</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>translator-loopback</artifactId>
Modified: branches/7.1.x/connectors/translator-salesforce/pom.xml
===================================================================
--- branches/7.1.x/connectors/translator-salesforce/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/connectors/translator-salesforce/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>connectors</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>translator-salesforce</artifactId>
Modified: branches/7.1.x/connectors/translator-ws/pom.xml
===================================================================
--- branches/7.1.x/connectors/translator-ws/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/connectors/translator-ws/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>connectors</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>translator-ws</artifactId>
Modified: branches/7.1.x/console/pom.xml
===================================================================
--- branches/7.1.x/console/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/console/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -4,7 +4,7 @@
<parent>
<artifactId>teiid-parent</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
Modified: branches/7.1.x/documentation/admin-guide/pom.xml
===================================================================
--- branches/7.1.x/documentation/admin-guide/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/documentation/admin-guide/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -2,7 +2,7 @@
<parent>
<groupId>org.jboss.teiid</groupId>
<artifactId>documentation</artifactId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>admin-guide</artifactId>
Modified: branches/7.1.x/documentation/caching-guide/pom.xml
===================================================================
--- branches/7.1.x/documentation/caching-guide/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/documentation/caching-guide/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -2,7 +2,7 @@
<parent>
<groupId>org.jboss.teiid</groupId>
<artifactId>documentation</artifactId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>caching-guide</artifactId>
Modified: branches/7.1.x/documentation/client-developers-guide/pom.xml
===================================================================
--- branches/7.1.x/documentation/client-developers-guide/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/documentation/client-developers-guide/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -2,7 +2,7 @@
<parent>
<groupId>org.jboss.teiid</groupId>
<artifactId>documentation</artifactId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>client-developers-guide</artifactId>
Modified: branches/7.1.x/documentation/developer-guide/pom.xml
===================================================================
--- branches/7.1.x/documentation/developer-guide/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/documentation/developer-guide/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -2,7 +2,7 @@
<parent>
<groupId>org.jboss.teiid</groupId>
<artifactId>documentation</artifactId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>developer-guide</artifactId>
Modified: branches/7.1.x/documentation/pom.xml
===================================================================
--- branches/7.1.x/documentation/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/documentation/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -2,7 +2,7 @@
<parent>
<artifactId>teiid-parent</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version> </parent>
+ <version>7.1.1.GA</version> </parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.jboss.teiid</groupId>
<artifactId>documentation</artifactId>
Modified: branches/7.1.x/documentation/quick-start-example/pom.xml
===================================================================
--- branches/7.1.x/documentation/quick-start-example/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/documentation/quick-start-example/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -2,7 +2,7 @@
<parent>
<groupId>org.jboss.teiid</groupId>
<artifactId>documentation</artifactId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>quick-start-example</artifactId>
Modified: branches/7.1.x/documentation/reference/pom.xml
===================================================================
--- branches/7.1.x/documentation/reference/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/documentation/reference/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -2,7 +2,7 @@
<parent>
<groupId>org.jboss.teiid</groupId>
<artifactId>documentation</artifactId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>reference</artifactId>
Modified: branches/7.1.x/engine/pom.xml
===================================================================
--- branches/7.1.x/engine/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/engine/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>teiid-parent</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>teiid-engine</artifactId>
Modified: branches/7.1.x/hibernate-dialect/pom.xml
===================================================================
--- branches/7.1.x/hibernate-dialect/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/hibernate-dialect/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -2,7 +2,7 @@
<parent>
<artifactId>teiid-parent</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>teiid-hibernate-dialect</artifactId>
Modified: branches/7.1.x/jboss-integration/pom.xml
===================================================================
--- branches/7.1.x/jboss-integration/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/jboss-integration/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -2,7 +2,7 @@
<parent>
<artifactId>teiid-parent</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.jboss.teiid</groupId>
Modified: branches/7.1.x/metadata/pom.xml
===================================================================
--- branches/7.1.x/metadata/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/metadata/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>teiid-parent</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>teiid-metadata</artifactId>
Modified: branches/7.1.x/pom.xml
===================================================================
--- branches/7.1.x/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -5,7 +5,7 @@
<artifactId>teiid-parent</artifactId>
<packaging>pom</packaging>
<name>Teiid</name>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
<description>Federated SQL and XML query engine.</description>
<properties>
<ant.version>1.7.0</ant.version>
Modified: branches/7.1.x/runtime/pom.xml
===================================================================
--- branches/7.1.x/runtime/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/runtime/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>teiid-parent</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.jboss.teiid</groupId>
Modified: branches/7.1.x/test-integration/common/pom.xml
===================================================================
--- branches/7.1.x/test-integration/common/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/test-integration/common/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>teiid-test-integration</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>test-integration-common</artifactId>
Modified: branches/7.1.x/test-integration/db/pom.xml
===================================================================
--- branches/7.1.x/test-integration/db/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/test-integration/db/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -9,7 +9,7 @@
<parent>
<artifactId>teiid-test-integration</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
Modified: branches/7.1.x/test-integration/pom.xml
===================================================================
--- branches/7.1.x/test-integration/pom.xml 2011-02-07 18:50:57 UTC (rev 2898)
+++ branches/7.1.x/test-integration/pom.xml 2011-02-07 19:35:34 UTC (rev 2899)
@@ -3,7 +3,7 @@
<parent>
<artifactId>teiid-parent</artifactId>
<groupId>org.jboss.teiid</groupId>
- <version>7.1.1</version>
+ <version>7.1.1.GA</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>teiid-test-integration</artifactId>
13 years, 10 months
teiid SVN: r2898 - in trunk: build/kits/jboss-container and 6 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-02-07 13:50:57 -0500 (Mon, 07 Feb 2011)
New Revision: 2898
Modified:
trunk/api/src/main/java/org/teiid/translator/SourceSystemFunctions.java
trunk/build/kits/jboss-container/teiid-releasenotes.html
trunk/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml
trunk/engine/src/main/java/org/teiid/query/function/FunctionMethods.java
trunk/engine/src/main/java/org/teiid/query/function/source/SystemSource.java
trunk/engine/src/main/resources/org/teiid/query/i18n.properties
trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java
trunk/hibernate-dialect/src/main/java/org/teiid/dialect/TeiidDialect.java
Log:
TEIID-1464 adding support for a uuid function
Modified: trunk/api/src/main/java/org/teiid/translator/SourceSystemFunctions.java
===================================================================
--- trunk/api/src/main/java/org/teiid/translator/SourceSystemFunctions.java 2011-02-03 22:15:05 UTC (rev 2897)
+++ trunk/api/src/main/java/org/teiid/translator/SourceSystemFunctions.java 2011-02-07 18:50:57 UTC (rev 2898)
@@ -145,5 +145,7 @@
public static final String XMLPI = "xmlpi"; //$NON-NLS-1$
public static final String JSONTOXML = "jsontoxml"; //$NON-NLS-1$
+
+ public static final String UUID = "uuid"; //$NON-NLS-1$
}
Modified: trunk/build/kits/jboss-container/teiid-releasenotes.html
===================================================================
--- trunk/build/kits/jboss-container/teiid-releasenotes.html 2011-02-03 22:15:05 UTC (rev 2897)
+++ trunk/build/kits/jboss-container/teiid-releasenotes.html 2011-02-07 18:50:57 UTC (rev 2898)
@@ -29,6 +29,7 @@
<LI><B>Virtual procedure out params</B> - virtual procedures can now have RETURN/OUT/INOUT parameters to return values.
<LI><B>OLAP</B> - OLAP translator is now part of Teiid kit using OLAP4J
<LI><B>Multi-source procedures</B> - multi-source handling was expanded to cover stored procedure execution. See the Reference for more.
+ <LI><B>UUID function</B> - was added to generate type 4 UUIDs and the Hibernate dialect was updated to support the GUIDGenerator.
</UL>
<h2><a name="Compatibility">Compatibility Issues</a></h2>
Modified: trunk/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml
===================================================================
--- trunk/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml 2011-02-03 22:15:05 UTC (rev 2897)
+++ trunk/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml 2011-02-07 18:50:57 UTC (rev 2898)
@@ -2074,6 +2074,17 @@
<para>The two argument form is provided for backwards compatibility. roleType is a string and must be 'data'</para>
</section>
</section>
+ <section>
+ <title>Miscellaneous Functions</title>
+ <para>Other functions.</para>
+ <section>
+ <title>uuid</title>
+ <para>Retuns a universally unique identifier.</para>
+ <para><synopsis>uuid()</synopsis></para>
+ <para>the return type is string.</para>
+ <para>Generates a type 4 (pseudo randomly generated) UUID using a cryptographically strong random number generator. The format is XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX where each X is a hex digit.</para>
+ </section>
+ </section>
<section id="nondeterministic_functions">
<title>Nondeterministic Function Handling</title>
<para>Teiid categorizes functions by varying degrees of determinism.
Modified: trunk/engine/src/main/java/org/teiid/query/function/FunctionMethods.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/FunctionMethods.java 2011-02-03 22:15:05 UTC (rev 2897)
+++ trunk/engine/src/main/java/org/teiid/query/function/FunctionMethods.java 2011-02-07 18:50:57 UTC (rev 2898)
@@ -41,6 +41,7 @@
import java.util.Date;
import java.util.Properties;
import java.util.TimeZone;
+import java.util.UUID;
import org.teiid.api.exception.query.ExpressionEvaluationException;
import org.teiid.api.exception.query.FunctionExecutionException;
@@ -1375,4 +1376,8 @@
return i;
}
+ public static String uuid() {
+ return UUID.randomUUID().toString();
+ }
+
}
Modified: trunk/engine/src/main/java/org/teiid/query/function/source/SystemSource.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/source/SystemSource.java 2011-02-03 22:15:05 UTC (rev 2897)
+++ trunk/engine/src/main/java/org/teiid/query/function/source/SystemSource.java 2011-02-07 18:50:57 UTC (rev 2898)
@@ -193,6 +193,7 @@
}
addUnescape();
+ addUuidFunction();
}
private void addUnescape() {
@@ -284,6 +285,14 @@
rand.setDeterminism(Determinism.NONDETERMINISTIC);
functions.add(rand);
}
+
+ private void addUuidFunction() {
+ FunctionMethod rand = new FunctionMethod(SourceSystemFunctions.UUID, QueryPlugin.Util.getString("SystemSource.uuid_desc"), MISCELLANEOUS, FUNCTION_CLASS, "uuid", //$NON-NLS-1$ //$NON-NLS-2$
+ new FunctionParameter[] {},
+ new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, QueryPlugin.Util.getString("SystemSource.uuid_result_desc")) ); //$NON-NLS-1$ //$NON-NLS-2$
+ rand.setDeterminism(Determinism.NONDETERMINISTIC);
+ functions.add(rand);
+ }
private void addDoubleFunction(String name, String description) {
functions.add(
Modified: trunk/engine/src/main/resources/org/teiid/query/i18n.properties
===================================================================
--- trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2011-02-03 22:15:05 UTC (rev 2897)
+++ trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2011-02-07 18:50:57 UTC (rev 2898)
@@ -386,6 +386,8 @@
SystemSource.Rand_desc=Random Number
SystemSource.Rand_arg=Number
SystemSource.Rand_result_desc=Generated Random Number
+SystemSource.uuid_desc=UUID
+SystemSource.uuid_result_desc=type 4 UUID
SystemSource.Double_arg2=Number
SystemSource.Atan_arg1=Number parameter1
SystemSource.Atan_arg2=Number parameter2
Modified: trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java 2011-02-03 22:15:05 UTC (rev 2897)
+++ trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java 2011-02-07 18:50:57 UTC (rev 2898)
@@ -1405,4 +1405,8 @@
assertEquals("\r\t", helpInvokeMethod("unescape", new Class[] {DefaultDataClasses.STRING}, new Object[] { "\r\\\t" }, null)); //$NON-NLS-1$
}
+ @Test() public void testUuid() throws Exception {
+ assertNotNull(helpInvokeMethod("uuid", new Class[] {}, new Object[] {}, null)); //$NON-NLS-1$
+ }
+
}
Modified: trunk/hibernate-dialect/src/main/java/org/teiid/dialect/TeiidDialect.java
===================================================================
--- trunk/hibernate-dialect/src/main/java/org/teiid/dialect/TeiidDialect.java 2011-02-03 22:15:05 UTC (rev 2897)
+++ trunk/hibernate-dialect/src/main/java/org/teiid/dialect/TeiidDialect.java 2011-02-07 18:50:57 UTC (rev 2898)
@@ -138,6 +138,14 @@
registerFunction("modifytimezone", new StandardSQLFunction("modifytimezone", Hibernate.TIMESTAMP)); //$NON-NLS-1$ //$NON-NLS-2$
registerFunction("convert", new StandardSQLFunction("convert")); //$NON-NLS-1$ //$NON-NLS-2$
+
+ registerFunction("to_bytes", new StandardSQLFunction("to_bytes", Hibernate.BLOB)); //$NON-NLS-1$ //$NON-NLS-2$
+ registerFunction("to_chars", new StandardSQLFunction("to_chars", Hibernate.CLOB)); //$NON-NLS-1$ //$NON-NLS-2$
+ registerFunction("from_unittime", new StandardSQLFunction("from_unittime", Hibernate.TIMESTAMP)); //$NON-NLS-1$ //$NON-NLS-2$
+ registerFunction("session_id", new StandardSQLFunction("session_id", Hibernate.STRING)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ registerFunction("uuid", new StandardSQLFunction("uuid", Hibernate.STRING)); //$NON-NLS-1$ //$NON-NLS-2$
+ registerFunction("unescape", new StandardSQLFunction("unescape", Hibernate.STRING)); //$NON-NLS-1$ //$NON-NLS-2$
}
public boolean dropConstraints() {
@@ -243,6 +251,11 @@
public String getForUpdateString(String aliases) {
return ""; //$NON-NLS-1$
}
+
+ @Override
+ public String getSelectGUIDString() {
+ return "select uuid()"; //$NON-NLS-1$
+ }
}
13 years, 10 months
teiid SVN: r2897 - in trunk: api/src/main/java/org/teiid/metadata and 30 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-02-03 17:15:05 -0500 (Thu, 03 Feb 2011)
New Revision: 2897
Removed:
trunk/engine/src/test/java/org/teiid/query/function/TestFunctionDescriptorImpl.java
Modified:
trunk/api/src/main/java/org/teiid/language/Function.java
trunk/api/src/main/java/org/teiid/metadata/FunctionMethod.java
trunk/api/src/main/java/org/teiid/metadata/Schema.java
trunk/api/src/main/java/org/teiid/translator/ExecutionFactory.java
trunk/build/kits/jboss-container/teiid-releasenotes.html
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/modeshape/ModeShapeExecutionFactory.java
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/oracle/OracleSpatialFunctions.java
trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/modeshape/TestModeShapeSqlTranslator.java
trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/sqlserver/TestSqlServerConversionVisitor.java
trunk/connectors/translator-salesforce/src/main/java/org/teiid/translator/salesforce/SalesForceExecutionFactory.java
trunk/documentation/developer-guide/src/main/docbook/en-US/content/udf.xml
trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java
trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java
trunk/engine/src/main/java/org/teiid/query/function/FunctionDescriptor.java
trunk/engine/src/main/java/org/teiid/query/function/FunctionForm.java
trunk/engine/src/main/java/org/teiid/query/function/FunctionLibrary.java
trunk/engine/src/main/java/org/teiid/query/function/FunctionTree.java
trunk/engine/src/main/java/org/teiid/query/function/SystemFunctionManager.java
trunk/engine/src/main/java/org/teiid/query/function/UDFSource.java
trunk/engine/src/main/java/org/teiid/query/function/metadata/FunctionMetadataValidator.java
trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CapabilitiesUtil.java
trunk/engine/src/main/java/org/teiid/query/report/ActivityReport.java
trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
trunk/engine/src/main/java/org/teiid/query/sql/symbol/Function.java
trunk/engine/src/main/resources/org/teiid/query/i18n.properties
trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java
trunk/engine/src/test/java/org/teiid/query/function/TestFunctionTree.java
trunk/engine/src/test/java/org/teiid/query/function/metadata/TestFunctionMetadataValidator.java
trunk/engine/src/test/java/org/teiid/query/optimizer/FakeFunctionMetadataSource.java
trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java
trunk/engine/src/test/java/org/teiid/query/optimizer/relational/rules/TestCapabilitiesUtil.java
trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java
trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java
trunk/engine/src/test/java/org/teiid/query/unittest/RealMetadataFactory.java
trunk/metadata/src/test/java/org/teiid/cdk/api/TranslationUtility.java
trunk/metadata/src/test/java/org/teiid/metadata/index/VDBMetadataFactory.java
trunk/runtime/src/main/java/org/teiid/deployers/CompositeVDB.java
trunk/runtime/src/main/java/org/teiid/deployers/UDFMetaData.java
trunk/runtime/src/main/java/org/teiid/deployers/VDBParserDeployer.java
trunk/runtime/src/test/java/org/teiid/deployers/TestCompositeVDB.java
Log:
TEIID-231 various refinements to function handling.
Modified: trunk/api/src/main/java/org/teiid/language/Function.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/Function.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/api/src/main/java/org/teiid/language/Function.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -26,16 +26,18 @@
import java.util.List;
import org.teiid.language.visitor.LanguageObjectVisitor;
+import org.teiid.metadata.FunctionMethod;
/**
* Represents a function. A function has a name and 0..n
* Expressions that are parameters.
*/
-public class Function extends BaseLanguageObject implements Expression {
+public class Function extends BaseLanguageObject implements Expression, MetadataReference<FunctionMethod> {
private String name;
private List<Expression> parameters;
private Class<?> type;
+ private FunctionMethod metadataObject;
public Function(String name, List<? extends Expression> params, Class<?> type) {
this.name = name;
@@ -47,6 +49,15 @@
this.type = type;
}
+ @Override
+ public FunctionMethod getMetadataObject() {
+ return metadataObject;
+ }
+
+ public void setMetadataObject(FunctionMethod metadataObject) {
+ this.metadataObject = metadataObject;
+ }
+
/**
* Get name of the function
* @return Function name
Modified: trunk/api/src/main/java/org/teiid/metadata/FunctionMethod.java
===================================================================
--- trunk/api/src/main/java/org/teiid/metadata/FunctionMethod.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/api/src/main/java/org/teiid/metadata/FunctionMethod.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -29,6 +29,7 @@
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
+import org.teiid.core.util.EquivalenceUtil;
import org.teiid.core.util.HashCodeUtil;
@@ -109,7 +110,8 @@
@XmlElement(name="inputParameters")
protected List<FunctionParameter> inParameters = new ArrayList<FunctionParameter>();
private FunctionParameter outputParameter;
-
+ private Schema parent;
+
protected FunctionMethod() {
}
@@ -371,7 +373,7 @@
List<FunctionParameter> otherInputs = other.getInputParameters();
for(int i=0; i<thisInputs.size(); i++) {
- boolean paramMatch = compareWithNull(thisInputs.get(i), otherInputs.get(i));
+ boolean paramMatch = EquivalenceUtil.areEqual(thisInputs.get(i), otherInputs.get(i));
if(! paramMatch) {
return false;
}
@@ -385,26 +387,6 @@
}
/**
- * Compare two objects that may or may not be null and consider null==null
- * as true.
- * @param o1 Object 1
- * @param o2 Object 2
- * @return True if o1 and o2 are null or if they both aren't and they are equal
- */
- private boolean compareWithNull(Object o1, Object o2) {
- if(o1 == null) {
- if(o2 == null) {
- return true;
- }
- return false;
- }
- if(o2 == null) {
- return false;
- }
- return o1.equals(o2);
- }
-
- /**
* Return string version for debugging purposes
* @return String representation of function method
*/
@@ -473,5 +455,13 @@
}
return false;
}
-
+
+ public void setParent(Schema parent) {
+ this.parent = parent;
+ }
+
+ @Override
+ public Schema getParent() {
+ return parent;
+ }
}
Modified: trunk/api/src/main/java/org/teiid/metadata/Schema.java
===================================================================
--- trunk/api/src/main/java/org/teiid/metadata/Schema.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/api/src/main/java/org/teiid/metadata/Schema.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -52,7 +52,10 @@
}
public void addFunction(FunctionMethod function) {
- this.functions.put(function.getName().toLowerCase(), function);
+ function.setParent(this);
+ if (this.functions.put(function.getName().toLowerCase(), function) != null) {
+ throw new AssertionError("Duplicate function " + function.getName()); //$NON-NLS-1$
+ }
}
/**
Modified: trunk/api/src/main/java/org/teiid/translator/ExecutionFactory.java
===================================================================
--- trunk/api/src/main/java/org/teiid/translator/ExecutionFactory.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/api/src/main/java/org/teiid/translator/ExecutionFactory.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -650,7 +650,7 @@
}
public List<FunctionMethod> getPushDownFunctions(){
- return Collections.EMPTY_LIST;
+ return Collections.emptyList();
}
/**
Modified: trunk/build/kits/jboss-container/teiid-releasenotes.html
===================================================================
--- trunk/build/kits/jboss-container/teiid-releasenotes.html 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/build/kits/jboss-container/teiid-releasenotes.html 2011-02-03 22:15:05 UTC (rev 2897)
@@ -40,7 +40,8 @@
<h4>from 7.3</h4>
<ul>
<li>The use of an IN procedure parameter with the name "source_name" in a multi-source model, will now be treated the parameter that controls which source
- the procedure will execute against.
+ the procedure will execute against.
+ <li>Dynamic VDB functions injected via ExecutionFactory.getPushdownFunctions are now scoped to the SYS schema and have a fully qualified name that includes their source type. For example, instead of oracle_model.relate - which was only valid against the oracle_model source, there is now the SYS.oracle_sdo.relate function that is valid for all Oracle sources. Any fully-qualified reference to these functions will need updated.
</ul>
<h4>from 7.2</h4>
@@ -189,9 +190,8 @@
<h2><a name="Licenses">Licenses</a></h2>
<p>Teiid is licensed under the <a href="LICENSE-lgpl-2.1.txt">LGPL</a>. The
-license texts for Teiid and the thirdparty components it uses may be found in the teiid-docs/licenses
-directory of the distribution. <a href="teiid-docs/licenses">Browse
-Licenses</a>
+license texts for Teiid and the thirdparty components it uses may be found in the <a href="teiid-docs/licenses">teiid-docs/licenses</a>
+directory of the distribution.
</p>
Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/modeshape/ModeShapeExecutionFactory.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/modeshape/ModeShapeExecutionFactory.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/modeshape/ModeShapeExecutionFactory.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -116,31 +116,31 @@
@Override
public List<FunctionMethod> getPushDownFunctions(){
List<FunctionMethod> pushdownFunctions = new ArrayList<FunctionMethod>();
- pushdownFunctions.add(new FunctionMethod(JCR_ISCHILDNODE, JCR_ISCHILDNODE, JCR,
+ pushdownFunctions.add(new FunctionMethod(JCR + '.' + JCR_ISCHILDNODE, JCR_ISCHILDNODE, JCR,
new FunctionParameter[] {
new FunctionParameter("path1", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("path2", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.BOOLEAN, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- pushdownFunctions.add(new FunctionMethod(JCR_ISDESCENDANTNODE, JCR_ISDESCENDANTNODE, JCR,
+ pushdownFunctions.add(new FunctionMethod(JCR + '.' + JCR_ISDESCENDANTNODE, JCR_ISDESCENDANTNODE, JCR,
new FunctionParameter[] {
new FunctionParameter("path1", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("path2", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.BOOLEAN, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- pushdownFunctions.add(new FunctionMethod(JCR_ISSAMENODE, JCR_ISSAMENODE, JCR,
+ pushdownFunctions.add(new FunctionMethod(JCR + '.' + JCR_ISSAMENODE, JCR_ISSAMENODE, JCR,
new FunctionParameter[] {
new FunctionParameter("path1", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("path2", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.BOOLEAN, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- pushdownFunctions.add(new FunctionMethod(JCR_CONTAINS, JCR_CONTAINS, JCR,
+ pushdownFunctions.add(new FunctionMethod(JCR + '.' + JCR_CONTAINS, JCR_CONTAINS, JCR,
new FunctionParameter[] {
new FunctionParameter("selectorOrProperty", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("searchExpr", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.BOOLEAN, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- pushdownFunctions.add(new FunctionMethod(JCR_REFERENCE, JCR_REFERENCE, JCR,
+ pushdownFunctions.add(new FunctionMethod(JCR + '.' + JCR_REFERENCE, JCR_REFERENCE, JCR,
new FunctionParameter[] {
new FunctionParameter("selectorOrProperty", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.BOOLEAN, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/oracle/OracleSpatialFunctions.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/oracle/OracleSpatialFunctions.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/oracle/OracleSpatialFunctions.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -38,42 +38,42 @@
public static final String FILTER = "sdo_filter"; //$NON-NLS-1$
public static final String WITHIN_DISTANCE = "sdo_within_distance"; //$NON-NLS-1$
public static final String NEAREST_NEIGHBOR_DISTANCE = "sdo_nn_distance"; //$NON-NLS-1$
- private static final String ORACLE_SDO = "Oracle-SDO"; //$NON-NLS-1$
+ public static final String ORACLE_SDO = "Oracle-SDO"; //$NON-NLS-1$
public static List<FunctionMethod> getOracleSpatialFunctions(){
List<FunctionMethod> spatialFuncs = new ArrayList<FunctionMethod>();
- spatialFuncs.add(new FunctionMethod(RELATE, RELATE, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + RELATE, RELATE, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("PARAMS", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(RELATE, RELATE, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + RELATE, RELATE, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("PARAMS", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(RELATE, RELATE, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + RELATE, RELATE, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("PARAMS", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(RELATE, RELATE, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + RELATE, RELATE, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("PARAMS", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(NEAREST_NEIGHBOR, NEAREST_NEIGHBOR, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + NEAREST_NEIGHBOR, NEAREST_NEIGHBOR, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
@@ -81,7 +81,7 @@
new FunctionParameter("NUMBER", DataTypeManager.DefaultDataTypes.INTEGER, "") }, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(NEAREST_NEIGHBOR, NEAREST_NEIGHBOR, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + NEAREST_NEIGHBOR, NEAREST_NEIGHBOR, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
@@ -89,7 +89,7 @@
new FunctionParameter("NUMBER", DataTypeManager.DefaultDataTypes.INTEGER, "") }, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(NEAREST_NEIGHBOR, NEAREST_NEIGHBOR, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + NEAREST_NEIGHBOR, NEAREST_NEIGHBOR, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
@@ -97,47 +97,47 @@
new FunctionParameter("NUMBER", DataTypeManager.DefaultDataTypes.INTEGER, "") }, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(NEAREST_NEIGHBOR_DISTANCE, NEAREST_NEIGHBOR_DISTANCE, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + NEAREST_NEIGHBOR_DISTANCE, NEAREST_NEIGHBOR_DISTANCE, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("NUMBER", DataTypeManager.DefaultDataTypes.INTEGER, "") }, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.INTEGER, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(WITHIN_DISTANCE, WITHIN_DISTANCE, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + WITHIN_DISTANCE, WITHIN_DISTANCE, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("PARAMS", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(WITHIN_DISTANCE, WITHIN_DISTANCE, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + WITHIN_DISTANCE, WITHIN_DISTANCE, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("PARAMS", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(WITHIN_DISTANCE, WITHIN_DISTANCE, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + WITHIN_DISTANCE, WITHIN_DISTANCE, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("PARAMS", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(FILTER, FILTER, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + FILTER, FILTER, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("PARAMS", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(FILTER, FILTER, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + FILTER, FILTER, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("PARAMS", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(FILTER, FILTER, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + FILTER, FILTER, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
Modified: trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/modeshape/TestModeShapeSqlTranslator.java
===================================================================
--- trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/modeshape/TestModeShapeSqlTranslator.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/modeshape/TestModeShapeSqlTranslator.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -91,7 +91,7 @@
public void testPredicate() throws Exception {
String input = "SELECT x.jcr_primaryType from nt_base inner join nt_base as x on jcr_issamenode(nt_base.jcr_path, x.jcr_path) = true where jcr_isdescendantnode(nt_base.jcr_path, 'x/y/z') = true and jcr_reference(nt_base.mode_properties) = 'x'"; //$NON-NLS-1$
- String output = "SELECT g_1.\"jcr:primaryType\" FROM \"nt:base\" AS g_0 INNER JOIN \"nt:base\" AS g_1 ON issamenode(g_0, g_1) WHERE isdescendantnode(g_0, 'x/y/z') AND reference(g_0.*) = 'x'"; //$NON-NLS-1$
+ String output = "SELECT g_1.\"jcr:primaryType\" FROM \"nt:base\" AS g_0 INNER JOIN \"nt:base\" AS g_1 ON ISSAMENODE(g_0, g_1) WHERE ISDESCENDANTNODE(g_0, 'x/y/z') AND REFERENCE(g_0.*) = 'x'"; //$NON-NLS-1$
helpTestVisitor(input, output);
Modified: trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/sqlserver/TestSqlServerConversionVisitor.java
===================================================================
--- trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/sqlserver/TestSqlServerConversionVisitor.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/sqlserver/TestSqlServerConversionVisitor.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -128,7 +128,7 @@
@Test
public void testDateFunctions() throws Exception {
String input = "select dayName(timestampValue), dayOfWeek(timestampValue), quarter(timestampValue) from bqt1.smalla"; //$NON-NLS-1$
- String output = "SELECT {fn dayName(SmallA.TimestampValue)}, {fn dayOfWeek(SmallA.TimestampValue)}, {fn quarter(SmallA.TimestampValue)} FROM SmallA"; //$NON-NLS-1$
+ String output = "SELECT {fn dayname(SmallA.TimestampValue)}, {fn dayofweek(SmallA.TimestampValue)}, {fn quarter(SmallA.TimestampValue)} FROM SmallA"; //$NON-NLS-1$
helpTestVisitor(getBQTVDB(),
input,
Modified: trunk/connectors/translator-salesforce/src/main/java/org/teiid/translator/salesforce/SalesForceExecutionFactory.java
===================================================================
--- trunk/connectors/translator-salesforce/src/main/java/org/teiid/translator/salesforce/SalesForceExecutionFactory.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/connectors/translator-salesforce/src/main/java/org/teiid/translator/salesforce/SalesForceExecutionFactory.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -142,13 +142,13 @@
@Override
public List<FunctionMethod> getPushDownFunctions(){
List<FunctionMethod> pushdownFunctions = new ArrayList<FunctionMethod>();
- pushdownFunctions.add(new FunctionMethod(INCLUDES, INCLUDES, SALESFORCE,
+ pushdownFunctions.add(new FunctionMethod(SALESFORCE + '.' +INCLUDES, INCLUDES, SALESFORCE,
new FunctionParameter[] {
new FunctionParameter("columnName", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("param", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.BOOLEAN, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- pushdownFunctions.add(new FunctionMethod(EXCLUDES, EXCLUDES, SALESFORCE,
+ pushdownFunctions.add(new FunctionMethod(SALESFORCE + '.' + EXCLUDES, EXCLUDES, SALESFORCE,
new FunctionParameter[] {
new FunctionParameter("columnName", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("param", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
Modified: trunk/documentation/developer-guide/src/main/docbook/en-US/content/udf.xml
===================================================================
--- trunk/documentation/developer-guide/src/main/docbook/en-US/content/udf.xml 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/documentation/developer-guide/src/main/docbook/en-US/content/udf.xml 2011-02-03 22:15:05 UTC (rev 2897)
@@ -8,7 +8,7 @@
creating a UDF.</para>
<section id="define_udf">
<title>UDF Definition</title>
- <para>The FunctionDefinition.xmi file provides metadata to the
+ <para>A FunctionDefinition.xmi file provides metadata to the
query engine on User Defined Functions. See the Designer Documentation for more on creating a Function Definition Model.</para>
<itemizedlist>
<para>The following are used to define a UDF.</para>
@@ -19,24 +19,20 @@
mind:
<itemizedlist>
<listitem>
- <para>You cannot use a reserved word, which includes
- existing Teiid System function names. You cannot
- overload existing Teiid System functions.</para>
+ <para>You cannot overload existing Teiid System functions.</para>
</listitem>
<listitem>
<para>The function name must be unique among user-defined
- functions for the number of arguments. You can use the
+ functions in its model for the number of arguments. You can use the
same function name for different numbers of types of
arguments. Hence, you can overload your user-defined
functions.</para>
</listitem>
<listitem>
- <para>The function name can only contain letters,
- numbers, and the underscore (_). Your function name must
- start with a letter.</para>
+ <para>The function name cannot contain the '.' character.</para>
</listitem>
<listitem>
- <para>The function name cannot exceed 128 characters.
+ <para>The function name cannot exceed 255 characters.
</para>
</listitem>
</itemizedlist>
@@ -225,4 +221,18 @@
created in in the Designer Tool, it can be added to the VDB for use
by Teiid.</para>
</section>
+ <section>
+ <title>User Defined Functions in Dynamic VDBs</title>
+ <para>Dynamic VDBs do not use Designer generated artifacts, such as a FunctionDefinition.xmi file.
+ Even with that limitation dynamic vdbs may still utilize UDFs through custom coding.
+ The <code>ExecutionFactory.getMetadata</code> call allows for the definition of metadata via a <code>MetadataFactory.</code>
+ Use the <code>MetadataFactory.addFunction</code> to add function for use only by that translator instance.
+ Functions added directly to the source schema are specific to that schema - their fully qualified name will include the schema and the function can not be pushed to a different source.
+ </para>
+ <para>The <code>ExecutionFactory.getPushdownFunctions</code> method can be used to describe functions that are valid against all instances of a given translator type. The function names are expected to be
+ prefixed by the translator type, or some other logical grouping, e.g. salesforce.includes. The full name of the function once imported into the system will qualified by the SYS schema, e.g. SYS.salesforce.includes.
+ </para>
+ <para>Any funcitons added via these mechanisms do not need to be declared in <code>ExecutionFactory.getSupportedFunctions.</code> Any of the additional handling, such as adding a <code>FunctionModifier</code>, covered above is also applicable here. All pushdown functions will have function name set to only the simple name. Schema or other qualification will be removed.
+ Handling, such as function modifiers, can check the function metadata if there is the potential for an ambiguity.</para>
+ </section>
</chapter>
\ No newline at end of file
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -495,12 +495,22 @@
org.teiid.language.Function translate(Function function) {
Expression [] args = function.getArgs();
List<org.teiid.language.Expression> params = new ArrayList<org.teiid.language.Expression>(args.length);
- if (args != null) {
- for (int i = 0; i < args.length; i++) {
- params.add(translate(args[i]));
- }
+ for (int i = 0; i < args.length; i++) {
+ params.add(translate(args[i]));
}
- return new org.teiid.language.Function(function.getName(), params, function.getType());
+ String name = function.getName();
+ if (function.getFunctionDescriptor() != null) {
+ name = function.getFunctionDescriptor().getName();
+ }
+ name = SingleElementSymbol.getShortName(name);
+
+ //if there is any ambiguity in the function name it will be up to the translator logic to check the
+ //metadata
+ org.teiid.language.Function result = new org.teiid.language.Function(name, params, function.getType());
+ if (function.getFunctionDescriptor() != null) {
+ result.setMetadataObject(function.getFunctionDescriptor().getMethod());
+ }
+ return result;
}
SearchedCase translate(SearchedCaseExpression expr) {
@@ -515,7 +525,7 @@
org.teiid.language.Expression translate(ScalarSubquery ss) {
- return new org.teiid.language.ScalarSubquery(translate((QueryCommand)ss.getCommand()));
+ return new org.teiid.language.ScalarSubquery(translate(ss.getCommand()));
}
org.teiid.language.Expression translate(SingleElementSymbol symbol) {
@@ -562,11 +572,12 @@
/* Insert */
org.teiid.language.Insert translate(Insert insert) {
- List elements = insert.getVariables();
+ List<ElementSymbol> elements = insert.getVariables();
List<ColumnReference> translatedElements = new ArrayList<ColumnReference>();
- for (Iterator i = elements.iterator(); i.hasNext();) {
- translatedElements.add(translate((ElementSymbol)i.next()));
- }
+
+ for (ElementSymbol elementSymbol : elements) {
+ translatedElements.add(translate(elementSymbol));
+ }
InsertValueSource valueSource = null;
if (insert.getQueryExpression() != null) {
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -694,7 +694,7 @@
this.processWorkerPool = new ThreadReuseExecutor(DQPConfiguration.PROCESS_PLAN_QUEUE_NAME, config.getMaxThreads());
if (cacheFactory.isReplicated()) {
- matTables = new SessionAwareCache<CachedResults>(this.cacheFactory, SessionAwareCache.Type.RESULTSET, new CacheConfiguration(Policy.LRU, -1, -1, "MaterilizationTables")); //$NON-NLS-1$
+ matTables = new SessionAwareCache<CachedResults>(this.cacheFactory, SessionAwareCache.Type.RESULTSET, new CacheConfiguration(Policy.EXPIRATION, -1, -1, "MaterilizationTables")); //$NON-NLS-1$
matTables.setBufferManager(this.bufferManager);
}
Modified: trunk/engine/src/main/java/org/teiid/query/function/FunctionDescriptor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/FunctionDescriptor.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/function/FunctionDescriptor.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -31,33 +31,27 @@
import org.teiid.core.TeiidRuntimeException;
import org.teiid.core.types.DataTypeManager;
import org.teiid.core.types.TransformationException;
-import org.teiid.core.util.Assertion;
-import org.teiid.core.util.HashCodeUtil;
import org.teiid.core.util.PropertiesUtils;
-import org.teiid.metadata.FunctionMethod.PushDown;
+import org.teiid.metadata.FunctionMethod;
import org.teiid.metadata.FunctionMethod.Determinism;
+import org.teiid.metadata.FunctionMethod.PushDown;
import org.teiid.query.QueryPlugin;
import org.teiid.query.util.CommandContext;
/**
* The FunctionDescriptor describes a particular function instance enough
- * that the function library can retrieve a function instance based on the
- * descriptor.
+ * to invoke the function.
*/
public class FunctionDescriptor implements Serializable, Cloneable {
private static final long serialVersionUID = 5374103983118037242L;
private static final boolean ALLOW_NAN_INFINITY = PropertiesUtils.getBooleanProperty(System.getProperties(), "org.teiid.allowNanInfinity", false); //$NON-NLS-1$
- private String name;
- private PushDown pushdown = PushDown.CAN_PUSHDOWN;
- private Class[] types;
- private Class returnType;
- private int hash;
+ private Class<?>[] types;
+ private Class<?> returnType;
private boolean requiresContext;
- private boolean nullDependent;
- private Determinism deterministic = Determinism.DETERMINISTIC;
+ private FunctionMethod method;
// This is transient as it would be useless to invoke this method in
// a different VM. This function descriptor can be used to look up
@@ -67,52 +61,29 @@
FunctionDescriptor() {
}
- /**
- * Construct a function descriptor with all the info
- * @param name Name of function
- * @param types Types of the arguments
- * @param returnType Type of the return
- * @param invocationMethod Reflection method used to invoke the function
- * @param requiresContext during execution requires command context to be pushed into method as first argument
- */
- FunctionDescriptor(String name, PushDown pushdown, Class[] types, Class returnType, Method invocationMethod, boolean requiresContext, boolean nullDependent, Determinism deterministic) {
- Assertion.isNotNull(name);
- Assertion.isNotNull(types);
- Assertion.isNotNull(returnType);
-
- this.name = name;
- this.pushdown = pushdown;
+ FunctionDescriptor(FunctionMethod method, Class<?>[] types,
+ Class<?> outputType, Method invocationMethod,
+ boolean requiresContext) {
this.types = types;
- this.returnType = returnType;
+ this.returnType = outputType;
this.invocationMethod = invocationMethod;
this.requiresContext = requiresContext;
- this.nullDependent = nullDependent;
- this.deterministic = deterministic;
-
- // Compute hash code
- hash = HashCodeUtil.hashCode(0, name);
- for(int i=0; i<types.length; i++) {
- hash = HashCodeUtil.hashCode(hash, types[i]);
- }
+ this.method = method;
}
public String getName() {
- return this.name;
+ return this.method.getName();
}
public PushDown getPushdown() {
- return this.pushdown;
+ return this.method.getPushdown();
}
- void setPushdown(PushDown pushdown) {
- this.pushdown = pushdown;
- }
-
- public Class[] getTypes() {
+ public Class<?>[] getTypes() {
return this.types;
}
- public Class getReturnType() {
+ public Class<?> getReturnType() {
return this.returnType;
}
@@ -124,51 +95,8 @@
return this.requiresContext;
}
- public int hashCode() {
- return this.hash;
- }
-
- public boolean equals(Object obj) {
- if(obj == this) {
- return true;
- }
-
- if(obj == null || !(obj instanceof FunctionDescriptor)) {
- return false;
- }
- FunctionDescriptor other = (FunctionDescriptor) obj;
-
- // Compare names
- if(! this.getName().equals(other.getName())) {
- return false;
- }
-
- // Compare arg types
- Class[] thisTypes = this.getTypes();
- Class[] otherTypes = other.getTypes();
- if(thisTypes.length != otherTypes.length) {
- return false;
- }
- for(int i=0; i<thisTypes.length; i++) {
- if(! thisTypes[i].equals(otherTypes[i])) {
- return false;
- }
- }
-
- if (this.nullDependent != other.isNullDependent()) {
- return false;
- }
-
- if (this.deterministic != other.deterministic) {
- return false;
- }
-
- // Must be a match
- return true;
- }
-
public String toString() {
- StringBuffer str = new StringBuffer(this.name);
+ StringBuffer str = new StringBuffer(this.method.getName());
str.append("("); //$NON-NLS-1$
for(int i=0; i<types.length; i++) {
if(types[i] != null) {
@@ -190,17 +118,13 @@
}
public boolean isNullDependent() {
- return nullDependent;
+ return !this.method.isNullOnNull();
}
public Determinism getDeterministic() {
- return deterministic;
+ return this.method.getDeterminism();
}
- void setDeterministic(Determinism deterministic) {
- this.deterministic = deterministic;
- }
-
public Object clone() {
try {
return super.clone();
@@ -208,12 +132,15 @@
throw new TeiidRuntimeException(e);
}
}
+
+ public FunctionMethod getMethod() {
+ return method;
+ }
- void setReturnType(Class returnType) {
+ void setReturnType(Class<?> returnType) {
this.returnType = returnType;
}
-
/**
* Invoke the function described in the function descriptor, using the
* values provided. Return the result of the function.
Modified: trunk/engine/src/main/java/org/teiid/query/function/FunctionForm.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/FunctionForm.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/function/FunctionForm.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -40,7 +40,7 @@
* information and instead differentiates function signatures based on their
* function name and the names of the arguments.
*/
-public class FunctionForm implements Serializable, Comparable {
+public class FunctionForm implements Serializable, Comparable<FunctionForm> {
private static final long serialVersionUID = 2411783099304320334L;
private String name;
@@ -245,42 +245,32 @@
* @param obj Other object
* @return 1 if other > this, 0 if other == this, -1 if other < this
*/
- public int compareTo(Object obj) {
- if(obj == this) {
- return 0;
- } else if(obj == null) {
- // Should never happen, but sort nulls low
- return -1;
- } else {
- // may throw ClassCastException - this is expected for compareTo()
- FunctionForm other = (FunctionForm) obj;
+ public int compareTo(FunctionForm other) {
+ int compare = this.getName().compareTo( other.getName() );
+ if(compare != 0) {
+ return compare;
+ }
- int compare = this.getName().compareTo( other.getName() );
+ // Look further into arg names to compare as names are ==
+ List otherArgs = other.getArgNames();
+ List myArgs = this.getArgNames();
+
+ // Compare # of args first
+ if(myArgs.size() < otherArgs.size()) {
+ return -1;
+ } else if(myArgs.size() > otherArgs.size()) {
+ return 1;
+ } // else continue
+
+ // Same # of args
+ for(int i=0; i < myArgs.size(); i++) {
+ compare = ((String)myArgs.get(i)).compareTo( ((String)otherArgs.get(i)) );
if(compare != 0) {
return compare;
}
-
- // Look further into arg names to compare as names are ==
- List otherArgs = other.getArgNames();
- List myArgs = this.getArgNames();
-
- // Compare # of args first
- if(myArgs.size() < otherArgs.size()) {
- return -1;
- } else if(myArgs.size() > otherArgs.size()) {
- return 1;
- } // else continue
-
- // Same # of args
- for(int i=0; i < myArgs.size(); i++) {
- compare = ((String)myArgs.get(i)).compareTo( ((String)otherArgs.get(i)) );
- if(compare != 0) {
- return compare;
- }
- }
-
- // Same
- return 0;
}
+
+ // Same
+ return 0;
}
}
Modified: trunk/engine/src/main/java/org/teiid/query/function/FunctionLibrary.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/FunctionLibrary.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/function/FunctionLibrary.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -25,9 +25,9 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
-import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
+import java.util.TreeSet;
import org.teiid.api.exception.query.InvalidFunctionException;
import org.teiid.api.exception.query.QueryResolverException;
@@ -108,9 +108,9 @@
* Get all function categories, sorted in alphabetical order
* @return List of function category names, sorted in alphabetical order
*/
- public List getFunctionCategories() {
+ public List<String> getFunctionCategories() {
// Remove category duplicates
- HashSet categories = new HashSet();
+ TreeSet<String> categories = new TreeSet<String>();
categories.addAll( systemFunctions.getCategories() );
if (this.userFunctions != null) {
for (FunctionTree tree: this.userFunctions) {
@@ -118,9 +118,7 @@
}
}
- // Sort alphabetically
- ArrayList categoryList = new ArrayList(categories);
- Collections.sort(categoryList);
+ ArrayList<String> categoryList = new ArrayList<String>(categories);
return categoryList;
}
@@ -129,8 +127,8 @@
* @param category Category name
* @return List of {@link FunctionForm}s in a category
*/
- public List getFunctionForms(String category) {
- List forms = new ArrayList();
+ public List<FunctionForm> getFunctionForms(String category) {
+ List<FunctionForm> forms = new ArrayList<FunctionForm>();
forms.addAll(systemFunctions.getFunctionForms(category));
if (this.userFunctions != null) {
for (FunctionTree tree: this.userFunctions) {
@@ -170,7 +168,7 @@
* @param types Array of classes representing the types
* @return Descriptor if found, null if not found
*/
- public FunctionDescriptor findFunction(String name, Class[] types) {
+ public FunctionDescriptor findFunction(String name, Class<?>[] types) {
// First look in system functions
FunctionDescriptor descriptor = systemFunctions.getFunction(name, types);
@@ -323,7 +321,7 @@
* @param targetType The target type class
* @return A CONVERT function descriptor or null if not possible
*/
- public FunctionDescriptor findTypedConversionFunction(Class sourceType, Class targetType) {
+ public FunctionDescriptor findTypedConversionFunction(Class<?> sourceType, Class<?> targetType) {
FunctionDescriptor fd = findFunction(CONVERT, new Class[] {sourceType, DataTypeManager.DefaultDataClasses.STRING});
if (fd != null) {
return copyFunctionChangeReturnType(fd, targetType);
@@ -337,7 +335,7 @@
* @param returnType The return type to apply to the copied FunctionDescriptor.
* @return The copy of FunctionDescriptor.
*/
- public FunctionDescriptor copyFunctionChangeReturnType(FunctionDescriptor fd, Class returnType) {
+ public FunctionDescriptor copyFunctionChangeReturnType(FunctionDescriptor fd, Class<?> returnType) {
if(fd != null) {
FunctionDescriptor fdImpl = fd;
FunctionDescriptor copy = (FunctionDescriptor)fdImpl.clone();
Modified: trunk/engine/src/main/java/org/teiid/query/function/FunctionTree.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/FunctionTree.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/function/FunctionTree.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -29,15 +29,14 @@
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import org.teiid.core.CoreConstants;
import org.teiid.core.TeiidRuntimeException;
import org.teiid.core.types.DataTypeManager;
-import org.teiid.core.util.Assertion;
import org.teiid.core.util.ReflectionHelper;
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
@@ -75,55 +74,32 @@
*/
private Map treeRoot = new HashMap();
private boolean validateClass;
-
+
/**
* Construct a new tree with the given source of function metadata.
* @param source The metadata source
*/
- public FunctionTree(FunctionMetadataSource source) {
- this(source, false);
+ public FunctionTree(String name, FunctionMetadataSource source) {
+ this(name, source, false);
}
/**
* Construct a new tree with the given source of function metadata.
* @param source The metadata source
*/
- public FunctionTree(FunctionMetadataSource source, boolean validateClass) {
+ public FunctionTree(String name, FunctionMetadataSource source, boolean validateClass) {
// Load data structures
this.validateClass = validateClass;
- addSource(source);
- }
- /**
- * Add all functions from a metadata source to the data structures.
- * @param source The source of the functions
- */
- private void addSource(FunctionMetadataSource source) {
- if(source == null) {
- return;
+ Collection<FunctionMethod> functions = source.getFunctionMethods();
+ for (FunctionMethod method : functions) {
+ if (!containsIndistinguishableFunction(method)){
+ // Add to tree
+ addFunction(name, source, method);
+ } else if (!CoreConstants.SYSTEM_MODEL.equalsIgnoreCase(name)) {
+ LogManager.logWarning(LogConstants.CTX_FUNCTION_TREE, QueryPlugin.Util.getString("ERR.015.001.0046", new Object[]{method})); //$NON-NLS-1$
+ }
}
-
- Collection functions = source.getFunctionMethods();
- if(functions != null) {
- Iterator functionIter = functions.iterator();
- while(functionIter.hasNext()) {
- Object functionObj = functionIter.next();
- if(! (functionObj instanceof FunctionMethod)) {
- Assertion.failed(QueryPlugin.Util.getString("ERR.015.001.0045", functionObj.getClass().getName())); //$NON-NLS-1$
- }
- FunctionMethod method = (FunctionMethod) functionObj;
-
- if (!containsIndistinguishableFunction(method)){
- // Store method metadata for retrieval
- addMetadata(method);
-
- // Add to tree
- addFunction(source, method);
- } else {
- LogManager.logWarning(LogConstants.CTX_FUNCTION_TREE, QueryPlugin.Util.getString("ERR.015.001.0046", new Object[]{method})); //$NON-NLS-1$
- }
- }
- }
}
// ---------------------- FUNCTION SELECTION USE METHODS ----------------------
@@ -143,51 +119,6 @@
}
/**
- * Store the method in the function metadata.
- * @param method The function metadata for a particular method signature
- */
- private void addMetadata(FunctionMethod method) {
- String categoryKey = method.getCategory();
- if (categoryKey == null) {
- method.setCategory(FunctionCategoryConstants.MISCELLANEOUS);
- categoryKey = FunctionCategoryConstants.MISCELLANEOUS;
- }
- categoryKey = categoryKey.toUpperCase();
- String nameKey = method.getName().toUpperCase();
-
- // Look up function map (create if necessary)
- Set<String> functions = categories.get(categoryKey);
- if (functions == null) {
- functions = new HashSet<String>();
- categories.put(categoryKey, functions);
- }
-
- int index = -1;
- while (true){
- // Look up function in function map
- functions.add(nameKey);
-
- // Add method to list by function name
- List<FunctionMethod> knownMethods = functionsByName.get(nameKey);
- if(knownMethods == null) {
- knownMethods = new ArrayList<FunctionMethod>();
- functionsByName.put(nameKey, knownMethods);
- }
- knownMethods.add(method);
-
- // if the function is "." delimited, then add all possible forms
- index = nameKey.indexOf(AbstractMetadataRecord.NAME_DELIM_CHAR, index+1);
- if (index != -1) {
- nameKey = nameKey.substring(index+1);
- }
- else {
- break;
- }
- }
- allFunctions.add(method);
- }
-
- /**
* Get collection of category names.
* @return Category names
*/
@@ -258,28 +189,94 @@
* @param source The function metadata source, which knows how to obtain the invocation class
* @param method The function metadata for a particular method signature
*/
- private void addFunction(FunctionMetadataSource source, FunctionMethod method) {
+ private void addFunction(String schema, FunctionMetadataSource source, FunctionMethod method) {
+ String categoryKey = method.getCategory();
+ if (categoryKey == null) {
+ method.setCategory(FunctionCategoryConstants.MISCELLANEOUS);
+ categoryKey = FunctionCategoryConstants.MISCELLANEOUS;
+ }
+ categoryKey = categoryKey.toUpperCase();
+
+ // Look up function map (create if necessary)
+ Set<String> functions = categories.get(categoryKey);
+ if (functions == null) {
+ functions = new HashSet<String>();
+ categories.put(categoryKey, functions);
+ }
+
// Get method name
- String methodName = method.getName();
+ String methodName = schema + AbstractMetadataRecord.NAME_DELIM_CHAR + method.getName();
// Get input types for path
List<FunctionParameter> inputParams = method.getInputParameters();
- List<Class> inputTypes = new LinkedList<Class>();
+ List<Class<?>> inputTypes = new LinkedList<Class<?>>();
if(inputParams != null) {
for(int i=0; i<inputParams.size(); i++) {
String typeName = inputParams.get(i).getType();
inputTypes.add(DataTypeManager.getDataTypeClass(typeName));
}
}
- Class[] types = inputTypes.toArray(new Class[inputTypes.size()]);
+ Class<?>[] types = inputTypes.toArray(new Class[inputTypes.size()]);
if (method.isVarArgs()) {
inputTypes.set(inputTypes.size() - 1, Array.newInstance(inputTypes.get(inputTypes.size() - 1), 0).getClass());
}
- // Get return type
+ FunctionDescriptor descriptor = createFunctionDescriptor(source, method, inputTypes, types);
+ // Store this path in the function tree
+
+ int index = -1;
+ while(true) {
+ String nameKey = methodName.toUpperCase();
+
+ // Look up function in function map
+ functions.add(nameKey);
+
+ // Add method to list by function name
+ List<FunctionMethod> knownMethods = functionsByName.get(nameKey);
+ if(knownMethods == null) {
+ knownMethods = new ArrayList<FunctionMethod>();
+ functionsByName.put(nameKey, knownMethods);
+ }
+ knownMethods.add(method);
+
+ Map node = treeRoot;
+ Object[] path = buildPath(methodName, types);
+ for(int pathIndex = 0; pathIndex < path.length; pathIndex++) {
+ Object pathPart = path[pathIndex];
+ Map children = (Map) node.get(pathPart);
+ if(children == null) {
+ children = new HashMap();
+ node.put(pathPart, children);
+ }
+ if (method.isVarArgs() && pathIndex == path.length - 1) {
+ node.put(DESCRIPTOR_KEY, descriptor);
+ }
+ node = children;
+ }
+
+ if (method.isVarArgs()) {
+ node.put(types[types.length - 1], node);
+ }
+ // Store the leaf descriptor in the tree
+ node.put(DESCRIPTOR_KEY, descriptor);
+
+ index = methodName.indexOf(AbstractMetadataRecord.NAME_DELIM_CHAR, index+1);
+ if (index == -1) {
+ break;
+ }
+ methodName = methodName.substring(index+1);
+ }
+
+ allFunctions.add(method);
+ }
+
+ private FunctionDescriptor createFunctionDescriptor(
+ FunctionMetadataSource source, FunctionMethod method,
+ List<Class<?>> inputTypes, Class<?>[] types) {
+ // Get return type
FunctionParameter outputParam = method.getOutputParameter();
- Class outputType = null;
+ Class<?> outputType = null;
if(outputParam != null) {
outputType = DataTypeManager.getDataTypeClass(outputParam.getType());
}
@@ -329,39 +326,8 @@
inputTypes.add(0, CommandContext.class);
}
- FunctionDescriptor descriptor = new FunctionDescriptor(method.getName(), method.getPushdown(), types, outputType, invocationMethod, requiresContext, !method.isNullOnNull(), method.getDeterminism());
- // Store this path in the function tree
-
- int index = -1;
- while(true) {
- Map node = treeRoot;
- Object[] path = buildPath(methodName, types);
- for(int pathIndex = 0; pathIndex < path.length; pathIndex++) {
- Object pathPart = path[pathIndex];
- Map children = (Map) node.get(pathPart);
- if(children == null) {
- children = new HashMap();
- node.put(pathPart, children);
- }
- if (method.isVarArgs() && pathIndex == path.length - 1) {
- node.put(DESCRIPTOR_KEY, descriptor);
- }
- node = children;
- }
-
- if (method.isVarArgs()) {
- node.put(types[types.length - 1], node);
- }
- // Store the leaf descriptor in the tree
- node.put(DESCRIPTOR_KEY, descriptor);
-
- index = methodName.indexOf(AbstractMetadataRecord.NAME_DELIM_CHAR, index+1);
- if (index == -1) {
- break;
- }
- methodName = methodName.substring(index+1);
- }
- }
+ return new FunctionDescriptor(method, types, outputType, invocationMethod, requiresContext);
+ }
/**
* Look up a function descriptor by signature in the tree. If none is
@@ -370,7 +336,7 @@
* @param argTypes Types of each argument in the function
* @return Descriptor which can be used to invoke the function
*/
- FunctionDescriptor getFunction(String name, Class[] argTypes) {
+ FunctionDescriptor getFunction(String name, Class<?>[] argTypes) {
// Build search path
Object[] path = buildPath(name, argTypes);
@@ -399,7 +365,7 @@
* @param argTypes Types of each arguments
* @return Path in function storage tree
*/
- private Object[] buildPath(String name, Class[] argTypes) {
+ private Object[] buildPath(String name, Class<?>[] argTypes) {
Object[] path = new Object[argTypes.length + 1];
path[0] = name.toUpperCase();
System.arraycopy(argTypes, 0, path, 1, argTypes.length);
Modified: trunk/engine/src/main/java/org/teiid/query/function/SystemFunctionManager.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/SystemFunctionManager.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/function/SystemFunctionManager.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -22,8 +22,8 @@
package org.teiid.query.function;
import java.util.Collection;
-import java.util.Collections;
+import org.teiid.core.CoreConstants;
import org.teiid.query.QueryPlugin;
import org.teiid.query.function.metadata.FunctionMetadataValidator;
import org.teiid.query.function.source.SystemSource;
@@ -47,13 +47,13 @@
// Should never happen as SystemSourcTe doesn't change
System.err.println(QueryPlugin.Util.getString("ERR.015.001.0005", report)); //$NON-NLS-1$
}
- systemFunctionTree = new FunctionTree(systemSource, true);
+ systemFunctionTree = new FunctionTree(CoreConstants.SYSTEM_MODEL, systemSource, true);
}
return systemFunctionTree;
}
public FunctionLibrary getSystemFunctionLibrary() {
- return new FunctionLibrary(getSystemFunctions(), new FunctionTree(new UDFSource(Collections.EMPTY_LIST)));
+ return new FunctionLibrary(getSystemFunctions());
}
/**
Modified: trunk/engine/src/main/java/org/teiid/query/function/UDFSource.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/UDFSource.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/function/UDFSource.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -36,11 +36,11 @@
this.methods = methods;
}
- public Collection getFunctionMethods() {
+ public Collection<FunctionMethod> getFunctionMethods() {
return this.methods;
}
- public Class getInvocationClass(String className) throws ClassNotFoundException {
+ public Class<?> getInvocationClass(String className) throws ClassNotFoundException {
return Class.forName(className);
}
}
Modified: trunk/engine/src/main/java/org/teiid/query/function/metadata/FunctionMetadataValidator.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/metadata/FunctionMetadataValidator.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/function/metadata/FunctionMetadataValidator.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -253,26 +253,9 @@
* @throws FunctionMetadataException Thrown when string uses characters not in allowed character sets
*/
private static final void validateNameCharacters(String name, String strName) throws FunctionMetadataException {
- // First check first character
- if(name.length() > 0) {
- // Check special cases
- if(name.equals("+") || name.equals("-") || name.equals("*") || name.equals("/") || name.equals("||")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
- return;
- }
-
- char firstChar = name.charAt(0);
- if(! Character.isLetter(firstChar)) {
- throw new FunctionMetadataException("ERR.015.001.0056", QueryPlugin.Util.getString("ERR.015.001.0056",strName, new Character(firstChar))); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- // Then check the rest of the characters
- for(int i=1; i<name.length(); i++) {
- char ch = name.charAt(i);
- if(! (Character.isLetterOrDigit(ch) || ch == '_')) {
- throw new FunctionMetadataException("ERR.015.001.0057", QueryPlugin.Util.getString("ERR.015.001.0057",strName, new Character(ch))); //$NON-NLS-1$ //$NON-NLS-2$
- }
- }
- }
+ if (name.indexOf('.') > 0) {
+ throw new FunctionMetadataException("ERR.015.001.0057", QueryPlugin.Util.getString("ERR.015.001.0057",strName, '.')); //$NON-NLS-1$ //$NON-NLS-2$
+ }
}
/**
Modified: trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -142,7 +142,7 @@
* TransformationMetadata constructor
* @param context Object containing the info needed to lookup metadta.
*/
- public TransformationMetadata(VDBMetaData vdbMetadata, final CompositeMetadataStore store, Map<String, Resource> vdbEntries, FunctionTree systemFunctions, FunctionTree... udfFunctions) {
+ public TransformationMetadata(VDBMetaData vdbMetadata, final CompositeMetadataStore store, Map<String, Resource> vdbEntries, FunctionTree systemFunctions, Collection<FunctionTree> functionTrees) {
ArgCheck.isNotNull(store);
this.vdbMetaData = vdbMetadata;
this.store = store;
@@ -151,7 +151,11 @@
} else {
this.vdbEntries = vdbEntries;
}
- this.functionLibrary = new FunctionLibrary(systemFunctions, udfFunctions);
+ if (functionTrees == null) {
+ this.functionLibrary = new FunctionLibrary(systemFunctions);
+ } else {
+ this.functionLibrary = new FunctionLibrary(systemFunctions, functionTrees.toArray(new FunctionTree[functionTrees.size()]));
+ }
}
//==================================================================================
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CapabilitiesUtil.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CapabilitiesUtil.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CapabilitiesUtil.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -30,6 +30,7 @@
import org.teiid.api.exception.query.QueryMetadataException;
import org.teiid.core.TeiidComponentException;
import org.teiid.core.types.DataTypeManager;
+import org.teiid.metadata.Schema;
import org.teiid.query.function.FunctionLibrary;
import org.teiid.query.metadata.QueryMetadataInterface;
import org.teiid.query.optimizer.capabilities.CapabilitiesFinder;
@@ -206,12 +207,20 @@
if (metadata.isVirtualModel(modelID)){
return false;
}
+
+ //capabilities check is only valid for non-schema scoped functions
+ //technically the other functions are scoped to SYS, but that's
+ //not formally part of their metadata yet
+ Schema schema = function.getFunctionDescriptor().getMethod().getParent();
+ if (schema == null) {
+ // Find capabilities
+ SourceCapabilities caps = getCapabilities(modelID, metadata, capFinder);
- // Find capabilities
- SourceCapabilities caps = getCapabilities(modelID, metadata, capFinder);
-
- if (!caps.supportsFunction(function.getName().toLowerCase())) {
- return false;
+ if (!caps.supportsFunction(function.getFunctionDescriptor().getName().toLowerCase())) {
+ return false;
+ }
+ } else if (!schema.getFullName().equalsIgnoreCase(metadata.getFullName(modelID))) {
+ return false; //not the right schema
}
//special check to ensure that special conversions are not pushed down (this can be removed after we support type based function pushdown)
Modified: trunk/engine/src/main/java/org/teiid/query/report/ActivityReport.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/report/ActivityReport.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/report/ActivityReport.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -88,5 +88,10 @@
public Collection<R> getItems() {
return items;
}
+
+ @Override
+ public String toString() {
+ return reportType + " " + getItems(); //$NON-NLS-1$
+ }
}
Modified: trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -2221,11 +2221,19 @@
//rewrite alias functions
String functionLowerName = function.getName().toLowerCase();
String actualName =ALIASED_FUNCTIONS.get(functionLowerName);
+ FunctionLibrary funcLibrary = this.metadata.getFunctionLibrary();
+
if (actualName != null) {
function.setName(actualName);
+ Expression[] args = function.getArgs();
+ Class<?>[] types = new Class[args.length];
+ for(int i=0; i<args.length; i++) {
+ types[i] = args[i].getType();
+ }
+ FunctionDescriptor descriptor = funcLibrary.findFunction(actualName, types);
+ function.setFunctionDescriptor(descriptor);
}
- FunctionLibrary funcLibrary = this.metadata.getFunctionLibrary();
Integer code = FUNCTION_MAP.get(functionLowerName);
if (code != null) {
switch (code) {
Modified: trunk/engine/src/main/java/org/teiid/query/sql/symbol/Function.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/symbol/Function.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/sql/symbol/Function.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -192,12 +192,16 @@
return true;
}
- if(obj == null || ! (obj instanceof Function)) {
+ if(! (obj instanceof Function)) {
return false;
}
Function other = (Function) obj;
- if(! other.getName().equalsIgnoreCase(getName())) {
+ if (this.descriptor != null && other.descriptor != null) {
+ if (!this.descriptor.getMethod().getFullName().equals(other.descriptor.getMethod().getFullName())) {
+ return false;
+ }
+ } else if(! other.getName().equalsIgnoreCase(getName())) {
return false;
}
Modified: trunk/engine/src/main/resources/org/teiid/query/i18n.properties
===================================================================
--- trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2011-02-03 22:15:05 UTC (rev 2897)
@@ -39,7 +39,6 @@
ERR.015.001.0042 = Illegal argument for formating: {0}
ERR.015.001.0043 = Parse Exception occurs for executing: {0} {1}
ERR.015.001.0044 = Function metadata source is of invalid type: {0}
-ERR.015.001.0045 = Function method is of invalid type: {0}
ERR.015.001.0046 = The function "{0}" will not be added because a function with the same name and signature already exists.
ERR.015.001.0047 = Unexpected exception while loading "{1}.{2}" for UDF "{0}"
FunctionTree.not_void = UDF "{0}" method "{1}" must not return void.
Deleted: trunk/engine/src/test/java/org/teiid/query/function/TestFunctionDescriptorImpl.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/function/TestFunctionDescriptorImpl.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/function/TestFunctionDescriptorImpl.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -1,115 +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.query.function;
-
-import java.lang.reflect.Method;
-
-import junit.framework.TestCase;
-
-import org.teiid.core.types.DataTypeManager;
-import org.teiid.core.util.UnitTestUtil;
-import org.teiid.metadata.FunctionMethod.Determinism;
-import org.teiid.metadata.FunctionMethod.PushDown;
-
-
-public class TestFunctionDescriptorImpl extends TestCase {
-
- /**
- * Constructor for TestFunctionDescriptorImpl.
- * @param name
- */
- public TestFunctionDescriptorImpl(String name) {
- super(name);
- }
-
- /**
- * Find the invocation method for a function.
- * @param source The function metadata source, which knows how to obtain the invocation class
- * @param invocationClass The class to invoke for this function
- * @param invocationMethod The method to invoke for this function
- * @param numArgs Number of arguments in method
- * @throws NoSuchMethodException
- * @throws SecurityException
- */
- private Method lookupMethod(String invocationClass, String invocationMethod, int numArgs) throws SecurityException, NoSuchMethodException {
- // Build signature
- Class[] objectSignature = new Class[numArgs];
- for(int i=0; i<numArgs; i++) {
- objectSignature[i] = Integer.TYPE;
- }
-
- // Find Method
- Method method = null;
- try {
- Class methodClass = Class.forName(invocationClass);
- method = methodClass.getMethod(invocationMethod, objectSignature);
- } catch(ClassNotFoundException e) {
- // Failed to load class, so can't load method - this will fail at invocation time.
- // We don't fail here because this situation can occur in the modeler, which does
- // not have the function jar files. The modeler never invokes, so this isn't a
- // problem.
- return null;
- }
-
- return method;
- }
-
- public void test1() throws Exception {
- FunctionDescriptor f1 = new FunctionDescriptor("+", PushDown.CAN_PUSHDOWN, //$NON-NLS-1$
- new Class[] { DataTypeManager.DefaultDataClasses.INTEGER, DataTypeManager.DefaultDataClasses.INTEGER },
- DataTypeManager.DefaultDataClasses.INTEGER,
- lookupMethod("com.metamatrix.query.function.FunctionMethods", "plus", 2) , false, true, Determinism.DETERMINISTIC); //$NON-NLS-1$ //$NON-NLS-2$
-
- UnitTestUtil.helpTestEquivalence(0, f1, f1);
- }
-
- public void test2() throws Exception {
- FunctionDescriptor f1 = new FunctionDescriptor("+", PushDown.CAN_PUSHDOWN,//$NON-NLS-1$
- new Class[] { DataTypeManager.DefaultDataClasses.INTEGER, DataTypeManager.DefaultDataClasses.INTEGER },
- DataTypeManager.DefaultDataClasses.INTEGER,
- lookupMethod("com.metamatrix.query.function.FunctionMethods", "plus", 2), false, true, Determinism.DETERMINISTIC ); //$NON-NLS-1$ //$NON-NLS-2$
-
- FunctionDescriptor f2 = new FunctionDescriptor("+", PushDown.CAN_PUSHDOWN,//$NON-NLS-1$
- new Class[] { DataTypeManager.DefaultDataClasses.INTEGER, DataTypeManager.DefaultDataClasses.INTEGER },
- DataTypeManager.DefaultDataClasses.INTEGER,
- lookupMethod("com.metamatrix.query.function.FunctionMethods", "plus", 2), false, true, Determinism.DETERMINISTIC ); //$NON-NLS-1$ //$NON-NLS-2$
-
- UnitTestUtil.helpTestEquivalence(0, f1, f2);
- }
-
- public void test3() throws Exception {
- FunctionDescriptor f1 = new FunctionDescriptor("+", PushDown.CAN_PUSHDOWN,//$NON-NLS-1$
- new Class[] { DataTypeManager.DefaultDataClasses.INTEGER, DataTypeManager.DefaultDataClasses.INTEGER },
- DataTypeManager.DefaultDataClasses.INTEGER,
- lookupMethod("com.metamatrix.query.function.FunctionMethods", "plus", 2), false, false, Determinism.DETERMINISTIC ); //$NON-NLS-1$ //$NON-NLS-2$
-
-
- FunctionDescriptor f2 = new FunctionDescriptor("+", PushDown.CAN_PUSHDOWN,//$NON-NLS-1$
- new Class[] { DataTypeManager.DefaultDataClasses.INTEGER, DataTypeManager.DefaultDataClasses.INTEGER },
- DataTypeManager.DefaultDataClasses.INTEGER,
- lookupMethod("com.metamatrix.query.function.FunctionMethods", "plus", 2), false, true, Determinism.DETERMINISTIC ); //$NON-NLS-1$ //$NON-NLS-2$
-
- assertNotSame("objects should not be equal", f1, f2); //$NON-NLS-1$
- }
-
-}
Modified: trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -22,12 +22,7 @@
package org.teiid.query.function;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.Assert.*;
import java.math.BigDecimal;
import java.math.BigInteger;
@@ -38,7 +33,6 @@
import java.sql.Timestamp;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
import java.util.Iterator;
import java.util.Properties;
import java.util.TimeZone;
@@ -84,7 +78,7 @@
private static final Class<Date> T_DATE = DataTypeManager.DefaultDataClasses.DATE;
private static final Class<Timestamp> T_TIMESTAMP = DataTypeManager.DefaultDataClasses.TIMESTAMP;
- private FunctionLibrary library = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(Collections.EMPTY_LIST)));
+ private FunctionLibrary library = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions());
@Before public void setUp() {
TimestampWithTimezone.resetCalendar(TimeZone.getTimeZone("GMT-06:00")); //$NON-NLS-1$
Modified: trunk/engine/src/test/java/org/teiid/query/function/TestFunctionTree.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/function/TestFunctionTree.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/function/TestFunctionTree.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -50,7 +50,7 @@
*/
@Test public void testWalkTree() {
SystemSource source = new SystemSource(false);
- FunctionTree ft = new FunctionTree(source);
+ FunctionTree ft = new FunctionTree("foo", source);
Collection<String> categories = ft.getCategories();
for (String category : categories) {
@@ -78,11 +78,11 @@
new FunctionParameter("output", DataTypeManager.DefaultDataTypes.STRING), false, Determinism.DETERMINISTIC); //$NON-NLS-1$
//allowed, since we're not validating the class
- new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(Arrays.asList(method))));
+ new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new UDFSource(Arrays.asList(method))));
//should fail, no class
try {
- new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(Arrays.asList(method)), true));
+ new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new UDFSource(Arrays.asList(method)), true));
fail();
} catch (TeiidRuntimeException e) {
@@ -92,7 +92,7 @@
//should fail, no method
try {
- new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(Arrays.asList(method)), true));
+ new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new UDFSource(Arrays.asList(method)), true));
fail();
} catch (TeiidRuntimeException e) {
@@ -102,7 +102,7 @@
//should fail, not void
try {
- new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(Arrays.asList(method)), true));
+ new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new UDFSource(Arrays.asList(method)), true));
fail();
} catch (TeiidRuntimeException e) {
@@ -112,7 +112,7 @@
//should fail, not public
try {
- new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(Arrays.asList(method)), true));
+ new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new UDFSource(Arrays.asList(method)), true));
fail();
} catch (TeiidRuntimeException e) {
@@ -122,7 +122,7 @@
//should fail, not static
try {
- new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(Arrays.asList(method)), true));
+ new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new UDFSource(Arrays.asList(method)), true));
fail();
} catch (TeiidRuntimeException e) {
@@ -131,7 +131,7 @@
method.setInvocationMethod("y");
//valid!
- new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(Arrays.asList(method)), true));
+ new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new UDFSource(Arrays.asList(method)), true));
}
@Test public void testNullCategory() {
@@ -144,7 +144,7 @@
Collection<org.teiid.metadata.FunctionMethod> list = Arrays.asList(method);
FunctionMetadataSource fms = Mockito.mock(FunctionMetadataSource.class);
Mockito.stub(fms.getFunctionMethods()).toReturn(list);
- FunctionTree ft = new FunctionTree(fms);
+ FunctionTree ft = new FunctionTree("foo", fms);
assertEquals(1, ft.getFunctionForms(FunctionCategoryConstants.MISCELLANEOUS).size());
}
Modified: trunk/engine/src/test/java/org/teiid/query/function/metadata/TestFunctionMetadataValidator.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/function/metadata/TestFunctionMetadataValidator.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/function/metadata/TestFunctionMetadataValidator.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -92,12 +92,8 @@
helpTestValidateNameFail(null);
}
- public void testValidateNameFail2() {
- helpTestValidateNameFail("123"); //$NON-NLS-1$
- }
-
public void testValidateNameFail3() {
- helpTestValidateNameFail("a b"); //$NON-NLS-1$
+ helpTestValidateNameFail("a.b"); //$NON-NLS-1$
}
public void testValidateFunction1() {
Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/FakeFunctionMetadataSource.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/FakeFunctionMetadataSource.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/FakeFunctionMetadataSource.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -27,7 +27,6 @@
import java.util.List;
import org.teiid.core.types.DataTypeManager;
-import org.teiid.metadata.Datatype;
import org.teiid.metadata.FunctionParameter;
import org.teiid.metadata.FunctionMethod.PushDown;
import org.teiid.query.function.FunctionMetadataSource;
Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -22,11 +22,7 @@
package org.teiid.query.optimizer;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.Arrays;
@@ -46,7 +42,6 @@
import org.teiid.query.analysis.AnalysisRecord;
import org.teiid.query.function.FunctionLibrary;
import org.teiid.query.function.FunctionTree;
-import org.teiid.query.function.UDFSource;
import org.teiid.query.mapping.relational.QueryNode;
import org.teiid.query.metadata.QueryMetadataInterface;
import org.teiid.query.optimizer.capabilities.BasicSourceCapabilities;
@@ -4265,7 +4260,7 @@
caps.setFunctionSupport("xyz", true); //$NON-NLS-1$
capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$
- FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(new FakeFunctionMetadataSource().getFunctionMethods())));
+ FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new FakeFunctionMetadataSource()));
FakeMetadataFacade metadata = new FakeMetadataFacade(FakeMetadataFactory.example1Cached().getStore(), funcLibrary);
Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/relational/rules/TestCapabilitiesUtil.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/relational/rules/TestCapabilitiesUtil.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/relational/rules/TestCapabilitiesUtil.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -25,7 +25,10 @@
import java.util.ArrayList;
import java.util.List;
+import junit.framework.TestCase;
+
import org.teiid.api.exception.query.QueryMetadataException;
+import org.teiid.api.exception.query.QueryResolverException;
import org.teiid.core.TeiidComponentException;
import org.teiid.language.SQLConstants.NonReserved;
import org.teiid.query.optimizer.capabilities.BasicSourceCapabilities;
@@ -33,7 +36,7 @@
import org.teiid.query.optimizer.capabilities.FakeCapabilitiesFinder;
import org.teiid.query.optimizer.capabilities.SourceCapabilities;
import org.teiid.query.optimizer.capabilities.SourceCapabilities.Capability;
-import org.teiid.query.optimizer.relational.rules.CapabilitiesUtil;
+import org.teiid.query.resolver.util.ResolverVisitor;
import org.teiid.query.sql.lang.JoinType;
import org.teiid.query.sql.lang.SetQuery.Operation;
import org.teiid.query.sql.symbol.AggregateSymbol;
@@ -46,9 +49,7 @@
import org.teiid.query.unittest.FakeMetadataFactory;
import org.teiid.query.unittest.FakeMetadataObject;
-import junit.framework.TestCase;
-
/**
*/
public class TestCapabilitiesUtil extends TestCase {
@@ -369,7 +370,7 @@
helpTestSupportsAggregateFunction(caps, aggregate, true);
}
- public void helpTestSupportsScalar(SourceCapabilities caps, Function function, boolean expectedValue) throws QueryMetadataException, TeiidComponentException {
+ public void helpTestSupportsScalar(SourceCapabilities caps, Function function, boolean expectedValue) throws QueryMetadataException, TeiidComponentException, QueryResolverException {
// Set up metadata
FakeMetadataFacade metadata = FakeMetadataFactory.example1Cached();
FakeMetadataObject modelID = metadata.getStore().findObject("pm1", FakeMetadataObject.MODEL); //$NON-NLS-1$
@@ -377,7 +378,7 @@
// Set up capabilities
FakeCapabilitiesFinder finder = new FakeCapabilitiesFinder();
finder.addCapabilities("pm1", caps); //$NON-NLS-1$
-
+ ResolverVisitor.resolveLanguageObject(function, metadata);
// Test capabilities util
boolean actual = CapabilitiesUtil.supportsScalarFunction(modelID, function, metadata, finder);
assertEquals("Got wrong answer for supports", expectedValue, actual); //$NON-NLS-1$
@@ -387,7 +388,7 @@
public void testSupportsScalar1() throws Exception {
BasicSourceCapabilities caps = new BasicSourceCapabilities();
- Function func = new Function("+", new Expression[] { new ElementSymbol("x"), new ElementSymbol("y") }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ Function func = new Function("+", new Expression[] { new Constant(1), new Constant(2) }); //$NON-NLS-1$
helpTestSupportsScalar(caps, func, false);
}
@@ -409,14 +410,6 @@
helpTestSupportsScalar(caps, func, true);
}
- // Test where function is unknown
- public void testSupportsScalar5() throws Exception {
- BasicSourceCapabilities caps = new BasicSourceCapabilities();
-
- Function func = new Function("sasquatch", new Expression[] { }); //$NON-NLS-1$
- helpTestSupportsScalar(caps, func, false);
- }
-
public void testSupportsDistinct1() throws Exception {
// Set up metadata
FakeMetadataFacade metadata = FakeMetadataFactory.example1Cached();
Modified: trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -62,7 +62,6 @@
import org.teiid.query.analysis.AnalysisRecord;
import org.teiid.query.function.FunctionLibrary;
import org.teiid.query.function.FunctionTree;
-import org.teiid.query.function.UDFSource;
import org.teiid.query.mapping.relational.QueryNode;
import org.teiid.query.metadata.QueryMetadataInterface;
import org.teiid.query.metadata.TempMetadataAdapter;
@@ -5261,7 +5260,7 @@
caps.setFunctionSupport("myrtrim", true); //$NON-NLS-1$
capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$
- FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(new FakeFunctionMetadataSource().getFunctionMethods())));
+ FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new FakeFunctionMetadataSource()));
FakeMetadataFacade metadata = new FakeMetadataFacade(FakeMetadataFactory.example1Cached().getStore(), funcLibrary);
processPreparedStatement(sql, expected, dataManager, capFinder,
@@ -5309,7 +5308,7 @@
caps.setFunctionSupport("concat", true); //$NON-NLS-1$
capFinder.addCapabilities("pm4", caps); //$NON-NLS-1$
- FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(new FakeFunctionMetadataSource().getFunctionMethods())));
+ FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new FakeFunctionMetadataSource()));
FakeMetadataFacade metadata = new FakeMetadataFacade(FakeMetadataFactory.example1Cached().getStore(), funcLibrary);
processPreparedStatement(sql, expected, dataManager, capFinder,
Modified: trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -22,13 +22,7 @@
package org.teiid.query.resolver;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.Assert.*;
import java.math.BigDecimal;
import java.math.BigInteger;
@@ -57,7 +51,6 @@
import org.teiid.query.function.FunctionDescriptor;
import org.teiid.query.function.FunctionLibrary;
import org.teiid.query.function.FunctionTree;
-import org.teiid.query.function.UDFSource;
import org.teiid.query.mapping.relational.QueryNode;
import org.teiid.query.metadata.QueryMetadataInterface;
import org.teiid.query.metadata.TempMetadataID;
@@ -1587,7 +1580,7 @@
@Test public void testNamespacedFunction() throws Exception {
String sql = "SELECT namespace.func('e1') FROM vm1.g1 "; //$NON-NLS-1$
- FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(new FakeFunctionMetadataSource().getFunctionMethods())));
+ FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new FakeFunctionMetadataSource()));
FakeMetadataFacade metadata = new FakeMetadataFacade(FakeMetadataFactory.example1Cached().getStore(), funcLibrary);
Query command = (Query) helpParse(sql);
Modified: trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -46,7 +46,6 @@
import org.teiid.core.util.TimestampWithTimezone;
import org.teiid.query.function.FunctionLibrary;
import org.teiid.query.function.FunctionTree;
-import org.teiid.query.function.UDFSource;
import org.teiid.query.metadata.QueryMetadataInterface;
import org.teiid.query.optimizer.FakeFunctionMetadataSource;
import org.teiid.query.parser.QueryParser;
@@ -2364,7 +2363,7 @@
}
@Test public void testUDFParse() throws Exception {
- FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(new FakeFunctionMetadataSource().getFunctionMethods())));
+ FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new FakeFunctionMetadataSource()));
FakeMetadataFacade metadata = new FakeMetadataFacade(FakeMetadataFactory.example1Cached().getStore(), funcLibrary);
String sql = "parsedate_(pm1.g1.e1) = {d'2001-01-01'}";
helpTestRewriteCriteria(sql, parseCriteria(sql, metadata), metadata);
Modified: trunk/engine/src/test/java/org/teiid/query/unittest/RealMetadataFactory.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/unittest/RealMetadataFactory.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/unittest/RealMetadataFactory.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -302,9 +302,11 @@
List<FunctionTree> udfs = new ArrayList<FunctionTree>();
for (Schema schema : metadataStore.getSchemas().values()) {
vdbMetaData.addModel(FakeMetadataFactory.createModel(schema.getName(), schema.isPhysical()));
- udfs.add(new FunctionTree(new UDFSource(schema.getFunctions().values()), true));
+ if (!schema.getFunctions().isEmpty()) {
+ udfs.add(new FunctionTree(schema.getName(), new UDFSource(schema.getFunctions().values()), true));
+ }
}
- return new TransformationMetadata(vdbMetaData, store, null, FakeMetadataFactory.SFM.getSystemFunctions(), udfs.toArray(new FunctionTree[udfs.size()]));
+ return new TransformationMetadata(vdbMetaData, store, null, FakeMetadataFactory.SFM.getSystemFunctions(), udfs);
}
/**
Modified: trunk/metadata/src/test/java/org/teiid/cdk/api/TranslationUtility.java
===================================================================
--- trunk/metadata/src/test/java/org/teiid/cdk/api/TranslationUtility.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/metadata/src/test/java/org/teiid/cdk/api/TranslationUtility.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -104,7 +104,7 @@
@Override
public FunctionLibrary getFunctionLibrary() {
SystemFunctionManager sfm = new SystemFunctionManager();
- return new FunctionLibrary(sfm.getSystemFunctions(), new FunctionTree(new UDFSource(methods)));
+ return new FunctionLibrary(sfm.getSystemFunctions(), new FunctionTree("foo", new UDFSource(methods))); //$NON-NLS-1$
}
};
}
Modified: trunk/metadata/src/test/java/org/teiid/metadata/index/VDBMetadataFactory.java
===================================================================
--- trunk/metadata/src/test/java/org/teiid/metadata/index/VDBMetadataFactory.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/metadata/src/test/java/org/teiid/metadata/index/VDBMetadataFactory.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -83,11 +83,14 @@
IndexMetadataFactory imf = loadMetadata(vdbURL);
Collection <FunctionMethod> methods = null;
+ Collection<FunctionTree> trees = null;
if (udfFile != null) {
+ String schema = FileUtils.getFilenameWithoutExtension(udfFile.getPath());
methods = FunctionMetadataReader.loadFunctionMethods(udfFile.openStream());
+ trees = Arrays.asList(new FunctionTree(schema, new UDFSource(methods), true));
}
SystemFunctionManager sfm = new SystemFunctionManager();
- vdbmetadata = new TransformationMetadata(null, new CompositeMetadataStore(Arrays.asList(getSystem(), imf.getMetadataStore(getSystem().getDatatypes()))), imf.getEntriesPlusVisibilities(), sfm.getSystemFunctions(), new FunctionTree(new UDFSource(methods), true));
+ vdbmetadata = new TransformationMetadata(null, new CompositeMetadataStore(Arrays.asList(getSystem(), imf.getMetadataStore(getSystem().getDatatypes()))), imf.getEntriesPlusVisibilities(), sfm.getSystemFunctions(), trees);
VDB_CACHE.put(vdbURL, vdbmetadata);
return vdbmetadata;
} catch (URISyntaxException e) {
Modified: trunk/runtime/src/main/java/org/teiid/deployers/CompositeVDB.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/deployers/CompositeVDB.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/runtime/src/main/java/org/teiid/deployers/CompositeVDB.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -25,15 +25,16 @@
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
import org.teiid.adminapi.DataPolicy;
import org.teiid.adminapi.Model;
import org.teiid.adminapi.impl.DataPolicyMetadata;
import org.teiid.adminapi.impl.ModelMetaData;
import org.teiid.adminapi.impl.VDBMetaData;
+import org.teiid.core.CoreConstants;
import org.teiid.dqp.internal.datamgr.ConnectorManager;
import org.teiid.dqp.internal.datamgr.ConnectorManagerRepository;
-import org.teiid.metadata.AbstractMetadataRecord;
import org.teiid.metadata.FunctionMethod;
import org.teiid.metadata.MetadataStore;
import org.teiid.metadata.Schema;
@@ -100,8 +101,8 @@
private TransformationMetadata buildTransformationMetaData(VDBMetaData vdb, LinkedHashMap<String, Resource> visibilityMap, MetadataStoreGroup stores, UDFMetaData udf, FunctionTree systemFunctions) {
Collection <FunctionTree> udfs = new ArrayList<FunctionTree>();
if (udf != null) {
- for (Collection<FunctionMethod> methods:udf.getFunctions()) {
- udfs.add(new FunctionTree(new UDFSource(methods), true));
+ for (Map.Entry<String, Collection<FunctionMethod>> entry : udf.getFunctions().entrySet()) {
+ udfs.add(new FunctionTree(entry.getKey(), new UDFSource(entry.getValue()), true));
}
}
@@ -110,7 +111,7 @@
compositeStore.addMetadataStore(s);
}
- TransformationMetadata metadata = new TransformationMetadata(vdb, compositeStore, visibilityMap, systemFunctions, udfs.toArray(new FunctionTree[udfs.size()]));
+ TransformationMetadata metadata = new TransformationMetadata(vdb, compositeStore, visibilityMap, systemFunctions, udfs);
return metadata;
}
@@ -161,28 +162,23 @@
mergedUDF.addFunctions(this.udf);
}
if (this.stores != null) {
+ //schema scoped source functions - this is only a dynamic vdb concept
for(MetadataStore store:this.stores.getStores()) {
for (Schema schema:store.getSchemas().values()) {
Collection<FunctionMethod> funcs = schema.getFunctions().values();
- for(FunctionMethod func:funcs) {
- func.setNameInSource(func.getName());
- func.setName(schema.getName() + AbstractMetadataRecord.NAME_DELIM_CHAR + func.getName());
- }
- mergedUDF.addFunctions(funcs);
+ mergedUDF.addFunctions(schema.getName(), funcs);
}
}
}
if (this.cmr != null) {
+ //system scoped common source functions
for (ConnectorManager cm:this.cmr.getConnectorManagers().values()) {
List<FunctionMethod> funcs = cm.getPushDownFunctions();
- for(FunctionMethod func:funcs) {
- func.setNameInSource(cm.getTranslatorName()+ AbstractMetadataRecord.NAME_DELIM_CHAR + func.getName());
- func.setName(cm.getModelName() + AbstractMetadataRecord.NAME_DELIM_CHAR + func.getName());
- }
- mergedUDF.addFunctions(funcs);
+ mergedUDF.addFunctions(CoreConstants.SYSTEM_MODEL, funcs);
}
}
if (this.children != null) {
+ //udf model functions - also scoped to the model
for (CompositeVDB child:this.children.values()) {
UDFMetaData funcs = child.getUDF();
if (funcs != null) {
Modified: trunk/runtime/src/main/java/org/teiid/deployers/UDFMetaData.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/deployers/UDFMetaData.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/runtime/src/main/java/org/teiid/deployers/UDFMetaData.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -25,20 +25,26 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import javax.xml.bind.JAXBException;
import org.jboss.managed.api.annotation.ManagementObject;
import org.jboss.virtual.VirtualFile;
+import org.teiid.api.exception.query.QueryMetadataException;
import org.teiid.metadata.FunctionMethod;
+import org.teiid.query.QueryPlugin;
import org.teiid.query.function.metadata.FunctionMetadataReader;
+import org.teiid.query.function.metadata.FunctionMetadataValidator;
+import org.teiid.query.report.ActivityReport;
+import org.teiid.query.report.ReportItem;
import org.teiid.runtime.RuntimePlugin;
@ManagementObject
public class UDFMetaData {
- private Collection<Collection <FunctionMethod>> methods = new ArrayList<Collection<FunctionMethod>>();
-
+ private HashMap<String, Collection <FunctionMethod>> methods = new HashMap<String, Collection<FunctionMethod>>();
private HashMap<String, VirtualFile> files = new HashMap<String, VirtualFile>();
public void addModelFile(VirtualFile file) {
@@ -46,31 +52,45 @@
}
- void buildFunctionModelFile(String name) throws IOException, JAXBException {
+ void buildFunctionModelFile(String name, String path) throws IOException, JAXBException, QueryMetadataException {
for (String f:files.keySet()) {
- if (f.endsWith(name)) {
- name = f;
+ if (f.endsWith(path)) {
+ path = f;
break;
}
}
- VirtualFile file =this.files.get(name);
- if (file != null) {
- this.methods.add(FunctionMetadataReader.loadFunctionMethods(file.openStream()));
- }
- else {
+ VirtualFile file =this.files.get(path);
+ if (file == null) {
throw new IOException(RuntimePlugin.Util.getString("udf_model_not_found", name)); //$NON-NLS-1$
}
+ List<FunctionMethod> udfMethods = FunctionMetadataReader.loadFunctionMethods(file.openStream());
+ ActivityReport<ReportItem> report = new ActivityReport<ReportItem>("UDF load"); //$NON-NLS-1$
+ FunctionMetadataValidator.validateFunctionMethods(udfMethods,report);
+ if(report.hasItems()) {
+ throw new QueryMetadataException(QueryPlugin.Util.getString("ERR.015.001.0005", report)); //$NON-NLS-1$
+ }
+ this.methods.put(name, udfMethods);
}
- public Collection<Collection <FunctionMethod>> getFunctions(){
+ public Map<String, Collection <FunctionMethod>> getFunctions(){
return this.methods;
}
- public void addFunctions(Collection <FunctionMethod> funcs){
- this.methods.add(funcs);
+ public void addFunctions(String name, Collection <FunctionMethod> funcs){
+ if (funcs.isEmpty()) {
+ return;
+ }
+ Collection <FunctionMethod> old = this.methods.put(name, funcs);
+ if (old != null) {
+ ArrayList<FunctionMethod> combined = new ArrayList<FunctionMethod>(old);
+ combined.addAll(funcs);
+ this.methods.put(name, combined);
+ }
}
public void addFunctions(UDFMetaData funcs){
- this.methods.addAll(funcs.getFunctions());
+ for (Map.Entry<String, Collection<FunctionMethod>> entry : funcs.getFunctions().entrySet()) {
+ addFunctions(entry.getKey(), entry.getValue());
+ }
}
}
Modified: trunk/runtime/src/main/java/org/teiid/deployers/VDBParserDeployer.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/deployers/VDBParserDeployer.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/runtime/src/main/java/org/teiid/deployers/VDBParserDeployer.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -168,7 +168,7 @@
if (path == null) {
throw new DeploymentException(RuntimePlugin.Util.getString("invalid_udf_file", model.getName())); //$NON-NLS-1$
}
- udf.buildFunctionModelFile(path);
+ udf.buildFunctionModelFile(model.getName(), path);
}
}
Modified: trunk/runtime/src/test/java/org/teiid/deployers/TestCompositeVDB.java
===================================================================
--- trunk/runtime/src/test/java/org/teiid/deployers/TestCompositeVDB.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/runtime/src/test/java/org/teiid/deployers/TestCompositeVDB.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -116,7 +116,7 @@
@Test
public void testTranslatorDefinedFunction() throws Exception {
- helpResolve("SELECT bqt1.echo(BQT1.SmallA.INTKEY) FROM BQT1.SmallA");
+ helpResolve("SELECT SYS.echo(BQT1.SmallA.INTKEY) FROM BQT1.SmallA");
}
@Test
@@ -126,7 +126,7 @@
@Test
public void testFullyQualifiedDuplicate() throws Exception {
- helpResolve("SELECT bqt1.duplicate_func(BQT1.SmallA.STRINGKEY) FROM BQT1.SmallA");
+ helpResolve("SELECT SYS.duplicate_func(BQT1.SmallA.STRINGKEY) FROM BQT1.SmallA");
}
@Test
13 years, 10 months
teiid SVN: r2896 - in trunk: documentation/reference/src/main/docbook/en-US and 10 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2011-02-01 16:22:45 -0500 (Tue, 01 Feb 2011)
New Revision: 2896
Added:
trunk/documentation/reference/src/main/docbook/en-US/content/multisource.xml
Modified:
trunk/build/kits/jboss-container/teiid-releasenotes.html
trunk/documentation/reference/src/main/docbook/en-US/Reference.xml
trunk/documentation/reference/src/main/docbook/en-US/content/translators.xml
trunk/engine/src/main/java/org/teiid/dqp/internal/process/multisource/MultiSourceElementReplacementVisitor.java
trunk/engine/src/main/java/org/teiid/dqp/internal/process/multisource/MultiSourceMetadataWrapper.java
trunk/engine/src/main/java/org/teiid/dqp/internal/process/multisource/MultiSourcePlanToProcessConverter.java
trunk/engine/src/main/java/org/teiid/query/metadata/BasicQueryMetadataWrapper.java
trunk/engine/src/main/java/org/teiid/query/metadata/QueryMetadataInterface.java
trunk/engine/src/main/java/org/teiid/query/sql/lang/StoredProcedure.java
trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java
trunk/engine/src/main/resources/org/teiid/query/i18n.properties
trunk/engine/src/test/java/org/teiid/dqp/internal/process/multisource/TestMultiSourceElementReplacementVisitor.java
trunk/engine/src/test/java/org/teiid/dqp/internal/process/multisource/TestMultiSourcePlanToProcessConverter.java
trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
trunk/engine/src/test/java/org/teiid/query/unittest/FakeMetadataFactory.java
trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java
Log:
TEIID-99 adding handling for multi-source procedures. also adding validation and fixing multisource updates when no source is selected.
Modified: trunk/build/kits/jboss-container/teiid-releasenotes.html
===================================================================
--- trunk/build/kits/jboss-container/teiid-releasenotes.html 2011-02-01 17:34:53 UTC (rev 2895)
+++ trunk/build/kits/jboss-container/teiid-releasenotes.html 2011-02-01 21:22:45 UTC (rev 2896)
@@ -28,6 +28,7 @@
<UL>
<LI><B>Virtual procedure out params</B> - virtual procedures can now have RETURN/OUT/INOUT parameters to return values.
<LI><B>OLAP</B> - OLAP translator is now part of Teiid kit using OLAP4J
+ <LI><B>Multi-source procedures</B> - multi-source handling was expanded to cover stored procedure execution. See the Reference for more.
</UL>
<h2><a name="Compatibility">Compatibility Issues</a></h2>
@@ -35,6 +36,13 @@
<li>TRANSLATE/HAS CRITERIA has been deprecated. An alternative approach to update procedures will be introduced in a subsequent version.
<li>Support for named parameter syntax using param=value has been deprecated, since it is ambiguous with a comparison predicate boolean value expression. param<b>=></b>value should be used instead.
</ul>
+
+<h4>from 7.3</h4>
+<ul>
+ <li>The use of an IN procedure parameter with the name "source_name" in a multi-source model, will now be treated the parameter that controls which source
+ the procedure will execute against.
+</ul>
+
<h4>from 7.2</h4>
<ul>
<li>The default JDBC credentials are user/user - not admin/teiid
Modified: trunk/documentation/reference/src/main/docbook/en-US/Reference.xml
===================================================================
--- trunk/documentation/reference/src/main/docbook/en-US/Reference.xml 2011-02-01 17:34:53 UTC (rev 2895)
+++ trunk/documentation/reference/src/main/docbook/en-US/Reference.xml 2011-02-01 21:22:45 UTC (rev 2896)
@@ -56,6 +56,7 @@
<xi:include href="content/transaction_support.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="content/dataroles.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="content/system_schema.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/multisource.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="content/translators.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="content/federated_planning.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="content/architecture.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
Added: trunk/documentation/reference/src/main/docbook/en-US/content/multisource.xml
===================================================================
--- trunk/documentation/reference/src/main/docbook/en-US/content/multisource.xml (rev 0)
+++ trunk/documentation/reference/src/main/docbook/en-US/content/multisource.xml 2011-02-01 21:22:45 UTC (rev 2896)
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % CustomDTD SYSTEM "../../../../../../docbook/custom.dtd">
+%CustomDTD;
+]>
+<chapter id="multisource">
+ <title>Multi-source models</title>
+ <para>Multi-source models can be used to quickly access data in multiple sources with homogeneous metadata.
+ Since all sources utilize the same physical metadata, this feature is most appropriate for accessing the same source type with multiple instances.
+ <para>A model is marked as supporting multi-source by setting the property supports-multi-source-bindings to true.
+ With supports-multi-source-bindings set to true, 1 or more uniquely named source elements can be added to the model.
+ See <xref linkend="dynamic_vdbs"/> for a full template of the vdb.xml.</para>
+ A physical table in a multi-source model is effectively treated as a view that is a
+ union all of the actual physical table from each of the configured sources. These tables tables are implicitly partitioned on a string pseudo-column "source_name".
+ The "source_name" column will be available to your use queries for a multi-source model regardless of whether it is explicitly part of the metadata.
+ The source_name column value for a particular row is the source name used to obtain that row.
+ More complex partitioning scenarios, such as heterogeneous sources or list partitioning will require the use of a <xref linkend="partitioned_union"/></para>
+ <para>In some scenarios, the source_name column can be manually added to the physical metadata in the Designer tool so that virtual layer logic can be multi-source aware.
+ It is important to understand that a column or IN procedure parameter named source_name will always be treated as the explicit form of the multi-source source_name column
+ and will no longer be treated as an actual physical column or procedure parameter.</para>
+ <section>
+ <title>Multi-source SELECTs</title>
+ <para>A multi-source SELECT may use the source_name column anywhere a column reference is allowed. As a final stage of planning, a source query will be generated against each source and each instance of the source_name column replaced by the appropriate value.
+ If the resulting query still needs executed, it is sent to the source. If the WHERE clause evaluates to always false, then the query is pruned from the result. All results are then unioned together and returned as the full result.
+ </para>
+ </section>
+ <section>
+ <title>Multi-source INSERTs</title>
+ <para>A multi-source INSERT may use the source_name column as an insert target column to specify which source should be targeted by the INSERT. Only a INSERT using the VALUES clause is supported and the source_name column value must be a literal.
+ If the source_name column is not part of the INSERT column, then the INSERT will be issued against every source. The sum of the update counts will be returned as the resultant update count.</para>
+ </section>
+ <section>
+ <title>Multi-source UPDATEs</title>
+ <para>A multi-source delete functions just like SELECT, however it is not possible to use the source_name column as a target column in the change set. Any other usage of the source_name column will be the appropriate value for each source.
+ If the WHERE clause evaluates to always false, then no update will be issued to the source. The sum of the update counts will be returned as the resultant update count.</para>
+ </section>
+ <section>
+ <title>Multi-source DELETEs</title>
+ <para>A multi-source delete functions just like SELECT. Any usage of the source_name column will be the appropriate value for each source.
+ If the WHERE clause evaluates to always false, then no delete will be issued to the source. The sum of the update counts will be returned as the resultant update count.</para>
+ </section>
+ <section>
+ <title>Multi-source Stored Procedures</title>
+ <para>A physical stored procedures requires the manual addition of a string source_name parameter to allow for specifying which source the procedure is executed on.
+ If the source_name parameter is not added or if named parameters are used and the source_name parameter is allowed to default to a null value, then the procedure will be executed on
+ each source and the results unioned together.</para>
+ <para>It is not possible to execute procedures that required to return IN/OUT, OUT, or RETURN parameters values on more than 1 source at a time.</para>
+ </section>
+ <section>
+ <title>Additional Concerns</title>
+ <para>When running under a transaction of in a mode that detects the need for a transation and multiple updates are performed, an attempt will be made to enlist each source in the same XA transaction.</para>
+ </section>
+</chapter>
\ No newline at end of file
Property changes on: trunk/documentation/reference/src/main/docbook/en-US/content/multisource.xml
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: trunk/documentation/reference/src/main/docbook/en-US/content/translators.xml
===================================================================
--- trunk/documentation/reference/src/main/docbook/en-US/content/translators.xml 2011-02-01 17:34:53 UTC (rev 2895)
+++ trunk/documentation/reference/src/main/docbook/en-US/content/translators.xml 2011-02-01 21:22:45 UTC (rev 2896)
@@ -1149,6 +1149,7 @@
<source name="${source-name}" translator-name="${translator-name}"
connection-jndi-name="${deployed-jndi-name}">
+ ...
</model>
<!-- create translator instances that override default properties -->
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/multisource/MultiSourceElementReplacementVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/multisource/MultiSourceElementReplacementVisitor.java 2011-02-01 17:34:53 UTC (rev 2895)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/multisource/MultiSourceElementReplacementVisitor.java 2011-02-01 21:22:45 UTC (rev 2896)
@@ -23,11 +23,6 @@
package org.teiid.dqp.internal.process.multisource;
import org.teiid.core.types.DataTypeManager;
-import org.teiid.query.rewriter.QueryRewriter;
-import org.teiid.query.sql.lang.From;
-import org.teiid.query.sql.lang.Insert;
-import org.teiid.query.sql.lang.Query;
-import org.teiid.query.sql.lang.Select;
import org.teiid.query.sql.symbol.Constant;
import org.teiid.query.sql.symbol.ElementSymbol;
import org.teiid.query.sql.symbol.Expression;
@@ -56,28 +51,4 @@
return expr;
}
- public void visit(Insert obj) {
- for (int i = 0; i < obj.getVariables().size(); i++) {
- Expression expr = (Expression)obj.getVariables().get(i);
- if(expr instanceof ElementSymbol) {
- ElementSymbol elem = (ElementSymbol) expr;
- Object metadataID = elem.getMetadataID();
- if(metadataID instanceof MultiSourceElement) {
- Constant source = (Constant)obj.getValues().get(i);
- obj.getVariables().remove(i);
- obj.getValues().remove(i);
- if (!source.getValue().equals(this.bindingName)) {
- Select select = new Select(obj.getVariables());
- From from = new From();
- from.addGroup(obj.getGroup());
- Query query = new Query();
- query.setSelect(select);
- query.setFrom(from);
- query.setCriteria(QueryRewriter.FALSE_CRITERIA);
- obj.setQueryExpression(query);
- }
- }
- }
- }
- }
}
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/multisource/MultiSourceMetadataWrapper.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/multisource/MultiSourceMetadataWrapper.java 2011-02-01 17:34:53 UTC (rev 2895)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/multisource/MultiSourceMetadataWrapper.java 2011-02-01 21:22:45 UTC (rev 2896)
@@ -337,8 +337,20 @@
}
@Override
- public boolean isMultiSourceElement(Object elementId) {
- return elementId instanceof MultiSourceElement;
+ public boolean isMultiSourceElement(Object elementId) throws QueryMetadataException, TeiidComponentException {
+ if (elementId instanceof MultiSourceElement) {
+ return true;
+ }
+ Object gid = getGroupIDForElementID(elementId);
+ if (isProcedure(gid)) {
+ Object modelID = this.getModelID(gid);
+ String modelName = this.getFullName(modelID);
+ if(multiSourceModels.contains(modelName)) {
+ String shortName = getShortElementName(getFullName(elementId));
+ return shortName.equalsIgnoreCase(MultiSourceElement.MULTI_SOURCE_ELEMENT_NAME);
+ }
+ }
+ return false;
}
}
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/multisource/MultiSourcePlanToProcessConverter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/multisource/MultiSourcePlanToProcessConverter.java 2011-02-01 17:34:53 UTC (rev 2895)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/multisource/MultiSourcePlanToProcessConverter.java 2011-02-01 21:22:45 UTC (rev 2896)
@@ -23,11 +23,14 @@
package org.teiid.dqp.internal.process.multisource;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.teiid.adminapi.impl.ModelMetaData;
import org.teiid.adminapi.impl.VDBMetaData;
+import org.teiid.api.exception.query.ExpressionEvaluationException;
import org.teiid.api.exception.query.QueryPlannerException;
import org.teiid.api.exception.query.QueryValidatorException;
import org.teiid.core.TeiidComponentException;
@@ -36,6 +39,7 @@
import org.teiid.core.types.DataTypeManager;
import org.teiid.dqp.internal.process.DQPWorkContext;
import org.teiid.language.SQLConstants.NonReserved;
+import org.teiid.query.QueryPlugin;
import org.teiid.query.analysis.AnalysisRecord;
import org.teiid.query.metadata.QueryMetadataInterface;
import org.teiid.query.optimizer.capabilities.CapabilitiesFinder;
@@ -53,10 +57,16 @@
import org.teiid.query.resolver.util.ResolverUtil;
import org.teiid.query.rewriter.QueryRewriter;
import org.teiid.query.sql.lang.Command;
+import org.teiid.query.sql.lang.Insert;
+import org.teiid.query.sql.lang.SPParameter;
+import org.teiid.query.sql.lang.StoredProcedure;
import org.teiid.query.sql.navigator.DeepPreOrderNavigator;
import org.teiid.query.sql.symbol.AggregateSymbol;
+import org.teiid.query.sql.symbol.Constant;
+import org.teiid.query.sql.symbol.ElementSymbol;
import org.teiid.query.sql.symbol.Expression;
import org.teiid.query.sql.symbol.ExpressionSymbol;
+import org.teiid.query.sql.symbol.SingleElementSymbol;
import org.teiid.query.util.CommandContext;
@@ -120,6 +130,12 @@
ModelMetaData model = vdb.getModel(modelName);
List<AccessNode> accessNodes = new ArrayList<AccessNode>();
+ boolean hasOutParams = false;
+ if (accessNode.getCommand() instanceof StoredProcedure) {
+ StoredProcedure sp = (StoredProcedure)accessNode.getCommand();
+ hasOutParams = sp.returnParameters() && sp.getProjectedSymbols().size() > sp.getResultSetColumns().size();
+ }
+
for(String sourceName:model.getSourceNames()) {
// Create a new cloned version of the access node and set it's model name to be the bindingUUID
@@ -130,13 +146,12 @@
// Modify the command to pull the instance column and evaluate the criteria
Command command = (Command)instanceNode.getCommand().clone();
- // Replace all multi-source elements with the source name
- DeepPreOrderNavigator.doVisit(command, new MultiSourceElementReplacementVisitor(sourceName));
+ command = rewriteCommand(sourceName, command);
+
+ if (command == null) {
+ continue;
+ }
- if (!RelationalNodeUtil.shouldExecute(command, false)) {
- continue;
- }
-
// Rewrite the command now that criteria may have been simplified
try {
command = QueryRewriter.rewrite(command, metadata, null);
@@ -151,10 +166,21 @@
accessNodes.add(instanceNode);
}
+
+ if (hasOutParams && accessNodes.size() != 1) {
+ throw new QueryPlannerException(QueryPlugin.Util.getString("MultiSource.out_procedure", accessNode.getCommand())); //$NON-NLS-1$
+ }
switch(accessNodes.size()) {
case 0:
{
+ if (RelationalNodeUtil.isUpdate(accessNode.getCommand())) {
+ //should return a 0 update count
+ ProjectNode pnode = new ProjectNode(getID());
+ pnode.setElements(accessNode.getElements());
+ pnode.setSelectSymbols(Arrays.asList(new ExpressionSymbol("x", new Constant(0)))); //$NON-NLS-1$
+ return pnode;
+ }
// Replace existing access node with a NullNode
NullNode nullNode = new NullNode(getID());
nullNode.setElements(accessNode.getElements());
@@ -206,4 +232,50 @@
}
}
+ private Command rewriteCommand(String sourceName, Command command) throws ExpressionEvaluationException, TeiidComponentException {
+ if (command instanceof StoredProcedure) {
+ StoredProcedure obj = (StoredProcedure)command;
+ for (Iterator<SPParameter> params = obj.getMapOfParameters().values().iterator(); params.hasNext();) {
+ SPParameter param = params.next();
+ if (param.getParameterType() != SPParameter.IN) {
+ continue;
+ }
+ String shortName = SingleElementSymbol.getShortName(param.getName());
+ if(shortName.equalsIgnoreCase(MultiSourceElement.MULTI_SOURCE_ELEMENT_NAME)) {
+ Constant source = (Constant)param.getExpression();
+ params.remove();
+ if (param.isUsingDefault() && source.isNull()) {
+ continue;
+ }
+ if (!source.getValue().equals(sourceName)) {
+ return null;
+ }
+ }
+ }
+ } if (command instanceof Insert) {
+ Insert obj = (Insert)command;
+ for (int i = 0; i < obj.getVariables().size(); i++) {
+ ElementSymbol elem = obj.getVariables().get(i);
+ Object metadataID = elem.getMetadataID();
+ if(metadataID instanceof MultiSourceElement) {
+ Constant source = (Constant)obj.getValues().get(i);
+ obj.getVariables().remove(i);
+ obj.getValues().remove(i);
+ if (!source.getValue().equals(sourceName)) {
+ return null;
+ }
+ }
+ }
+ } else {
+ // Replace all multi-source elements with the source name
+ DeepPreOrderNavigator.doVisit(command, new MultiSourceElementReplacementVisitor(sourceName));
+ }
+
+ if (!RelationalNodeUtil.shouldExecute(command, false)) {
+ return null;
+ }
+
+ return command;
+ }
+
}
Modified: trunk/engine/src/main/java/org/teiid/query/metadata/BasicQueryMetadataWrapper.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/metadata/BasicQueryMetadataWrapper.java 2011-02-01 17:34:53 UTC (rev 2895)
+++ trunk/engine/src/main/java/org/teiid/query/metadata/BasicQueryMetadataWrapper.java 2011-02-01 21:22:45 UTC (rev 2896)
@@ -380,7 +380,7 @@
}
@Override
- public boolean isMultiSourceElement(Object elementId) {
+ public boolean isMultiSourceElement(Object elementId) throws QueryMetadataException, TeiidComponentException {
return actualMetadata.isMultiSourceElement(elementId);
}
Modified: trunk/engine/src/main/java/org/teiid/query/metadata/QueryMetadataInterface.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/metadata/QueryMetadataInterface.java 2011-02-01 17:34:53 UTC (rev 2895)
+++ trunk/engine/src/main/java/org/teiid/query/metadata/QueryMetadataInterface.java 2011-02-01 21:22:45 UTC (rev 2896)
@@ -683,5 +683,5 @@
boolean isMultiSource(Object modelId) throws QueryMetadataException, TeiidComponentException;
- boolean isMultiSourceElement(Object elementId);
+ boolean isMultiSourceElement(Object elementId) throws QueryMetadataException, TeiidComponentException;
}
Modified: trunk/engine/src/main/java/org/teiid/query/sql/lang/StoredProcedure.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/lang/StoredProcedure.java 2011-02-01 17:34:53 UTC (rev 2895)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/StoredProcedure.java 2011-02-01 21:22:45 UTC (rev 2896)
@@ -163,6 +163,10 @@
List<SPParameter> listOfParameters = new ArrayList<SPParameter>(mapOfParameters.values());
return listOfParameters;
}
+
+ public Map<Integer, SPParameter> getMapOfParameters() {
+ return mapOfParameters;
+ }
public SPParameter getParameter(int index){
return mapOfParameters.get(new Integer(index));
Modified: trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java 2011-02-01 17:34:53 UTC (rev 2895)
+++ trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java 2011-02-01 21:22:45 UTC (rev 2896)
@@ -126,7 +126,6 @@
import org.teiid.query.sql.symbol.AggregateSymbol.Type;
import org.teiid.query.sql.util.SymbolMap;
import org.teiid.query.sql.visitor.AggregateSymbolCollectorVisitor;
-import org.teiid.query.sql.visitor.CommandCollectorVisitor;
import org.teiid.query.sql.visitor.ElementCollectorVisitor;
import org.teiid.query.sql.visitor.EvaluatableVisitor;
import org.teiid.query.sql.visitor.FunctionCollectorVisitor;
@@ -418,6 +417,31 @@
}
}
}
+
+ @Override
+ public void visit(StoredProcedure obj) {
+ for (SPParameter param : obj.getInputParameters()) {
+ try {
+ if (!(param.getExpression() instanceof Constant) && getMetadata().isMultiSourceElement(param.getMetadataID())) {
+ handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.multisource_constant", param.getParameterSymbol()), param.getParameterSymbol()); //$NON-NLS-1$
+ continue;
+ }
+ if (EvaluatableVisitor.isFullyEvaluatable(param.getExpression(), true)) {
+ try {
+ // If nextValue is an expression, evaluate it before checking for null
+ Object evaluatedValue = Evaluator.evaluate(param.getExpression());
+ if(evaluatedValue == null && ! getMetadata().elementSupports(param.getMetadataID(), SupportConstants.Element.NULL)) {
+ handleValidationError(QueryPlugin.Util.getString("ERR.015.012.0055", param.getParameterSymbol()), param.getParameterSymbol()); //$NON-NLS-1$
+ }
+ } catch(ExpressionEvaluationException e) {
+ //ignore for now, we don't have the context which could be the problem
+ }
+ }
+ } catch (TeiidComponentException e) {
+ handleException(e);
+ }
+ }
+ }
private void validateAssignment(LanguageObject obj,
ElementSymbol variable) {
@@ -790,14 +814,12 @@
}
// Get elements in the group.
- Collection insertElmnts = new LinkedList(ResolverUtil.resolveElementsInGroup(insertGroup, getMetadata()));
+ Collection<ElementSymbol> insertElmnts = new LinkedList<ElementSymbol>(ResolverUtil.resolveElementsInGroup(insertGroup, getMetadata()));
// remove all elements specified in insert to get the ignored elements
insertElmnts.removeAll(vars);
- Iterator ignoreIter = insertElmnts.iterator();
- while(ignoreIter.hasNext()) {
- ElementSymbol nextElmnt = (ElementSymbol) ignoreIter.next();
+ for (ElementSymbol nextElmnt : insertElmnts) {
if(!getMetadata().elementSupports(nextElmnt.getMetadataID(), SupportConstants.Element.DEFAULT_VALUE) &&
!getMetadata().elementSupports(nextElmnt.getMetadataID(), SupportConstants.Element.NULL) &&
!getMetadata().elementSupports(nextElmnt.getMetadataID(), SupportConstants.Element.AUTO_INCREMENT) &&
@@ -812,12 +834,17 @@
Expression nextValue = (Expression) valIter.next();
ElementSymbol nextVar = (ElementSymbol) varIter.next();
+ if (!(nextValue instanceof Constant) && getMetadata().isMultiSourceElement(nextVar.getMetadataID())) {
+ handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.multisource_constant", nextVar), nextVar); //$NON-NLS-1$
+ continue;
+ }
+
if (EvaluatableVisitor.isFullyEvaluatable(nextValue, true)) {
try {
// If nextValue is an expression, evaluate it before checking for null
Object evaluatedValue = Evaluator.evaluate(nextValue);
if(evaluatedValue == null && ! getMetadata().elementSupports(nextVar.getMetadataID(), SupportConstants.Element.NULL)) {
- handleValidationError(QueryPlugin.Util.getString("ERR.015.012.0055", SQLStringVisitor.getSQLString(nextVar)), nextVar); //$NON-NLS-1$
+ handleValidationError(QueryPlugin.Util.getString("ERR.015.012.0055", nextVar), nextVar); //$NON-NLS-1$
}
} catch(ExpressionEvaluationException e) {
//ignore for now, we don't have the context which could be the problem
Modified: trunk/engine/src/main/resources/org/teiid/query/i18n.properties
===================================================================
--- trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2011-02-01 17:34:53 UTC (rev 2895)
+++ trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2011-02-01 21:22:45 UTC (rev 2896)
@@ -197,6 +197,7 @@
ValidationVisitor.nonUpdatable = The specified change set {0} against an inherently updatable view does not map to a key preserving group.
ValidationVisitor.insert_qe_partition = Inserts with query expressions cannot be performed against a partitioned UNION view {0}.
ValidationVisitor.insert_no_partition = Could not determine INSERT target for a partitioned UNION view {0} with values {1}.
+ValidationVisitor.multisource_constant = The multisource column or parameter {0} requires a literal value.
ERR.015.012.0029 = INSERT, UPDATE, and DELETE not allowed on XML documents
ERR.015.012.0030 = Commands used in stored procedure language not allowed on XML documents
ERR.015.012.0031 = Queries against XML documents can not have a GROUP By clause
@@ -891,4 +892,6 @@
RelationalPlanner.nonpushdown_command=Source UPDATE or DELETE command "{0}" contains non-pushdown constructs and no compensating action can be taken as the table lacks a unique key or the source does not support equality predicates.
-Translate.error=Cannot translate criteria "{0}", it is not matched by selector "{1}"
\ No newline at end of file
+Translate.error=Cannot translate criteria "{0}", it is not matched by selector "{1}"
+
+MultiSource.out_procedure=The multisource plan must execute a procedure returning parameter values exactly 1: {0}
\ No newline at end of file
Modified: trunk/engine/src/test/java/org/teiid/dqp/internal/process/multisource/TestMultiSourceElementReplacementVisitor.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/dqp/internal/process/multisource/TestMultiSourceElementReplacementVisitor.java 2011-02-01 17:34:53 UTC (rev 2895)
+++ trunk/engine/src/test/java/org/teiid/dqp/internal/process/multisource/TestMultiSourceElementReplacementVisitor.java 2011-02-01 21:22:45 UTC (rev 2896)
@@ -122,22 +122,4 @@
"SELECT a FROM MultiModel.Phys WHERE 'x' = (SELECT b FROM MultiModel.Phys WHERE 'x' IN ('x'))"); //$NON-NLS-1$
}
- public void testInsertMatching() throws Exception {
- helpTest("INSERT INTO MultiModel.Phys(a, SOURCE_NAME) VALUES ('a', 'x')", //$NON-NLS-1$
- getMetadata(),
- "INSERT INTO MultiModel.Phys (a) VALUES ('a')"); //$NON-NLS-1$
- }
-
- public void testInsertNotMatching() throws Exception {
- helpTest("INSERT INTO MultiModel.Phys(a, SOURCE_NAME) VALUES ('a', 'y')", //$NON-NLS-1$
- getMetadata(),
- "INSERT INTO MultiModel.Phys (a) SELECT a FROM MultiModel.Phys WHERE 1 = 0"); //$NON-NLS-1$
- }
-
- public void testInsertAll() throws Exception {
- helpTest("INSERT INTO MultiModel.Phys(a) VALUES('a')", //$NON-NLS-1$
- getMetadata(),
- "INSERT INTO MultiModel.Phys (a) VALUES ('a')"); //$NON-NLS-1$
- }
-
}
Modified: trunk/engine/src/test/java/org/teiid/dqp/internal/process/multisource/TestMultiSourcePlanToProcessConverter.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/dqp/internal/process/multisource/TestMultiSourcePlanToProcessConverter.java 2011-02-01 17:34:53 UTC (rev 2895)
+++ trunk/engine/src/test/java/org/teiid/dqp/internal/process/multisource/TestMultiSourcePlanToProcessConverter.java 2011-02-01 21:22:45 UTC (rev 2896)
@@ -26,7 +26,6 @@
import java.util.Arrays;
import java.util.Collection;
-import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Set;
@@ -57,8 +56,6 @@
import org.teiid.query.unittest.FakeMetadataFactory;
import org.teiid.query.util.CommandContext;
-
-
/**
* It's important here that the MultiSourceCapabilityFinder is used since some capabilities
* will never be pushed to the source
@@ -76,10 +73,9 @@
public TupleSource registerRequest(CommandContext context, Command command, String modelName, String connectorBindingId, int nodeID) throws org.teiid.core.TeiidComponentException {
assertNotNull(connectorBindingId);
- Collection elements = ElementCollectorVisitor.getElements(command, true, true);
+ Collection<ElementSymbol> elements = ElementCollectorVisitor.getElements(command, true, true);
- for (Iterator i = elements.iterator(); i.hasNext();) {
- ElementSymbol symbol = (ElementSymbol)i.next();
+ for (ElementSymbol symbol : elements) {
if (symbol.getMetadataID() instanceof MultiSourceElement) {
fail("Query Contains a MultiSourceElement -- MultiSource expansion did not happen"); //$NON-NLS-1$
}
@@ -261,5 +257,64 @@
dataMgr.addData("UPDATE MultiModel.Phys SET a = '1' WHERE b = 'z'", new List[] {Arrays.asList(1)}); //$NON-NLS-1$
helpTestMultiSourcePlan(metadata, userSql, multiModel, sources, dataMgr, expected, FakeMetadataFactory.exampleMultiBindingVDB());
}
+
+ @Test public void testInsertMatching() throws Exception {
+ final QueryMetadataInterface metadata = FakeMetadataFactory.exampleMultiBinding();
+ final String userSql = "INSERT INTO MultiModel.Phys(a, SOURCE_NAME) VALUES ('a', 'a')"; //$NON-NLS-1$
+ final String multiModel = "MultiModel"; //$NON-NLS-1$
+ final int sources = 3;
+ final List[] expected = new List[] { Arrays.asList(1)};
+ final MultiSourceDataManager dataMgr = new MultiSourceDataManager();
+ dataMgr.setMustRegisterCommands(true);
+ dataMgr.addData("INSERT INTO MultiModel.Phys (a) VALUES ('a')", new List[] {Arrays.asList(1)}); //$NON-NLS-1$
+ helpTestMultiSourcePlan(metadata, userSql, multiModel, sources, dataMgr, expected, FakeMetadataFactory.exampleMultiBindingVDB());
+ }
+
+ @Test public void testInsertNotMatching() throws Exception {
+ final QueryMetadataInterface metadata = FakeMetadataFactory.exampleMultiBinding();
+ final String userSql = "INSERT INTO MultiModel.Phys(a, SOURCE_NAME) VALUES ('a', 'x')"; //$NON-NLS-1$
+ final String multiModel = "MultiModel"; //$NON-NLS-1$
+ final int sources = 3;
+ final List[] expected = new List[] { Arrays.asList(0)};
+ final MultiSourceDataManager dataMgr = new MultiSourceDataManager();
+ dataMgr.setMustRegisterCommands(true);
+ helpTestMultiSourcePlan(metadata, userSql, multiModel, sources, dataMgr, expected, FakeMetadataFactory.exampleMultiBindingVDB());
+ }
+
+ @Test public void testInsertAll() throws Exception {
+ final QueryMetadataInterface metadata = FakeMetadataFactory.exampleMultiBinding();
+ final String userSql = "INSERT INTO MultiModel.Phys(a) VALUES ('a')"; //$NON-NLS-1$
+ final String multiModel = "MultiModel"; //$NON-NLS-1$
+ final int sources = 3;
+ final List[] expected = new List[] { Arrays.asList(3)};
+ final MultiSourceDataManager dataMgr = new MultiSourceDataManager();
+ dataMgr.setMustRegisterCommands(true);
+ dataMgr.addData("INSERT INTO MultiModel.Phys (a) VALUES ('a')", new List[] {Arrays.asList(1)}); //$NON-NLS-1$
+ helpTestMultiSourcePlan(metadata, userSql, multiModel, sources, dataMgr, expected, FakeMetadataFactory.exampleMultiBindingVDB());
+ }
+
+ @Test public void testProcedure() throws Exception {
+ final QueryMetadataInterface metadata = FakeMetadataFactory.exampleMultiBinding();
+ final String userSql = "exec MultiModel.proc('b', 'a')"; //$NON-NLS-1$
+ final String multiModel = "MultiModel"; //$NON-NLS-1$
+ final int sources = 3;
+ final List[] expected = new List[] { Arrays.asList(1)};
+ final MultiSourceDataManager dataMgr = new MultiSourceDataManager();
+ dataMgr.setMustRegisterCommands(true);
+ dataMgr.addData("EXEC MultiModel.proc('b')", new List[] {Arrays.asList(1)}); //$NON-NLS-1$
+ helpTestMultiSourcePlan(metadata, userSql, multiModel, sources, dataMgr, expected, FakeMetadataFactory.exampleMultiBindingVDB());
+ }
+
+ @Test public void testProcedureAll() throws Exception {
+ final QueryMetadataInterface metadata = FakeMetadataFactory.exampleMultiBinding();
+ final String userSql = "exec MultiModel.proc(\"in\"=>'b')"; //$NON-NLS-1$
+ final String multiModel = "MultiModel"; //$NON-NLS-1$
+ final int sources = 3;
+ final List[] expected = new List[] { Arrays.asList(1), Arrays.asList(1), Arrays.asList(1)};
+ final MultiSourceDataManager dataMgr = new MultiSourceDataManager();
+ dataMgr.setMustRegisterCommands(true);
+ dataMgr.addData("EXEC MultiModel.proc('b')", new List[] {Arrays.asList(1)}); //$NON-NLS-1$
+ helpTestMultiSourcePlan(metadata, userSql, multiModel, sources, dataMgr, expected, FakeMetadataFactory.exampleMultiBindingVDB());
+ }
}
Modified: trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java 2011-02-01 17:34:53 UTC (rev 2895)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java 2011-02-01 21:22:45 UTC (rev 2896)
@@ -69,7 +69,6 @@
import org.teiid.query.metadata.TempMetadataStore;
import org.teiid.query.optimizer.FakeFunctionMetadataSource;
import org.teiid.query.optimizer.QueryOptimizer;
-import org.teiid.query.optimizer.TestAggregatePushdown;
import org.teiid.query.optimizer.TestOptimizer;
import org.teiid.query.optimizer.TestRuleRaiseNull;
import org.teiid.query.optimizer.TestOptimizer.ComparisonMode;
@@ -97,7 +96,6 @@
import org.teiid.query.unittest.FakeMetadataFactory;
import org.teiid.query.unittest.FakeMetadataObject;
import org.teiid.query.unittest.FakeMetadataStore;
-import org.teiid.query.unittest.RealMetadataFactory;
import org.teiid.query.unittest.TimestampUtil;
import org.teiid.query.util.CommandContext;
import org.teiid.query.validator.Validator;
Modified: trunk/engine/src/test/java/org/teiid/query/unittest/FakeMetadataFactory.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/unittest/FakeMetadataFactory.java 2011-02-01 17:34:53 UTC (rev 2895)
+++ trunk/engine/src/test/java/org/teiid/query/unittest/FakeMetadataFactory.java 2011-02-01 21:22:45 UTC (rev 2896)
@@ -2321,6 +2321,15 @@
QueryNode sq2n1 = new QueryNode("pm1.sq1", "CREATE VIRTUAL PROCEDURE BEGIN\n" //$NON-NLS-1$ //$NON-NLS-2$
+ "execute string 'SELECT a, b FROM MultiModel.Phys where SOURCE_NAME = Virt.sq1.in'; END"); //$NON-NLS-1$
FakeMetadataObject sq1 = FakeMetadataFactory.createVirtualProcedure("Virt.sq1", virtModel, Arrays.asList(new FakeMetadataObject[] { rs2p1, rs2p2 }), sq2n1); //$NON-NLS-1$
+
+ FakeMetadataObject rs3 = FakeMetadataFactory.createResultSet("MultiModel.rs1", virtModel, new String[] { "a", "b" }, new String[] { DataTypeManager.DefaultDataTypes.STRING, DataTypeManager.DefaultDataTypes.STRING }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ FakeMetadataObject rs3p1 = FakeMetadataFactory.createParameter("ret", 1, ParameterInfo.RESULT_SET, DataTypeManager.DefaultDataTypes.OBJECT, rs3); //$NON-NLS-1$
+ FakeMetadataObject rs3p2 = FakeMetadataFactory.createParameter("in", 2, ParameterInfo.IN, DataTypeManager.DefaultDataTypes.STRING, null); //$NON-NLS-1$
+ FakeMetadataObject rs3p3 = FakeMetadataFactory.createParameter("source_name", 3, ParameterInfo.IN, DataTypeManager.DefaultDataTypes.STRING, null); //$NON-NLS-1$
+ rs3p3.putProperty(FakeMetadataObject.Props.NULL, Boolean.TRUE);
+ FakeMetadataObject sq2 = FakeMetadataFactory.createStoredProcedure("MultiModel.proc", physModel, Arrays.asList(new FakeMetadataObject[] { rs3p1, rs3p2, rs3p3 }), "MultiModel.proc");
+ rs3p2.putProperty(FakeMetadataObject.Props.GROUP, sq2);
+ rs3p3.putProperty(FakeMetadataObject.Props.GROUP, sq2);
FakeMetadataStore store = new FakeMetadataStore();
store.addObject(virtModel);
@@ -2332,6 +2341,8 @@
store.addObject(rs2);
store.addObject(sq1);
+ store.addObject(rs3);
+ store.addObject(sq2);
return new FakeMetadataFacade(store);
}
Modified: trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java 2011-02-01 17:34:53 UTC (rev 2895)
+++ trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java 2011-02-01 21:22:45 UTC (rev 2896)
@@ -2029,5 +2029,11 @@
@Test public void testTextAggHeader() throws Exception {
helpValidate("select textagg(for e1 || 1 HEADER) from pm1.g1", new String[] {"TEXTAGG(FOR (e1 || 1) HEADER)"}, FakeMetadataFactory.example1Cached()); //$NON-NLS-1$
}
+
+ @Test public void testMultiSourceProcValue() throws Exception {
+ Set<String> models = new HashSet<String>();
+ models.add("MultiModel");
+ helpValidate("exec MultiModel.proc('a', (select 1))", new String[] {"MultiModel.proc.source_name"}, new MultiSourceMetadataWrapper(FakeMetadataFactory.exampleMultiBinding(), models)); //$NON-NLS-1$
+ }
}
13 years, 10 months