[teiid-commits] teiid SVN: r3991 - in trunk: api/src/main/java/org/teiid/metadata and 7 other directories.

teiid-commits at lists.jboss.org teiid-commits at lists.jboss.org
Wed Apr 11 11:17:18 EDT 2012


Author: shawkins
Date: 2012-04-11 11:17:17 -0400 (Wed, 11 Apr 2012)
New Revision: 3991

Removed:
   trunk/api/src/main/javacc/
Modified:
   trunk/api/src/main/java/org/teiid/metadata/AbstractMetadataRecord.java
   trunk/api/src/main/java/org/teiid/metadata/FunctionMethod.java
   trunk/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html
   trunk/engine/src/main/java/org/teiid/query/parser/SQLParserUtil.java
   trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
   trunk/engine/src/test/java/org/teiid/query/metadata/TestMetadataValidator.java
   trunk/engine/src/test/java/org/teiid/query/parser/TestDDLParser.java
   trunk/metadata/src/main/java/org/teiid/metadata/index/IndexMetadataStore.java
   trunk/metadata/src/test/java/org/teiid/metadata/index/VDBMetadataFactory.java
Log:
TEIID-1560 TEIID-1280 allowing user defined aggregates to be specified via ddl and ddl changes to be consistent with extension metadata

Modified: trunk/api/src/main/java/org/teiid/metadata/AbstractMetadataRecord.java
===================================================================
--- trunk/api/src/main/java/org/teiid/metadata/AbstractMetadataRecord.java	2012-04-11 14:39:26 UTC (rev 3990)
+++ trunk/api/src/main/java/org/teiid/metadata/AbstractMetadataRecord.java	2012-04-11 15:17:17 UTC (rev 3991)
@@ -22,10 +22,12 @@
 
 package org.teiid.metadata;
 
+import java.io.IOException;
 import java.io.Serializable;
 import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.Map;
+import java.util.TreeMap;
 import java.util.concurrent.atomic.AtomicLong;
 
 import org.teiid.core.types.DataTypeManager;
@@ -56,7 +58,7 @@
     
     private String nameInSource;
 	
-	private LinkedHashMap<String, String> properties;
+	private Map<String, String> properties;
 	private String annotation;
 
 	public static final String RELATIONAL_URI = "{http://www.teiid.org/ext/relational/2012}"; //$NON-NLS-1$
@@ -159,13 +161,20 @@
     		return this.properties.remove(key);
     	}
     	if (this.properties == null) {
-    		this.properties = new LinkedHashMap<String, String>();
+    		this.properties = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
     	}
     	return this.properties.put(DataTypeManager.getCanonicalString(key), DataTypeManager.getCanonicalString(value));
     }
     
