[MarkLogic Dev General] Referencing astringvariablewithincts:search

Danny Sokolsky dsokolsky at marklogic.com
Tue Jun 26 19:30:20 PDT 2007

While xdmp:eval is fine and useful for many things, there are a few
reasons I know of to avoid xdmp:eval.

First, xdmp:eval starts a completely new context, which means the new
query has to be parsed from scratch and evaluated.

Second, because it always starts a new context, and because the XQuery
main module does not exist on the filesystem or in a database, the
xdmp:eval call cannot be cached (and therefore must incur that overhead
each time it is called).  Therefore it is more efficient to call

These two issues can affect performance, although they might still
perform fine for many applications.

The other reason I know of, and perhaps a more serious one, is that it
can potentially open you up to things analagous to SQL Injection Bugs
(google returns over a million hits on this topic).  These are bugs
which can potentially allow malicious users to issue arbitrary queries
into your system.

I hope that helps some.

-----Original Message-----
From: general-bounces at developer.marklogic.com
[mailto:general-bounces at developer.marklogic.com] On Behalf Of Mattio
Sent: Tuesday, June 26, 2007 7:15 PM
To: General Mark Logic Developer Discussion
Subject: Re: [MarkLogic Dev General] Referencing

Sorry.  One more follow-up question.

This discussion started from my assumption that xdmp:eval() works but it
may not be the best way to go, and your feedback implies the same. Why
is that?  What's the issue with using xdmp:eval()?  I've been looking in
the docs and I found anything yet.

On 6/26/07, Danny Sokolsky <dsokolsky at marklogic.com> wrote:
> You cannot pass that string in via XCC and have it used as a 
> cts:query.
> To make this work, you will have to move the code that parses your 
> input into a cts:query  from your .net/java code into your XQuery 
> code.  For example, you can pass in two string variables from the 
> .net/java side:
>  *  "or" to signify it is an or-query.
>  *  "blues jazz" for the words to be queried.
> Your XQuery module on the MarkLogic Server side might then look 
> something like this (this is an extremely simple query 
> parser/generator that simply tokenizes the input on spaces):
>  define variable $query-type as xs:string external
>  define variable $query as xs:string external
>  let $query-tokens := fn:tokenize(fn:normalize-space($query), " ")  
> let $ctsquery :=
>      for $x in $query-tokens
>      return
>      cts:word-query($x, ("case-insensitive", "diacritic-insensitive") 
> )  let $newquery :=
>     if ( $query-type = "or" )
>     then cts:or-query($ctsquery)
>     else cts:and-query($ctsquery)
>  return
>  <results>
>    <cts-query-expr>{$newquery}</cts-query-expr>
>    <search>{xdmp:estimate(cts:search(doc(), $newquery))}</search>  
> </results>
> and you can run this code with something like this:
>  xdmp:invoke("invoke.xqy", ((xs:QName("query-type"), "or"),
>                           (xs:QName("query"), "blues jazz")))
> The other alternative you have is to construct the entire search on 
> the .net/java side, including the cts:search and the cts:query, and 
> then send in the whole query to execute via xcc.
> -Danny
General mailing list
General at developer.marklogic.com

More information about the General mailing list