Rob,

Good point about the vars preventing optimization, I didn’t look too closely at 
the actual expression being evaluated.

Doing an eval/value on an expression is not necessarily bad though, the Search 
API has always done that too to allow dynamic sorting.

Also don’t be mistaken: the xdmp:value within the order by (as opposed to the 
large one) doesn’t prevent nor limit code injection. You only prevent that by 
simply not string-joining anything provided from external, or do heavy checking 
on what is being passed through. An xs:QName cast on the $element value could 
be a good check for instance, otherwise you could open a predicate, and go wild 
inside there.

Also keep in mind that the xdmp:value inside the order by would be evaluated 
for each iteration, adding more overhead than one big xdmp:value.

I do agree that plain code would be much easier to maintain, and allows for 
normal static syntax checking. I second using cts:index-order as a way to 
possibly eliminate xdmp:value altogether. It was a good thing it was added in 
MarkLogic 8..

Cheers,
Geert

From: 
<[email protected]<mailto:[email protected]>>
 on behalf of Rob Szkutak 
<[email protected]<mailto:[email protected]>>
Reply-To: MarkLogic Developer Discussion 
<[email protected]<mailto:[email protected]>>
Date: Wednesday, January 6, 2016 at 2:00 PM
To: MarkLogic Developer Discussion 
<[email protected]<mailto:[email protected]>>
Subject: Re: [MarkLogic Dev General] Unexpected token syntax error, unexpected 
Vbar_

Well, there are some caveats to that. For example, $set would need to be either 
a cts:search expression or fully searchable XPath expression. You won't get the 
optimization at all if it is referenced via a variable. 
https://docs.marklogic.com/guide/performance/order_by#id_59622 ("The search or 
XPath expression must be part of the FLWOR, not bound to a variable that is 
referenced in the FLWOR.")

So based on what I'm seeing in his shared code that optimization won't be made. 
("for $output in $outputs")

My rationale behind the recommendation was that it would be easier to debug and 
less prone to injection than a massive xdmp:value with multiple xdmp:value 
therein. I think that also ends up being worse for performance when you have 
multiple layers of xdmp:value?

I do suspect the whole thing could be refactored as a cts:search expression 
including a cts:index-order and then the results iterated through to do his 
transform. That would be the best thing :)

Best,
Rob

Rob Szkutak
Associate Consultant
MarkLogic Corporation
[email protected]<mailto:[email protected]>
Cell +1.716.562.8464
www.marklogic.com<http://www.marklogic.com>

________________________________
From: 
[email protected]<mailto:[email protected]>
 
[[email protected]<mailto:[email protected]>]
 on behalf of Geert Josten 
[[email protected]<mailto:[email protected]>]
Sent: Wednesday, January 06, 2016 6:26 AM
To: MarkLogic Developer Discussion
Subject: Re: [MarkLogic Dev General] Unexpected token syntax error, unexpected 
Vbar_

Doing an if inside the order by (good suggestion by the way) would be most 
useful if you can eliminate the need for xdmp:value entirely. Doing xdmp:value 
inside the order by sounds worse to me than doing it for the entire flwor 
statement. If you do it for the entire flwor statement, static analysis might 
be able to leverage indexes to speed up sorting..

Cheers,
Geert

From: 
<[email protected]<mailto:[email protected]>>
 on behalf of Rob Szkutak 
<[email protected]<mailto:[email protected]>>
Reply-To: MarkLogic Developer Discussion 
<[email protected]<mailto:[email protected]>>
Date: Wednesday, January 6, 2016 at 1:21 PM
To: MarkLogic Developer Discussion 
<[email protected]<mailto:[email protected]>>
Subject: Re: [MarkLogic Dev General] Unexpected token syntax error, unexpected 
Vbar_

Couple of thoughts:

1) You're not sharing your full code ($outputs and $aliases are not defined, 
for instance) . Any chance the error is in something not shown?

2) Have you checked the query you're passing into xdmp:value() to make sure 
there isn't an error in that?

Looking at your code I see this:


3) You have another syntax error at the bottom of your code. No $ before return 
$results. So there's no way this would run on either Windows or Linux ;-)

4) I wouldn't really recommend writing a query this way just to dynamically 
build an order by. I'd encourage you to use syntax like this instead (I'm using 
your variable names but you may still need to refactor this further):

