A GlobalVariableDefinition gets linked to all the variable references that reference that variable, which means that it's not possible for the same GlobalVariableDefinition to be used with more than one query (whether or not they use the same StaticQueryContext). I'll make sure this limitation is documented in future.
 
Michael Kay
http://www.saxonica.com/


From: saxon-help-bounces@lists.sourceforge.net [mailto:saxon-help-bounces@lists.sourceforge.net] On Behalf Of Ian Carr
Sent: 01 September 2006 14:04
To: saxon-help@lists.sourceforge.net
Subject: [saxon] Programatic declaration of global variables

A colleague is attempting to add support for parameter like global variables to our application.

 

He is getting an exception during compilation not of the first query to reference the variable, but on trying to compile a subsequent query in the same StaticQueryContext.

 

The exception is:

 

Exception in thread "main" java.lang.IllegalStateException: Variable $a has not been fixed up

      at net.sf.saxon.expr.VariableReference.typeCheck(VariableReference.java:80)

      at net.sf.saxon.query.XQueryExpression.<init>(XQueryExpression.java:64)

      at net.sf.saxon.query.QueryParser.makeXQueryExpression(QueryParser.java:109)

      at net.sf.saxon.query.StaticQueryContext.compileQuery(StaticQueryContext.java:468)

      at fsl.gr.xquery.XQueryTest.testVariables(XQueryTest.java:100)

      at fsl.gr.xquery.XQueryTest.main(XQueryTest.java:49)

 

We can generate the same exception from the following mock up of the actual code scenario:

 

      public static void testVariables() throws XPathException {

 

        final Configuration config = new Configuration();

        final StaticQueryContext sqc = new StaticQueryContext(config);

        final DynamicQueryContext dynamicContext = new DynamicQueryContext(config);

 

        GlobalVariableDefinition gvd = new GlobalVariableDefinition();

            gvd.setVariableName("a");

            gvd.setIsParameter(true);

            gvd.setRequiredType(SequenceType.SINGLE_STRING);

           

            int i = sqc.getNamePool().allocate("", "", "a");

            gvd.setNameCode(i);

           

            sqc.declareVariable(gvd);

           

            dynamicContext.setParameter("a", "hello");

 

            StaticQueryContext copy1 = sqc.copy();

            XQueryExpression exp = copy1.compileQuery("declare namespace gr=\"java:fsl.gr.xquery.function.Functions\";declare namespace fbs=\"http://www.focus-solutions.co.uk/FPAQ/1.1\";1");

           

            StaticQueryContext copy2 = sqc.copy();

            XQueryExpression exp1 = copy2.compileQuery("declare namespace gr=\"java:fsl.gr.xquery.function.Functions\";declare namespace fbs=\"http://www.focus-solutions.co.uk/FPAQ/1.1\";$a");

 

            /*

            XQueryExpression exp = sqc.compileQuery("declare namespace gr=\"java:fsl.gr.xquery.function.Functions\";declare namespace fbs=\"http://www.focus-solutions.co.uk/FPAQ/1.1\";1");

            XQueryExpression exp1 = sqc.compileQuery("declare namespace gr=\"java:fsl.gr.xquery.function.Functions\";declare namespace fbs=\"http://www.focus-solutions.co.uk/FPAQ/1.1\";$a");

            */

 

        final Properties props = new Properties();

        props.setProperty(OutputKeys.METHOD, "xml");

        props.setProperty(OutputKeys.INDENT, "yes");

       

        System.out.print("RESULT:[");

        exp.run(dynamicContext, new StreamResult(System.out), props);

        System.out.println("]");

      }

 

As you can see we are basically trying to compile the same query text twice. Our understanding was that the compile operation cloned the static context to avoid pollution of the original. And hence expected to be able to perform the same compile operation on the original many times?  As you can see from the currently ‘commented in’ code we have tried to do this explicitly ( ‘commented out’ version implicitly ) but receive the same exception.

 

Any help gratefully received!

 

Ian