use of org.exist.dom.persistent.NodeSet in project exist by eXist-db.
the class SimpleStep method eval.
/* (non-Javadoc)
* @see org.exist.xquery.Expression#eval(org.exist.dom.persistent.DocumentSet, org.exist.xquery.value.Sequence, org.exist.xquery.value.Item)
*/
public Sequence eval(Sequence contextSequence, Item contextItem) throws XPathException {
if (context.getProfiler().isEnabled()) {
context.getProfiler().start(this);
context.getProfiler().message(this, Profiler.DEPENDENCIES, "DEPENDENCIES", Dependency.getDependenciesName(this.getDependencies()));
if (contextSequence != null) {
context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT SEQUENCE", contextSequence);
}
if (contextItem != null) {
context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT ITEM", contextItem.toSequence());
}
}
if (contextItem != null) {
contextSequence = contextItem.toSequence();
}
Sequence result = Sequence.EMPTY_SEQUENCE;
final Sequence set = expression.eval(contextSequence);
if (!set.isEmpty()) {
if (set.isPersistentSet()) {
final NodeSet nodeSet = set.toNodeSet();
switch(axis) {
case Constants.DESCENDANT_SELF_AXIS:
result = nodeSet.selectAncestorDescendant(contextSequence.toNodeSet(), NodeSet.DESCENDANT, true, contextId, true);
break;
case Constants.CHILD_AXIS:
result = nodeSet.selectParentChild(contextSequence.toNodeSet(), NodeSet.DESCENDANT, contextId);
break;
default:
throw new XPathException(this, "Wrong axis specified");
}
} else {
final MemoryNodeSet ctxNodes = contextSequence.toMemNodeSet();
final MemoryNodeSet nodes = set.toMemNodeSet();
switch(axis) {
case Constants.DESCENDANT_SELF_AXIS:
result = ctxNodes.selectDescendants(nodes);
break;
case Constants.CHILD_AXIS:
result = ctxNodes.selectChildren(nodes);
break;
}
}
}
if (context.getProfiler().isEnabled()) {
context.getProfiler().end(this, "", result);
}
return result;
}
use of org.exist.dom.persistent.NodeSet in project exist by eXist-db.
the class ValueComparison method nodeSetCompare.
protected Sequence nodeSetCompare(NodeSet nodes, Sequence contextSequence) throws XPathException {
if (context.getProfiler().isEnabled()) {
context.getProfiler().message(this, Profiler.OPTIMIZATION_FLAGS, "OPTIMIZATION CHOICE", "nodeSetCompare");
}
final NodeSet result = new ExtArrayNodeSet();
final Collator collator = getCollator(contextSequence);
if (contextSequence != null && !contextSequence.isEmpty()) {
for (final NodeProxy current : nodes) {
ContextItem context = current.getContext();
if (context == null) {
throw new XPathException(this, ErrorCodes.XPDY0002, "Context is missing for node set comparison");
}
do {
final AtomicValue lv = current.atomize();
final Sequence rs = getRight().eval(context.getNode().toSequence());
if (!rs.hasOne()) {
throw new XPathException(this, ErrorCodes.XPTY0004, "Type error: sequence with less or more than one item is not allowed here");
}
if (compareAtomic(collator, lv, rs.itemAt(0).atomize(), StringTruncationOperator.NONE, relation)) {
result.add(current);
}
} while ((context = context.getNextDirect()) != null);
}
} else {
final Sequence rs = getRight().eval(null);
if (!rs.hasOne()) {
throw new XPathException(this, ErrorCodes.XPTY0004, "Type error: sequence with less or more than one item is not allowed here");
}
final AtomicValue rv = rs.itemAt(0).atomize();
for (final NodeProxy current : nodes) {
final AtomicValue lv = current.atomize();
if (compareAtomic(collator, lv, rv, StringTruncationOperator.NONE, Comparison.EQ)) {
result.add(current);
}
}
}
return result;
}
use of org.exist.dom.persistent.NodeSet in project exist by eXist-db.
the class OpAnd method eval.
public Sequence eval(Sequence contextSequence, Item contextItem) throws XPathException {
if (context.getProfiler().isEnabled()) {
context.getProfiler().start(this);
context.getProfiler().message(this, Profiler.DEPENDENCIES, "DEPENDENCIES", Dependency.getDependenciesName(this.getDependencies()));
if (contextSequence != null) {
context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT SEQUENCE", contextSequence);
}
if (contextItem != null) {
context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT ITEM", contextItem.toSequence());
}
}
Sequence result;
if (getLength() == 0) {
result = Sequence.EMPTY_SEQUENCE;
} else {
if (contextItem != null) {
contextSequence = contextItem.toSequence();
}
boolean doOptimize = optimize;
if (contextSequence != null && !contextSequence.isPersistentSet()) {
doOptimize = false;
}
final Expression left = getLeft();
final Expression right = getRight();
// setContextId(getExpressionId());
if (doOptimize && contextSequence != null) {
contextSequence.setSelfAsContext(getContextId());
}
final Sequence ls = left.eval(contextSequence, null);
doOptimize = doOptimize && (ls.isPersistentSet() || ls.isEmpty());
if (doOptimize) {
if (inPredicate) {
NodeSet lr = ls.toNodeSet();
lr = lr.getContextNodes(getContextId());
if (lr.isEmpty()) {
return NodeSet.EMPTY_SET;
}
final Sequence rs = right.eval(lr, null);
final NodeSet rr = rs.toNodeSet();
result = rr.getContextNodes(getContextId());
} else {
final Sequence rs = right.eval(contextSequence, null);
final boolean rl = ls.effectiveBooleanValue();
if (!rl) {
result = BooleanValue.FALSE;
} else {
final boolean rr = rs.effectiveBooleanValue();
result = (rl && rr) ? BooleanValue.TRUE : BooleanValue.FALSE;
}
}
} else {
boolean rl = ls.effectiveBooleanValue();
// Immediately return false if the left operand is false
if (!rl) {
result = BooleanValue.FALSE;
} else {
final Sequence rs = right.eval(contextSequence, null);
final boolean rr = rs.effectiveBooleanValue();
result = (rl && rr) ? BooleanValue.TRUE : BooleanValue.FALSE;
}
}
}
if (context.getProfiler().isEnabled()) {
context.getProfiler().end(this, "", result);
}
return result;
}
use of org.exist.dom.persistent.NodeSet in project exist by eXist-db.
the class IndexKeys method eval.
/*
* (non-Javadoc)
*
* @see org.exist.xquery.BasicFunction#eval(org.exist.xquery.value.Sequence[],
* org.exist.xquery.value.Sequence)
*/
public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
if (args[0].isEmpty()) {
return Sequence.EMPTY_SEQUENCE;
}
NodeSet nodes = null;
DocumentSet docs = null;
Sequence qnames = null;
if (isCalledAs("index-keys-by-qname")) {
qnames = args[0];
docs = contextSequence == null ? context.getStaticallyKnownDocuments() : contextSequence.getDocumentSet();
} else {
nodes = args[0].toNodeSet();
docs = nodes.getDocumentSet();
}
final Sequence result = new ValueSequence();
try (final FunctionReference ref = (FunctionReference) args[2].itemAt(0)) {
int max = -1;
if (args[3].hasOne()) {
max = ((IntegerValue) args[3].itemAt(0)).getInt();
}
// if we have 5 arguments, query the user-specified index
if (this.getArgumentCount() == 5) {
final IndexWorker indexWorker = context.getBroker().getIndexController().getWorkerByIndexName(args[4].itemAt(0).getStringValue());
// IndexWorker indexWorker = context.getBroker().getBrokerPool().getIndexManager().getIndexByName(args[4].itemAt(0).getStringValue()).getWorker();
if (indexWorker == null) {
throw new XPathException(this, "Unknown index: " + args[4].itemAt(0).getStringValue());
}
final Map<String, Object> hints = new HashMap<>();
if (max != -1) {
hints.put(IndexWorker.VALUE_COUNT, new IntegerValue(max));
}
if (indexWorker instanceof OrderedValuesIndex) {
hints.put(OrderedValuesIndex.START_VALUE, args[1].getStringValue());
} else {
logger.warn("{} isn't an instance of org.exist.indexing.OrderedValuesIndex. Start value '{}' ignored.", indexWorker.getClass().getName(), args[1]);
}
if (qnames != null) {
final List<QName> qnameList = new ArrayList<>(qnames.getItemCount());
for (final SequenceIterator i = qnames.iterate(); i.hasNext(); ) {
final QNameValue qv = (QNameValue) i.nextItem();
qnameList.add(qv.getQName());
}
hints.put(QNamedKeysIndex.QNAMES_KEY, qnameList);
}
final Occurrences[] occur = indexWorker.scanIndex(context, docs, nodes, hints);
// TODO : add an extra argument to pass the END_VALUE ?
final int len = (max != -1 && occur.length > max ? max : occur.length);
final Sequence[] params = new Sequence[2];
ValueSequence data = new ValueSequence();
for (int j = 0; j < len; j++) {
params[0] = new StringValue(occur[j].getTerm().toString());
data.add(new IntegerValue(occur[j].getOccurrences(), Type.UNSIGNED_INT));
data.add(new IntegerValue(occur[j].getDocuments(), Type.UNSIGNED_INT));
data.add(new IntegerValue(j + 1, Type.UNSIGNED_INT));
params[1] = data;
result.addAll(ref.evalFunction(Sequence.EMPTY_SEQUENCE, null, params));
data.clear();
}
// no index specified: use the range index
} else {
final Indexable indexable = (Indexable) args[1].itemAt(0);
ValueOccurrences[] occur = null;
// First check for indexes defined on qname
final QName[] allQNames = getDefinedIndexes(context.getBroker(), docs);
if (allQNames.length > 0) {
occur = context.getBroker().getValueIndex().scanIndexKeys(docs, nodes, allQNames, indexable);
}
// Also check if there's an index defined by path
ValueOccurrences[] occur2 = context.getBroker().getValueIndex().scanIndexKeys(docs, nodes, indexable);
// Merge the two results
if (occur == null || occur.length == 0) {
occur = occur2;
} else {
ValueOccurrences[] t = new ValueOccurrences[occur.length + occur2.length];
System.arraycopy(occur, 0, t, 0, occur.length);
System.arraycopy(occur2, 0, t, occur.length, occur2.length);
occur = t;
}
final int len = (max != -1 && occur.length > max ? max : occur.length);
final Sequence[] params = new Sequence[2];
ValueSequence data = new ValueSequence();
for (int j = 0; j < len; j++) {
params[0] = occur[j].getValue();
data.add(new IntegerValue(occur[j].getOccurrences(), Type.UNSIGNED_INT));
data.add(new IntegerValue(occur[j].getDocuments(), Type.UNSIGNED_INT));
data.add(new IntegerValue(j + 1, Type.UNSIGNED_INT));
params[1] = data;
result.addAll(ref.evalFunction(Sequence.EMPTY_SEQUENCE, null, params));
data.clear();
}
}
}
logger.debug("Returning: {}", result.getItemCount());
return result;
}
use of org.exist.dom.persistent.NodeSet in project exist by eXist-db.
the class IndexType method eval.
/*
* (non-Javadoc)
*
* @see org.exist.xquery.BasicFunction#eval(org.exist.xquery.value.Sequence[],
* org.exist.xquery.value.Sequence)
*/
public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
if (context.getProfiler().isEnabled()) {
context.getProfiler().start(this);
context.getProfiler().message(this, Profiler.DEPENDENCIES, "DEPENDENCIES", Dependency.getDependenciesName(this.getDependencies()));
if (contextSequence != null) {
context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT SEQUENCE", contextSequence);
}
}
Sequence result;
if (args[0].isEmpty()) {
result = Sequence.EMPTY_SEQUENCE;
} else {
final NodeSet nodes = args[0].toNodeSet();
// Remember it is the default value when no index is defined
if (nodes.getIndexType() == Type.ANY_TYPE) {
result = Sequence.EMPTY_SEQUENCE;
} else {
result = new StringValue(Type.getTypeName(nodes.getIndexType()));
}
}
if (context.getProfiler().isEnabled()) {
context.getProfiler().end(this, "", result);
}
return result;
}
Aggregations