[teiid-commits] teiid SVN: r2903 - in trunk: api/src/main/java/org/teiid/translator and 21 other directories.

teiid-commits at lists.jboss.org teiid-commits at lists.jboss.org
Thu Feb 10 14:56:38 EST 2011


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> ( &lt;COMMA&gt; <link linkend="prod2">id</link> <link linkend="prod35">dataType</link> )*</para></entry></row>
+<link linkend="prod2">id</link> <link linkend="prod19">dataTypeString</link> ( &lt;COMMA&gt; <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> | ( &lt;LPAREN&gt; <link linkend="prod68">joinedTable</link> &lt;RPAREN&gt; ) ) ( ( &lt;MAKEDEP&gt; ) | ( &lt;MAKENOTDEP&gt; ) )?</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> | ( &lt;LPAREN&gt; <link linkend="prod68">joinedTable</link> &lt;RPAREN&gt; ) ) ( ( &lt;MAKEDEP&gt; ) | ( &lt;MAKENOTDEP&gt; ) )?</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>::= 
 &lt;XMLSERIALIZE&gt; &lt;LPAREN&gt; ( <link linkend="prod18">nonReserved</link> )? <link linkend="prod21">expression</link> ( &lt;AS&gt; ( &lt;STRING&gt; | &lt;VARCHAR&gt; | &lt;CLOB&gt; ) )? &lt;RPAREN&gt;</para></entry></row>
 <row>
@@ -638,35 +638,39 @@
 <entry align="left" valign="top"><para>::= 
 &lt;ID&gt;</para></entry></row>
 <row>