-    public void setProperties(LinkedHashMap<String, String> properties) {
-		this.properties = properties;
+    public void setProperties(Map<String, String> properties) {
+    	if (this.properties == null) {
+    		this.properties = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
+    	} else {
+    		this.properties.clear();
+    	}
+		if (properties != null) {
+			this.properties.putAll(properties);
+		}
 	}
 
     public String getAnnotation() {
@@ -192,6 +201,13 @@
 
         return EquivalenceUtil.areEqual(this.getUUID(), other.getUUID());
     }
+    
+    private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
+    	in.defaultReadObject();
+    	if (this.properties != null && !(this.properties instanceof TreeMap<?, ?>)) {
+    		this.setProperties(this.getProperties());
+    	}
+    }
 
     public int hashCode() {
         return getUUID().hashCode();

Modified: trunk/api/src/main/java/org/teiid/metadata/FunctionMethod.java
===================================================================
--- trunk/api/src/main/java/org/teiid/metadata/FunctionMethod.java	2012-04-11 14:39:26 UTC (rev 3990)
+++ trunk/api/src/main/java/org/teiid/metadata/FunctionMethod.java	2012-04-11 15:17:17 UTC (rev 3991)
@@ -493,4 +493,34 @@
     public void setAggregateAttributes(AggregateAttributes aggregateAttributes) {
 		this.aggregateAttributes = aggregateAttributes;
 	}
+    
+	public static void convertExtensionMetadata(Procedure procedureRecord,
+			FunctionMethod function) {
+		String deterministic = procedureRecord.getProperty(AbstractMetadataRecord.RELATIONAL_URI + "deterministic", true); //$NON-NLS-1$
+		boolean nullOnNull = Boolean.valueOf(procedureRecord.getProperty(AbstractMetadataRecord.RELATIONAL_URI + "null-on-null", true)); //$NON-NLS-1$
+		boolean varargs = Boolean.valueOf(procedureRecord.getProperty(AbstractMetadataRecord.RELATIONAL_URI + "varargs", true)); //$NON-NLS-1$
+		boolean aggregate = Boolean.valueOf(procedureRecord.getProperty(AbstractMetadataRecord.RELATIONAL_URI + "aggregate", true)); //$NON-NLS-1$
+		if (deterministic != null) {
+			function.setDeterminism(Boolean.valueOf(deterministic)?Determinism.DETERMINISTIC:Determinism.NONDETERMINISTIC);
+		}
+		function.setNullOnNull(nullOnNull);
+		if (varargs && !function.getInputParameters().isEmpty()) {
+			function.getInputParameters().get(function.getInputParameterCount() - 1).setVarArg(varargs);
+		}
+		if (aggregate) {
+			boolean analytic = Boolean.valueOf(procedureRecord.getProperty(AbstractMetadataRecord.RELATIONAL_URI + "analytic", true)); //$NON-NLS-1$
+			boolean allowsOrderBy = Boolean.valueOf(procedureRecord.getProperty(AbstractMetadataRecord.RELATIONAL_URI + "allows-orderby", true)); //$NON-NLS-1$
+			boolean usesDistinctRows = Boolean.valueOf(procedureRecord.getProperty(AbstractMetadataRecord.RELATIONAL_URI + "uses-distinct-rows", true)); //$NON-NLS-1$
+			boolean allowsDistinct = Boolean.valueOf(procedureRecord.getProperty(AbstractMetadataRecord.RELATIONAL_URI + "allows-distinct", true)); //$NON-NLS-1$
+			boolean decomposable = Boolean.valueOf(procedureRecord.getProperty(AbstractMetadataRecord.RELATIONAL_URI + "decomposable", true)); //$NON-NLS-1$
+			AggregateAttributes aa = new AggregateAttributes();
+			aa.setAnalytic(analytic);
+			aa.setAllowsOrderBy(allowsOrderBy);
+			aa.setUsesDistinctRows(usesDistinctRows);
+			aa.setAllowsDistinct(allowsDistinct);
+			aa.setDecomposable(decomposable);
+			function.setAggregateAttributes(aa);
+		}
+	}
+
 }

Modified: trunk/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html
===================================================================
--- trunk/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html	2012-04-11 14:39:26 UTC (rev 3990)
+++ trunk/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html	2012-04-11 15:17:17 UTC (rev 3991)
@@ -47,7 +47,7 @@
   <LI><B>VARBINARY type support</B> - the Teiid VARBINARY type can now be used to support source BINARY and VARBINARY types.
   <LI><B>Greenplum Translator</B> - for use with the Greenplum database.
   <LI><B>Enhanced parse/format pushdown</B> - added more built-in support and extension points for parse/format function pushdown.  Added parse/format timestamp handling for SQLServer, Sybase, Oracle, and PostgreSQL.
-  <LI><B>User Defined Aggregates</B> - user defined aggregate functions can be defined via extension metadata or connector metadata. 
+  <LI><B>User Defined Aggregates</B> - user defined aggregate functions can be defined via extension metadata, DDL, or connector metadata. 
 </UL>
 
 <h2><a name="Compatibility">Compatibility Issues</a></h2>
@@ -73,7 +73,8 @@
   <li>Unaliased derived columns in the SELECT clause have different default names than prior releases.  The name will be exprX where X is the SELECT clause position.
   <li>The translator API facilities for iterator/bulk updates were combined and updated.  Multi-valued literals were replaced by the Parameter class with an associated value iterator 
       available on the BatchedCommand.  The IteratorValueSource class was also removed.
-  <li>varbinary was added as a reserved word.    
+  <li>VARBINARY, OPTIONS, and OUT were added as reserved words.
+  <li>AbstractMetadataRecord and its sub-classes use a case-insensitive map for properties rather than a LinkedHashMap.  Thus, property key lookups are now case-insensitive.    
 </ul>
 
 <h4>from 7.7</h4>

Modified: trunk/engine/src/main/java/org/teiid/query/parser/SQLParserUtil.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/parser/SQLParserUtil.java	2012-04-11 14:39:26 UTC (rev 3990)
+++ trunk/engine/src/main/java/org/teiid/query/parser/SQLParserUtil.java	2012-04-11 15:17:17 UTC (rev 3991)
@@ -34,6 +34,7 @@
 import org.teiid.core.util.PropertiesUtils;
 import org.teiid.core.util.StringUtil;
 import org.teiid.language.SQLConstants.Reserved;
+import org.teiid.metadata.AbstractMetadataRecord;
 import org.teiid.metadata.Column;
 import org.teiid.metadata.FunctionMethod;
 import org.teiid.metadata.FunctionParameter;
