Extensions to the XQuery Processing Model


To support updates, DataDirect XQuery extends the XQuery processing model, as discussed in this section.

Extension to Function Declaration

The syntax of an XQuery function declaration is extended to include an optional keyword, updating, as shown in the following BNF syntax for a function declaration:

FunctionDecl := "declare" "updating"? "function" QName
                "(" ParamList? ") ("as" SequenceType)?
                 (EnclosedExpr | "external") 

If the keyword "updating" is not specified, the semantics are as specified in XQuery 1.0. If the keyword "updating" is specified, the semantics are as follows:

Here is an example of a declaration for a user-defined updating function:

declare updating function local:delete($rows as element()*) 
{ 
ddtek:sql-delete($rows) 
}; 
local:delete(collection(’test’)/test) 

Extensions to XQuery Expressions

The basic building block of XQuery is an expression. Because of the update capability of DataDirect XQuery, two types of expressions exist for XQueries when using DataDirect XQuery:

An expression is either updating or non-updating; therefore, an XQuery does either an update or returns a result, not both. The following is an example of an updating expression in the Return clause of a FLWOR expression:

for $u in collection("users")//users 
return 
  ddtek:sql-insert ("users2", "userid", $u/userid, name", $u/name) 

Updating expressions can occur only in the following XQuery expressions:

All other XQuery expressions cannot contain an operand that is an updating expression; if it does, a static error is raised.

FLWOR Expressions

To support updates of relational databases, DataDirect XQuery extends the semantics of a FLWOR expression in the following ways:

The following example shows a FLWOR expression that is an updating expression:

for $u in collection("USERS")//USERS 
return 
  ddtek:sql-insert ("USERS2", "USERID", $u/USERID, "NAME", $u/NAME) 

Typeswitch Expressions

To support updates of relational databases, DataDirect XQuery extends the semantics of a typeswitch expression in the following ways:

The following example shows a Typeswitch expression that is an updating expression:

typeswitch($node) 
case $a as element() return ddtek:sql-insert("holdings", "userid",
  $a/name, "stockticker", $a/ticker, "shares", $a/amount) 
default return ddtek:sql-insert("holdings", "userid", $node, "stockticker",
   "PRGS", "shares", 200) 

Conditional Expressions

To support updates of relational databases, DataDirect XQuery extends the semantics of a conditional expression in the following ways:

For example, if you are unsure whether an existing row needs to be updated with the new quantity, or if a new row needs to be created, you can use a simple conditional expression:

let $previousHolding := collection("holdings")/holdings[ 
    userid = "minollo" and stockticker = "PRGS"] 
return 
    if ($previousHolding) then 
        ddtek:sql-update($previousHolding, 
            "shares", $previousHolding/shares + 500) 
    else 
        ddtek:sql-insert("holdings", "userid", "Minollo", 
            "stockticker", "PRGS", "shares", 100)  
Comma Expressions

To support updates of relational databases, DataDirect XQuery extends the semantics of a comma expression in the following way:

If any operand of a comma expression is an updating expression, the comma expression is an updating expression. In this case, each of the operands must contain either:

Parenthesized Expressions

To support updates of relational databases, DataDirect XQuery extends the semantics of a parenthesized expression in the following way: If any operand of a parenthesized expression is an updating expression, the parenthesized expression is an updating expression.

Parentheses can be used to enforce a particular evaluation order in expressions that contain multiple operators.

Snapshot Semantics

The concept of snapshot semantics is introduced with the new functionality of updating relational database tables through DataDirect XQuery. DataDirect XQuery evaluates all updating and non-updating expressions of an XQuery and creates a virtual "snapshot" of the queried XDM instances before any updates are applied to the underlying database table, which is referred to as snapshot semantics. Then, this snapshot is used to execute all non-updating expressions before any updating expressions are executed. For example, if you have an XQuery that defines a non-updating expression, an updating expression, and then another non-updating expression, you will not see the update of the data for the second non-updating expression because both of the non-updating expressions are executed before the updating expression is executed. Snapshot semantics is supported on a per query basis.