Skip to content

Commit

Permalink
Merge pull request #1732 from adamretter/1664
Browse files Browse the repository at this point in the history
Fixes a regression with XQuery Update insert
  • Loading branch information
dizzzz authored Feb 13, 2018
2 parents 912a29e + eaef790 commit 659082b
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 8 deletions.
39 changes: 32 additions & 7 deletions src/org/exist/dom/persistent/ElementImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ public class ElementImpl extends NamedNode implements Element {
public static final int LENGTH_NS_ID = 2; //sizeof short
public static final int LENGTH_PREFIX_LENGTH = 2; //sizeof short

private short attributes = 0;
private int children = 0;
private short attributes = 0; // number of attributes
private int children = 0; // number of elements AND attributes

private int position = 0;
private Map<String, String> namespaceMappings = null;
Expand Down Expand Up @@ -583,7 +583,7 @@ public void appendChildren(final Txn transaction, NodeList nodes, final int chil
final IStoredNode<?> last = (IStoredNode<?>) cl.item(child - 2);
insertAfter(transaction, nodes, last);
} else {
final IStoredNode<?> last = (IStoredNode<?>) getLastChild();
final IStoredNode<?> last = (IStoredNode<?>) getLastChild(true);
appendChildren(transaction, last.getNodeId().nextSibling(), null,
new NodeImplRef(getLastNode(last)), path, nodes, listener);
}
Expand Down Expand Up @@ -1030,16 +1030,41 @@ public Node getFirstChild() {

@Override
public Node getLastChild() {
if(!hasChildNodes()) {
return getLastChild(false);
}

/**
* Get the last child.
*
* @param attributesAreChildren In the DLN model attributes have child node ids,
* however in the DOM model attributes are not child nodes. Set true for DLN
* or false for DOM.
*
* @return the last child.
*/
private Node getLastChild(final boolean attributesAreChildren) {
if ((!attributesAreChildren) && (!hasChildNodes())) {
// DOM model
return null;
} else if (!(hasChildNodes() || hasAttributes())) {
// DLN model
return null;
}

Node node = null;
if(!isDirty) {
if (!isDirty) {
final NodeId child = nodeId.getChild(children);
node = ownerDocument.getNode(new NodeProxy(ownerDocument, child));
}
if(node == null) {
final NodeList cl = getChildNodes();
if (node == null) {
final NodeList cl;
if (!attributesAreChildren) {
// DOM model
cl = getChildNodes();
} else {
// DLN model
cl = getAttrsAndChildNodes();
}
return cl.item(cl.getLength() - 1);
}
return node;
Expand Down
3 changes: 2 additions & 1 deletion test/src/xquery/suite.xql
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ test:suite((
inspect:module-functions(xs:anyURI("nill.xql")),
inspect:module-functions(xs:anyURI("ft-match.xql")),
inspect:module-functions(xs:anyURI("types.xql")),
inspect:module-functions(xs:anyURI("unparsed-text.xql"))
inspect:module-functions(xs:anyURI("unparsed-text.xql")),
inspect:module-functions(xs:anyURI("xquery-update.xql"))
))
57 changes: 57 additions & 0 deletions test/src/xquery/xquery-update.xql
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
xquery version "3.1";

module namespace xqu="http://exist-db.org/xquery/test/xquery-update";

import module namespace test="http://exist-db.org/xquery/xqsuite" at "resource:org/exist/xquery/lib/xqsuite/xqsuite.xql";


declare
%test:assertEquals('<root><child/></root>')
function xqu:root() {
let $f := xmldb:store('/db', 'xupdate.xml', <root/>)
let $u := update insert <child/> into doc($f)/root
return doc($f)
};

declare
%test:assertEquals('<root attr="1"><child/></root>')
function xqu:root_attribute() {
let $r := xmldb:remove('/db', 'xupdate.xml')
let $f := xmldb:store('/db', 'xupdate.xml', <root attr="1"/>)
let $u := update insert <child/> into doc($f)/root
return doc($f)
};

declare
%test:assertEquals('<root attr="1"><foo/><child/></root>')
function xqu:root_attribute_child() {
let $r := xmldb:remove('/db', 'xupdate.xml')
let $f := xmldb:store('/db', 'xupdate.xml', <root attr="1"><foo/></root>)
let $u := update insert <child/> into doc($f)/root
return doc($f)
};

declare
%test:assertEquals('<root attr="1"><foo bar="2"/><child/></root>')
function xqu:root_attribute_child_attribute() {
let $r := xmldb:remove('/db', 'xupdate.xml')
let $f := xmldb:store('/db', 'xupdate.xml', <root attr="1"><foo bar="2"/></root>)
let $u := update insert <child/> into doc($f)/root
return doc($f)
};

declare
%test:assertEquals('<root><!-- foobar --><child/></root>')
function xqu:root_comment() {
let $f := xmldb:store('/db', 'xupdate.xml', <root><!-- foobar --></root>)
let $u := update insert <child/> into doc($f)/root
return doc($f)
};

declare
%test:assertEquals('<root attr="1"><!-- foobar --><child/></root>')
function xqu:root_comment_attribute() {
let $f := xmldb:store('/db', 'xupdate.xml', <root attr="1"><!-- foobar --></root>)
let $u := update insert <child/> into doc($f)/root
return doc($f)
};

0 comments on commit 659082b

Please sign in to comment.