Uploaded image for project: 'Camel'
  1. Camel
  2. CAMEL-12154

Camel does not set Saxon parameters in a XQuery 3.0 compatible way

    XMLWordPrintableJSON

    Details

    • Type: Improvement
    • Status: Resolved
    • Priority: Minor
    • Resolution: Fixed
    • Affects Version/s: 2.18.5, 2.19.4, 2.20.1
    • Fix Version/s: 2.19.5, 2.20.2, 2.21.0
    • Component/s: camel-saxon
    • Labels:
      None
    • Environment:

      any

    • Estimated Complexity:
      Unknown

      Description

      When injecting parameters into the Saxon XQuery engine, the Camel component is not sophisticated enough to inject the parameter as the right type for Saxon to bind it properly.

      Let's say we have a XQuery 3.0 compliant variable definition:

      declare variable $extParam as xs:boolean external := false();
      

      and we set a property on the exchange

      exchange.setProperty("extParam ", true);
      

      our XQuery execution will fail with the following error as the value bound into Saxon is not a Boolean type:

      Type error on line 3 column 5 
       XPTY0004: Required item type of value of variable $extParam is xs:boolean; supplied value
       has item type xs:string
      

      The part(s) that need to get more sophisticated are:

      At the bare minimum probably should be supporting to set query parameters for all the basic types like string, boolean, int, decimal etc.

      I was thinking of a simple if then else block to check the content type and then call the appropriate Saxon value wrapper but am a bit unsure as the body could be simple type or DOM or Source or something else depending on the marshalling that is going on beforehand.

      Here a very basic setup that shows what is happening when Saxon parameters are just bound as Object values:

      package com.virginaustralia.bind.xquery;
      
      import static org.junit.Assert.*;
      import org.junit.Before;
      import org.junit.Test;
      
      import net.sf.saxon.Configuration;
      
      import net.sf.saxon.om.Item;
      import net.sf.saxon.om.StructuredQName;
      
      import net.sf.saxon.query.DynamicQueryContext;
      import net.sf.saxon.query.XQueryExpression;
      
      import net.sf.saxon.value.BooleanValue;
      import net.sf.saxon.value.ObjectValue;
      
      public class ParameterDynamicTest {
      
      private static final String TEST_QUERY = new StringBuilder()
       .append("xquery version \"3.0\" encoding \"UTF-8\";\n")
       .append("declare variable $extParam as xs:boolean external := false();\n")
       .append("if($extParam) then(true()) else (false())")
       .toString();
      
      Configuration conf = new Configuration();
      
      XQueryExpression query;
      
      DynamicQueryContext context;
      
      @Before
       public void setup() throws Exception {
       conf.setCompileWithTracing(true);
       query = conf.newStaticQueryContext().compileQuery(TEST_QUERY);
       context = new DynamicQueryContext(conf);
       }
      
      /**
       * This is what Camel XQueryBuilder executes, which leads to a parameter binding type error.
       *
       */
       @Test
       public void testObjectParameter() throws Exception {
       context.setParameter(StructuredQName.fromClarkName("extParam"), new ObjectValue<>(true));
       Item result = query.iterator(context).next();
       assertTrue(result instanceof BooleanValue);
       assertEquals(true, ((BooleanValue) result).getBooleanValue());
       }
      
      /**
       * This is what Camel XQueryBuilder should execute to allow Saxon to bind the parameter type properly.
       */
       @Test
       public void testBooleanParameter() throws Exception {
       context.setParameter(StructuredQName.fromClarkName("extParam"), BooleanValue.TRUE);
       Item result = query.iterator(context).next();
       assertTrue(result instanceof BooleanValue);
       assertEquals(true, ((BooleanValue) result).getBooleanValue());
       }
      
      }
      

        Attachments

          Activity

            People

            • Assignee:
              davsclaus Claus Ibsen
              Reporter:
              niels.bertram Niels Bertram
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: