Re: XQuery Update Facility: insert as first vs. insert as last

Roel Vercammen wrote:
> There seems to be something odd in the specification of insert in
> Section 2.3 of the XQuery Update Facility WD. According to 4.a "insert
> as last" is compiled into update primitives of the form
> "upd:insertIntoAsLast", while "insert as first" does not have a
> designated update primitive.

I don't think there is an error here, but I agree that the specification 
is asymmetrical here. We were trying to keep the number of primitives 
small, but adding upd:insertIntoAsFirst() would not be a big step in 
complexity, and would make the description more orderly.  For instance, 
it would have made the asymmetry you note ore obvious. We always prefer 
to keep the number of primitives small, but this one might be worth 
adding. (Personal opinion only, as is the rest of this reply.)

> Consider the following input bound to a variable $x := <a><b/></a> 
> If I'm not mistaken, the XQuery expression 
>   insert <c/> into $x as first, insert <d/> before $x/b 
> signals an incompatibility, while the expression
>   insert <c/> into $x as last, insert <d/> after $x/b 
> does not. The reasoning for this conclusion is as follows. Suppose n_a,
> n_b, n_c and n_d are the nodes that correspond to the nodes with the
> corresponding tag name. The first expression yields the following
> pending update list:
>   { upd:insertBefore(n_b, n_c), upd:insertBefore(n_b, n_d) }
> The second expression yields the following pending update list:
>   { upd:insertIntoAsLast(n_a, n_c), upd:insertAfter(n_b, n_d) }
> According to the compatibility matrix, the first pending update list
> contains a conflict, while the second doesn't. The result of the second
> expression is <a><b/><d/><c/></a> (no matter in which order the two
> primitives are evaluated).I don't think that this asymmetry is desired and see two ways to solve
> this issue:
> (1) Add an upd:insertAsFirst primitive.
> (2) If "as last" is specified in an insert statement, do something
> similar to "as first" when there is a child, i.e., insert after the last
> child node. When there are no children, perform upd:insertInto. This
> would remove the need for an upd:insertAsLast primitive, but would cause
> the second expression to signal a conflict.

I just checked the compatibility table:

http://www.w3.org/TR/2006/WD-xqupdate-20060127/#id-compatibility

I get the same results you do:

insert <c/> into $x as first, insert <d/> before $x/b
=  { upd:insertBefore(n_b, n_c), upd:insertBefore(n_b, n_d) }
=> conflict

insert <c/> into $x as last, insert <d/> after $x/b
=  { upd:insertIntoAsLast(n_a, n_c), upd:insertAfter(n_b, n_d) }
=> <a><b/><d/><c/></a>

Now suppose we had a primitive upd:insertIntoAsFirst, with compatibility 
similar to upd:insertIntoAsLast: I suppose the primitive 
insAsFirst(t1,r1) would probably have the following compatibility table 
entries:
   
insAsFirst(t1,r1)
--------------------------------------------------
delete(t2): yes
rename(t2,r2): yes
repVal(t2,r2): yes
insBef(t2,r2): yes
insAft(t2,r2): yes
insInto(t2,r2): no(1) - not compatible if t1 is t2
insAsFirst(t2,r2): no(1) - not compatible if t1 is t2
insAsLast(t2,r2): yes
insAttrs(t2,r2): yes

And we could change the mapping to:

insert <c/> into $x as first, insert <d/> before $x/b
=  { upd:insertAsFirst(n_a, n_c), upd:insertBefore(n_b, n_d) }
=> <a><c/><d/><b/></a>

I think this would be an improvement for precisely the reasons you give.

Jonathan
(personal opinion only)

-- 
Read my Blog: http://blogs.datadirect.com/jonathan_robie/
Learn XQuery: http://media.datadirect.com/download/docs/ddxquery/tutorial_query.html
Learn XQJ (the JDBC for XQuery): http://www.datadirect.com/developer/xquery/topics/xqj_tutorial/
Get DataDirect XQuery: http://www.datadirect.com/products/xquery/

Received on Thursday, 9 March 2006 16:28:26 UTC