use of org.exist.xquery.value.AtomicValue in project exist by eXist-db.
the class GMLHSQLIndexWorker method getGeometricPropertyForNode.
@Override
protected AtomicValue getGeometricPropertyForNode(XQueryContext context, NodeProxy p, Connection conn, String propertyName) throws SQLException, XPathException {
PreparedStatement ps = conn.prepareStatement("SELECT " + propertyName + " FROM " + GMLHSQLIndex.TABLE_NAME + " WHERE DOCUMENT_URI = ? AND NODE_ID_UNITS = ? AND NODE_ID = ?");
ps.setString(1, p.getOwnerDocument().getURI().toString());
ps.setInt(2, p.getNodeId().units());
byte[] bytes = new byte[p.getNodeId().size()];
p.getNodeId().serialize(bytes, 0);
ps.setBytes(3, bytes);
ResultSet rs = null;
try {
rs = ps.executeQuery();
if (!rs.next())
// Nothing returned
return AtomicValue.EMPTY_VALUE;
AtomicValue result = null;
if (rs.getMetaData().getColumnClassName(1).equals(Boolean.class.getName())) {
result = new BooleanValue(rs.getBoolean(1));
} else if (rs.getMetaData().getColumnClassName(1).equals(Double.class.getName())) {
result = new DoubleValue(rs.getDouble(1));
} else if (rs.getMetaData().getColumnClassName(1).equals(String.class.getName())) {
result = new StringValue(rs.getString(1));
} else if (rs.getMetaData().getColumnType(1) == java.sql.Types.BINARY) {
result = BinaryValueFromInputStream.getInstance(context, new Base64BinaryValueType(), new UnsynchronizedByteArrayInputStream(rs.getBytes(1)));
} else
throw new SQLException("Unable to make an atomic value from '" + rs.getMetaData().getColumnClassName(1) + "'");
if (rs.next()) {
// Should be impossible
throw new SQLException("More than one geometry for node " + p);
}
return result;
} finally {
if (rs != null)
rs.close();
ps.close();
}
}
use of org.exist.xquery.value.AtomicValue in project exist by eXist-db.
the class NativeValueIndex method scanIndexKeys.
/**
* Scan all index keys indexed by the given QName. Return {@link org.exist.util.ValueOccurrences} for those index entries pointing to descendants
* of the specified context set. The first argument specifies the set of documents to include in the scan. Nodes which are not in this document
* set will be ignored.
*
* @param docs set of documents to scan
* @param contextSet if != null, return only index entries pointing to nodes which are descendants of nodes in the context set
* @param qnames an array of QNames: defines the index entries to be scanned.
* @param start an optional start value: only index keys starting with or being greater than this start value (depends on the type of the
* index key) will be scanned
* @return a list of ValueOccurrences
*/
public ValueOccurrences[] scanIndexKeys(final DocumentSet docs, final NodeSet contextSet, QName[] qnames, final Indexable start) {
if (qnames == null) {
final List<QName> qnlist = getDefinedIndexes(docs);
qnames = new QName[qnlist.size()];
qnames = qnlist.toArray(qnames);
}
final int type = start.getType();
final boolean stringType = Type.subTypeOf(type, Type.STRING);
final IndexScanCallback cb = new IndexScanCallback(docs, contextSet, type, true);
for (final QName qname : qnames) {
for (final Iterator<Collection> i = docs.getCollectionIterator(); i.hasNext(); ) {
try (final ManagedLock<ReentrantLock> bfileLock = lockManager.acquireBtreeReadLock(dbValues.getLockName())) {
final int collectionId = i.next().getId();
// Compute a key for the start value in the collection
final Value startKey = new QNameValue(collectionId, qname, start, broker.getBrokerPool().getSymbols());
if (stringType) {
final IndexQuery query = new IndexQuery(IndexQuery.TRUNC_RIGHT, startKey);
dbValues.query(query, cb);
} else {
final Value prefixKey = new QNamePrefixValue(collectionId, qname, start.getType(), broker.getBrokerPool().getSymbols());
final IndexQuery query = new IndexQuery(IndexQuery.GEQ, startKey);
dbValues.query(query, prefixKey, cb);
}
} catch (final EXistException | BTreeException | IOException | TerminatedException e) {
LOG.error(e.getMessage(), e);
} catch (final LockException e) {
LOG.warn("Failed to acquire lock for '{}'", FileUtils.fileName(dbValues.getFile()), e);
}
}
}
final Map<AtomicValue, ValueOccurrences> map = cb.map;
final ValueOccurrences[] result = new ValueOccurrences[map.size()];
return map.values().toArray(result);
}
use of org.exist.xquery.value.AtomicValue in project exist by eXist-db.
the class NativeValueIndex method scanIndexKeys.
public ValueOccurrences[] scanIndexKeys(final DocumentSet docs, final NodeSet contextSet, final Indexable start) {
final int type = start.getType();
final boolean stringType = Type.subTypeOf(type, Type.STRING);
final IndexScanCallback cb = new IndexScanCallback(docs, contextSet, type, false);
for (final Iterator<Collection> i = docs.getCollectionIterator(); i.hasNext(); ) {
try (final ManagedLock<ReentrantLock> bfileLock = lockManager.acquireBtreeReadLock(dbValues.getLockName())) {
final Collection c = i.next();
final int collectionId = c.getId();
// Compute a key for the start value in the collection
final Value startKey = new SimpleValue(collectionId, start);
if (stringType) {
final IndexQuery query = new IndexQuery(IndexQuery.TRUNC_RIGHT, startKey);
dbValues.query(query, cb);
} else {
final Value prefixKey = new SimplePrefixValue(collectionId, start.getType());
final IndexQuery query = new IndexQuery(IndexQuery.GEQ, startKey);
dbValues.query(query, prefixKey, cb);
}
} catch (final EXistException | IOException | TerminatedException | BTreeException e) {
LOG.error(e.getMessage(), e);
} catch (final LockException e) {
LOG.warn("Failed to acquire lock for '{}'", FileUtils.fileName(dbValues.getFile()), e);
}
}
final Map<AtomicValue, ValueOccurrences> map = cb.map;
final ValueOccurrences[] result = new ValueOccurrences[map.size()];
return map.values().toArray(result);
}
use of org.exist.xquery.value.AtomicValue in project exist by eXist-db.
the class FunSort method sort.
private Sequence sort(Sequence seq, ArrayList<Sequence> keys, Collator collator) throws XPathException {
final Holder<XPathException> exception = new Holder<>();
// preparing
final int size = seq.getItemCount();
final Integer[] order = new Integer[size];
for (int i = 0; i < size; i++) order[i] = i;
// sorting
try {
Arrays.sort(order, (i1, i2) -> {
Sequence seq1 = keys.get(i1);
Sequence seq2 = keys.get(i2);
int size1 = seq1.getItemCount();
int size2 = seq2.getItemCount();
int minSize = Math.min(size1, size2);
if (size1 == 0) {
return -size2;
}
for (int pos = 0; pos < minSize; pos++) {
Item item1 = seq1.itemAt(pos);
Item item2 = seq2.itemAt(pos);
// int res;
// if (item1 instanceof org.exist.dom.memtree.NodeImpl && (!(item2 instanceof org.exist.dom.memtree.NodeImpl))) {
// res = Constants.INFERIOR;
// } else if (item1 instanceof Comparable && item2 instanceof Comparable) {
// res = ((Comparable) item1).compareTo(item2);
// } else {
// res = Constants.INFERIOR;
// }
int res = Constants.EQUAL;
if (FunDeepEqual.deepEquals(item1, item2, collator)) {
continue;
}
if (Type.subTypeOfUnion(item1.getType(), Type.NUMBER) && ((NumericValue) item1).isNaN()) {
res = Constants.INFERIOR;
} else if (Type.subTypeOf(item1.getType(), Type.STRING) && Type.subTypeOf(item2.getType(), Type.STRING)) {
try {
res = Collations.compare(collator, item1.getStringValue(), item2.getStringValue());
} catch (XPathException e) {
exception.set(e);
}
} else if (item1 instanceof AtomicValue && item2 instanceof AtomicValue) {
try {
// throw type error if values cannot be compared with lt
ValueComparison.compareAtomic(collator, (AtomicValue) item1, (AtomicValue) item2, Constants.StringTruncationOperator.NONE, Constants.Comparison.LT);
res = ((AtomicValue) item1).compareTo(collator, (AtomicValue) item2);
} catch (XPathException e) {
exception.set(e);
throw new IllegalArgumentException();
}
// } else if (item1 instanceof Comparable && item2 instanceof Comparable) {
// res = ((Comparable) item1).compareTo(item2);
} else {
res = Constants.INFERIOR;
}
if (res != Constants.EQUAL) {
return res;
}
}
return (size1 - size2);
});
} catch (IllegalArgumentException e) {
if (exception.get() != null) {
throw new XPathException(FunSort.this, ErrorCodes.XPTY0004, exception.get());
} else {
throw new XPathException(FunSort.this, ErrorCodes.XPTY0004, e.getMessage());
}
}
// form final sequence
final ValueSequence result = new ValueSequence(seq.getItemCount());
result.keepUnOrdered(true);
for (int i = 0; i < size; i++) {
result.add(seq.itemAt(order[i]));
}
return result;
}
use of org.exist.xquery.value.AtomicValue in project exist by eXist-db.
the class FunSum 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;
final Sequence inner = getArgument(0).eval(contextSequence, contextItem);
if (inner.isEmpty()) {
// If $zero is not specified, then the value returned for an empty sequence is the xs:integer value 0
Sequence zero = IntegerValue.ZERO;
if (getSignature().getArgumentCount() == 2) {
zero = getArgument(1).eval(contextSequence, contextItem);
}
result = zero;
} else {
final SequenceIterator iter = inner.iterate();
Item item = iter.nextItem();
AtomicValue value = item.atomize();
value = check(value, null);
// Set the first value
ComputableValue sum = (ComputableValue) value;
while (iter.hasNext()) {
item = iter.nextItem();
value = item.atomize();
value = check(value, sum);
if (Type.subTypeOfUnion(value.getType(), Type.NUMBER)) {
if (((NumericValue) value).isInfinite()) {
gotInfinity = true;
}
if (((NumericValue) value).isNaN()) {
sum = DoubleValue.NaN;
break;
}
}
sum = (ComputableValue) sum.promote(value);
// Aggregate next values
sum = sum.plus((ComputableValue) value);
}
result = sum;
}
if (!gotInfinity) {
if (Type.subTypeOfUnion(result.getItemType(), Type.NUMBER) && ((NumericValue) result).isInfinite()) {
// Throw an overflow eception here since we get an infinity
// whereas is hasn't been provided by the sequence
}
}
if (context.getProfiler().isEnabled()) {
context.getProfiler().end(this, "", result);
}
return result;
}
Aggregations