+<entry align="right" valign="top"><para><anchor id="prod73" xreflabel="arrayTable"/>arrayTable</para></entry>
+<entry align="left" valign="top"><para>::= 
+&lt;ID&gt; &lt;LPAREN&gt; <link linkend="prod21">expression</link> <link linkend="prod18">nonReserved</link> <link linkend="prod39">createElementsWithTypes</link> &lt;RPAREN&gt; ( &lt;AS&gt; )? <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>::= 
-&lt;ID&gt; &lt;LPAREN&gt; <link linkend="prod21">expression</link> <link linkend="prod18">nonReserved</link> <link linkend="prod77">textColumn</link> ( &lt;COMMA&gt; <link linkend="prod77">textColumn</link> )* ( &lt;ID&gt; <link linkend="prod65">charVal</link> )? ( ( &lt;ESCAPE&gt; <link linkend="prod65">charVal</link> ) | ( &lt;ID&gt; <link linkend="prod65">charVal</link> ) )? ( &lt;ID&gt; ( <link linkend="prod78">intVal</link> )? )? ( &lt;ID&gt; <link linkend="prod78">intVal</link> )? &lt;RPAREN&gt; ( &lt;AS&gt; )? <link linkend="prod2">id</link></para></entry></row>
+&lt;ID&gt; &lt;LPAREN&gt; <link linkend="prod21">expression</link> <link linkend="prod18">nonReserved</link> <link linkend="prod78">textColumn</link> ( &lt;COMMA&gt; <link linkend="prod78">textColumn</link> )* ( &lt;ID&gt; <link linkend="prod65">charVal</link> )? ( ( &lt;ESCAPE&gt; <link linkend="prod65">charVal</link> ) | ( &lt;ID&gt; <link linkend="prod65">charVal</link> ) )? ( &lt;ID&gt; ( <link linkend="prod79">intVal</link> )? )? ( &lt;ID&gt; <link linkend="prod79">intVal</link> )? &lt;RPAREN&gt; ( &lt;AS&gt; )? <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> ( &lt;ID&gt; <link linkend="prod78">intVal</link> )?</para></entry></row>
+<link linkend="prod2">id</link> <link linkend="prod35">dataType</link> ( &lt;ID&gt; <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>::= 
-&lt;XMLQUERY&gt; &lt;LPAREN&gt; ( <link linkend="prod80">xmlNamespaces</link> &lt;COMMA&gt; )? <link linkend="prod1">stringVal</link> ( &lt;ID&gt; <link linkend="prod62">derivedColumn</link> ( &lt;COMMA&gt; <link linkend="prod62">derivedColumn</link> )* )? ( ( &lt;NULL&gt; | <link linkend="prod18">nonReserved</link> ) &lt;ON&gt; <link linkend="prod18">nonReserved</link> )? &lt;RPAREN&gt;</para></entry></row>
+&lt;XMLQUERY&gt; &lt;LPAREN&gt; ( <link linkend="prod81">xmlNamespaces</link> &lt;COMMA&gt; )? <link linkend="prod1">stringVal</link> ( &lt;ID&gt; <link linkend="prod62">derivedColumn</link> ( &lt;COMMA&gt; <link linkend="prod62">derivedColumn</link> )* )? ( ( &lt;NULL&gt; | <link linkend="prod18">nonReserved</link> ) &lt;ON&gt; <link linkend="prod18">nonReserved</link> )? &lt;RPAREN&gt;</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>::= 
-&lt;XMLTABLE&gt; &lt;LPAREN&gt; ( <link linkend="prod80">xmlNamespaces</link> &lt;COMMA&gt; )? <link linkend="prod1">stringVal</link> ( &lt;ID&gt; <link linkend="prod62">derivedColumn</link> ( &lt;COMMA&gt; <link linkend="prod62">derivedColumn</link> )* )? ( &lt;ID&gt; <link linkend="prod81">xmlColumn</link> ( &lt;COMMA&gt; <link linkend="prod81">xmlColumn</link> )* )? &lt;RPAREN&gt; ( &lt;AS&gt; )? <link linkend="prod2">id</link></para></entry></row>
+&lt;XMLTABLE&gt; &lt;LPAREN&gt; ( <link linkend="prod81">xmlNamespaces</link> &lt;COMMA&gt; )? <link linkend="prod1">stringVal</link> ( &lt;ID&gt; <link linkend="prod62">derivedColumn</link> ( &lt;COMMA&gt; <link linkend="prod62">derivedColumn</link> )* )? ( &lt;ID&gt; <link linkend="prod82">xmlColumn</link> ( &lt;COMMA&gt; <link linkend="prod82">xmlColumn</link> )* )? &lt;RPAREN&gt; ( &lt;AS&gt; )? <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> ( ( &lt;FOR&gt; <link linkend="prod18">nonReserved</link> ) | ( <link linkend="prod35">dataType</link> ( &lt;DEFAULT_KEYWORD&gt; <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>::= 
 &lt;INTEGERVAL&gt;</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>::= 
 ( &lt;TABLE&gt; )? &lt;LPAREN&gt; ( <link linkend="prod10">queryExpression</link> | <link linkend="prod11">storedProcedure</link> ) &lt;RPAREN&gt; ( &lt;AS&gt; )? <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>::= 
 ( &lt;ID&gt; ( ( &lt;AS&gt; )? <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> ( &lt;OR&gt; <link linkend="prod83">compoundCritAnd</link> )*</para></entry></row>
+<link linkend="prod84">compoundCritAnd</link> ( &lt;OR&gt; <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> ( &lt;AND&gt; <link linkend="prod84">notCrit</link> )*</para></entry></row>
+<link linkend="prod85">notCrit</link> ( &lt;AND&gt; <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>::= 
-( &lt;NOT&gt; )? <link linkend="prod85">booleanPrimary</link></para></entry></row>
+( &lt;NOT&gt; )? <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>::= 
 ( &lt;EQ&gt; | &lt;NE&gt; | &lt;NE2&gt; | &lt;LT&gt; | &lt;LE&gt; | &lt;GT&gt; | &lt;GE&gt; )</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>::= 
 &lt;LPAREN&gt; ( <link linkend="prod10">queryExpression</link> | ( <link linkend="prod11">storedProcedure</link> ) ) &lt;RPAREN&gt;</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> ( &lt;ANY&gt; | &lt;SOME&gt; | &lt;ALL&gt; ) <link linkend="prod95">subquery</link></para></entry></row>
+<link linkend="prod95">operator</link> ( &lt;ANY&gt; | &lt;SOME&gt; | &lt;ALL&gt; ) <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>::= 
-( &lt;NOT&gt; )? &lt;LIKE&gt; <link linkend="prod86">commonValueExpression</link> ( &lt;ESCAPE&gt; <link linkend="prod65">charVal</link> | ( &lt;LBRACE&gt; &lt;ESCAPE&gt; <link linkend="prod65">charVal</link> &lt;RBRACE&gt; ) )?</para></entry></row>
+( &lt;NOT&gt; )? &lt;LIKE&gt; <link linkend="prod87">commonValueExpression</link> ( &lt;ESCAPE&gt; <link linkend="prod65">charVal</link> | ( &lt;LBRACE&gt; &lt;ESCAPE&gt; <link linkend="prod65">charVal</link> &lt;RBRACE&gt; ) )?</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>::= 
-( &lt;NOT&gt; )? &lt;BETWEEN&gt; <link linkend="prod86">commonValueExpression</link> &lt;AND&gt; <link linkend="prod86">commonValueExpression</link></para></entry></row>
+( &lt;NOT&gt; )? &lt;BETWEEN&gt; <link linkend="prod87">commonValueExpression</link> &lt;AND&gt; <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>::= 
 &lt;IS&gt; ( &lt;NOT&gt; )? &lt;NULL&gt;</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>::= 
-( &lt;NOT&gt; )? &lt;IN&gt; ( ( <link linkend="prod95">subquery</link> ) | ( &lt;LPAREN&gt; <link linkend="prod86">commonValueExpression</link> ( &lt;COMMA&gt; <link linkend="prod86">commonValueExpression</link> )* &lt;RPAREN&gt; ) )</para></entry></row>
+( &lt;NOT&gt; )? &lt;IN&gt; ( ( <link linkend="prod96">subquery</link> ) | ( &lt;LPAREN&gt; <link linkend="prod87">commonValueExpression</link> ( &lt;COMMA&gt; <link linkend="prod87">commonValueExpression</link> )* &lt;RPAREN&gt; ) )</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>::= 
-&lt;EXISTS&gt; <link linkend="prod95">subquery</link></para></entry></row>
+&lt;EXISTS&gt; <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>::= 
-&lt;GROUP&gt; &lt;BY&gt; ( <link linkend="prod96">groupByItem</link> ( &lt;COMMA&gt; <link linkend="prod96">groupByItem</link> )* )</para></entry></row>
+&lt;GROUP&gt; &lt;BY&gt; ( <link linkend="prod97">groupByItem</link> ( &lt;COMMA&gt; <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>::= 
-&lt;ORDER&gt; &lt;BY&gt; <link linkend="prod97">sortSpecification</link> ( &lt;COMMA&gt; <link linkend="prod97">sortSpecification</link> )*</para></entry></row>
+&lt;ORDER&gt; &lt;BY&gt; <link linkend="prod98">sortSpecification</link> ( &lt;COMMA&gt; <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> ( &lt;ASC&gt; | &lt;DESC&gt; )? ( <link linkend="prod18">nonReserved</link> <link linkend="prod18">nonReserved</link> )?</para></entry></row>
+<link linkend="prod99">sortKey</link> ( &lt;ASC&gt; | &lt;DESC&gt; )? ( <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> ( &lt;CONCAT_OP&gt; <link linkend="prod99">plusExpression</link> )* )</para></entry></row>
+( <link linkend="prod100">plusExpression</link> ( &lt;CONCAT_OP&gt; <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>::= 
 ( &lt;PLUS&gt; | &lt;MINUS&gt; )</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>::= 
 ( &lt;STAR&gt; | &lt;SLASH&gt; )</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>::= 
-( &lt;QMARK&gt; | <link linkend="prod104">literal</link> | ( &lt;LBRACE&gt; <link linkend="prod18">nonReserved</link> <link linkend="prod105">function</link> &lt;RBRACE&gt; ) | ( <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> ) | ( &lt;ID&gt; ) | <link linkend="prod95">subquery</link> | ( &lt;LPAREN&gt; <link linkend="prod21">expression</link> &lt;RPAREN&gt; ) | <link linkend="prod106">searchedCaseExpression</link> | <link linkend="prod107">caseExpression</link> )</para></entry></row>
+( &lt;QMARK&gt; | <link linkend="prod105">literal</link> | ( &lt;LBRACE&gt; <link linkend="prod18">nonReserved</link> <link linkend="prod106">function</link> &lt;RBRACE&gt; ) | ( <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> ) | ( &lt;ID&gt; ) | <link linkend="prod96">subquery</link> | ( &lt;LPAREN&gt; <link linkend="prod21">expression</link> &lt;RPAREN&gt; ) | <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>::= 
 &lt;CASE&gt; <link linkend="prod21">expression</link> ( &lt;WHEN&gt; <link linkend="prod21">expression</link> &lt;THEN&gt; <link linkend="prod21">expression</link> )+ ( &lt;ELSE&gt; <link linkend="prod21">expression</link> )? &lt;END&gt;</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>::= 
 &lt;CASE&gt; ( &lt;WHEN&gt; <link linkend="prod32">criteria</link> &lt;THEN&gt; <link linkend="prod21">expression</link> )+ ( &lt;ELSE&gt; <link linkend="prod21">expression</link> )? &lt;END&gt;</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>::= 
-( ( &lt;CONVERT&gt; &lt;LPAREN&gt; <link linkend="prod21">expression</link> &lt;COMMA&gt; <link linkend="prod35">dataType</link> &lt;RPAREN&gt; ) | ( &lt;CAST&gt; &lt;LPAREN&gt; <link linkend="prod21">expression</link> &lt;AS&gt; <link linkend="prod35">dataType</link> &lt;RPAREN&gt; ) | ( <link linkend="prod18">nonReserved</link> &lt;LPAREN&gt; <link linkend="prod21">expression</link> &lt;COMMA&gt; <link linkend="prod108">stringConstant</link> &lt;RPAREN&gt; ) | ( <link linkend="prod18">nonReserved</link> &lt;LPAREN&gt; <link linkend="prod109">intervalType</link> &lt;COMMA&gt; <link linkend="prod21">expression</link> &lt;COMMA&gt; <link linkend="prod21">expression</link> &lt;RPAREN&gt; ) | <link linkend="prod110">queryString</link> | ( ( &lt;LEFT&gt; | &lt;RIGHT&gt; | &lt;CHAR&gt; | &lt;USER&gt; | &lt;YEAR&gt; | &lt;MONTH&gt; | &lt;HOUR&gt; | &lt;MINUTE&gt; | &lt;SECOND&gt; | &lt;XMLCONCAT&gt; | &lt;XMLCOMMENT&gt; ) &lt;LPAREN&gt; ( <link linkend="prod21">expression</link> !
 ( &lt;COMMA&gt; <link linkend="prod21">expression</link> )* )? &lt;RPAREN&gt; ) | ( ( &lt;INSERT&gt; ) &lt;LPAREN&gt; ( <link linkend="prod21">expression</link> ( &lt;COMMA&gt; <link linkend="prod21">expression</link> )* )? &lt;RPAREN&gt; ) | ( ( &lt;TRANSLATE&gt; ) &lt;LPAREN&gt; ( <link linkend="prod21">expression</link> ( &lt;COMMA&gt; <link linkend="prod21">expression</link> )* )? &lt;RPAREN&gt; ) | <link linkend="prod111">xmlParse</link> | <link linkend="prod112">xmlElement</link> | ( &lt;XMLPI&gt; &lt;LPAREN&gt; ( &lt;ID&gt; <link linkend="prod113">idExpression</link> | <link linkend="prod113">idExpression</link> ) ( &lt;COMMA&gt; <link linkend="prod21">expression</link> )? &lt;RPAREN&gt; ) | <link linkend="prod114">xmlForest</link> | <link linkend="prod76">xmlSerialize</link> | <link linkend="prod79">xmlQuery</link> | ( <link linkend="prod2">id</link> &lt;LPAREN&gt; ( <link linkend="prod21">expression</link> ( &lt;COMMA&gt; <link linkend="prod21">expression</link> )*!
  )? &lt;RPAREN&gt; ) )</para></entry></row>
+( ( &lt;CONVERT&gt; &lt;LPAREN&gt; <link linkend="prod21">expression</link> &lt;COMMA&gt; <link linkend="prod35">dataType</link> &lt;RPAREN&gt; ) | ( &lt;CAST&gt; &lt;LPAREN&gt; <link linkend="prod21">expression</link> &lt;AS&gt; <link linkend="prod35">dataType</link> &lt;RPAREN&gt; ) | ( <link linkend="prod18">nonReserved</link> &lt;LPAREN&gt; <link linkend="prod21">expression</link> &lt;COMMA&gt; <link linkend="prod109">stringConstant</link> &lt;RPAREN&gt; ) | ( <link linkend="prod18">nonReserved</link> &lt;LPAREN&gt; <link linkend="prod110">intervalType</link> &lt;COMMA&gt; <link linkend="prod21">expression</link> &lt;COMMA&gt; <link linkend="prod21">expression</link> &lt;RPAREN&gt; ) | <link linkend="prod111">queryString</link> | ( ( &lt;LEFT&gt; | &lt;RIGHT&gt; | &lt;CHAR&gt; | &lt;USER&gt; | &lt;YEAR&gt; | &lt;MONTH&gt; | &lt;HOUR&gt; | &lt;MINUTE&gt; | &lt;SECOND&gt; | &lt;XMLCONCAT&gt; | &lt;XMLCOMMENT&gt; ) &lt;LPAREN&gt; ( <link linkend="prod21">expression</link> !
 ( &lt;COMMA&gt; <link linkend="prod21">expression</link> )* )? &lt;RPAREN&gt; ) | ( ( &lt;INSERT&gt; ) &lt;LPAREN&gt; ( <link linkend="prod21">expression</link> ( &lt;COMMA&gt; <link linkend="prod21">expression</link> )* )? &lt;RPAREN&gt; ) | ( ( &lt;TRANSLATE&gt; ) &lt;LPAREN&gt; ( <link linkend="prod21">expression</link> ( &lt;COMMA&gt; <link linkend="prod21">expression</link> )* )? &lt;RPAREN&gt; ) | <link linkend="prod112">xmlParse</link> | <link linkend="prod113">xmlElement</link> | ( &lt;XMLPI&gt; &lt;LPAREN&gt; ( &lt;ID&gt; <link linkend="prod114">idExpression</link> | <link linkend="prod114">idExpression</link> ) ( &lt;COMMA&gt; <link linkend="prod21">expression</link> )? &lt;RPAREN&gt; ) | <link linkend="prod115">xmlForest</link> | <link linkend="prod77">xmlSerialize</link> | <link linkend="prod80">xmlQuery</link> | ( <link linkend="prod2">id</link> &lt;LPAREN&gt; ( <link linkend="prod21">expression</link> ( &lt;COMMA&gt; <link linkend="prod21">expression</link> )*!
  )? &lt;RPAREN&gt; ) )</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>::= 
 &lt;XMLPARSE&gt; &lt;LPAREN&gt; <link linkend="prod18">nonReserved</link> <link linkend="prod21">expression</link> ( <link linkend="prod18">nonReserved</link> )? &lt;RPAREN&gt;</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> &lt;LPAREN&gt; <link linkend="prod21">expression</link> ( &lt;COMMA&gt; <link linkend="prod62">derivedColumn</link> )* &lt;RPAREN&gt;</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>::= 
-&lt;XMLELEMENT&gt; &lt;LPAREN&gt; ( &lt;ID&gt; <link linkend="prod2">id</link> | <link linkend="prod2">id</link> ) ( &lt;COMMA&gt; <link linkend="prod80">xmlNamespaces</link> )? ( &lt;COMMA&gt; <link linkend="prod115">xmlAttributes</link> )? ( &lt;COMMA&gt; <link linkend="prod21">expression</link> )* &lt;RPAREN&gt;</para></entry></row>
+&lt;XMLELEMENT&gt; &lt;LPAREN&gt; ( &lt;ID&gt; <link linkend="prod2">id</link> | <link linkend="prod2">id</link> ) ( &lt;COMMA&gt; <link linkend="prod81">xmlNamespaces</link> )? ( &lt;COMMA&gt; <link linkend="prod116">xmlAttributes</link> )? ( &lt;COMMA&gt; <link linkend="prod21">expression</link> )* &lt;RPAREN&gt;</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>::= 
 &lt;XMLATTRIBUTES&gt; &lt;LPAREN&gt; <link linkend="prod62">derivedColumn</link> ( &lt;COMMA&gt; <link linkend="prod62">derivedColumn</link> )* &lt;RPAREN&gt;</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>::= 
-&lt;XMLFOREST&gt; &lt;LPAREN&gt; ( <link linkend="prod80">xmlNamespaces</link> &lt;COMMA&gt; )? <link linkend="prod62">derivedColumn</link> ( &lt;COMMA&gt; <link linkend="prod62">derivedColumn</link> )* &lt;RPAREN&gt;</para></entry></row>
+&lt;XMLFOREST&gt; &lt;LPAREN&gt; ( <link linkend="prod81">xmlNamespaces</link> &lt;COMMA&gt; )? <link linkend="prod62">derivedColumn</link> ( &lt;COMMA&gt; <link linkend="prod62">derivedColumn</link> )* &lt;RPAREN&gt;</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>::= 
-&lt;XMLNAMESPACES&gt; &lt;LPAREN&gt; <link linkend="prod116">namespaceItem</link> ( &lt;COMMA&gt; <link linkend="prod116">namespaceItem</link> )* &lt;RPAREN&gt;</para></entry></row>
+&lt;XMLNAMESPACES&gt; &lt;LPAREN&gt; <link linkend="prod117">namespaceItem</link> ( &lt;COMMA&gt; <link linkend="prod117">namespaceItem</link> )* &lt;RPAREN&gt;</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> &lt;AS&gt; <link linkend="prod2">id</link> )</para></entry></row>
 <row>
@@ -846,7 +850,7 @@
 <entry align="left" valign="top"><para>::= 
 ( &lt;DEFAULT_KEYWORD&gt; <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> | &lt;INTEGERVAL&gt; | &lt;FLOATVAL&gt; | &lt;FALSE&gt; | &lt;TRUE&gt; | &lt;UNKNOWN&gt; | &lt;NULL&gt; | ( ( &lt;BOOLEANTYPE&gt; | &lt;TIMESTAMPTYPE&gt; | &lt;DATETYPE&gt; | &lt;TIMETYPE&gt; ) <link linkend="prod1">stringVal</link> &lt;RBRACE&gt; ) )</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 &lt;COLUMN&gt;, ...) 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;
+
+ at 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() {



More information about the teiid-commits mailing list