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("'",$result,"'")) 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
