Hello,
suppose I have a table with Geometries. This kind of datatype is handled by
the ValueGeometry class, and an entry appears to be handled in a *Page, *that
organizes its entries in an R-Tree, using the *SpatialKey *class as keys.
Getting an entry can then be effectively performed by a simple
contains-relation that is well-defined on the bounding box of
each SpatialKey - unless the Geometry is null.
The *contains *Function in *SpatialDataType.java *always returns false when
a key to be found is null. In that case, one can never access a row with a
null-geometry, and I end up with an exception like this
Caused by: org.h2.jdbc.JdbcSQLException: Row not found when trying to
delete from index "PUBLIC.GEOMETRIES: 105" [90112-192]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
at org.h2.message.DbException.get(DbException.java:179)
at org.h2.message.DbException.get(DbException.java:155)
at org.h2.mvstore.db.MVSpatialIndex.remove(MVSpatialIndex.java:177)
at org.h2.mvstore.db.MVTable.removeRow(MVTable.java:677)
at org.h2.table.Table.updateRows(Table.java:489)
at org.h2.command.dml.Update.update(Update.java:145)
at org.h2.command.CommandContainer.update(CommandContainer.java:98)
at org.h2.command.Command.executeUpdate(Command.java:258)
... 10 more
This is caused by the following function in SpatialDataType.java:
public boolean contains(Object objA, Object objB) {
SpatialKey a = (SpatialKey) objA;
SpatialKey b = (SpatialKey) objB;
if (a.isNull() || b.isNull()) {
return false;
}
for (int i = 0; i < dimensions; i++) {
if (a.min(i) > b.min(i) || a.max(i) < b.max(i)) {
return false;
}
}
return true;
}
Now in order for the key to be found, a at least some contains-relation HAS
to be present for empty SpatialKeys, for which we only have the ID.
What *seems *to work is a simple relation that works on the IDs abusing the
<= relation:
public boolean contains(Object objA, Object objB) {
SpatialKey a = (SpatialKey) objA;
SpatialKey b = (SpatialKey) objB;
if (a.isNull() || b.isNull()) {
return a.getId() <= b.getId(); // <-----------
}
for (int i = 0; i < dimensions; i++) {
if (a.min(i) > b.min(i) || a.max(i) < b.max(i)) {
return false;
}
}
return true;
}
Even simpler seems to be to always return true:
public boolean contains(Object objA, Object objB) {
SpatialKey a = (SpatialKey) objA;
SpatialKey b = (SpatialKey) objB;
if (a.isNull() || b.isNull()) {
return true; // <------------
}
for (int i = 0; i < dimensions; i++) {
if (a.min(i) > b.min(i) || a.max(i) < b.max(i)) {
return false;
}
}
return true;
}
However, I have no insight as to how the MVTree is then built up, and how
that may affect performance.
In any case, this change will *never work on existing databases, and any
changes to this relation will render all empty Geometries unreachable.*
Does anyone have a deeper understanding of this kind of data retrieval, or
do you have a remark on the fixes I suggest? I would greatly appreciate any
remark...
Kind regards,
Sven
--
You received this message because you are subscribed to the Google Groups "H2
Database" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/h2-database.
For more options, visit https://groups.google.com/d/optout.