@@ -41,19 +42,11 @@
 import org.teiid.metadata.Procedure;
 import org.teiid.metadata.ProcedureParameter;
 import org.teiid.metadata.Table;
+import org.teiid.metadata.Column.SearchType;
 import org.teiid.query.QueryPlugin;
 import org.teiid.query.function.FunctionMethods;
-import org.teiid.query.sql.lang.AlterTrigger;
-import org.teiid.query.sql.lang.CacheHint;
-import org.teiid.query.sql.lang.CompareCriteria;
+import org.teiid.query.sql.lang.*;
 import org.teiid.query.sql.lang.ExistsCriteria.SubqueryHint;
-import org.teiid.query.sql.lang.FromClause;
-import org.teiid.query.sql.lang.JoinType;
-import org.teiid.query.sql.lang.Limit;
-import org.teiid.query.sql.lang.Option;
-import org.teiid.query.sql.lang.QueryCommand;
-import org.teiid.query.sql.lang.SetQuery;
-import org.teiid.query.sql.lang.SourceHint;
 import org.teiid.query.sql.proc.Block;
 import org.teiid.query.sql.proc.Statement;
 import org.teiid.query.sql.symbol.GroupSymbol;
@@ -361,110 +354,95 @@
     	return new Block(stmt);
     }
     
