|
From: <pm_...@us...> - 2011-05-24 13:32:31
|
Revision: 4366
http://mxquery.svn.sourceforge.net/mxquery/?rev=4366&view=rev
Author: pm_fischer
Date: 2011-05-24 13:32:19 +0000 (Tue, 24 May 2011)
Log Message:
-----------
annotation (e..g, %private, %updating) support: definitions, tests and helper structures
Modified Paths:
--------------
trunk/MXQuery/android/src/ch/ethz/mxquery/query/parser/SchemaParser.java
trunk/MXQuery/midp_src/ch/ethz/mxquery/query/webservice/WSDLHandler.java
trunk/MXQuery/src/ch/ethz/mxquery/contextConfig/Context.java
trunk/MXQuery/src/ch/ethz/mxquery/contextConfig/XQStaticContext.java
trunk/MXQuery/src/ch/ethz/mxquery/datamodel/types/TypeInfo.java
trunk/MXQuery/src/ch/ethz/mxquery/functions/FGPopulator.java
trunk/MXQuery/src/ch/ethz/mxquery/functions/Function.java
trunk/MXQuery/src/ch/ethz/mxquery/functions/FunctionSignature.java
trunk/MXQuery/src/ch/ethz/mxquery/functions/NativeFunctionImporter.java
trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Filter.java
trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Fold.java
trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Map.java
trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/MapPairs.java
trunk/MXQuery/src/ch/ethz/mxquery/iterators/SequenceTypeIterator.java
trunk/MXQuery/src/ch/ethz/mxquery/model/VariableHolder.java
trunk/MXQuery/src/ch/ethz/mxquery/query/parser/Parser.java
trunk/MXQuery/src/ch/ethz/mxquery/query/parser/SchemaParser.java
trunk/MXQuery/src/ch/ethz/mxquery/query/webservice/WSDLHandler.java
trunk/MXQuery/src/examples/ExternalFunctionExample.java
trunk/MXQuery/xqib_src/ch/ethz/mxquery/functions/FGPopulator.java
trunk/MXQuery/xqib_src/ch/ethz/mxquery/functions/Function.java
trunk/MXQuery_Testing/src/ch/ethz/mxquery/test/xq11streaming/MiscTests.java
Added Paths:
-----------
trunk/MXQuery_Testing/XQTests/Queries/xquery11/annotations-func.xq
trunk/MXQuery_Testing/XQTests/Queries/xquery11/annotations-import-default.xq
trunk/MXQuery_Testing/XQTests/Queries/xquery11/annotations-import-defaultvar.xq
trunk/MXQuery_Testing/XQTests/Queries/xquery11/annotations-import-private.xq
trunk/MXQuery_Testing/XQTests/Queries/xquery11/annotations-import-privatevar.xq
trunk/MXQuery_Testing/XQTests/Queries/xquery11/annotations-import-public.xq
trunk/MXQuery_Testing/XQTests/Queries/xquery11/annotations-import-publicvar.xq
trunk/MXQuery_Testing/XQTests/Queries/xquery11/annotations-missing-literal.xq
trunk/MXQuery_Testing/XQTests/Queries/xquery11/annotations-module.xq
trunk/MXQuery_Testing/XQTests/Queries/xquery11/annotations-nondet-UDT.xq
trunk/MXQuery_Testing/XQTests/Queries/xquery11/annotations-nondet-func.xq
trunk/MXQuery_Testing/XQTests/Queries/xquery11/annotations-nondet-sequential-func.xq
trunk/MXQuery_Testing/XQTests/Queries/xquery11/annotations-privateprivatefunc.xq
trunk/MXQuery_Testing/XQTests/Queries/xquery11/annotations-privatepublicfunc.xq
trunk/MXQuery_Testing/XQTests/Queries/xquery11/annotations-publicpublicfunc.xq
trunk/MXQuery_Testing/XQTests/Queries/xquery11/annotations-unknown-namespace.xq
trunk/MXQuery_Testing/XQTests/Queries/xquery11/annotations-var.xq
trunk/MXQuery_Testing/XQTests/Queries/xquery11/functest-deterministic-builtin.xq
trunk/MXQuery_Testing/XQTests/Queries/xquery11/functest-deterministic-external-nondet-coercion.xq
trunk/MXQuery_Testing/XQTests/Queries/xquery11/functest-deterministic-external-nondet-partial.xq
trunk/MXQuery_Testing/XQTests/Queries/xquery11/functest-deterministic-external-nondet.xq
Modified: trunk/MXQuery/android/src/ch/ethz/mxquery/query/parser/SchemaParser.java
===================================================================
--- trunk/MXQuery/android/src/ch/ethz/mxquery/query/parser/SchemaParser.java 2011-05-23 09:59:07 UTC (rev 4365)
+++ trunk/MXQuery/android/src/ch/ethz/mxquery/query/parser/SchemaParser.java 2011-05-24 13:32:19 UTC (rev 4366)
@@ -48,6 +48,7 @@
import ch.ethz.mxquery.functions.xs.XSConstructorIterator;
import ch.ethz.mxquery.model.XDMIterator;
import ch.ethz.mxquery.util.URIUtils;
+import ch.ethz.mxquery.util.Hashtable;
public class SchemaParser implements DOMErrorHandler {
/**
@@ -287,7 +288,7 @@
Type.OCCURRENCE_IND_ZERO_OR_MORE);
FunctionSignature signature = new FunctionSignature(qn, paramTypes,
FunctionSignature.SYSTEM_FUNCTION,
- XDMIterator.EXPR_CATEGORY_SIMPLE, false, true);
+ new Hashtable());
XDMIterator it = XSConstructorIterator.getBaseTypeConstructor(ctx, Type.getTypeFootprint(
qn, dict), dict);
if (it != null) {
Modified: trunk/MXQuery/midp_src/ch/ethz/mxquery/query/webservice/WSDLHandler.java
===================================================================
--- trunk/MXQuery/midp_src/ch/ethz/mxquery/query/webservice/WSDLHandler.java 2011-05-23 09:59:07 UTC (rev 4365)
+++ trunk/MXQuery/midp_src/ch/ethz/mxquery/query/webservice/WSDLHandler.java 2011-05-24 13:32:19 UTC (rev 4366)
@@ -200,7 +200,9 @@
// only function name and arity
params[i] = new TypeInfo(Type.ITEM,Type.OCCURRENCE_IND_ZERO_OR_MORE);
}
- FunctionSignature signature = new FunctionSignature(functionName,params,FunctionSignature.EXTERNAL_FUNCTION,XDMIterator.EXPR_CATEGORY_SEQUENTIAL,true,false);
+ Hashtable annotations = new Hashtable();
+ annotations.put(FunctionSignature.NONDETERMINISTIC_ANNOTATION, new XDMIterator[]{});
+ FunctionSignature signature = new FunctionSignature(functionName,params,FunctionSignature.EXTERNAL_FUNCTION,annotations);
Function function = new Function(null,signature,wf,null,null);
context.addFunction(function, true, true);
Modified: trunk/MXQuery/src/ch/ethz/mxquery/contextConfig/Context.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/contextConfig/Context.java 2011-05-23 09:59:07 UTC (rev 4365)
+++ trunk/MXQuery/src/ch/ethz/mxquery/contextConfig/Context.java 2011-05-24 13:32:19 UTC (rev 4366)
@@ -395,33 +395,33 @@
public void registerVariable(QName qname, boolean isFFLWOR)
throws MXQueryException {
- registerVariable(qname, false, isFFLWOR, null, false);
+ registerVariable(qname, false, isFFLWOR, null, new Hashtable());
}
public void registerVariable(QName qname, boolean isFFLWOR,
- XDMIterator seqTypeIter, boolean assignable)
+ XDMIterator seqTypeIter, Hashtable annotations)
throws MXQueryException {
- registerVariable(qname, false, isFFLWOR, seqTypeIter, assignable);
+ registerVariable(qname, false, isFFLWOR, seqTypeIter, annotations);
}
public void registerNewContextItem() throws MXQueryException {
- registerVariable(CONTEXT_ITEM, false, null, false);
+ registerVariable(CONTEXT_ITEM, false, null, new Hashtable());
}
public void registerNewContextItem(XDMIterator seqTypeIter) throws MXQueryException {
- registerVariable(CONTEXT_ITEM, false, seqTypeIter, false);
+ registerVariable(CONTEXT_ITEM, false, seqTypeIter, new Hashtable());
}
public void registerVariable(QName qname, boolean external,
- boolean isFFLWOR, XDMIterator seqTypeIter, boolean assignable)
+ boolean isFFLWOR, XDMIterator seqTypeIter, Hashtable annotations)
throws MXQueryException {
registerVariable(qname, external, isFFLWOR, seqTypeIter, true,
- assignable, true);
+ annotations, true);
}
public void registerVariable(QName qname, boolean external,
boolean isFFLWOR, XDMIterator seqTypeIter, boolean resolve,
- boolean assignable, boolean declared) throws MXQueryException {
+ Hashtable annotations, boolean declared) throws MXQueryException {
XQName resolvedQName = qname;
if (resolve && qname.getNamespaceURI() == null)
resolvedQName = qname.resolveQNameNamespace(this, false);
@@ -442,18 +442,17 @@
holder.setDeclared(declared);
}
} else {
- holder = new VariableHolder(this, external,variableMap.size());
+ holder = new VariableHolder(this, external,variableMap.size(),annotations);
holder.setDeclared(declared);
variableMap.put(resolvedQName, holder);
}
holder.setSeqTypeIt(seqTypeIter);
- holder.setAssignable(assignable);
}
public QName registerAnonymousVariable() {
QName qname = new QName(ANONYM_VARIABLE_PREFIX, ANONYM_VARIABLE_PREFIX
+ ++anonymVariableCounter);
- variableMap.put(qname, new VariableHolder(this, false,variableMap.size()));
+ variableMap.put(qname, new VariableHolder(this, false,variableMap.size(),new Hashtable()));
return qname;
}
@@ -522,7 +521,7 @@
throws MXQueryException {
VariableHolder holder = getVariable(qname);
if (holder == null) {
- registerVariable(qname, true,false,null,true,false,false);
+ registerVariable(qname, true,false,null,true,new Hashtable(),false);
holder = getVariable(qname);
}
Modified: trunk/MXQuery/src/ch/ethz/mxquery/contextConfig/XQStaticContext.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/contextConfig/XQStaticContext.java 2011-05-23 09:59:07 UTC (rev 4365)
+++ trunk/MXQuery/src/ch/ethz/mxquery/contextConfig/XQStaticContext.java 2011-05-24 13:32:19 UTC (rev 4366)
@@ -458,11 +458,11 @@
* @param qname
* @param isFFLWOR
* @param seqTypeIter
- * @param assignable
+ * @param annotations
* @throws MXQueryException
*/
public void registerVariable(QName qname, boolean isFFLWOR, XDMIterator seqTypeIter,
- boolean assignable) throws MXQueryException;
+ Hashtable annotations) throws MXQueryException;
/**
* Registers a new context item in this scope
* @throws MXQueryException
@@ -483,11 +483,11 @@
* @param external
* @param isFFLWOR
* @param seqTypeIter
- * @param assignable
+ * @param annotations
* @throws MXQueryException
*/
public void registerVariable(QName qname, boolean external, boolean isFFLWOR,
- XDMIterator seqTypeIter, boolean assignable) throws MXQueryException;
+ XDMIterator seqTypeIter, Hashtable annotations) throws MXQueryException;
/**
* Registers a new variable. If the variable already exists, an error is thrown.
@@ -496,12 +496,12 @@
* @param isFFLWOR
* @param seqTypeIter
* @param resolve
- * @param assignable
+ * @param annotations
* @param declared TODO
* @throws MXQueryException
*/
public void registerVariable(QName qname, boolean external, boolean isFFLWOR,
- XDMIterator seqTypeIter, boolean resolve, boolean assignable, boolean declared) throws MXQueryException;
+ XDMIterator seqTypeIter, boolean resolve, Hashtable annotations, boolean declared) throws MXQueryException;
/**
* Registers a new "anonymous" (=internal) variable
* @return the QName of the registered variable
Modified: trunk/MXQuery/src/ch/ethz/mxquery/datamodel/types/TypeInfo.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/datamodel/types/TypeInfo.java 2011-05-23 09:59:07 UTC (rev 4365)
+++ trunk/MXQuery/src/ch/ethz/mxquery/datamodel/types/TypeInfo.java 2011-05-24 13:32:19 UTC (rev 4366)
@@ -20,6 +20,7 @@
package ch.ethz.mxquery.datamodel.types;
import ch.ethz.mxquery.datamodel.XQName;
+import ch.ethz.mxquery.util.Hashtable;
/** Some of node kind types (e.g. element, attribute, PI) might have name part in the type definition.
* It's not possible to represent type with integer number in these cases.
@@ -33,6 +34,7 @@
private int typeAnnotation =UNDEFINED;
private TypeInfo [] paramTypes = null;
private TypeInfo returnType=null;
+ private Hashtable annotations=null;
private final static int MASK_GET_START_TAG = Integer.parseInt("0001100000000000000000000000000", 2);
private final static int MASK_CLEAN_START_TAG = Integer.parseInt("1110011111111111111111111111111", 2);
@@ -59,11 +61,12 @@
this.typeAnnotation = typeAn;
}
- public TypeInfo(int type, int occurIndID, TypeInfo[] params,TypeInfo retType) {
+ public TypeInfo(int type, int occurIndID, TypeInfo[] params,TypeInfo retType, Hashtable annotations) {
this.type = type;
this.occurID = occurIndID;
this.paramTypes = params;
this.returnType = retType;
+ this.annotations = annotations;
}
@@ -164,11 +167,15 @@
return returnType;
}
+ public Hashtable getAnnotations() {
+ return annotations;
+ }
+
public TypeInfo copy() {
if (typeAnnotation != UNDEFINED)
return new TypeInfo(type,occurID,qn,typeAnnotation);
else if (type ==Type.FUNCTION_ITEM)
- return new TypeInfo(type, occurID, paramTypes, returnType);
+ return new TypeInfo(type, occurID, paramTypes, returnType,annotations);
else
return new TypeInfo(type, occurID,qn);
}
Modified: trunk/MXQuery/src/ch/ethz/mxquery/functions/FGPopulator.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/functions/FGPopulator.java 2011-05-23 09:59:07 UTC (rev 4365)
+++ trunk/MXQuery/src/ch/ethz/mxquery/functions/FGPopulator.java 2011-05-24 13:32:19 UTC (rev 4366)
@@ -16,7 +16,7 @@
import ch.ethz.mxquery.exceptions.ErrorCodes;
import ch.ethz.mxquery.exceptions.MXQueryException;
import ch.ethz.mxquery.exceptions.QueryLocation;
-import ch.ethz.mxquery.model.XDMIterator;
+import ch.ethz.mxquery.util.Hashtable;
import ch.ethz.mxquery.util.IOLib;
class FGPopulator {
@@ -133,7 +133,7 @@
for (int i=0;i<paramTypes.length;i++)
paramTypes[i] = new TypeInfo(FunctionGallery.getType(parameters[i],ctx),FunctionGallery.getOccur(parameters[i]));
- FunctionSignature signature = new FunctionSignature(qn, paramTypes, FunctionSignature.SYSTEM_FUNCTION, XDMIterator.EXPR_CATEGORY_SIMPLE, false, false);
+ FunctionSignature signature = new FunctionSignature(qn, paramTypes, FunctionSignature.SYSTEM_FUNCTION, new Hashtable());
Function function = new Function(baseLoc+loc+"."+funcDesc[2],signature, null, operation, type );
fg.add(function);
Modified: trunk/MXQuery/src/ch/ethz/mxquery/functions/Function.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/functions/Function.java 2011-05-23 09:59:07 UTC (rev 4365)
+++ trunk/MXQuery/src/ch/ethz/mxquery/functions/Function.java 2011-05-24 13:32:19 UTC (rev 4366)
@@ -26,6 +26,7 @@
import ch.ethz.mxquery.exceptions.StaticException;
import ch.ethz.mxquery.iterators.UserdefFuncCall;
import ch.ethz.mxquery.model.XDMIterator;
+import ch.ethz.mxquery.util.Hashtable;
/**
* Holds information on the function metadata and methods to retrieve the
@@ -79,9 +80,10 @@
public Function getAsExternalFunction(String prefix) {
QName fName = new QName(signature.getName().getNamespaceURI(), prefix,
signature.getName().getLocalPart());
+ Hashtable annotations = signature.getAllAnnotations();
+ annotations.put(FunctionSignature.PRIVATE_ANNOTATION,new XDMIterator[]{});
FunctionSignature newSig = new FunctionSignature(fName, signature.paramTypes
- , FunctionSignature.EXTERNAL_FUNCTION,
- signature.getExpressionCategory(), false, true);
+ , FunctionSignature.EXTERNAL_FUNCTION,annotations);
Function func = new Function(className, newSig, iter, operation, returnType);
return func;
}
Modified: trunk/MXQuery/src/ch/ethz/mxquery/functions/FunctionSignature.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/functions/FunctionSignature.java 2011-05-23 09:59:07 UTC (rev 4365)
+++ trunk/MXQuery/src/ch/ethz/mxquery/functions/FunctionSignature.java 2011-05-24 13:32:19 UTC (rev 4366)
@@ -15,12 +15,15 @@
package ch.ethz.mxquery.functions;
+import java.util.Enumeration;
+
import ch.ethz.mxquery.contextConfig.XQStaticContext;
import ch.ethz.mxquery.datamodel.QName;
import ch.ethz.mxquery.datamodel.XQName;
import ch.ethz.mxquery.datamodel.types.Type;
import ch.ethz.mxquery.datamodel.types.TypeInfo;
import ch.ethz.mxquery.model.XDMIterator;
+import ch.ethz.mxquery.util.Hashtable;
/**
* Holds information on the signature (Name, parameters, classification) of an XQuery function
@@ -30,6 +33,14 @@
public class FunctionSignature {
+ public static final QName PRIVATE_ANNOTATION = new QName(XQStaticContext.URI_FN,"fn","private");
+ public static final QName PUBLIC_ANNOTATION = new QName(XQStaticContext.URI_FN,"fn","public");
+ public static final QName DETERMINISTIC_ANNOTATION = new QName(XQStaticContext.URI_FN,"fn","deterministic");
+ public static final QName NONDETERMINISTIC_ANNOTATION = new QName(XQStaticContext.URI_FN,"fn","nondeterministic");
+ public static final QName SIMPLE_ANNOTATION = new QName(XQStaticContext.URI_FN,"fn","simple");
+ public static final QName UPDATING_ANNOTATION = new QName(XQStaticContext.URI_FN,"fn","updating");
+ public static final QName SEQUENTIAL_ANNOTATION = new QName(XQStaticContext.URI_FN,"fn","sequential");
+
protected QName qname;
TypeInfo [] paramTypes;
@@ -37,13 +48,9 @@
int arity = 0;
protected int type;
-
- protected int expressionType;
-
- protected boolean nondet;
-
- protected boolean privateScope;
-
+
+ Hashtable annotations;
+
//Undefined is just for locking up values
private static final int UNDEFINED_TYPE=0;
@@ -53,18 +60,16 @@
//public static final int LOCAL_SCOPE_FUNCTION=4;
FunctionSignature(QName qname, TypeInfo [] parameterType){
- this(qname, parameterType, UNDEFINED_TYPE, XDMIterator.EXPR_CATEGORY_SIMPLE, false, false);
+ this(qname, parameterType, UNDEFINED_TYPE, new Hashtable());
}
- public FunctionSignature(QName qname, TypeInfo[] parameterType, int type, int exprType, boolean nondeterministic, boolean isPrivate){
+ public FunctionSignature(QName qname, TypeInfo[] parameterType, int type, Hashtable annotations){
this.qname = qname;
this.paramTypes = parameterType;
this.type = type;
- expressionType = exprType;
- nondet = nondeterministic;
- privateScope = isPrivate;
if (this.paramTypes != null)
arity = paramTypes.length;
+ this.annotations = annotations;
}
/**
* Checks the equality of Function Signatures.
@@ -128,28 +133,43 @@
* @return The expression type of this function: SIMPLE, UPDATING, SCRIPTING
*/
public int getExpressionCategory() {
- return expressionType;
+ if (annotations.containsKey(UPDATING_ANNOTATION))
+ return XDMIterator.EXPR_CATEGORY_UPDATING;
+ if (annotations.containsKey(SEQUENTIAL_ANNOTATION))
+ return XDMIterator.EXPR_CATEGORY_SEQUENTIAL;
+ return XDMIterator.EXPR_CATEGORY_SIMPLE;
}
/**
* Is this a deterministic or non-deterministic functions (as defined in XQuery 1.1)
* @return true if the function is non-deterministic
*/
public boolean isNonDeterministic() {
- return nondet;
+ return annotations.containsKey(NONDETERMINISTIC_ANNOTATION);
}
/**
* Is this a private function (XQuery 1.1, exempt from module import)
* @return true if this is a private function
*/
public boolean isPrivateFunction() {
- return privateScope;
+ return annotations.containsKey(PRIVATE_ANNOTATION);
}
+ public Hashtable getAllAnnotations() {
+ Hashtable ht = new Hashtable();
+ Enumeration keys = annotations.keys();
+ while (keys.hasMoreElements()) {
+ Object key = keys.nextElement();
+ Object val = annotations.get(key);
+ ht.put(key, val);
+ }
+ return ht;
+ }
+
public FunctionSignature copy() {
QName qn = null;
if (qname != null)
qn = qname.copy();
- FunctionSignature fs = new FunctionSignature(qn, paramTypes, type, expressionType, nondet, privateScope);
+ FunctionSignature fs = new FunctionSignature(qn, paramTypes, type, annotations);
fs.arity = arity;
return fs;
}
Modified: trunk/MXQuery/src/ch/ethz/mxquery/functions/NativeFunctionImporter.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/functions/NativeFunctionImporter.java 2011-05-23 09:59:07 UTC (rev 4365)
+++ trunk/MXQuery/src/ch/ethz/mxquery/functions/NativeFunctionImporter.java 2011-05-24 13:32:19 UTC (rev 4366)
@@ -17,6 +17,7 @@
import ch.ethz.mxquery.exceptions.StaticException;
import ch.ethz.mxquery.iterators.NativeFuncCall;
import ch.ethz.mxquery.model.XDMIterator;
+import ch.ethz.mxquery.util.Hashtable;
public class NativeFunctionImporter {
@@ -181,7 +182,10 @@
while (allFuncts.hasNext()) {
MethodData md = (MethodData)allFuncts.next();
QName qn = new QName("java:"+className,"javamethod",md.methodName);
- FunctionSignature fs = new FunctionSignature(qn, md.paramTypes,FunctionSignature.EXTERNAL_FUNCTION,XDMIterator.EXPR_CATEGORY_SEQUENTIAL,true,false);
+ Hashtable annotations = new Hashtable();
+ annotations.put(FunctionSignature.SEQUENTIAL_ANNOTATION,new XDMIterator[]{});
+ annotations.put(FunctionSignature.NONDETERMINISTIC_ANNOTATION,new XDMIterator[]{});
+ FunctionSignature fs = new FunctionSignature(qn, md.paramTypes,FunctionSignature.EXTERNAL_FUNCTION,annotations);
Function fn = new Function(null, fs, new NativeFuncCall(ctx, md.paramTypes, toImport, md.methodName, md.returnType, null, XDMIterator.EXPR_CATEGORY_SIMPLE, QueryLocation.OUTSIDE_QUERY_LOC), null, null);
ctx.addFunction(fn);
}
@@ -220,4 +224,4 @@
public static boolean isNativeUri(String uri) {
return uri.startsWith("java:");
}
-}
\ No newline at end of file
+}
Modified: trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Filter.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Filter.java 2011-05-23 09:59:07 UTC (rev 4365)
+++ trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Filter.java 2011-05-24 13:32:19 UTC (rev 4366)
@@ -15,6 +15,7 @@
import ch.ethz.mxquery.model.CurrentBasedIterator;
import ch.ethz.mxquery.model.Iterator;
import ch.ethz.mxquery.model.XDMIterator;
+import ch.ethz.mxquery.util.Hashtable;
public class Filter extends CurrentBasedIterator {
@@ -31,7 +32,7 @@
// if (!(predicate instanceof FFLWORIterator))
TypeInfo [] params = new TypeInfo[1];
params[0] = new TypeInfo(Type.ITEM,Type.OCCURRENCE_IND_EXACTLY_ONE);
- TypeInfo tInfo = new TypeInfo(Type.FUNCTION_ITEM, Type.OCCURRENCE_IND_EXACTLY_ONE, params, new TypeInfo(Type.BOOLEAN,Type.OCCURRENCE_IND_EXACTLY_ONE));
+ TypeInfo tInfo = new TypeInfo(Type.FUNCTION_ITEM, Type.OCCURRENCE_IND_EXACTLY_ONE, params, new TypeInfo(Type.BOOLEAN,Type.OCCURRENCE_IND_EXACTLY_ONE), new Hashtable());
SequenceTypeIterator st = new SequenceTypeIterator(tInfo, true, true, context, loc, true);
st.setSubIters(subIters[0]);
Iterator[] its = null;
Modified: trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Fold.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Fold.java 2011-05-23 09:59:07 UTC (rev 4365)
+++ trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Fold.java 2011-05-24 13:32:19 UTC (rev 4366)
@@ -20,6 +20,7 @@
import ch.ethz.mxquery.model.VariableHolder;
import ch.ethz.mxquery.model.Window;
import ch.ethz.mxquery.model.XDMIterator;
+import ch.ethz.mxquery.util.Hashtable;
public class Fold extends CurrentBasedIterator implements RequestTypeMulti{
@@ -38,7 +39,7 @@
TypeInfo [] params = new TypeInfo[2];
params[0] = new TypeInfo(Type.ITEM,Type.OCCURRENCE_IND_ZERO_OR_MORE);
params[1] = new TypeInfo(Type.ITEM,Type.OCCURRENCE_IND_ZERO_OR_MORE);
- TypeInfo tInfo = new TypeInfo(Type.FUNCTION_ITEM, Type.OCCURRENCE_IND_EXACTLY_ONE, params, new TypeInfo(Type.ITEM,Type.OCCURRENCE_IND_ZERO_OR_MORE));
+ TypeInfo tInfo = new TypeInfo(Type.FUNCTION_ITEM, Type.OCCURRENCE_IND_EXACTLY_ONE, params, new TypeInfo(Type.ITEM,Type.OCCURRENCE_IND_ZERO_OR_MORE), new Hashtable());
SequenceTypeIterator st = new SequenceTypeIterator(tInfo, true, true, context, loc, true);
st.setSubIters(subIters[0]);
st.setResettable(true);
Modified: trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Map.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Map.java 2011-05-23 09:59:07 UTC (rev 4365)
+++ trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/Map.java 2011-05-24 13:32:19 UTC (rev 4366)
@@ -15,6 +15,7 @@
import ch.ethz.mxquery.model.CurrentBasedIterator;
import ch.ethz.mxquery.model.Iterator;
import ch.ethz.mxquery.model.XDMIterator;
+import ch.ethz.mxquery.util.Hashtable;
public class Map extends CurrentBasedIterator {
@@ -31,7 +32,7 @@
// if (!(predicate instanceof FFLWORIterator))
TypeInfo [] params = new TypeInfo[1];
params[0] = new TypeInfo(Type.ITEM,Type.OCCURRENCE_IND_ZERO_OR_MORE);
- TypeInfo tInfo = new TypeInfo(Type.FUNCTION_ITEM, Type.OCCURRENCE_IND_EXACTLY_ONE, params, new TypeInfo(Type.ITEM,Type.OCCURRENCE_IND_ZERO_OR_MORE));
+ TypeInfo tInfo = new TypeInfo(Type.FUNCTION_ITEM, Type.OCCURRENCE_IND_EXACTLY_ONE, params, new TypeInfo(Type.ITEM,Type.OCCURRENCE_IND_ZERO_OR_MORE), new Hashtable());
SequenceTypeIterator st = new SequenceTypeIterator(tInfo, true, true, context, loc, true);
st.setSubIters(subIters[0]);
Modified: trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/MapPairs.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/MapPairs.java 2011-05-23 09:59:07 UTC (rev 4365)
+++ trunk/MXQuery/src/ch/ethz/mxquery/functions/fn/MapPairs.java 2011-05-24 13:32:19 UTC (rev 4366)
@@ -18,6 +18,7 @@
import ch.ethz.mxquery.model.VariableHolder;
import ch.ethz.mxquery.model.Window;
import ch.ethz.mxquery.model.XDMIterator;
+import ch.ethz.mxquery.util.Hashtable;
public class MapPairs extends CurrentBasedIterator {
Window wnd1, wnd2;
@@ -34,7 +35,7 @@
params[0] = new TypeInfo(Type.ITEM,Type.OCCURRENCE_IND_EXACTLY_ONE);
params[1] = new TypeInfo(Type.ITEM,Type.OCCURRENCE_IND_EXACTLY_ONE);
- TypeInfo tInfo = new TypeInfo(Type.FUNCTION_ITEM, Type.OCCURRENCE_IND_EXACTLY_ONE, params, new TypeInfo(Type.ITEM,Type.OCCURRENCE_IND_ZERO_OR_MORE));
+ TypeInfo tInfo = new TypeInfo(Type.FUNCTION_ITEM, Type.OCCURRENCE_IND_EXACTLY_ONE, params, new TypeInfo(Type.ITEM,Type.OCCURRENCE_IND_ZERO_OR_MORE), new Hashtable());
st = new SequenceTypeIterator(tInfo, true, true, context, loc, true);
st.setSubIters(subIters[0]);
st.setResettable(true);
Modified: trunk/MXQuery/src/ch/ethz/mxquery/iterators/SequenceTypeIterator.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/iterators/SequenceTypeIterator.java 2011-05-23 09:59:07 UTC (rev 4365)
+++ trunk/MXQuery/src/ch/ethz/mxquery/iterators/SequenceTypeIterator.java 2011-05-24 13:32:19 UTC (rev 4366)
@@ -39,6 +39,7 @@
import ch.ethz.mxquery.model.CurrentBasedIterator;
import ch.ethz.mxquery.model.XDMIterator;
import ch.ethz.mxquery.util.KXmlSerializer;
+import ch.ethz.mxquery.util.Hashtable;
public class SequenceTypeIterator extends CurrentBasedIterator {
@@ -343,8 +344,8 @@
if (tok.getEventType()!=Type.FUNCTION_ITEM)
return false;
TypeInfo [] params = tInfo.getParameterTypes();
+ FunctionSignature fs = ((FunctionItemToken)tok).getFunction().getFunctionSignature();
if (params != null) {
- FunctionSignature fs = ((FunctionItemToken)tok).getFunction().getFunctionSignature();
if (fs.getArity() != params.length)
return false;
for (int i=0;i<params.length;i++) {
@@ -359,6 +360,21 @@
!Type.isOccCompatible(retType.getOccurID(),tInfo.getReturnType().getOccurID()))
return false;
}
+ if (tInfo.getAnnotations().size() > 0) {
+ Hashtable annToCheck = tInfo.getAnnotations();
+ if (annToCheck.containsKey(FunctionSignature.DETERMINISTIC_ANNOTATION) &&
+ fs.isNonDeterministic())
+ return false;
+ if (annToCheck.containsKey(FunctionSignature.SIMPLE_ANNOTATION) &&
+ fs.getExpressionCategory() != XDMIterator.EXPR_CATEGORY_SIMPLE)
+ return false;
+ if (annToCheck.contains(FunctionSignature.UPDATING_ANNOTATION) &&
+ fs.getExpressionCategory() != XDMIterator.EXPR_CATEGORY_SEQUENTIAL)
+ return false;
+ if (annToCheck.contains(FunctionSignature.SEQUENTIAL_ANNOTATION) &&
+ fs.getExpressionCategory() != XDMIterator.EXPR_CATEGORY_UPDATING)
+ return false;
+ }
return true;
}
@@ -391,7 +407,7 @@
FunctionSignature origSig = tok.getFunction().getFunctionSignature();
if (origSig.getArity() != targetType.getParameterTypes().length)
throw new TypeException(ErrorCodes.E0004_TYPE_INAPPROPRIATE_TYPE,"Wrong arity for function item",loc);
- FunctionSignature fs = new FunctionSignature(tok.getQNameTokenValue(), targetType.getParameterTypes(), FunctionSignature.USER_DEFINED_FUNCTION, origSig.getExpressionCategory(), origSig.isNonDeterministic(), origSig.isPrivateFunction());
+ FunctionSignature fs = new FunctionSignature(tok.getQNameTokenValue(), targetType.getParameterTypes(), FunctionSignature.USER_DEFINED_FUNCTION, origSig.getAllAnnotations());
Function fun = new Function(null,fs,tok.getFunction().getFunctionImplementation(getContext()),null,targetType.getReturnType());
return tok.coerce(fun);
}
Modified: trunk/MXQuery/src/ch/ethz/mxquery/model/VariableHolder.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/model/VariableHolder.java 2011-05-23 09:59:07 UTC (rev 4365)
+++ trunk/MXQuery/src/ch/ethz/mxquery/model/VariableHolder.java 2011-05-24 13:32:19 UTC (rev 4366)
@@ -21,6 +21,7 @@
import ch.ethz.mxquery.bindings.WindowFactory;
import ch.ethz.mxquery.contextConfig.Context;
import ch.ethz.mxquery.contextConfig.XQStaticContext;
+import ch.ethz.mxquery.datamodel.QName;
import ch.ethz.mxquery.datamodel.Source;
import ch.ethz.mxquery.datamodel.types.Type;
import ch.ethz.mxquery.datamodel.types.TypeInfo;
@@ -29,14 +30,19 @@
import ch.ethz.mxquery.exceptions.QueryLocation;
import ch.ethz.mxquery.exceptions.StaticException;
import ch.ethz.mxquery.iterators.VariableIterator;
+import ch.ethz.mxquery.util.Hashtable;
public class VariableHolder {
+
+ public static final QName ASSIGNABLE_ANNOTATION = new QName(XQStaticContext.URI_FN,"fn","assignable");
+ public static final QName UNASSIGNABLE_ANNOTATION = new QName(XQStaticContext.URI_FN,"fn","assignable");
+
private XDMIterator iter;
private boolean external;
private boolean declared=false;
private int useCounter=0;
private boolean resetable=false;
- private boolean assignable=true;
+ private Hashtable annotations;
private int requriedOptions = 0;
private int contextPos;
private Context ctx;
@@ -48,19 +54,20 @@
this.seqTypeIt = seqTypeIt;
}
- public VariableHolder(Context ctx, boolean external, int pos){
- this(ctx, null, external,pos);
+ public VariableHolder(Context ctx, boolean external, int pos, Hashtable ann){
+ this(ctx, null, external,pos, ann);
}
// public VariableHolder(Context ctx, XDMIterator iter){
// this(ctx, iter, false);
// }
- public VariableHolder(Context ctx, XDMIterator iter, boolean external, int pos){
+ public VariableHolder(Context ctx, XDMIterator iter, boolean external, int pos, Hashtable ann){
this.external = external;
this.iter = iter;
this.ctx = ctx;
contextPos = pos;
+ annotations = ann;
}
public void setIter(XDMIterator iter) throws MXQueryException {
@@ -113,13 +120,12 @@
}
public boolean isAssignable() {
- return assignable;
+ if (annotations.containsKey(ASSIGNABLE_ANNOTATION))
+ return true;
+ else
+ return false;
}
- public void setAssignable(boolean assignable) {
- this.assignable = assignable;
- }
-
public TypeInfo getType() {
if (seqTypeIt != null)
return seqTypeIt.getStaticType();
@@ -196,7 +202,7 @@
VariableHolder copy = new VariableHolder(
context,
iter==null?null:iter.copy(context, null, false, nestedPredCtxStack),
- external,contextPos);
+ external,contextPos, annotations);
copy.setResetable(resetable);
copy.useCounter = useCounter;
if (seqTypeIt != null)
@@ -242,5 +248,7 @@
return requriedOptions;
}
-
+ public Hashtable getAnnotations(){
+ return annotations;
+ }
}
Modified: trunk/MXQuery/src/ch/ethz/mxquery/query/parser/Parser.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/query/parser/Parser.java 2011-05-23 09:59:07 UTC (rev 4365)
+++ trunk/MXQuery/src/ch/ethz/mxquery/query/parser/Parser.java 2011-05-24 13:32:19 UTC (rev 4366)
@@ -294,30 +294,30 @@
Set pendingVars;
}
- private class FunctionOptions {
+// private class FunctionOptions {
+//
+// public FunctionOptions(int expCategory, int visbility, int execution) {
+// super();
+// this.expCategory = expCategory;
+// if (visbility == VISIBILITY_PRIVATE)
+// this.privateVisbility = true;
+// else
+// privateVisbility = false;
+// if (execution == EXECUTION_NONDET)
+// this.nondeterministic = true;
+// else
+// this.nondeterministic = false;
+// }
+//
+// public static final int VISIBILITY_PUBLIC = 0;
+// public static final int VISIBILITY_PRIVATE = 1;
+// public static final int EXECUTION_DET = 0;
+// public static final int EXECUTION_NONDET = 1;
+// int expCategory;
+// boolean privateVisbility;
+// boolean nondeterministic;
+// }
- public FunctionOptions(int expCategory, int visbility, int execution) {
- super();
- this.expCategory = expCategory;
- if (visbility == VISIBILITY_PRIVATE)
- this.privateVisbility = true;
- else
- privateVisbility = false;
- if (execution == EXECUTION_NONDET)
- this.nondeterministic = true;
- else
- this.nondeterministic = false;
- }
-
- public static final int VISIBILITY_PUBLIC = 0;
- public static final int VISIBILITY_PRIVATE = 1;
- public static final int EXECUTION_DET = 0;
- public static final int EXECUTION_NONDET = 1;
- int expCategory;
- boolean privateVisbility;
- boolean nondeterministic;
- }
-
/**
* Used for static checking of continue and break<br/>
* They can only appear in loop => during parsing of a break/coninue must be
@@ -1498,6 +1498,8 @@
continue;
VariableHolder vh = (VariableHolder) ht.get(qn);
+ if (vh.getAnnotations().containsKey(FunctionSignature.PRIVATE_ANNOTATION))
+ continue;
if (!vh.isExternal()) {
// all variables need to be in the
// target namespace of the module
@@ -1510,8 +1512,10 @@
// getCurrentContext().registerExternalVariable(qn,
// vh.getIter(), false);
QName newQn = new QName(ns_uri, temp, qn.getLocalPart());
+ Hashtable annotations = new Hashtable();
+ annotations.put(FunctionSignature.PRIVATE_ANNOTATION, new XDMIterator[]{});
getCurrentContext().registerVariable(newQn, true, false, null,
- false, false, true);
+ false, annotations, true);
XDMIterator varVal;
if (!(vh.getIter() instanceof Window)) {
varVal = vh.getIter().copy(vh.getIter().getContext(),vh.getIter().getContext(),false,new Vector());
@@ -1539,10 +1543,75 @@
// boolean isCopy = false;
if (parseKeyword("declare")) {
int declareIndex = index;
- boolean assignable = false;
boolean expectVar = false;
+ if (co.isXquery11()
+ && (parseStringGetResult("context", true)) != null) {
+
+ if (!parseString("item", true, false)) {
+ generateStaticError(
+ ErrorCodes.E0003_STATIC_NOT_A_VALID_GRAMMAR_ELEMENT,
+ "Error while parsing: 'item' expected (for context item)!");
+ }
+
+ TypeInfo typeInfo = new TypeInfo();
+ if (parseKeyword("as")) {
+ typeInfo = SequenceType();
+ seqTypeIt = new SequenceTypeIterator(typeInfo, true, false,
+ getCurrentContext(), getCurrentLoc(), false);
+ }
+
+ boolean external = false;
+ Iterator expr = null;
+ if (parseKeyword("external")) {
+ external = true;
+ }
+
+ if (parseString(":=", true, false)) {
+ createNewContextScope();
+ expr = ExprSingle();
+ checkingPrologInitializer(expr, Context.CONTEXT_ITEM);
+ removeContextScope();
+ } else if (!external)
+ generateStaticError(
+ ErrorCodes.E0003_STATIC_NOT_A_VALID_GRAMMAR_ELEMENT,
+ "Variable declared in a prolog need to either have an initializing expression or marked external");
+
+ if (!parseString(";", true, false)) {
+ generateStaticError(
+ ErrorCodes.E0003_STATIC_NOT_A_VALID_GRAMMAR_ELEMENT,
+ "Error while parsing: ';' expected!");
+ }
+
+ if (contextItemDefined)
+ generateStaticError(
+ ErrorCodes.E0099_STATIC_CTXITEM_LATE_DUPLICATE,
+ "Duplicate context item definition");
+ else
+ contextItemDefined = true;
+
+ if (!getCurrentContext().checkVariableLocal(
+ Context.CONTEXT_ITEM))
+ getCurrentContext().registerNewContextItem();
+
+ VariableHolder vh = getCurrentContext().getVariable(
+ Context.CONTEXT_ITEM);
+ if (seqTypeIt != null) {
+ vh.setSeqTypeIt(seqTypeIt);
+ }
+
+ if (expr != null) {
+ getCurrentContext().setVariableValue(Context.CONTEXT_ITEM,
+ expr);
+ }
+ return true;
+ } else {
+ index = declareIndex;
+ }
+
+ Hashtable annotations = Annotation();
+ declareIndex = index;
if (parseKeyword("assignable")) {
- assignable = true;
+ annotations.put(VariableHolder.ASSIGNABLE_ANNOTATION, new XDMIterator[]{});
expectVar = true;
} else if (parseKeyword("unassignable")) {
expectVar = true;
@@ -1560,9 +1629,7 @@
// skippingAllowed = true;
if (qname == null) {
- generateStaticError(
- ErrorCodes.E0003_STATIC_NOT_A_VALID_GRAMMAR_ELEMENT,
- "Error while parsing: 'QName' expected!");
+ generateParseError("QName");
}
TypeInfo typeInfo = new TypeInfo();
@@ -1597,10 +1664,10 @@
}
if (external) {
getCurrentContext().registerVariable(qname, external,
- false, seqTypeIt, assignable);
+ false, seqTypeIt, annotations);
} else {
getCurrentContext().registerVariable(qname, external,
- false, null, assignable);
+ false, null, annotations);
}
// In the web service case: exposing the global variables
@@ -1612,9 +1679,10 @@
qname.getNamespacePrefix(), "get"
+ qname.getLocalPart());
TypeInfo getterTypeInfo[] = new TypeInfo[0];
+ annotations.put(FunctionSignature.NONDETERMINISTIC_ANNOTATION, new XDMIterator[]{});
getterSignature = new FunctionSignature(getterFunctionName,
getterTypeInfo, FunctionSignature.SYSTEM_FUNCTION,
- XDMIterator.EXPR_CATEGORY_SIMPLE, true, false);
+ annotations);
VariableIterator vIter = new VariableIterator(
getCurrentContext(), qname, false, getCurrentLoc());
vIter.setReturnType(typeInfo.getType());
@@ -1648,71 +1716,8 @@
index = declareIndex;
}
- if (co.isXquery11()
- && (parseStringGetResult("context", true)) != null) {
- if (!parseString("item", true, false)) {
- generateStaticError(
- ErrorCodes.E0003_STATIC_NOT_A_VALID_GRAMMAR_ELEMENT,
- "Error while parsing: 'item' expected (for context item)!");
- }
-
- TypeInfo typeInfo = new TypeInfo();
- if (parseKeyword("as")) {
- typeInfo = SequenceType();
- seqTypeIt = new SequenceTypeIterator(typeInfo, true, false,
- getCurrentContext(), getCurrentLoc(), false);
- }
-
- boolean external = false;
- Iterator expr = null;
- if (parseKeyword("external")) {
- external = true;
- }
-
- if (parseString(":=", true, false)) {
- createNewContextScope();
- expr = ExprSingle();
- checkingPrologInitializer(expr, Context.CONTEXT_ITEM);
- removeContextScope();
- } else if (!external)
- generateStaticError(
- ErrorCodes.E0003_STATIC_NOT_A_VALID_GRAMMAR_ELEMENT,
- "Variable declared in a prolog need to either have an initializing expression or marked external");
-
- if (!parseString(";", true, false)) {
- generateStaticError(
- ErrorCodes.E0003_STATIC_NOT_A_VALID_GRAMMAR_ELEMENT,
- "Error while parsing: ';' expected!");
- }
-
- if (contextItemDefined)
- generateStaticError(
- ErrorCodes.E0099_STATIC_CTXITEM_LATE_DUPLICATE,
- "Duplicate context item definition");
- else
- contextItemDefined = true;
-
- if (!getCurrentContext().checkVariableLocal(
- Context.CONTEXT_ITEM))
- getCurrentContext().registerNewContextItem();
-
- VariableHolder vh = getCurrentContext().getVariable(
- Context.CONTEXT_ITEM);
- if (seqTypeIt != null) {
- vh.setSeqTypeIt(seqTypeIt);
- }
-
- if (expr != null) {
- getCurrentContext().setVariableValue(Context.CONTEXT_ITEM,
- expr);
- }
- return true;
- } else {
- index = declareIndex;
- }
-
- FunctionOptions funOpts = functionOptions();
+ annotations = functionOptions(annotations);
if (parseKeyword("function")) {
@@ -1731,7 +1736,7 @@
.getDefaultFunctionNamespace());
// skippingAllowed = true;
- Function fn = parseFunctionDef(funOpts, qname,true);
+ Function fn = parseFunctionDef(annotations, qname,true);
if (!parseString(";", true, false)) {
generateStaticError(
ErrorCodes.E0003_STATIC_NOT_A_VALID_GRAMMAR_ELEMENT,
@@ -1803,7 +1808,68 @@
return false;
}
- private Function parseFunctionDef(FunctionOptions funOpts, QName qname, boolean allowExternal)
+ private Hashtable Annotation() throws MXQueryException {
+ Hashtable annotations = new Hashtable();
+ while (co.isXquery30() && parseString("%",true,false)) {
+ QName annName = EQName();
+ if (annName == null)
+ generateParseError("EQName");
+
+ if (annName.getNamespaceURI() == null)
+ if (annName.getNamespacePrefix() == null
+ || annName.getNamespacePrefix().equals("")) {
+ annName.setNamespaceURI(getCurrentContext()
+ .getDefaultFunctionNamespace());
+ } else {
+ annName = (QName)annName.resolveQNameNamespace(getCurrentContext(),
+ false);
+ }
+ Vector literals = new Vector();
+ if (parseString("(",true,false)) {
+ XDMIterator lit = Literal();
+ if (lit == null)
+ generateParseError("Literal");
+ else
+ literals.addElement(lit);
+ while (parseString(",", true, false)) {
+ lit = Literal();
+ if (lit == null)
+ generateParseError("Literal");
+ literals.addElement(lit);
+ }
+ parseKeywordYieldError(")");
+
+ }
+ XDMIterator [] annotationLiterals = new XDMIterator[literals.size()];
+ literals.copyInto(annotationLiterals);
+ if (annotations.containsKey(annName)) {
+ if (annName.equals(FunctionSignature.DETERMINISTIC_ANNOTATION)||
+ annName.equals(FunctionSignature.NONDETERMINISTIC_ANNOTATION)||
+ annName.equals(FunctionSignature.PRIVATE_ANNOTATION)||
+ annName.equals(FunctionSignature.PUBLIC_ANNOTATION))
+ generateStaticError(ErrorCodes.E0106_STATIC_MULTIPLE_PRIVATE_NONDET_FUNCTION,
+ "Duplicate annotation "+annName);
+ else
+ generateStaticError(ErrorCodes.A0009_EC_EVALUATION_NOT_POSSIBLE,
+ "Duplicate annotation "+annName);
+ }
+ if (annName.equals(FunctionSignature.PRIVATE_ANNOTATION)||
+ annName.equals(FunctionSignature.PUBLIC_ANNOTATION))
+ checkVisibilityAnnotation(annotations);
+ if (annName.equals(FunctionSignature.DETERMINISTIC_ANNOTATION)||
+ annName.equals(FunctionSignature.NONDETERMINISTIC_ANNOTATION))
+ checkDeterministicAnnotation(annotations);
+ if (annName.equals(FunctionSignature.SIMPLE_ANNOTATION)||
+ annName.equals(FunctionSignature.UPDATING_ANNOTATION)||
+ annName.equals(FunctionSignature.SEQUENTIAL_ANNOTATION))
+ checkExprTypeAnnotation(annotations);
+
+ annotations.put(annName, annotationLiterals);
+ }
+ return annotations;
+ }
+
+ private Function parseFunctionDef(Hashtable annotations, QName qname, boolean allowExternal)
throws StaticException, MXQueryException {
Iterator seqTypeIt;
if (!parseString("(", true, false)) {
@@ -1856,7 +1922,7 @@
if (!returnType.isUndefined()
&& !co.isScripting()
- && funOpts.expCategory == XDMIterator.EXPR_CATEGORY_UPDATING)
+ && annotations.containsKey(FunctionSignature.UPDATING_ANNOTATION))
throw new StaticException(
ErrorCodes.U0028_UPDATE_STATIC_FUNCTION_UPDATING_RETURNTYPE,
"'updating' function must not specify a return type",
@@ -1868,7 +1934,7 @@
external = true;
// TODO: Insert runtime PUL checking for external functions
} else {
- if (funOpts.nondeterministic)
+ if (annotations.containsKey(FunctionSignature.NONDETERMINISTIC_ANNOTATION))
generateStaticError(
ErrorCodes.E0106_STATIC_MULTIPLE_PRIVATE_NONDET_FUNCTION,
"A UDF cannot be specified as nondeterminitic");
@@ -1886,13 +1952,16 @@
true, true, getCurrentContext(),
getCurrentLoc(), true); // streaming
}
+ Hashtable paramAnnotations = new Hashtable();
+ if (annotations.containsKey(FunctionSignature.SEQUENTIAL_ANNOTATION))
+ paramAnnotations.put(VariableHolder.ASSIGNABLE_ANNOTATION, new XDMIterator[]{});
getCurrentContext().registerVariable(
(QName) paramNames.elementAt(i), false,
- seqTypeIt, false);
+ seqTypeIt, annotations);
}
Iterator body;
- if (funOpts.expCategory == XDMIterator.EXPR_CATEGORY_SEQUENTIAL) {
+ if (annotations.containsKey(FunctionSignature.SEQUENTIAL_ANNOTATION)) {
body = Block();
} else {
body = EnclosedExpr(false);
@@ -1905,15 +1974,22 @@
seqTypeIt = null;
}
+ int exprCategory = XDMIterator.EXPR_CATEGORY_SIMPLE;
+ if (annotations.containsKey(FunctionSignature.UPDATING_ANNOTATION))
+ exprCategory = XDMIterator.EXPR_CATEGORY_UPDATING;
+ if (annotations.containsKey(FunctionSignature.SEQUENTIAL_ANNOTATION))
+ exprCategory = XDMIterator.EXPR_CATEGORY_SEQUENTIAL;
+
funcCallIter = new UserdefFuncCall(getCurrentContext(),
qname, paramArr, arrParamTypes, body, returnType,
- seqTypeIt, funOpts.expCategory, getCurrentLoc());
+ seqTypeIt, exprCategory, getCurrentLoc());
funcCallIter.staticInit();
funcCallIter = (UserdefFuncCall)funcCallIter.require(0);
if (!allowExternal) {
// if inline function
// compute the closure
// all variable references which are not resolved within the
+ // context
Vector subs = funcCallIter.getAllSubItersRecursive();
Vector closure = new Vector();
for (int i=0;i<subs.size();i++) {
@@ -1942,8 +2018,7 @@
fs = new FunctionSignature(qname,
arrParamTypes,
FunctionSignature.USER_DEFINED_FUNCTION,
- funOpts.expCategory, !funOpts.nondeterministic,
- funOpts.privateVisbility);
+ annotations);
// Check if the category can be resolved now
funcCallIter.getExpressionCategoryType(co.isScripting());
addedFunctions.addElement(funcCallIter);
@@ -1951,80 +2026,67 @@
} else {
fs = new FunctionSignature(qname,
arrParamTypes, FunctionSignature.EXTERNAL_FUNCTION,
- funOpts.expCategory, !funOpts.nondeterministic,
- !funOpts.privateVisbility);
+ annotations);
}
- Function fn = new Function(null, fs, funcCallIter, null, null);
+ Function fn = new Function(null, fs, funcCallIter, null, returnType);
return fn;
}
- private FunctionOptions functionOptions() throws MXQueryException {
-
- int expressionCategory = -1;
- int visibilityMode = -1;
- int deterministicMode = -1;
-
+ private Hashtable functionOptions(Hashtable annotations) throws MXQueryException {
while (true) {
int oldPos = index;
if (co.isUpdate() && parseKeyword("updating")) {
- if (expressionCategory != -1)
- generateStaticError(
- ErrorCodes.E0003_STATIC_NOT_A_VALID_GRAMMAR_ELEMENT,
- "Only a one of 'updating','sequential','simple' allowed");
- expressionCategory = XDMIterator.EXPR_CATEGORY_UPDATING;
+ checkExprTypeAnnotation(annotations);
+ annotations.put(FunctionSignature.UPDATING_ANNOTATION, new XDMIterator[]{});
} else if (co.isScripting() && parseKeyword("sequential")) {
- if (expressionCategory != -1)
- generateStaticError(
- ErrorCodes.E0003_STATIC_NOT_A_VALID_GRAMMAR_ELEMENT,
- "Only a one of 'updating','sequential','simple' allowed");
- expressionCategory = XDMIterator.EXPR_CATEGORY_SEQUENTIAL;
+ checkExprTypeAnnotation(annotations);
} else if (parseKeyword("simple")) {
- if (expressionCategory != -1)
- generateStaticError(
- ErrorCodes.E0003_STATIC_NOT_A_VALID_GRAMMAR_ELEMENT,
- "Only a one of 'updating','sequential','simple' allowed");
+ checkExprTypeAnnotation(annotations);
+ annotations.put(FunctionSignature.SEQUENTIAL_ANNOTATION, new XDMIterator[]{});
} else if (co.isXquery11() && parseKeyword("private")) {
- if (visibilityMode != -1)
- generateStaticError(
- ErrorCodes.E0106_STATIC_MULTIPLE_PRIVATE_NONDET_FUNCTION,
- "Only a one of 'private','public'allowed");
- visibilityMode = FunctionOptions.VISIBILITY_PRIVATE;
+ checkVisibilityAnnotation(annotations);
+ annotations.put(FunctionSignature.PRIVATE_ANNOTATION, new XDMIterator[]{});
} else if (co.isXquery11() && parseKeyword("public")) {
- if (visibilityMode != -1)
- generateStaticError(
- ErrorCodes.E0106_STATIC_MULTIPLE_PRIVATE_NONDET_FUNCTION,
- "Only a one of 'private','public'allowed");
- visibilityMode = FunctionOptions.VISIBILITY_PUBLIC;
+ checkVisibilityAnnotation(annotations);
+ annotations.put(FunctionSignature.PUBLIC_ANNOTATION, new XDMIterator[]{});
} else if (co.isXquery11() && parseKeyword("nondeterministic")) {
- if (deterministicMode != -1)
- generateStaticError(
- ErrorCodes.E0106_STATIC_MULTIPLE_PRIVATE_NONDET_FUNCTION,
- "Only a one of 'deterministic','nondeterministic'allowed");
- deterministicMode = FunctionOptions.EXECUTION_NONDET;
+ checkDeterministicAnnotation(annotations);
+ annotations.put(FunctionSignature.NONDETERMINISTIC_ANNOTATION, new XDMIterator[]{});
} else if (co.isXquery11() && parseKeyword("deterministic")) {
- if (deterministicMode != -1)
- generateStaticError(
- ErrorCodes.E0106_STATIC_MULTIPLE_PRIVATE_NONDET_FUNCTION,
- "Only a one of 'deterministic','nondeterministic'allowed");
- deterministicMode = FunctionOptions.EXECUTION_DET;
+ checkDeterministicAnnotation(annotations);
+ annotations.put(FunctionSignature.DETERMINISTIC_ANNOTATION, new XDMIterator[]{});
} else {
index = oldPos;
break;
}
}
+ return annotations;
+ }
- if (expressionCategory == -1)
- expressionCategory = XDMIterator.EXPR_CATEGORY_SIMPLE;
- if (visibilityMode == -1)
- visibilityMode = FunctionOptions.VISIBILITY_PUBLIC; // public
- if (deterministicMode == -1)
- deterministicMode = FunctionOptions.EXECUTION_DET;
+ void checkDeterministicAnnotation(Hashtable annotations)
+ throws StaticException {
+ if (annotations.containsKey(FunctionSignature.DETERMINISTIC_ANNOTATION) || annotations.containsKey(FunctionSignature.NONDETERMINISTIC_ANNOTATION))
+ generateStaticError(
+ ErrorCodes.E0106_STATIC_MULTIPLE_PRIVATE_NONDET_FUNCTION,
+ "Only a one of 'deterministic','nondeterministic'allowed");
+ }
- FunctionOptions fo = new FunctionOptions(expressionCategory,
- visibilityMode, deterministicMode);
+ void checkVisibilityAnnotation(Hashtable annotations)
+ throws StaticException {
+ if (annotations.containsKey(FunctionSignature.PUBLIC_ANNOTATION) || annotations.containsKey(FunctionSignature.PRIVATE_ANNOTATION))
+ generateStaticError(
+ ErrorCodes.E0106_STATIC_MULTIPLE_PRIVATE_NONDET_FUNCTION,
+ "Only a one of 'private','public'allowed");
+ }
- return fo;
+ void checkExprTypeAnnotation(Hashtable annotations) throws StaticException {
+ if (annotations.containsKey(FunctionSignature.SEQUENTIAL_ANNOTATION) ||
+ annotations.containsKey(FunctionSignature.SIMPLE_ANNOTATION) ||
+ annotations.containsKey(FunctionSignature.UPDATING_ANNOTATION))
+ generateStaticError(
+ ErrorCodes.E0003_STATIC_NOT_A_VALID_GRAMMAR_ELEMENT,
+ "Only a one of 'updating','sequential','simple' allowed");
}
private void checkingPrologInitializer(Iterator expr, QName varname)
@@ -2637,7 +2699,7 @@
extendCurrentContextScope();
getCurrentContext().registerVariable(varQName, true, seqTypeIt,
- false);
+ new Hashtable());
Context current = getCurrentContext();
return generatePatternIterator(varQName, qType, seq,
windowType, selectionType, current, outerContext, pat);
@@ -2910,7 +2972,7 @@
}
}
getCurrentContext().registerVariable(varQName, true, seqTypeIt,
- false);
+ new Hashtable());
return generateForseqIterator(varQName, qType, seq, windowType,
outerContext, startVars, startExpr, forceEnd, endVars,
@@ -2973,7 +3035,7 @@
}
if (windowType == 0) {
getCurrentContext().registerVariable(varQName, true, seqTypeIt,
- false);
+ new Hashtable());
return new ForseqGeneralIterator(getCurrentContext(),
windowType, varQName, qType, seq,
ForseqIterator.ORDER_MODE_END, getCurrentLoc());
@@ -3045,7 +3107,7 @@
resolveVarsOnReset = false;
getCurrentContext().registerVariable(varQName, true, seqTypeIt,
- false);
+ new Hashtable());
return generateForseqIterator(varQName, qType, seq, windowType,
outerContext, startVars, startExpr, forceEnd, endVars,
@@ -3248,7 +3310,7 @@
if ((inIt = ExprSingle()) != null) {
// wait with the new context until in is parsed
extendCurrentContextScope().registerVariable(q, true,
- seqTypeIt, false);
+ seqTypeIt, new Hashtable());
if (p != null) {
getCurrentContext().registerVariable(p, true);
@@ -3302,7 +3364,7 @@
// parsed
extendCurrentContextScope()
.registerVariable(qname, false,
- seqTypeIt, false);
+ seqTypeIt, new Hashtable());
if (p1 != null) {
getCurrentContext().registerVariable(
p1, true);
@@ -3452,7 +3514,7 @@
if (score) {
useFTScoring = false;
extendCurrentContextScope().registerVariable(q,
- false, seqTypeIt, false);
+ false, seqTypeIt, new Hashtable());
Score s = new Score(inIt, getCurrentContext(),
getCurrentLoc());
its.insertElementAt(new LetIterator(
@@ -3461,7 +3523,7 @@
} else {
extendCurrentContextScope().registerVariable(q,
- false, seqTypeIt, false);
+ false, seqTypeIt, new Hashtable());
its.insertElementAt(new LetIterator(
getCurrentContext(),
new Iterator[] { inIt }, q, t,
@@ -3506,7 +3568,7 @@
if ((inIt1 = ExprSingle()) != null) {
extendCurrentContextScope()
.registerVariable(qname, false,
- seqTypeIt, false);
+ seqTypeIt, new Hashtable());
its.insertElementAt(new LetIterator(
getCurrentContext(),
new Iterator[] { inIt1 }, qname,
@@ -3680,11 +3742,12 @@
}
private TypeInfo FunctionTest() throws MXQueryException {
+ Hashtable annotations = Annotation();
if (parseKeyword("function"))
if (parseString("(",true,false)) {
if (parseString("*",true,false)) {
parseKeywordYieldError(")");
- return new TypeInfo(Type.FUNCTION_ITEM, Type.OCCURRENCE_IND_EXACTLY_ONE);
+ return new TypeInfo(Type.FUNCTION_ITEM, Type.OCCURRENCE_IND_EXACTLY_ONE,null,null,annotations);
} else {
Vector params = new Vector();
TypeInfo param;
@@ -3709,7 +3772,7 @@
TypeInfo returnType = TypeDeclaration();
TypeInfo [] paramTypes = new TypeInfo[params.size()];
params.copyInto(paramTypes);
- return new TypeInfo(Type.FUNCTION_ITEM, Type.OCCURRENCE_IND_EXACTLY_ONE,paramTypes,returnType);
+ return new TypeInfo(Type.FUNCTION_ITEM, Type.OCCURRENCE_IND_EXACTLY_ONE,paramTypes,returnType,annotations);
}
}
@@ -3986,7 +4049,7 @@
createNewContextScope();
inIt.setContext(getCurrentContext(), true);
getCurrentContext().registerVariable(q, false,
- seqTypeIt, false);
+ seqTypeIt, new Hashtable());
inIt = new ForIterator(getCurrentContext(),
new Iterator[] { inIt }, q, t, null,
getCurrentLoc(), false);
@@ -4014,7 +4077,7 @@
if ((inIt1 = ExprSingle()) != null) {
extendCurrentContextScope()
.registerVariable(qname, false,
- seqTypeIt, false);
+ seqTypeIt, new Hashtable());
inIt1 = new ForIterator(
getCurrentContext(),
new Iterator[] { inIt1 },
@@ -6517,7 +6580,7 @@
private Iterator InlineFunction() throws MXQueryException {
int startIndex = index;
if (parseKeyword("function")) {
- Function fn = parseFunctionDef(new FunctionOptions(XDMIterator.EXPR_CATEGORY_SIMPLE, FunctionOptions.VISIBILITY_PUBLIC, FunctionOptions.EXECUTION_DET), null, false);
+ Function fn = parseFunctionDef(new Hashtable(), null, false);
if (fn == null) {
index = startIndex;
return null;
@@ -7135,7 +7198,7 @@
}
TypeInfo [] wType = new TypeInfo[types.size()];
types.copyInto(wType);
- FunctionSignature fs = new FunctionSignature(null,wType,FunctionSignature.USER_DEFINED_FUNCTION,sig.getExpressionCategory(),sig.isNonDeterministic(),sig.isPrivateFunction());
+ FunctionSignature fs = new FunctionSignature(null,wType,FunctionSignature.USER_DEFINED_FUNCTION,sig.getAllAnnotations());
FunctionItemWrapperIterator fi = new FunctionItemWrapperIterator(getCurrentContext(),it, placeHolders, applied,getCurrentLoc());
Function fu = new Function(null,fs,fi,null,null);
FunctionItemToken ft = new FunctionItemToken(fu);
@@ -8648,8 +8711,10 @@
getCurrentContext(), getCurrentLoc(), false);
}
try {
+ Hashtable annotations = new Hashtable();
+ annotations.put(VariableHolder.ASSIGNABLE_ANNOTATION, new XDMIterator[]{});
getCurrentContext().registerVariable(varName, false,
- seqTypeIt, true);
+ seqTypeIt, annotations);
} catch (StaticException se) {
if (se.getErrorCode()
.equals(ErrorCodes.E0049_STATIC_MODULE_DUPLICATE_VARIABLE_NAMES))
Modified: trunk/MXQuery/src/ch/ethz/mxquery/query/parser/SchemaParser.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/query/parser/SchemaParser.java 2011-05-23 09:59:07 UTC (rev 4365)
+++ trunk/MXQuery/src/ch/ethz/mxquery/query/parser/SchemaParser.java 2011-05-24 13:32:19 UTC (rev 4366)
@@ -48,6 +48,7 @@
import ch.ethz.mxquery.functions.FunctionSignature;
import ch.ethz.mxquery.functions.xs.XSConstructorIterator;
import ch.ethz.mxquery.model.XDMIterator;
+import ch.ethz.mxquery.util.Hashtable;
import ch.ethz.mxquery.util.URIUtils;
public class SchemaParser implements DOMErrorHandler {
@@ -288,9 +289,10 @@
TypeInfo[] paramTypes = new TypeInfo[1];
paramTypes[0] = new TypeInfo(Type.ITEM,
Type.OCCURRENCE_IND_ZERO_OR_MORE);
+ Hashtable annotations = new Hashtable();
+ annotations.put(FunctionSignature.PRIVATE_ANNOTATION, new XDMIterator[]{});
FunctionSignature signature = new FunctionSignature(qn, paramTypes,
- FunctionSignature.SYSTEM_FUNCTION,
- XDMIterator.EXPR_CATEGORY_SIMPLE, false, true);
+ FunctionSignature.SYSTEM_FUNCTION,annotations);
XDMIterator it = XSConstructorIterator.getBaseTypeConstructor(ctx, Type.getTypeFootprint(
qn, dict), dict);
if (it != null) {
Modified: trunk/MXQuery/src/ch/ethz/mxquery/query/webservice/WSDLHandler.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/query/webservice/WSDLHandler.java 2011-05-23 09:59:07 UTC (rev 4365)
+++ trunk/MXQuery/src/ch/ethz/mxquery/query/webservice/WSDLHandler.java 2011-05-24 13:32:19 UTC (rev 4366)
@@ -314,7 +314,10 @@
// only function name and arity
params[i] = new TypeInfo(Type.ITEM,Type.OCCURRENCE_IND_ZERO_OR_MORE);
}
- FunctionSignature signature = new FunctionSignature(functionName,params,FunctionSignature.EXTERNAL_FUNCTION,XDMIterator.EXPR_CATEGORY_SEQUENTIAL,true, false);
+ Hashtable annotations = new Hashtable();
+ annotations.put(FunctionSignature.SEQUENTIAL_ANNOTATION,new XDMIterator[]{});
+ annotations.put(FunctionSignature.NONDETERMINISTIC_ANNOTATION,new XDMIterator[]{});
+ FunctionSignature signature = new FunctionSignature(functionName,params,FunctionSignature.EXTERNAL_FUNCTION,annotations);
Function function = new Function(null,signature,wf, null, null);
context.addFunction(function, true, true);
}
Modified: trunk/MXQuery/src/examples/ExternalFunctionExample.java
======================================...
[truncated message content] |