for $each in $set
if($sort = 'ascending' and $sortOrder != '') then order by 
xdmp:value(fn:concat("$doc","//", $element) ascending
else if($sort = 'descending' and $sortOrder != '') then order by 
xdmp:value(fn:concat("$doc","//", $element) descending


Rob Szkutak
Associate Consultant
MarkLogic Corporation
[email protected]<mailto:[email protected]>
Cell +1.716.562.8464
www.marklogic.com<http://www.marklogic.com>

________________________________
From:[email protected]<mailto:[email protected]>
 
[[email protected]<mailto:[email protected]>]
 on behalf of Geert Josten 
[[email protected]<mailto:[email protected]>]
Sent: Wednesday, January 06, 2016 5:01 AM
To: MarkLogic Developer Discussion
Subject: Re: [MarkLogic Dev General] Unexpected token syntax error, unexpected 
Vbar_

Hi Pragya,

It surprises me that this doesn’t error on Windows. The line that you marked 
ends with ||, but from the looks of it, there is no following string operand 
that I would expect. Try removing it..

Cheers,
Geert

From: 
<[email protected]<mailto:[email protected]>>
 on behalf of "Kapoor, Pragya" 
<[email protected]<mailto:[email protected]>>
Reply-To: MarkLogic Developer Discussion 
<[email protected]<mailto:[email protected]>>
Date: Wednesday, January 6, 2016 at 9:57 AM
To: MarkLogic Developer Discussion 
<[email protected]<mailto:[email protected]>>
Subject: [MarkLogic Dev General] Unexpected token syntax error, unexpected Vbar_

Hi,

Below code is working fine on windows server, but on linux server its giving 
the error.

XDMP-UNEXPECTED: (err:XPST0003) Unexpected token syntax error, unexpected Vbar_

 let $sort as xs:string := string-join(
for $output in $outputs
let $sortOrder := $output//sort/text()
return
(if($sortOrder != '') then
let $element :=
let $path:= $output/path
let $ns := $path/@ns
let $path := fn:tokenize($path,"/")
let $elem := fn:concat($ns,":",$path[fn:last()],"[1]")
let $elemParent := fn:concat($ns,":",$path[fn:last()-1],"[1]")
return fn:concat($elemParent,"/",$elem)
return fn:concat("$doc","//", $element," ",$sortOrder)
else ()),", ")

  let $results :=
'element report {
element columns {
for $alias in $aliases
return element title {$alias}},
element results {
for $docId in $docUris
let $doc := fn:doc($docId)
let $tempResult :=
element result {
for $output in $outputs
let $element :=
let $path:= $output/path
let $elem := fn:tokenize($path,"/")[fn:last()]
let $ns := $path/@ns
return fn:concat($ns,":",$elem)


let $functions := if($output/functions) then fn:data($output/functions) else ()
let $type :=  if($output/functions) then fn:data($output/functions/@type) else 
()
let $alias := fn:data($output/columnAlias)
let $result := $doc//*[name() = $element]/text()

let $result :=
if($type eq "string") then
let $exp := fn:replace($functions,$alias,fn:concat("&apos;",$result,"&apos;"))
return xdmp:value($exp)
else
  (:let $exp := (fn:replace($functions,$alias,$result[1])):)
   (:xdmp:value("$exp"):) $result
return
if($cartesianFlag eq "false") then
element {$alias} {fn:string-join($result,";")}
else
let $resultCount := fn:count($result)
return
if($resultCount > 1 ) then for $i in $result return  element {$alias} { ($i) }
else
  element {$alias} { ($result) }
}' ||  (if($sort != '') then fn:concat("order by ",$sort) else ()) || (: error 
on this line:)
' return
if($cartesianFlag eq "false") then
$tempResult
else
for $result in $tempResult
let $_ := xdmp:set($qt, "")
return local:transform-into-result($result)
}
}'
let $results :=  xdmp:value($results)
               return results

Thanks
Pragya


"This e-mail and any attachments transmitted with it are for the sole use of 
the intended recipient(s) and may contain confidential , proprietary or 
privileged information. If you are not the intended recipient, please contact 
the sender by reply e-mail and destroy all copies of the original message. Any 
unauthorized review, use, disclosure, dissemination, forwarding, printing or 
copying of this e-mail or any action taken in reliance on this e-mail is 
strictly prohibited and may be unlawful."
_______________________________________________
General mailing list
[email protected]
Manage your subscription at: 
http://developer.marklogic.com/mailman/listinfo/general

Reply via email to