-    void setColumnOption(Column c, String k, String v){
-    	int index = k.indexOf(':');
-    	if ( index != -1) {
-    		k = k.substring(index+1);
+    void setColumnOptions(Column c){
+    	Map<String, String> props = c.getProperties();
+		setCommonProperties(c, props);
+    	
+        String v = props.remove("CASE_SENSITIVE"); //$NON-NLS-1$
+    	c.setCaseSensitive(isTrue(v));
+    	
+    	v = props.remove("SELECTABLE"); //$NON-NLS-1$
+    	c.setSelectable(isTrue(v));
+    	
+    	v = props.remove("UPDATABLE"); //$NON-NLS-1$
+    	c.setUpdatable(isTrue(v));
+    	
+    	v = props.remove("SIGNED"); //$NON-NLS-1$
+    	c.setSigned(isTrue(v));
+    	
+    	v = props.remove("CURRENCY"); //$NON-NLS-1$
+    	c.setSigned(isTrue(v));
+
+    	v = props.remove("FIXED_LENGTH"); //$NON-NLS-1$
+    	c.setFixedLength(isTrue(v));
+    	
+    	v = props.remove("SEARCHABLE"); //$NON-NLS-1$
+    	if (v != null) {
+    		c.setSearchType(SearchType.valueOf(v.toUpperCase()));
     	}
-    	if(k.equalsIgnoreCase("UUID")) {  //$NON-NLS-1$
-    		c.setUUID(v);
+    	
+    	v = props.remove("MIN_VALUE"); //$NON-NLS-1$
+    	c.setMinimumValue(v);
+    	
+    	v = props.remove("MAX_VALUE"); //$NON-NLS-1$
+    	c.setMaximumValue(v);
+    	
+    	v = props.remove("CHAR_OCTET_LENGTH"); //$NON-NLS-1$
+    	if (v != null) {
+    		c.setCharOctetLength(Integer.parseInt(v));
     	}
-        else if(k.equalsIgnoreCase("NAMEINSOURCE")) { //$NON-NLS-1$
-        	c.setNameInSource(v);
-        }
-        else if(k.equalsIgnoreCase("CASE_SENSITIVE")) { //$NON-NLS-1$
-        	c.setCaseSensitive(isTrue(v));
-        }
-        else if(k.equalsIgnoreCase("SELECTABLE")) { //$NON-NLS-1$
-        	c.setSelectable(isTrue(v));
-        }
-        else if(k.equalsIgnoreCase("UPDATABLE")) { //$NON-NLS-1$
-        	c.setUpdatable(isTrue(v));
-        }
-        else if(k.equalsIgnoreCase("SIGNED")) { //$NON-NLS-1$
-        	c.setSigned(isTrue(v));
-        }
-        else if(k.equalsIgnoreCase("CURRENCY")) { //$NON-NLS-1$
-        	c.setSigned(isTrue(v));
-        }
-        else if(k.equalsIgnoreCase("FIXED_LENGTH")) { //$NON-NLS-1$
-        	c.setFixedLength(isTrue(v));
-        }
-        else if(k.equalsIgnoreCase("SEARCHABLE"))  { //$NON-NLS-1$
-        	//'YES|NO|LIKE_ONLY|ALL_EXCEPT_LIKE'
-        	if (v.equalsIgnoreCase("YES")){//$NON-NLS-1$
-        		c.setSearchType(Column.SearchType.Searchable);
-        	}
-        	else if (v.equalsIgnoreCase("NO")){//$NON-NLS-1$
-        		c.setSearchType(Column.SearchType.Unsearchable);
-        	}
-        	else if (v.equalsIgnoreCase("LIKE_ONLY")){ //$NON-NLS-1$
-        		c.setSearchType(Column.SearchType.Like_Only);
-        	}	
-        	else if (v.equalsIgnoreCase("ALL_EXCEPT_LIKE")){ //$NON-NLS-1$
-        		c.setSearchType(Column.SearchType.All_Except_Like);
-        	}			    		    	
-        }
-        else if(k.equalsIgnoreCase("MIN_VALUE")) { //$NON-NLS-1$
-        	c.setMinimumValue(v);
-        }
-        else if(k.equalsIgnoreCase("MAX_VALUE")) { //$NON-NLS-1$
-        	c.setMaximumValue(v);
-        }
-        else if(k.equalsIgnoreCase("CHAR_OCTET_LENGTH")) { //$NON-NLS-1$
-        	c.setCharOctetLength(Integer.parseInt(v));
-        }
-        else if(k.equalsIgnoreCase("ANNOTATION")) { //$NON-NLS-1$
-        	c.setAnnotation(v);
-        }
-        else if(k.equalsIgnoreCase("NATIVE_TYPE")) { //$NON-NLS-1$
-        	c.setNativeType(v);
-        }
-        else if(k.equalsIgnoreCase("RADIX")) { //$NON-NLS-1$
-        	c.setRadix(Integer.parseInt(v));
-        }
-        else if(k.equalsIgnoreCase("NULL_VALUE_COUNT")) { //$NON-NLS-1$
-        	c.setNullValues(Integer.parseInt(v));
-        }   
-        else if(k.equalsIgnoreCase("DISTINCT_VALUES")) { //$NON-NLS-1$
-        	c.setDistinctValues(Integer.parseInt(v));
-        }  
-        else {
-        	c.setProperty(k, v);
-        }
-    }
-    
-    void setTableOption(Table table, String k, String value) {
-    	int index = k.indexOf(':');
-    	if ( index != -1) {
-    		k = k.substring(index+1);
+        
+    	v = props.remove("NATIVE_TYPE"); //$NON-NLS-1$
+    	c.setNativeType(v);
+
+    	v = props.remove("RADIX"); //$NON-NLS-1$
+    	if (v != null) {
+    		c.setRadix(Integer.parseInt(v));
     	}
-    	if(k.equalsIgnoreCase("UUID")) { //$NON-NLS-1$
-    		table.setUUID(value);
+
+    	v = props.remove("NULL_VALUE_COUNT"); //$NON-NLS-1$
+    	if (v != null) {
+    		c.setNullValues(Integer.parseInt(v));
     	}
-    	else if(k.equalsIgnoreCase("NAMEINSOURCE")) { //$NON-NLS-1$
-    		table.setNameInSource(value);
+    	
+    	v = props.remove("DISTINCT_VALUES"); //$NON-NLS-1$
+    	if (v != null) {
+    		c.setDistinctValues(Integer.parseInt(v));
     	}
-    	else if(k.equalsIgnoreCase("MATERIALIZED")) { //$NON-NLS-1$
-    		table.setMaterialized(isTrue(value));
-    	}
-    	else if(k.equalsIgnoreCase("MATERIALIZED_TABLE")) { //$NON-NLS-1$
+    }
+
+	private void setCommonProperties(AbstractMetadataRecord c, Map<String, String> props) {
+		String v = props.remove("UUID"); //$NON-NLS-1$
+		c.setUUID(v);
+		
+    	v = props.remove("ANNOTATION"); //$NON-NLS-1$
+    	c.setAnnotation(v);
+		
+		v = props.remove("NAMEINSOURCE"); //$NON-NLS-1$
+    	c.setNameInSource(v);
+	}
+    
+    void setTableOptions(Table table) {
+    	Map<String, String> props = table.getProperties();
+    	setCommonProperties(table, props);
+    	
+    	String value = props.remove("MATERIALIZED"); //$NON-NLS-1$
+		table.setMaterialized(isTrue(value));
+		
+		value = props.remove("MATERIALIZED_TABLE"); //$NON-NLS-1$
+		if (value != null) {
     		Table mattable = new Table();
     		mattable.setName(value);
     		table.setMaterializedTable(mattable);
     	}
-    	else if(k.equalsIgnoreCase("UPDATABLE")) { //$NON-NLS-1$
-    		table.setSupportsUpdate(isTrue(value));
-    	}
-    	else if(k.equalsIgnoreCase("ANNOTATION")) { //$NON-NLS-1$
-    		table.setAnnotation(value);
-    	}
-    	else if(k.equalsIgnoreCase("CARDINALITY")) { //$NON-NLS-1$
+		
+		value = props.remove("UPDATABLE"); //$NON-NLS-1$
+		table.setSupportsUpdate(isTrue(value));
+		
+    	value = props.remove("CARDINALITY"); //$NON-NLS-1$
+    	if (value != null) {
     		table.setCardinality(Integer.parseInt(value));
     	}
-    	else {
-    		table.setProperty(k, value);
-    	}
     }     
     
     static void replaceProceduresWithFunctions(MetadataFactory factory) throws ParseException {
@@ -508,28 +486,28 @@
     		method.setUUID(proc.getUUID());
     		
     		Map<String, String> props = proc.getProperties();
+
+    		String value = props.remove("CATEGORY"); //$NON-NLS-1$
+    		method.setCategory(value);
+    		
+    		value = props.remove("DETERMINISM"); //$NON-NLS-1$
+    		if (value != null) {
+				method.setDeterminism(FunctionMethod.Determinism.valueOf(value.toUpperCase()));
+			}
+    		
+			value = props.remove("JAVA_CLASS"); //$NON-NLS-1$
+			method.setInvocationClass(value);
+			
+			value = props.remove("JAVA_METHOD"); //$NON-NLS-1$
+			method.setInvocationMethod(value);
+			
     		for (String key:props.keySet()) {
-    			String value = props.get(key);
-    			if(key.equalsIgnoreCase("CATEGORY")) { //$NON-NLS-1$
-    				method.setCategory(value);
-    			}
-    			else if(key.equalsIgnoreCase("DETERMINISTIC")) { //$NON-NLS-1$
-    				method.setDeterminism(FunctionMethod.Determinism.valueOf(value.toUpperCase()));
-    			}
-    			else if(key.equalsIgnoreCase("NULLONNULL")) { //$NON-NLS-1$
-    				method.setNullOnNull(isTrue(value));
-    			}
-    			else if(key.equalsIgnoreCase("JAVA_CLASS")) { //$NON-NLS-1$
-    				method.setInvocationClass(value);
-    			}
-    			else if(key.equalsIgnoreCase("JAVA_METHOD")) { //$NON-NLS-1$
-    				method.setInvocationMethod(value);
-    			}      
-    			else {
-    				method.setProperty(key, value);
-    			}     			
+    			value = props.get(key);
+				method.setProperty(key, value);
     		}
     		
+    		FunctionMethod.convertExtensionMetadata(proc, method);
+    		
     		factory.addFunction(method);
     	}
     	
@@ -539,31 +517,18 @@
     	}
     }
     
-
-    void setProcedureOption(Procedure proc, String k, String value) {
-    	int index = k.indexOf(':');
-    	if ( index != -1) {
-    		k = k.substring(index+1);
-    	}
-    	if(k.equalsIgnoreCase("UUID")) { //$NON-NLS-1$
-    		proc.setUUID(value);
-    	}
-    	else if(k.equalsIgnoreCase("NAMEINSOURCE")) { //$NON-NLS-1$
-    		proc.setNameInSource(value);
-    	}
-    	else if(k.equalsIgnoreCase("ANNOTATION")) { //$NON-NLS-1$
-    		proc.setAnnotation(value);
-    	}
-    	else if(k.equalsIgnoreCase("UPDATECOUNT")) { //$NON-NLS-1$
+    void setProcedureOptions(Procedure proc) {
+    	Map<String, String> props = proc.getProperties();
+    	setCommonProperties(proc, props);
+    	
+    	String value = props.remove("UPDATECOUNT"); //$NON-NLS-1$
+    	if (value != null) {
     		proc.setUpdateCount(Integer.parseInt(value));
-    	}        	
-    	else {
-    		proc.setProperty(k, value);
-    	}      	
+    	}
     }
 
     public static boolean isTrue(final String text) {
-        return ("YES".equalsIgnoreCase(text)); //$NON-NLS-1$
+        return Boolean.valueOf(text);
     }    
 	
 	Column getColumn(String columnName, Table table) {

Modified: trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
===================================================================
--- trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj	2012-04-11 14:39:26 UTC (rev 3990)
+++ trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj	2012-04-11 15:17:17 UTC (rev 3991)
@@ -4137,12 +4137,10 @@
 		
 		<RETURNS> (readProcedureReturn(factory, proc) | returnDataType = parseDataType())
 		
-	    [<OPTIONS> <LPAREN>
-		   readProcedureOption(proc)
-		   (<COMMA>
-			readProcedureOption(proc)
-		   )*	   
-		   <RPAREN>
+	    [ optionsClause(proc)
+		   {
+		      setProcedureOptions(proc);
+		   }
 		]
 		[<AS>
 		stmt = statement(info)])
@@ -4207,9 +4205,7 @@
 		} catch (TranslatorException e){
 			throw new ParseException(e.getMessage());
 		}
-	}
-	[nonReserved("VARARG") {param.setVarArg(true);}]
-	
+	}	
 }
 
 void readProcedureReturn(MetadataFactory factory, Procedure proc) :
@@ -4263,12 +4259,10 @@
         )*
     ]    
     <RPAREN>]    
-    [<OPTIONS> <LPAREN>
-	   readTableOption(table)
-	   (<COMMA>
-		readTableOption(table)
-	   )*	   
-	   <RPAREN>
+    [optionsClause(table)
+	   {
+	      setTableOptions(table);
+	   }
 	]
 	[<AS> query = queryExpression(new ParseInfo())]
 	{
@@ -4440,9 +4434,10 @@
 	  |(<PRIMARY> nonReserved("KEY") { pk = true; })	 
 	  ])
 	 [<DEFAULT_KEYWORD> defalt = stringVal()]
-	 [<OPTIONS> <LPAREN>
-	   readColumnOption(column) (<COMMA> readColumnOption(column))*	   
-	   <RPAREN>
+	 [optionsClause(column)
+	   {
+	      setColumnOptions(column);
+	   }
 	 ]
 	 {
 	 	try{
@@ -4472,66 +4467,32 @@
 	 }
 }
 
-void readColumnOption(Column column) :
+void optionsClause(AbstractMetadataRecord record) :
 {
-	Token value = null;
-	String key = null;
 }
 {
-	 key = id()
-	 ((value = <STRINGVAL>)
-	 { 
-	 	setColumnOption(column, key, normalizeStringLiteral(value.image)); 
-	 } 
-	 | (value = <INTEGERVAL>) 
-	 { 
-	 	setColumnOption(column, key, value.image); 
-	 }
-	 | (value = <DECIMALVAL>)
-	 { 
-	 	setColumnOption(column, key, value.image); 
-	 })
+  <OPTIONS> <LPAREN>
+  readOption(record) (<COMMA> readOption(record))*	   
+  <RPAREN> 
 }
 
-void readProcedureOption(Procedure proc) :
+void readOption(AbstractMetadataRecord record) :
 {
-	Token value = null;
+	String value = null;
 	String key = null;
-	Token tk = null;
+	Token t = null;
 }
 {
-	 (key=id()|tk=<DETERMINISTIC>{ key = tk.image;})
-	 ((value = <STRINGVAL>)
-	 { 
-	 	setProcedureOption(proc, key, normalizeStringLiteral(value.image)); 
-	 } 
-	 | (value = <INTEGERVAL>) 
-	 { 
-	 	setProcedureOption(proc, key, value.image); 
-	 }
-	 | (value = <DECIMALVAL>)
-	 { 
-	 	setProcedureOption(proc, key, value.image); 
-	 })
-}
-
-void readTableOption(Table table) :
-{
-	Token value = null;
-	String key = null;
-}
-{
 	 key = id()
-	 ((value = <STRINGVAL>)
+	 ((value = stringVal()) 
+ 	 |
+ 	 (t = <INTEGERVAL>)
+ 	 |
+ 	 (t = <DECIMALVAL>))
 	 { 
-	 	setTableOption(table, key, normalizeStringLiteral(value.image)); 
+	 	if (t != null) {
+	 		value = t.image;
+	 	}
+	 	record.setProperty(key, value); 
 	 } 
-	 | (value = <INTEGERVAL>) 
-	 { 
-	 	setTableOption(table, key, value.image); 
-	 }
-	 | (value = <DECIMALVAL>)
-	 { 
-	 	setTableOption(table, key, value.image); 
-	 })
-}
\ No newline at end of file
+}

Modified: trunk/engine/src/test/java/org/teiid/query/metadata/TestMetadataValidator.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/metadata/TestMetadataValidator.java	2012-04-11 14:39:26 UTC (rev 3990)
+++ trunk/engine/src/test/java/org/teiid/query/metadata/TestMetadataValidator.java	2012-04-11 15:17:17 UTC (rev 3991)
@@ -252,7 +252,7 @@
 	public void testExternalMaterializationValidate() throws Exception {
 		// note here the unique here does not matter for non-existent reference columns, only primary key counted.
 		String ddl = "CREATE FOREIGN TABLE G1(e1 integer, e2 varchar);";
-		String ddl2 = "CREATE VIEW G2 OPTIONS (MATERIALIZED 'YES', MATERIALIZED_TABLE 'pm1.G1') AS SELECT * FROM pm1.G1";		
+		String ddl2 = "CREATE VIEW G2 OPTIONS (MATERIALIZED 'true', MATERIALIZED_TABLE 'pm1.G1') AS SELECT * FROM pm1.G1";		
 		
 		buildModel("pm1", true, this.vdb, this.store, ddl);
 		buildModel("vm1", false, this.vdb, this.store, ddl2);

Modified: trunk/engine/src/test/java/org/teiid/query/parser/TestDDLParser.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/parser/TestDDLParser.java	2012-04-11 14:39:26 UTC (rev 3990)
+++ trunk/engine/src/test/java/org/teiid/query/parser/TestDDLParser.java	2012-04-11 15:17:17 UTC (rev 3991)
@@ -52,7 +52,7 @@
 						"e4 decimal(12,3),\n" +
 						"e5 integer auto_increment INDEX OPTIONS (UUID 'uuid', NAMEINSOURCE 'nis', SELECTABLE 'NO'),\n" +
 						"e6 varchar index default 'hello')\n" +
-						"OPTIONS (CARDINALITY 12, UUID 'uuid2',  UPDATABLE 'yes', FOO 'BAR', ANNOTATION 'Test Table')";
+						"OPTIONS (CARDINALITY 12, UUID 'uuid2',  UPDATABLE 'true', FOO 'BAR', ANNOTATION 'Test Table')";
 				
 		Schema s = helpParse(ddl, "model");
 		Map<String, Table> tableMap = s.getTables();
@@ -403,8 +403,8 @@
 	@Test
 	public void testUDF() throws Exception {
 		String ddl = "CREATE VIRTUAL FUNCTION SourceFunc(flag boolean, msg varchar) RETURNS varchar " +
-				"OPTIONS(CATEGORY 'misc', DETERMINISTIC 'DETERMINISTIC', " +
-				"NULLONNULL 'YES', JAVA_CLASS 'foo', JAVA_METHOD 'bar', RANDOM 'any')";
+				"OPTIONS(CATEGORY 'misc', DETERMINISM 'DETERMINISTIC', " +
+				"\"NULL-ON-NULL\" 'true', JAVA_CLASS 'foo', JAVA_METHOD 'bar', RANDOM 'any')";
 
 		Schema s = helpParse(ddl, "model");
 		
@@ -428,8 +428,32 @@
 	}
 	
 	@Test
+	public void testUDAggregate() throws Exception {
+		String ddl = "CREATE VIRTUAL FUNCTION SourceFunc(flag boolean, msg varchar) RETURNS varchar " +
+				"OPTIONS(CATEGORY 'misc', AGGREGATE 'true', \"allows-distinct\" 'true')";
+
+		Schema s = helpParse(ddl, "model");
+		
+		FunctionMethod fm = s.getFunction("SourceFunc");
+		assertNotNull(fm);
+		assertEquals("string", fm.getOutputParameter().getType());
+		assertEquals(FunctionMethod.PushDown.CAN_PUSHDOWN, fm.getPushdown());
+		assertEquals(2, fm.getInputParameterCount());
+		assertEquals("flag", fm.getInputParameters().get(0).getName());
+		assertEquals("boolean", fm.getInputParameters().get(0).getType());
+		assertEquals("msg", fm.getInputParameters().get(1).getName());
+		assertEquals("string", fm.getInputParameters().get(1).getType());
+		assertFalse( fm.getInputParameters().get(1).isVarArg());
+		assertNotNull(fm.getAggregateAttributes());
+		assertTrue(fm.getAggregateAttributes().allowsDistinct());
+		assertEquals(FunctionMethod.Determinism.DETERMINISTIC, fm.getDeterminism());
+		assertEquals("misc", fm.getCategory());
+		assertFalse(fm.isNullOnNull());
+	}
+	
+	@Test
 	public void testVarArgs() throws Exception {
-		String ddl = "CREATE FUNCTION SourceFunc(flag boolean vararg) RETURNS varchar";
+		String ddl = "CREATE FUNCTION SourceFunc(flag boolean) RETURNS varchar options (varargs 'true')";
 
 		Schema s = helpParse(ddl, "model");
 		

Modified: trunk/metadata/src/main/java/org/teiid/metadata/index/IndexMetadataStore.java
===================================================================
--- trunk/metadata/src/main/java/org/teiid/metadata/index/IndexMetadataStore.java	2012-04-11 14:39:26 UTC (rev 3990)
+++ trunk/metadata/src/main/java/org/teiid/metadata/index/IndexMetadataStore.java	2012-04-11 15:17:17 UTC (rev 3991)
@@ -544,10 +544,6 @@
 	    			procedureRecord.setQueryPlan(transformRecord.getTransformation());
 	    		}
 	        } else if (procedureRecord.isFunction()) {
-	        	boolean deterministic = Boolean.valueOf(procedureRecord.getProperty(AbstractMetadataRecord.RELATIONAL_URI + "deterministic", true)); //$NON-NLS-1$
-	        	boolean nullOnNull = Boolean.valueOf(procedureRecord.getProperty(AbstractMetadataRecord.RELATIONAL_URI + "null-on-null", false)); //$NON-NLS-1$
-	        	boolean varargs = Boolean.valueOf(procedureRecord.getProperty(AbstractMetadataRecord.RELATIONAL_URI + "varargs", false)); //$NON-NLS-1$
-	        	boolean aggregate = Boolean.valueOf(procedureRecord.getProperty(AbstractMetadataRecord.RELATIONAL_URI + "aggregate", false)); //$NON-NLS-1$
 	        	FunctionParameter outputParam = null;
 	        	List<FunctionParameter> args = new ArrayList<FunctionParameter>(procedureRecord.getParameters().size() - 1);
 	        	boolean valid = true;
@@ -572,25 +568,8 @@
 				}
 	        	if (valid && outputParam != null) {
 	        	    FunctionMethod function = new FunctionMethod(procedureRecord.getName(), procedureRecord.getAnnotation(), model.getName(), PushDown.MUST_PUSHDOWN, 
-		        			null, null, args, outputParam, false, deterministic?Determinism.DETERMINISTIC:Determinism.NONDETERMINISTIC);
-		        	function.setNullOnNull(nullOnNull);
-		        	if (varargs && !function.getInputParameters().isEmpty()) {
-		        		function.getInputParameters().get(args.size() - 1).setVarArg(varargs);
-		        	}
-		        	if (aggregate) {
-		        		boolean analytic = Boolean.valueOf(procedureRecord.getProperty(AbstractMetadataRecord.RELATIONAL_URI + "analytic", false)); //$NON-NLS-1$
-		        		boolean allowsOrderBy = Boolean.valueOf(procedureRecord.getProperty(AbstractMetadataRecord.RELATIONAL_URI + "allows-orderby", false)); //$NON-NLS-1$
-		        		boolean usesDistinctRows = Boolean.valueOf(procedureRecord.getProperty(AbstractMetadataRecord.RELATIONAL_URI + "uses-distinct-rows", false)); //$NON-NLS-1$
-		        		boolean allowsDistinct = Boolean.valueOf(procedureRecord.getProperty(AbstractMetadataRecord.RELATIONAL_URI + "allows-distinct", false)); //$NON-NLS-1$
-		        		boolean decomposable = Boolean.valueOf(procedureRecord.getProperty(AbstractMetadataRecord.RELATIONAL_URI + "decomposable", false)); //$NON-NLS-1$
-		        		AggregateAttributes aa = new AggregateAttributes();
-		        		aa.setAnalytic(analytic);
-		        		aa.setAllowsOrderBy(allowsOrderBy);
-		        		aa.setUsesDistinctRows(usesDistinctRows);
-		        		aa.setAllowsDistinct(allowsDistinct);
-		        		aa.setDecomposable(decomposable);
-		        		function.setAggregateAttributes(aa);
-		        	}
+		        			null, null, args, outputParam, false, Determinism.DETERMINISTIC);
+		        	FunctionMethod.convertExtensionMetadata(procedureRecord, function);
 					model.addFunction(function);
 					continue;
 	        	}

Modified: trunk/metadata/src/test/java/org/teiid/metadata/index/VDBMetadataFactory.java
===================================================================
--- trunk/metadata/src/test/java/org/teiid/metadata/index/VDBMetadataFactory.java	2012-04-11 14:39:26 UTC (rev 3990)
+++ trunk/metadata/src/test/java/org/teiid/metadata/index/VDBMetadataFactory.java	2012-04-11 15:17:17 UTC (rev 3991)
@@ -73,7 +73,7 @@
 			}
 			return system;
 		} catch (Exception e) {
-			throw new TeiidRuntimeException("System VDB not found");
+			throw new TeiidRuntimeException(e, "System VDB load error");
 		}
     }
 	



More information about the teiid-commits mailing list