Update of /cvsroot/exist/eXist-1.0/src/org/exist/xquery In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21081/src/org/exist/xquery Modified Files: FunctionFactory.java ValueComparison.java Module.java BindingExpression.java DescendantOrSelfSelector.java DocumentConstructor.java FunctionCall.java LocationStep.java EnclosedExpr.java XQueryContext.java Variable.java AbstractExpression.java RangeExpression.java JavaCall.java XQueryWatchDog.java Function.java XQuery.java GeneralComparison.java ForExpr.java LetExpr.java XPathUtil.java LiteralValue.java UserDefinedFunction.java Predicate.java VariableDeclaration.java QuantifiedExpression.java Added Files: LocalVariable.java Pragma.java Log Message: * Added support for XQuery pragmas to set serialization and watchdog settings. * org.exist.storage.serializers.Serializer now passes all output to an instance of the Receiver interface instead of a SAX ContentHandler. Receiver resembles SAX, but has methods that are closer to eXist's internal storage. For example, it directly accepts a QName in startElement to avoid unnecessary string allocations. * Fixed various performance leaks in cross-document joins. Index: JavaCall.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/xquery/JavaCall.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** JavaCall.java 13 Aug 2004 21:28:48 -0000 1.4 --- JavaCall.java 12 Sep 2004 09:25:14 -0000 1.5 *************** *** 173,177 **** } } ! LOG.debug("calling method " + bestMethod.toString()); Class paramTypes[] = null; boolean isStatic = true; --- 173,177 ---- } } ! // LOG.debug("calling method " + bestMethod.toString()); Class paramTypes[] = null; boolean isStatic = true; Index: QuantifiedExpression.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/xquery/QuantifiedExpression.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** QuantifiedExpression.java 28 May 2004 10:54:13 -0000 1.2 --- QuantifiedExpression.java 12 Sep 2004 09:25:14 -0000 1.3 *************** *** 52,57 **** public Sequence eval(Sequence contextSequence, Item contextItem, Sequence resultSequence) throws XPathException { ! context.pushLocalContext(false); ! Variable var = new Variable(QName.parse(context, varName)); context.declareVariable(var); Sequence inSeq = inputSequence.eval(null); --- 52,58 ---- public Sequence eval(Sequence contextSequence, Item contextItem, Sequence resultSequence) throws XPathException { ! // context.pushLocalContext(false); ! LocalVariable mark = context.markLocalVariables(); ! LocalVariable var = new LocalVariable(QName.parse(context, varName, null)); context.declareVariable(var); Sequence inSeq = inputSequence.eval(null); *************** *** 72,76 **** break; } ! context.popLocalContext(); return found ? BooleanValue.TRUE : BooleanValue.FALSE; } --- 73,78 ---- break; } ! // context.popLocalContext(); ! context.popLocalVariables(mark); return found ? BooleanValue.TRUE : BooleanValue.FALSE; } Index: XQueryContext.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/xquery/XQueryContext.java,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** XQueryContext.java 4 Aug 2004 19:00:05 -0000 1.22 --- XQueryContext.java 12 Sep 2004 09:25:14 -0000 1.23 *************** *** 30,35 **** --- 30,37 ---- import java.net.URI; import java.net.URL; + import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; + import java.util.List; import java.util.Map; import java.util.Stack; *************** *** 43,48 **** import org.exist.security.User; import org.exist.storage.DBBroker; - import org.exist.xquery.functions.text.TextModule; - import org.exist.xquery.functions.transform.ModuleImpl; import org.exist.xquery.parser.XQueryLexer; import org.exist.xquery.parser.XQueryParser; --- 45,48 ---- *************** *** 72,76 **** public final static String XQUERY_LOCAL_NS = "http://www.w3.org/2003/08/xquery-local-functions"; ! private final static Logger LOG = Logger.getLogger(XQueryContext.class); --- 72,78 ---- public final static String XQUERY_LOCAL_NS = "http://www.w3.org/2003/08/xquery-local-functions"; ! public final static String EXIST_NS = ! "http://exist.sourceforge.net/NS/exist"; ! private final static Logger LOG = Logger.getLogger(XQueryContext.class); *************** *** 93,108 **** private TreeMap declaredFunctions = new TreeMap(); ! // Globally declare variables private TreeMap globalVariables = new TreeMap(); ! // Local in-scope variables in the current context ! private TreeMap variables = new TreeMap(); - // Local in-scope variable stack - private Stack variableStack = new Stack(); - // Unresolved references to user defined functions private Stack forwardReferences = new Stack(); private XQueryWatchDog watchdog; --- 95,112 ---- private TreeMap declaredFunctions = new TreeMap(); ! // Globally declared variables private TreeMap globalVariables = new TreeMap(); + + // The last element in the linked list of local in-scope variables + private LocalVariable lastVar = null; ! // The current size of the variable stack ! private int variableStackSize = 0; // Unresolved references to user defined functions private Stack forwardReferences = new Stack(); + private List pragmas = null; + private XQueryWatchDog watchdog; *************** *** 123,127 **** private String moduleLoadPath = "."; ! private String defaultFunctionNamespace = Function.BUILTIN_FUNCTION_NS; /** --- 127,131 ---- private String moduleLoadPath = "."; ! private String defaultFunctionNamespace = Module.BUILTIN_FUNCTION_NS; /** *************** *** 359,363 **** builder.startDocument(); staticDocuments = null; ! variableStack.clear(); fragmentStack = new Stack(); watchdog.reset(); --- 363,367 ---- builder.startDocument(); staticDocuments = null; ! lastVar = null; fragmentStack = new Stack(); watchdog.reset(); *************** *** 466,470 **** /** ! * Declare a variable. This is called by variable binding expressions like * "let" and "for". * --- 470,474 ---- /** ! * Declare a local variable. This is called by variable binding expressions like * "let" and "for". * *************** *** 473,479 **** * @throws XPathException */ ! public Variable declareVariable(Variable var) throws XPathException { ! variables.put(var.getQName(), var); ! var.setStackPosition(variableStack.size()); return var; } --- 477,490 ---- * @throws XPathException */ ! public LocalVariable declareVariable(LocalVariable var) throws XPathException { ! // variables.put(var.getQName(), var); ! if(lastVar == null) ! lastVar = var; ! else { ! lastVar.addAfter(var); ! lastVar = var; ! } ! // var.setStackPosition(variableStack.size()); ! var.setStackPosition(variableStackSize); return var; } *************** *** 489,493 **** public Variable declareGlobalVariable(Variable var) throws XPathException { globalVariables.put(var.getQName(), var); ! var.setStackPosition(variableStack.size()); return var; } --- 500,504 ---- public Variable declareGlobalVariable(Variable var) throws XPathException { globalVariables.put(var.getQName(), var); ! var.setStackPosition(variableStackSize); return var; } *************** *** 507,511 **** */ public Variable declareVariable(String qname, Object value) throws XPathException { ! QName qn = QName.parse(this, qname); Variable var; Module module = getModule(qn.getNamespaceURI()); --- 518,522 ---- */ public Variable declareVariable(String qname, Object value) throws XPathException { ! QName qn = QName.parse(this, qname, null); Variable var; Module module = getModule(qn.getNamespaceURI()); *************** *** 552,556 **** return var; } ! var = (Variable) variables.get(qname); if (var == null) { var = (Variable) globalVariables.get(qname); --- 563,568 ---- return var; } ! var = resolveLocalVariable(qname); ! // var = (Variable) variables.get(qname); if (var == null) { var = (Variable) globalVariables.get(qname); *************** *** 561,564 **** --- 573,584 ---- } + private Variable resolveLocalVariable(QName qname) throws XPathException { + for(LocalVariable var = lastVar; var != null; var = var.before) { + if(qname.equals(var.getQName())) + return var; + } + return null; + } + /** * Turn on/off XPath 1.0 backwards compatibility. *************** *** 730,752 **** /** ! * Save the current context on top of a stack. * ! * Use {@link popContext()} to restore the current state. ! * This method saves the current in-scope variable ! * definitions. */ ! public void pushLocalContext(boolean emptyContext) { ! variableStack.push(variables); ! if (emptyContext) ! variables = new TreeMap(); ! else ! variables = new TreeMap(variables); } ! /** ! * Restore previous state. */ ! public void popLocalContext() { ! variables = (TreeMap) variableStack.pop(); } --- 750,775 ---- /** ! * Returns the last variable on the local variable stack. ! * The current variable context can be restored by passing ! * the return value to {@link #popLocalVariables(LocalVariable)}. * ! * @return */ ! public LocalVariable markLocalVariables() { ! variableStackSize++; ! return lastVar; } ! /** ! * Restore the local variable stack to the position marked ! * by variable var. ! * ! * @param var */ ! public void popLocalVariables(LocalVariable var) { ! if(var != null) ! var.after = null; ! lastVar = var; ! variableStackSize--; } *************** *** 758,762 **** */ public int getCurrentStackSize() { ! return variableStack.size(); } --- 781,785 ---- */ public int getCurrentStackSize() { ! return variableStackSize; } *************** *** 810,814 **** } XQueryContext context = new ModuleContext(this); ! XQueryLexer lexer = new XQueryLexer(reader); XQueryParser parser = new XQueryParser(lexer); XQueryTreeParser astParser = new XQueryTreeParser(context); --- 833,837 ---- } XQueryContext context = new ModuleContext(this); ! XQueryLexer lexer = new XQueryLexer(context, reader); XQueryParser parser = new XQueryParser(lexer); XQueryTreeParser astParser = new XQueryTreeParser(context); *************** *** 881,884 **** --- 904,913 ---- } + /** + * Called by XUpdate to tell the query engine that it is running in + * exclusive mode, i.e. no other query is executed at the same time. + * + * @param exclusive + */ public void setExclusiveMode(boolean exclusive) { this.exclusive = exclusive; *************** *** 889,892 **** --- 918,954 ---- } + public void addPragma(String qnameString, String contents) throws XPathException { + QName qn; + try { + qn = QName.parse(this, qnameString, defaultFunctionNamespace); + } catch (XPathException e) { + // unknown pragma: just ignore it + LOG.debug("Ignoring unknown pragma: " + qnameString); + return; + } + Pragma pragma = new Pragma(qn, contents); + if(pragmas == null) + pragmas = new ArrayList(); + pragmas.add(pragma); + + // check predefined pragmas + if(Pragma.TIMEOUT_QNAME.compareTo(qn) == 0) + watchdog.setTimeoutFromPragma(pragma); + if(Pragma.OUTPUT_SIZE_QNAME.compareTo(qn) == 0) + watchdog.setMaxNodesFromPragma(pragma); + } + + public Pragma getPragma(QName qname) { + if(pragmas != null) { + Pragma pragma; + for(int i = 0; i < pragmas.size(); i++) { + pragma = (Pragma)pragmas.get(i); + if(qname.compareTo(pragma.getQName()) == 0) + return pragma; + } + } + return null; + } + /** * Load the default prefix/namespace mappings table and set up *************** *** 910,932 **** declareNamespace("xdt", XPATH_DATATYPES_NS); declareNamespace("local", XQUERY_LOCAL_NS); ! declareNamespace("fn", Function.BUILTIN_FUNCTION_NS); // load built-in modules loadBuiltInModule( ! Function.BUILTIN_FUNCTION_NS, "org.exist.xquery.functions.ModuleImpl"); loadBuiltInModule( ! Function.UTIL_FUNCTION_NS, ! "org.exist.xquery.functions.util.ModuleImpl"); ! loadBuiltInModule(ModuleImpl.NAMESPACE_URI, ! "org.exist.xquery.functions.transform.ModuleImpl"); loadBuiltInModule( ! Function.XMLDB_FUNCTION_NS, ! "org.exist.xquery.functions.xmldb.ModuleImpl"); loadBuiltInModule( ! Function.REQUEST_FUNCTION_NS, "org.exist.xquery.functions.request.RequestModule"); loadBuiltInModule( ! TextModule.NAMESPACE_URI, "org.exist.xquery.functions.text.TextModule"); } --- 972,998 ---- declareNamespace("xdt", XPATH_DATATYPES_NS); declareNamespace("local", XQUERY_LOCAL_NS); ! declareNamespace("fn", Module.BUILTIN_FUNCTION_NS); ! declareNamespace("exist", EXIST_NS); // load built-in modules + + // these modules are loaded dynamically. It is not an error if the + // specified module class cannot be found in the classpath. loadBuiltInModule( ! Module.BUILTIN_FUNCTION_NS, "org.exist.xquery.functions.ModuleImpl"); loadBuiltInModule( ! Module.UTIL_FUNCTION_NS, ! "org.exist.xquery.functions.util.UtilModule"); ! loadBuiltInModule(Module.TRANSFORM_FUNCTION_NS, ! "org.exist.xquery.functions.transform.TransformModule"); loadBuiltInModule( ! Module.XMLDB_FUNCTION_NS, ! "org.exist.xquery.functions.xmldb.XMLDBModule"); loadBuiltInModule( ! Module.REQUEST_FUNCTION_NS, "org.exist.xquery.functions.request.RequestModule"); loadBuiltInModule( ! Module.TEXT_FUNCTION_NS, "org.exist.xquery.functions.text.TextModule"); } Index: LetExpr.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/xquery/LetExpr.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** LetExpr.java 28 May 2004 10:54:13 -0000 1.2 --- LetExpr.java 12 Sep 2004 09:25:14 -0000 1.3 *************** *** 26,29 **** --- 26,30 ---- import org.exist.xquery.value.Item; import org.exist.xquery.value.OrderedValueSequence; + import org.exist.xquery.value.PreorderedValueSequence; import org.exist.xquery.value.Sequence; import org.exist.xquery.value.Type; *************** *** 46,59 **** public Sequence eval(Sequence contextSequence, Item contextItem, Sequence resultSequence) throws XPathException { ! context.pushLocalContext(false); ! Variable var = new Variable(QName.parse(context, varName)); context.declareVariable(var); ! Sequence val = inputSequence.eval(null, null); if (sequenceType != null) { ! sequenceType.checkType(val.getItemType()); ! sequenceType.checkCardinality(val); } ! var.setValue(val); ! Sequence filtered = null; if (whereExpr != null) { --- 47,64 ---- public Sequence eval(Sequence contextSequence, Item contextItem, Sequence resultSequence) throws XPathException { ! // Save the local variable stack ! LocalVariable mark = context.markLocalVariables(); ! ! // Declare the iteration variable ! LocalVariable var = new LocalVariable(QName.parse(context, varName, null)); context.declareVariable(var); ! ! Sequence in = inputSequence.eval(null, null); if (sequenceType != null) { ! sequenceType.checkType(in.getItemType()); ! sequenceType.checkCardinality(in); } ! var.setValue(in); ! Sequence filtered = null; if (whereExpr != null) { *************** *** 66,72 **** return Sequence.EMPTY_SEQUENCE; } if(resultSequence == null) { ! if(orderSpecs != null) ! resultSequence = new OrderedValueSequence(orderSpecs, val.getLength()); else resultSequence = new ValueSequence(); --- 71,90 ---- return Sequence.EMPTY_SEQUENCE; } + + // Check if we can speed up the processing of the "order by" clause. + boolean fastOrderBy = checkOrderSpecs(in); + + // PreorderedValueSequence applies the order specs to all items + // in one single processing step + if(fastOrderBy) { + in = new PreorderedValueSequence(orderSpecs, in.toNodeSet()); + } + + // Otherwise, if there's an order by clause, wrap the result into + // an OrderedValueSequence. OrderedValueSequence will compute + // order expressions for every item when it is added to the result sequence. if(resultSequence == null) { ! if(orderSpecs != null && !fastOrderBy) ! resultSequence = new OrderedValueSequence(orderSpecs, in.getLength()); else resultSequence = new ValueSequence(); *************** *** 76,85 **** ((BindingExpression)returnExpr).eval(null, null, resultSequence); } else { ! val = returnExpr.eval(null); ! resultSequence.addAll(val); } ! if(orderSpecs != null) ((OrderedValueSequence)resultSequence).sort(); ! context.popLocalContext(); return resultSequence; } --- 94,105 ---- ((BindingExpression)returnExpr).eval(null, null, resultSequence); } else { ! in = returnExpr.eval(null); ! resultSequence.addAll(in); } ! if(orderSpecs != null && !fastOrderBy) ((OrderedValueSequence)resultSequence).sort(); ! ! // Restore the local variable stack ! context.popLocalVariables(mark); return resultSequence; } Index: UserDefinedFunction.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/xquery/UserDefinedFunction.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** UserDefinedFunction.java 28 May 2004 10:54:13 -0000 1.3 --- UserDefinedFunction.java 12 Sep 2004 09:25:14 -0000 1.4 *************** *** 53,57 **** public void addVariable(String varName) throws XPathException { ! QName qname = QName.parse(context, varName); parameters.add(qname); } --- 53,57 ---- public void addVariable(String varName) throws XPathException { ! QName qname = QName.parse(context, varName, null); parameters.add(qname); } *************** *** 72,81 **** throws XPathException { QName varName; ! Variable var; Sequence argSeq; int j = 0; for(Iterator i = parameters.iterator(); i.hasNext(); j++) { varName = (QName)i.next(); ! var = new Variable(varName); var.setValue(currentArguments[j]); context.declareVariable(var); --- 72,81 ---- throws XPathException { QName varName; ! LocalVariable var; Sequence argSeq; int j = 0; for(Iterator i = parameters.iterator(); i.hasNext(); j++) { varName = (QName)i.next(); ! var = new LocalVariable(varName); var.setValue(currentArguments[j]); context.declareVariable(var); Index: GeneralComparison.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/xquery/GeneralComparison.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** GeneralComparison.java 28 May 2004 10:54:12 -0000 1.5 --- GeneralComparison.java 12 Sep 2004 09:25:14 -0000 1.6 *************** *** 78,89 **** this.truncation = truncation; // simplify arguments ! if (left instanceof PathExpr && ((PathExpr) left).getLength() == 1) ! add(((PathExpr) left).getExpression(0)); ! else ! add(left); ! if (right instanceof PathExpr && ((PathExpr) right).getLength() == 1) ! add(((PathExpr) right).getExpression(0)); ! else ! add(right); } --- 78,89 ---- this.truncation = truncation; // simplify arguments ! if (left instanceof PathExpr && ((PathExpr) left).getLength() == 1) { ! left = ((PathExpr) left).getExpression(0); ! } ! add(left); ! if (right instanceof PathExpr && ((PathExpr) right).getLength() == 1) { ! right = ((PathExpr) right).getExpression(0); ! } ! add(right); } *************** *** 168,172 **** lv = ls.itemAt(0).atomize(); rv = rs.itemAt(0).atomize(); ! return new BooleanValue(compareValues(lv, rv)); } else { for (SequenceIterator i1 = ls.iterate(); i1.hasNext();) { --- 168,172 ---- lv = ls.itemAt(0).atomize(); rv = rs.itemAt(0).atomize(); ! return BooleanValue.valueOf(compareValues(lv, rv)); } else { for (SequenceIterator i1 = ls.iterate(); i1.hasNext();) { Index: LiteralValue.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/xquery/LiteralValue.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** LiteralValue.java 28 May 2004 10:54:13 -0000 1.2 --- LiteralValue.java 12 Sep 2004 09:25:14 -0000 1.3 *************** *** 23,27 **** package org.exist.xquery; - import org.exist.dom.DocumentSet; import org.exist.xquery.value.AtomicValue; import org.exist.xquery.value.Item; --- 23,26 ---- *************** *** 63,74 **** /* (non-Javadoc) - * @see org.exist.xquery.Expression#preselect(org.exist.dom.DocumentSet, org.exist.xquery.StaticContext) - */ - public DocumentSet preselect(DocumentSet in_docs) - throws XPathException { - return in_docs; - } - - /* (non-Javadoc) * @see org.exist.xquery.Expression#pprint() */ --- 62,65 ---- Index: ValueComparison.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/xquery/ValueComparison.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** ValueComparison.java 29 Jan 2004 15:06:41 -0000 1.1 --- ValueComparison.java 12 Sep 2004 09:25:14 -0000 1.2 *************** *** 26,30 **** import org.exist.dom.ContextItem; - import org.exist.dom.DocumentSet; import org.exist.dom.ExtArrayNodeSet; import org.exist.dom.NodeProxy; --- 26,29 ---- *************** *** 72,76 **** lv = ls.itemAt(0).atomize(); rv = rs.itemAt(0).atomize(); ! return new BooleanValue(compareValues(lv, rv)); } else throw new XPathException("Type error: sequence with less or more than one item is not allowed here"); --- 71,75 ---- lv = ls.itemAt(0).atomize(); rv = rs.itemAt(0).atomize(); ! return BooleanValue.valueOf(compareValues(lv, rv)); } else throw new XPathException("Type error: sequence with less or more than one item is not allowed here"); Index: Function.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/xquery/Function.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** Function.java 19 Jul 2004 13:06:24 -0000 1.5 --- Function.java 12 Sep 2004 09:25:14 -0000 1.6 *************** *** 48,73 **** */ public abstract class Function extends PathExpr { ! ! /** ! * XQuery/XPath 2.0 function namespace. ! */ public final static String BUILTIN_FUNCTION_NS = "http://www.w3.org/2003/05/xpath-functions"; - /** - * Namespace for the built-in xmldb functions. - */ - public final static String XMLDB_FUNCTION_NS = - "http://exist-db.org/xquery/xmldb"; - - /** - * Namespace for the built-in utility functions. - */ - public final static String UTIL_FUNCTION_NS = - "http://exist-db.org/xquery/util"; - - public final static String REQUEST_FUNCTION_NS = - "http://exist-db.org/xquery/request"; - // The signature of the function. protected FunctionSignature mySignature; --- 48,55 ---- */ public abstract class Function extends PathExpr { ! public final static String BUILTIN_FUNCTION_NS = "http://www.w3.org/2003/05/xpath-functions"; // The signature of the function. protected FunctionSignature mySignature; Index: Module.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/xquery/Module.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Module.java 28 May 2004 10:54:12 -0000 1.2 --- Module.java 12 Sep 2004 09:25:14 -0000 1.3 *************** *** 43,46 **** --- 43,76 ---- public interface Module { + /** + * XQuery/XPath 2.0 function namespace. + */ + public final static String BUILTIN_FUNCTION_NS = + "http://www.w3.org/2003/05/xpath-functions"; + + /** + * Namespace for the built-in xmldb module. + */ + public final static String XMLDB_FUNCTION_NS = + "http://exist-db.org/xquery/xmldb"; + + /** + * Namespace for the built-in utility module. + */ + public final static String UTIL_FUNCTION_NS = + "http://exist-db.org/xquery/util"; + + /** + * Namespace for the built-in request module. + */ + public final static String REQUEST_FUNCTION_NS = + "http://exist-db.org/xquery/request"; + + public final static String TRANSFORM_FUNCTION_NS = + "http://exist-db.org/xquery/transform"; + + public final static String TEXT_FUNCTION_NS = + "http://exist-db.org/xquery/text"; + /** * Returns the namespace URI that uniquely identifies this module. Index: RangeExpression.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/xquery/RangeExpression.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** RangeExpression.java 28 May 2004 10:54:12 -0000 1.2 --- RangeExpression.java 12 Sep 2004 09:25:14 -0000 1.3 *************** *** 40,44 **** public final static FunctionSignature signature = new FunctionSignature( ! new QName("to", BUILTIN_FUNCTION_NS), new SequenceType[] { new SequenceType(Type.INTEGER, Cardinality.EXACTLY_ONE), --- 40,44 ---- public final static FunctionSignature signature = new FunctionSignature( ! new QName("to", Module.BUILTIN_FUNCTION_NS), new SequenceType[] { new SequenceType(Type.INTEGER, Cardinality.EXACTLY_ONE), Index: XQueryWatchDog.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/xquery/XQueryWatchDog.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** XQueryWatchDog.java 22 Jun 2004 08:14:16 -0000 1.2 --- XQueryWatchDog.java 12 Sep 2004 09:25:14 -0000 1.3 *************** *** 50,58 **** public XQueryWatchDog(XQueryContext context) { this.context = context; ! configure(); startTime = System.currentTimeMillis(); } ! private void configure() { try { Configuration conf = BrokerPool.getInstance().getConfiguration(); --- 50,58 ---- public XQueryWatchDog(XQueryContext context) { this.context = context; ! configureDefaults(); startTime = System.currentTimeMillis(); } ! private void configureDefaults() { try { Configuration conf = BrokerPool.getInstance().getConfiguration(); *************** *** 70,73 **** --- 70,97 ---- } + public void setTimeoutFromPragma(Pragma pragma) throws XPathException { + String[] contents = pragma.tokenizeContents(); + if(contents.length != 1) + throw new XPathException("Pragma 'timeout' should have exactly one parameter: the timeout value."); + try { + timeout = Long.parseLong(contents[0]); + } catch (NumberFormatException e) { + throw new XPathException("Error parsing timeout value in pragma " + pragma.getQName().toString()); + } + LOG.debug("timeout set from pragma: " + timeout + "ms."); + } + + public void setMaxNodesFromPragma(Pragma pragma) throws XPathException { + String[] contents = pragma.tokenizeContents(); + if(contents.length != 1) + throw new XPathException("Pragma 'output-size-limit' should have exactly one parameter: the timeout value."); + try { + maxNodesLimit = Integer.parseInt(contents[0]); + } catch (NumberFormatException e) { + throw new XPathException("Error parsing size-limit value in pragma " + pragma.getQName().toString()); + } + LOG.debug("output-size-limit set from pragma: " + maxNodesLimit); + } + public void proceed(Expression expr) throws TerminatedException { final long elapsed = System.currentTimeMillis() - startTime; Index: Variable.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/xquery/Variable.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Variable.java 5 May 2004 18:05:41 -0000 1.2 --- Variable.java 12 Sep 2004 09:25:14 -0000 1.3 *************** *** 34,42 **** --- 34,54 ---- public class Variable { + // the name of the variable private QName qname; + + // the current value assigned to the variable private Sequence value = null; + + // the context position of this variable in the local variable stack + // this can be used to determine if a variable has been declared + // before another private int positionInStack = 0; + + // the cardinality of this variable private int cardinality = Cardinality.ZERO_OR_MORE; + + // the context document set private DocumentSet contextDocs = null; + /** * --- NEW FILE: Pragma.java --- /* * eXist Open Source Native XML Database * Copyright (C) 2001-04 Wolfgang M. Meier (wol...@ex...) * and others (see http://exist-db.org) * * This program 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 * of the License, or (at your option) any later version. * * This program 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 program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Id: Pragma.java,v 1.1 2004/09/12 09:25:14 wolfgang_m Exp $ */ package org.exist.xquery; import java.util.StringTokenizer; import org.apache.oro.text.perl.Perl5Util; import org.apache.oro.text.regex.MalformedPatternException; import org.apache.oro.text.regex.MatchResult; import org.apache.oro.text.regex.Pattern; import org.apache.oro.text.regex.Perl5Compiler; import org.apache.oro.text.regex.Perl5Matcher; import org.exist.dom.QName; /** * Represents an XQuery pragma. Pragmas are used to pass * vendor-specific information to the XQuery engine. They may * occur anywhere inside the query. The specified pragmas can * be accessed through method * {@link org.exist.xquery.XQueryContext#getPragma(QName)}. * * @author wolf */ public class Pragma { public final static QName TIMEOUT_QNAME = new QName("timeout", XQueryContext.EXIST_NS); public final static QName OUTPUT_SIZE_QNAME = new QName("output-size-limit", XQueryContext.EXIST_NS); public final static QName SERIALIZE_QNAME = new QName("serialize", XQueryContext.EXIST_NS); private final static String paramPattern = "\\s*([\\w\\.-]+)\\s*=\\s*('[^']*'|\"[^\"]*\"|[^\\s]+)"; private static Perl5Matcher matcher = new Perl5Matcher(); private static Pattern pattern; static { Perl5Compiler compiler = new Perl5Compiler(); try { pattern = compiler.compile(paramPattern); } catch (MalformedPatternException e) { throw new RuntimeException(e); } } private QName qname; private String contents; public Pragma(QName qname, String contents) { this.qname = qname; this.contents = contents; } public QName getQName() { return qname; } public String getContents() { return contents; } public String[] tokenizeContents() { if(contents == null) return new String[0]; StringTokenizer tok = new StringTokenizer(contents, " \r\t\n"); String[] items = new String[tok.countTokens()]; for(int i = 0; tok.hasMoreTokens(); i++) { items[i] = tok.nextToken(); } return items; } public static synchronized String[] parseKeyValuePair(String s) { if(matcher.matches(s, pattern)) { MatchResult result = matcher.getMatch(); String value = result.group(2); if(value.charAt(0) == '\'' || value.charAt(0) == '"') value = value.substring(1, value.length() - 1); return new String[] { result.group(1), value }; } return null; } } Index: Predicate.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/xquery/Predicate.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** Predicate.java 3 Jun 2004 10:31:36 -0000 1.3 --- Predicate.java 12 Sep 2004 09:25:14 -0000 1.4 *************** *** 94,99 **** for (Iterator i = nodes.iterator(); i.hasNext(); count++) { current = (NodeProxy) i.next(); ! if(lastDoc == null || current.doc != lastDoc) { ! lastDoc = current.doc; sizeHint = nodes.getSizeHint(lastDoc); } --- 94,99 ---- for (Iterator i = nodes.iterator(); i.hasNext(); count++) { current = (NodeProxy) i.next(); ! if(lastDoc == null || current.getDocument() != lastDoc) { ! lastDoc = current.getDocument(); sizeHint = nodes.getSizeHint(lastDoc); } Index: BindingExpression.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/xquery/BindingExpression.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** BindingExpression.java 15 Jul 2004 19:41:04 -0000 1.5 --- BindingExpression.java 12 Sep 2004 09:25:14 -0000 1.6 *************** *** 129,134 **** for (Iterator i = nodes.iterator(); i.hasNext(); count++) { current = (NodeProxy) i.next(); ! if(lastDoc == null || current.doc != lastDoc) { ! lastDoc = current.doc; sizeHint = nodes.getSizeHint(lastDoc); } --- 129,134 ---- for (Iterator i = nodes.iterator(); i.hasNext(); count++) { current = (NodeProxy) i.next(); ! if(lastDoc == null || current.getDocument() != lastDoc) { ! lastDoc = current.getDocument(); sizeHint = nodes.getSizeHint(lastDoc); } *************** *** 170,173 **** --- 170,194 ---- } + /** + * Check all order specs to see if we can process them in + * one single step. In general, this is possible if all order + * expressions return nodes. + * + * @return + */ + protected boolean checkOrderSpecs(Sequence in) { + if(orderSpecs == null) + return false; + if(!Type.subTypeOf(in.getItemType(), Type.NODE)) + return false; + for(int i = 0; i < orderSpecs.length; i++) { + Expression expr = orderSpecs[i].getSortExpression(); + if(!Type.subTypeOf(expr.returnsType(), Type.NODE) || + (expr.getDependencies() & Dependency.CONTEXT_ITEM ) != 0) + return false; + } + return true; + } + /* (non-Javadoc) * @see org.exist.xquery.Expression#preselect(org.exist.dom.DocumentSet, org.exist.xquery.StaticContext) Index: FunctionFactory.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/xquery/FunctionFactory.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** FunctionFactory.java 4 Aug 2004 19:00:05 -0000 1.5 --- FunctionFactory.java 12 Sep 2004 09:25:14 -0000 1.6 *************** *** 59,63 **** String uri = qname.getNamespaceURI(); Expression step = null; ! if(uri.equals(Function.BUILTIN_FUNCTION_NS)) { // near(node-set, string) if (local.equals("near")) { --- 59,63 ---- String uri = qname.getNamespaceURI(); Expression step = null; ! if(uri.equals(Module.BUILTIN_FUNCTION_NS)) { // near(node-set, string) if (local.equals("near")) { Index: DocumentConstructor.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/xquery/DocumentConstructor.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** DocumentConstructor.java 27 Jun 2004 21:10:06 -0000 1.1 --- DocumentConstructor.java 12 Sep 2004 09:25:14 -0000 1.2 *************** *** 25,29 **** import org.exist.memtree.MemTreeBuilder; import org.exist.memtree.NodeImpl; ! import org.exist.memtree.Receiver; import org.exist.xquery.value.Item; import org.exist.xquery.value.Sequence; --- 25,29 ---- import org.exist.memtree.MemTreeBuilder; import org.exist.memtree.NodeImpl; ! import org.exist.memtree.DocumentBuilderReceiver; import org.exist.xquery.value.Item; import org.exist.xquery.value.Sequence; *************** *** 60,64 **** context.pushDocumentContext(); MemTreeBuilder builder = context.getDocumentBuilder(); ! Receiver receiver = new Receiver(builder); if(contentSeq.getLength() == 0) --- 60,64 ---- context.pushDocumentContext(); MemTreeBuilder builder = context.getDocumentBuilder(); ! DocumentBuilderReceiver receiver = new DocumentBuilderReceiver(builder); if(contentSeq.getLength() == 0) Index: DescendantOrSelfSelector.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/xquery/DescendantOrSelfSelector.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** DescendantOrSelfSelector.java 25 Mar 2004 12:50:50 -0000 1.1 --- DescendantOrSelfSelector.java 12 Sep 2004 09:25:14 -0000 1.2 *************** *** 41,45 **** public boolean match(NodeProxy node) { NodeProxy p; ! if((p = context.parentWithChild(node.doc, node.gid, false, true, -1)) != null) { if (rememberContext) node.addContextNode(p); --- 41,45 ---- public boolean match(NodeProxy node) { NodeProxy p; ! if((p = context.parentWithChild(node.getDocument(), node.gid, false, true, -1)) != null) { if (rememberContext) node.addContextNode(p); Index: EnclosedExpr.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/xquery/EnclosedExpr.java,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** EnclosedExpr.java 28 May 2004 10:54:13 -0000 1.6 --- EnclosedExpr.java 12 Sep 2004 09:25:14 -0000 1.7 *************** *** 24,28 **** import org.exist.memtree.MemTreeBuilder; ! import org.exist.memtree.Receiver; import org.exist.xquery.value.Item; import org.exist.xquery.value.Sequence; --- 24,28 ---- import org.exist.memtree.MemTreeBuilder; ! import org.exist.memtree.DocumentBuilderReceiver; import org.exist.xquery.value.Item; import org.exist.xquery.value.Sequence; *************** *** 59,63 **** // create the output MemTreeBuilder builder = context.getDocumentBuilder(); ! Receiver receiver = new Receiver(builder); start = System.currentTimeMillis(); try { --- 59,63 ---- // create the output MemTreeBuilder builder = context.getDocumentBuilder(); ! DocumentBuilderReceiver receiver = new DocumentBuilderReceiver(builder); start = System.currentTimeMillis(); try { Index: XQuery.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/xquery/XQuery.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** XQuery.java 8 Aug 2004 19:03:26 -0000 1.4 --- XQuery.java 12 Sep 2004 09:25:14 -0000 1.5 *************** *** 72,76 **** public CompiledXQuery compile(XQueryContext context, Reader reader) throws XPathException { long start = System.currentTimeMillis(); ! XQueryLexer lexer = new XQueryLexer(reader); XQueryParser parser = new XQueryParser(lexer); XQueryTreeParser treeParser = new XQueryTreeParser(context); --- 72,76 ---- public CompiledXQuery compile(XQueryContext context, Reader reader) throws XPathException { long start = System.currentTimeMillis(); ! XQueryLexer lexer = new XQueryLexer(context, reader); XQueryParser parser = new XQueryParser(lexer); XQueryTreeParser treeParser = new XQueryTreeParser(context); Index: LocationStep.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/xquery/LocationStep.java,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** LocationStep.java 3 Aug 2004 15:25:59 -0000 1.15 --- LocationStep.java 12 Sep 2004 09:25:14 -0000 1.16 *************** *** 64,77 **** super(context, axis, test); } - - /* (non-Javadoc) - * @see org.exist.xquery.Step#returnsType() - */ - // public int returnsType() { - // if(axis == Constants.SELF_AXIS) - // return Type.ITEM; - // else - // return Type.NODE; - // } /* (non-Javadoc) --- 64,67 ---- *************** *** 114,117 **** --- 104,108 ---- if(!((NodeSet)contextSequence).hasChanged(timestamp)) { // LOG.debug("returning cached result"); + cachedResult.setIsCached(true); return (predicates.size() == 0) *************** *** 380,388 **** if (axis == Constants.ANCESTOR_SELF_AXIS && test.matches(p)) result.add( ! new NodeProxy(p.doc, p.gid, p.getInternalAddress())); ! while ((p.gid = XMLUtil.getParentId(p.doc, p.gid)) > 0) { p.nodeType = Node.ELEMENT_NODE; if (test.matches(p)) ! result.add(new NodeProxy(p.doc, p.gid)); } } --- 371,379 ---- if (axis == Constants.ANCESTOR_SELF_AXIS && test.matches(p)) result.add( ! new NodeProxy(p.getDocument(), p.gid, p.getInternalAddress())); ! while ((p.gid = XMLUtil.getParentId(p.getDocument(), p.gid)) > 0) { p.nodeType = Node.ELEMENT_NODE; if (test.matches(p)) ! result.add(new NodeProxy(p.getDocument(), p.gid)); } } --- NEW FILE: LocalVariable.java --- /* * eXist Open Source Native XML Database * Copyright (C) 2001-04 Wolfgang M. Meier (wol...@ex...) * and others (see http://exist-db.org) * * This program 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 * of the License, or (at your option) any later version. * * This program 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 program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Id: LocalVariable.java,v 1.1 2004/09/12 09:25:14 wolfgang_m Exp $ */ package org.exist.xquery; import org.exist.dom.QName; /** * Represents a local variable as declared by for and let. * * Local variables are stored as a linked list. * * @author wolf */ public class LocalVariable extends Variable { protected LocalVariable before = null; protected LocalVariable after = null; public LocalVariable(QName qname) { super(qname); } public void addAfter(LocalVariable var) { this.after = var; var.before = this; } } Index: AbstractExpression.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/xquery/AbstractExpression.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** AbstractExpression.java 5 May 2004 18:05:41 -0000 1.3 --- AbstractExpression.java 12 Sep 2004 09:25:14 -0000 1.4 *************** *** 23,31 **** import org.exist.dom.DocumentSet; - import org.exist.dom.NodeProxy; import org.exist.xquery.parser.XQueryAST; import org.exist.xquery.value.Item; import org.exist.xquery.value.Sequence; - import org.exist.xquery.value.SequenceIterator; public abstract class AbstractExpression implements Expression { --- 23,29 ---- *************** *** 82,94 **** } - public final static void setContext(Sequence seq) { - Item next; - for (SequenceIterator i = seq.unorderedIterator(); i.hasNext();) { - next = i.nextItem(); - if (next instanceof NodeProxy) - ((NodeProxy) next).addContextNode((NodeProxy) next); - } - } - /* (non-Javadoc) --- 80,83 ---- Index: ForExpr.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/xquery/ForExpr.java,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** ForExpr.java 10 Aug 2004 20:27:18 -0000 1.7 --- ForExpr.java 12 Sep 2004 09:25:14 -0000 1.8 *************** *** 30,33 **** --- 30,34 ---- import org.exist.xquery.value.Item; import org.exist.xquery.value.OrderedValueSequence; + import org.exist.xquery.value.PreorderedValueSequence; import org.exist.xquery.value.Sequence; import org.exist.xquery.value.SequenceIterator; *************** *** 60,100 **** Sequence resultSequence) throws XPathException { ! context.pushLocalContext(false); ! // declare the variable ! Variable var = new Variable(QName.parse(context, varName)); context.declareVariable(var); ! // declare positional variable ! Variable at = null; if(positionalVariable != null) { ! at = new Variable(QName.parse(context, positionalVariable)); context.declareVariable(at); } ! // evaluate the "in" expression Sequence in = inputSequence.eval(null, null); ! // assign to the bound variable var.setValue(in); if(in instanceof NodeSet) { DocumentSet contextDocs = ((NodeSet)in).getDocumentSet(); var.setContextDocs(contextDocs); } if(whereExpr != null) { whereExpr.setInPredicate(true); ! setContext(in); } boolean fastExec = whereExpr != null && ( whereExpr.getDependencies() & Dependency.CONTEXT_ITEM ) == 0 && at == null && in.getItemType() == Type.NODE; ! if(fastExec) { ! LOG.debug("fast evaluation mode"); in = applyWhereExpression(in); } ! // if there's an order by clause, wrap the result into ! // an OrderedValueSequence if(resultSequence == null) { ! if(orderSpecs != null) resultSequence = new OrderedValueSequence(orderSpecs, in.getLength()); --- 61,128 ---- Sequence resultSequence) throws XPathException { ! // Save the local variable stack ! LocalVariable mark = context.markLocalVariables(); ! ! // Declare the iteration variable ! LocalVariable var = new LocalVariable(QName.parse(context, varName, null)); context.declareVariable(var); ! // Declare positional variable ! LocalVariable at = null; if(positionalVariable != null) { ! at = new LocalVariable(QName.parse(context, positionalVariable, null)); context.declareVariable(at); } ! // Evaluate the "in" expression Sequence in = inputSequence.eval(null, null); ! ! // Assign the whole input sequence to the bound variable. ! // This is required if we process the "where" or "order by" clause ! // in one step. var.setValue(in); + + // Save the current context document set to the variable as a hint + // for path expressions occurring in the "return" clause. if(in instanceof NodeSet) { DocumentSet contextDocs = ((NodeSet)in).getDocumentSet(); var.setContextDocs(contextDocs); } + + // Check if we can speed up the processing of the "order by" clause. + boolean fastOrderBy = false; // checkOrderSpecs(in); + if(whereExpr != null) { whereExpr.setInPredicate(true); ! if(!(in.isCached() || fastOrderBy)) ! setContext(in); } + + // See if we can process the "where" clause in a single step (instead of + // calling the where expression for each item in the input sequence) + // This is possible if the input sequence is a node set and has no + // dependencies on the current context item. boolean fastExec = whereExpr != null && ( whereExpr.getDependencies() & Dependency.CONTEXT_ITEM ) == 0 && at == null && in.getItemType() == Type.NODE; ! ! // If possible, apply the where expression ahead of the iteration if(fastExec) { ! // LOG.debug("fast evaluation mode"); in = applyWhereExpression(in); } ! ! // PreorderedValueSequence applies the order specs to all items ! // in one single processing step ! if(fastOrderBy) { ! in = new PreorderedValueSequence(orderSpecs, in); ! } ! ! // Otherwise, if there's an order by clause, wrap the result into ! // an OrderedValueSequence. OrderedValueSequence will compute ! // order expressions for every item when it is added to the result sequence. if(resultSequence == null) { ! if(orderSpecs != null && !fastOrderBy) resultSequence = new OrderedValueSequence(orderSpecs, in.getLength()); *************** *** 108,112 **** if(positionalVariable != null) at.setValue(atVal); ! // loop through each variable binding for (SequenceIterator i = in.iterate(); i.hasNext(); p++) { context.proceed(this); --- 136,141 ---- if(positionalVariable != null) at.setValue(atVal); ! ! // Loop through each variable binding for (SequenceIterator i = in.iterate(); i.hasNext(); p++) { context.proceed(this); *************** *** 122,128 **** --- 151,159 ---- // check sequence type sequenceType.checkType(contextItem.getType()); + // set variable value to current item var.setValue(contextSequence); val = contextSequence; + // check optional where clause if (whereExpr != null && (!fastExec)) { *************** *** 148,157 **** } } ! if(orderSpecs != null) ((OrderedValueSequence)resultSequence).sort(); ! context.popLocalContext(); return resultSequence; } ! /* (non-Javadoc) * @see org.exist.xquery.Expression#pprint() --- 179,190 ---- } } ! if(orderSpecs != null && !fastOrderBy) ((OrderedValueSequence)resultSequence).sort(); ! ! // restore the local variable stack ! context.popLocalVariables(mark); return resultSequence; } ! /* (non-Javadoc) * @see org.exist.xquery.Expression#pprint() *************** *** 187,189 **** --- 220,231 ---- return Type.ITEM; } + + public final static void setContext(Sequence seq) { + Item next; + for (SequenceIterator i = seq.unorderedIterator(); i.hasNext();) { + next = i.nextItem(); + if (next instanceof NodeProxy) + ((NodeProxy) next).addContextNode((NodeProxy) next); + } + } } Index: FunctionCall.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/xquery/FunctionCall.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** FunctionCall.java 28 May 2004 10:54:12 -0000 1.4 --- FunctionCall.java 12 Sep 2004 09:25:14 -0000 1.5 *************** *** 106,110 **** functionDef.setArguments(seq); ! context.pushLocalContext(true); try { Sequence returnSeq = expression.eval(contextSequence, contextItem); --- 106,111 ---- functionDef.setArguments(seq); ! // context.pushLocalContext(true); ! LocalVariable mark = context.markLocalVariables(); try { Sequence returnSeq = expression.eval(contextSequence, contextItem); *************** *** 115,119 **** throw e; } finally { ! context.popLocalContext(); } } --- 116,121 ---- throw e; } finally { ! // context.popLocalContext(); ! context.popLocalVariables(mark); } } Index: VariableDeclaration.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/xquery/VariableDeclaration.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** VariableDeclaration.java 28 May 2004 10:54:13 -0000 1.2 --- VariableDeclaration.java 12 Sep 2004 09:25:14 -0000 1.3 *************** *** 66,70 **** Item contextItem) throws XPathException { ! QName qn = QName.parse(context, qname); Module myModule = context.getModule(qn.getNamespaceURI()); --- 66,70 ---- Item contextItem) throws XPathException { ! QName qn = QName.parse(context, qname, null); Module myModule = context.getModule(qn.getNamespaceURI()); Index: XPathUtil.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/xquery/XPathUtil.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** XPathUtil.java 17 May 2004 09:59:42 -0000 1.3 --- XPathUtil.java 12 Sep 2004 09:25:14 -0000 1.4 *************** *** 30,34 **** import org.exist.memtree.MemTreeBuilder; import org.exist.memtree.NodeImpl; ! import org.exist.memtree.Receiver; import org.exist.util.serializer.DOMStreamer; import org.exist.util.serializer.DOMStreamerPool; --- 30,34 ---- import org.exist.memtree.MemTreeBuilder; import org.exist.memtree.NodeImpl; ! import org.exist.memtree.DocumentBuilderReceiver; import org.exist.util.serializer.DOMStreamer; import org.exist.util.serializer.DOMStreamerPool; *************** *** 66,70 **** return new StringValue((String) obj); else if (obj instanceof Boolean) ! return new BooleanValue(((Boolean) obj).booleanValue()); else if (obj instanceof Float) return new FloatValue(((Float) obj).floatValue()); --- 66,70 ---- return new StringValue((String) obj); else if (obj instanceof Boolean) ! return BooleanValue.valueOf(((Boolean) obj).booleanValue()); else if (obj instanceof Float) return new FloatValue(((Float) obj).floatValue()); *************** *** 99,103 **** MemTreeBuilder builder = new MemTreeBuilder(); builder.startDocument(); ! Receiver receiver = new Receiver(builder); streamer.setContentHandler(receiver); ValueSequence seq = new ValueSequence(); --- 99,103 ---- MemTreeBuilder builder = new MemTreeBuilder(); builder.startDocument(); ! DocumentBuilderReceiver receiver = new DocumentBuilderReceiver(builder); streamer.setContentHandler(receiver); ValueSequence seq = new ValueSequence(); *************** *** 122,126 **** MemTreeBuilder builder = new MemTreeBuilder(); builder.startDocument(); ! Receiver receiver = new Receiver(builder); streamer.setContentHandler(receiver); streamer.serialize((Node)obj, false); --- 122,126 ---- MemTreeBuilder builder = new MemTreeBuilder(); builder.startDocument(); ! DocumentBuilderReceiver receiver = new DocumentBuilderReceiver(builder); streamer.setContentHandler(receiver); streamer.serialize((Node)obj, false); |