diff --git a/src/main/java/org/caosdb/server/query/Backreference.java b/src/main/java/org/caosdb/server/query/Backreference.java index 2fb2e0435e38eb65b5165a75d169d0ab1e9a4e96..987a59d1c54bc00ae046e1cefafaf2fa7731a3dd 100644 --- a/src/main/java/org/caosdb/server/query/Backreference.java +++ b/src/main/java/org/caosdb/server/query/Backreference.java @@ -24,6 +24,7 @@ package org.caosdb.server.query; import static java.sql.Types.VARCHAR; import static org.caosdb.server.database.DatabaseUtils.bytes2UTF8; + import java.sql.CallableStatement; import java.sql.Connection; import java.sql.PreparedStatement; @@ -213,7 +214,7 @@ public class Backreference implements EntityFilterInterface, QueryInterface { final long t3 = System.currentTimeMillis(); try (final PreparedStatement callFinishSubProperty = - getConnection().prepareCall("call finishSubProperty(?,?,?)")) { + getConnection().prepareCall("call finishSubProperty(?,?,?,?)")) { callFinishSubProperty.setString(1, query.getSourceSet()); // sourceSet if (query.getTargetSet() != null) { // targetSet callFinishSubProperty.setString(2, query.getTargetSet()); @@ -221,6 +222,7 @@ public class Backreference implements EntityFilterInterface, QueryInterface { callFinishSubProperty.setNull(2, VARCHAR); } callFinishSubProperty.setString(3, this.sourceSet); // list + callFinishSubProperty.setBoolean(4, this.isVersioned()); final ResultSet rs2 = callFinishSubProperty.executeQuery(); rs2.next(); this.statistics.put("finishSubPropertyStmt", rs2.getString("finishSubPropertyStmt")); diff --git a/src/main/java/org/caosdb/server/query/Conjunction.java b/src/main/java/org/caosdb/server/query/Conjunction.java index 4e2bc069fb7cb6872e5c21eec6f5823b178c9adc..2e44aea4f64a43ebb2a1c1edb153c6f68c172f8e 100644 --- a/src/main/java/org/caosdb/server/query/Conjunction.java +++ b/src/main/java/org/caosdb/server/query/Conjunction.java @@ -23,6 +23,7 @@ package org.caosdb.server.query; import static org.caosdb.server.database.DatabaseUtils.bytes2UTF8; + import java.sql.CallableStatement; import java.sql.Connection; import java.sql.PreparedStatement; @@ -62,8 +63,9 @@ public class Conjunction extends EntityFilterContainer implements QueryInterface // generate empty temporary targetSet if query.getTargetSet() is not // empty anyways. final PreparedStatement callInitEmptyTarget = - getConnection().prepareStatement("call initEmptyTargetSet(?)"); + getConnection().prepareStatement("call initEmptyTargetSet(?,?)"); callInitEmptyTarget.setString(1, query.getTargetSet()); + callInitEmptyTarget.setBoolean(2, query.isVersioned()); final ResultSet initEmptyTargetResultSet = callInitEmptyTarget.executeQuery(); if (initEmptyTargetResultSet.next()) { this.targetSet = bytes2UTF8(initEmptyTargetResultSet.getBytes("newTableName")); @@ -148,4 +150,9 @@ public class Conjunction extends EntityFilterContainer implements QueryInterface public void addBenchmark(final String str, final long time) { this.query.addBenchmark(this.getClass().getSimpleName() + "." + str, time); } + + @Override + public boolean isVersioned() { + return this.query.isVersioned(); + } } diff --git a/src/main/java/org/caosdb/server/query/Disjunction.java b/src/main/java/org/caosdb/server/query/Disjunction.java index 3bd2f32fdd3bfb64ad2a07c527b91136e965c22b..31288f2f169d4ebce1cf3d4da5b2ab369fcd5e1f 100644 --- a/src/main/java/org/caosdb/server/query/Disjunction.java +++ b/src/main/java/org/caosdb/server/query/Disjunction.java @@ -51,7 +51,8 @@ public class Disjunction extends EntityFilterContainer implements QueryInterface // targetTable // which will be used to collect the entities. final PreparedStatement callInitDisjunctionFilter = - getConnection().prepareStatement("call initDisjunctionFilter()"); + getConnection().prepareStatement("call initDisjunctionFilter(?)"); + callInitDisjunctionFilter.setBoolean(1, this.isVersioned()); final ResultSet initDisjuntionFilterResultSet = callInitDisjunctionFilter.executeQuery(); if (initDisjuntionFilterResultSet.next()) { this.targetSet = bytes2UTF8(initDisjuntionFilterResultSet.getBytes("newTableName")); @@ -69,11 +70,12 @@ public class Disjunction extends EntityFilterContainer implements QueryInterface if (query.getTargetSet() == null) { // calculate the difference and store to sourceSet - final CallableStatement callFinishNegationFilter = - getConnection().prepareCall("call calcIntersection(?,?)"); - callFinishNegationFilter.setString(1, getSourceSet()); - callFinishNegationFilter.setString(2, this.targetSet); - callFinishNegationFilter.execute(); + final CallableStatement callFinishDisjunctionFilter = + getConnection().prepareCall("call calcIntersection(?,?,?)"); + callFinishDisjunctionFilter.setString(1, getSourceSet()); + callFinishDisjunctionFilter.setString(2, this.targetSet); + callFinishDisjunctionFilter.setBoolean(3, this.isVersioned()); + callFinishDisjunctionFilter.execute(); } // ELSE: the query.getTargetSet() is identical to targetSet and is // not @@ -136,4 +138,9 @@ public class Disjunction extends EntityFilterContainer implements QueryInterface public void addBenchmark(final String str, final long time) { this.query.addBenchmark(this.getClass().getSimpleName() + "." + str, time); } + + @Override + public boolean isVersioned() { + return this.query.isVersioned(); + } } diff --git a/src/main/java/org/caosdb/server/query/EntityFilterContainer.java b/src/main/java/org/caosdb/server/query/EntityFilterContainer.java index a9e26887ea87534022e96bc19b6ab42e6b2c8677..c2409f90ecc43cfb318a17cc8a9f3ba6df60beb0 100644 --- a/src/main/java/org/caosdb/server/query/EntityFilterContainer.java +++ b/src/main/java/org/caosdb/server/query/EntityFilterContainer.java @@ -38,9 +38,4 @@ public abstract class EntityFilterContainer implements EntityFilterInterface { public void addAll(final EntityFilterContainer filter) { getFilters().addAll(filter.getFilters()); } - - public boolean isVersioned() { - // TODO stub - return false; - } } diff --git a/src/main/java/org/caosdb/server/query/IDFilter.java b/src/main/java/org/caosdb/server/query/IDFilter.java index 1a4f3650cc7b29078b268f69b1ae4c3db726de24..12f53b44472d5b897c3d8b2a065388969c1edcbc 100644 --- a/src/main/java/org/caosdb/server/query/IDFilter.java +++ b/src/main/java/org/caosdb/server/query/IDFilter.java @@ -25,6 +25,7 @@ package org.caosdb.server.query; import static java.sql.Types.CHAR; import static java.sql.Types.INTEGER; import static java.sql.Types.VARCHAR; + import java.sql.CallableStatement; import java.sql.Connection; import java.sql.SQLException; diff --git a/src/main/java/org/caosdb/server/query/Negation.java b/src/main/java/org/caosdb/server/query/Negation.java index 4fd7735500427e77a4d6e1b928a784745e7c9370..981b4c8f2ca19a1a6ec47df9e85f108ab7bb01ac 100644 --- a/src/main/java/org/caosdb/server/query/Negation.java +++ b/src/main/java/org/caosdb/server/query/Negation.java @@ -23,6 +23,7 @@ package org.caosdb.server.query; import static org.caosdb.server.database.DatabaseUtils.bytes2UTF8; + import java.sql.CallableStatement; import java.sql.Connection; import java.sql.PreparedStatement; @@ -89,8 +90,8 @@ public class Negation implements EntityFilterInterface, QueryInterface { // generate empty temporary targetSet if query.getTargetSet() is not // empty anyways. final PreparedStatement callInitEmptyTarget = - getConnection().prepareStatement("call initEmptyTargetSet(?)"); - callInitEmptyTarget.setString(1, query.getTargetSet()); + getConnection().prepareStatement("call initDisjunctionFilter(?)"); + callInitEmptyTarget.setBoolean(1, query.isVersioned()); final ResultSet initEmptyTargetResultSet = callInitEmptyTarget.executeQuery(); if (initEmptyTargetResultSet.next()) { this.targetSet = bytes2UTF8(initEmptyTargetResultSet.getBytes("newTableName")); @@ -99,19 +100,22 @@ public class Negation implements EntityFilterInterface, QueryInterface { this.filter.apply(this); - if (query.getTargetSet() != null && !this.targetSet.equalsIgnoreCase(query.getTargetSet())) { - // merge temporary targetSet with query.getTargetSet() + if (query.getTargetSet() == null) { + // intersect temporary targetSet with query.getSourceSet() final CallableStatement callFinishConjunctionFilter = - query.getConnection().prepareCall("call calcUnion(?,?)"); - callFinishConjunctionFilter.setString(1, query.getTargetSet()); + query.getConnection().prepareCall("call calcDifference(?,?,?)"); + callFinishConjunctionFilter.setString(1, query.getSourceSet()); callFinishConjunctionFilter.setString(2, this.targetSet); + callFinishConjunctionFilter.setBoolean(3, this.isVersioned()); callFinishConjunctionFilter.execute(); - } else if (query.getTargetSet() == null) { - // intersect temporary targetSet with query.getSourceSet() + } else { + // merge temporary targetSet with query.getTargetSet() final CallableStatement callFinishConjunctionFilter = - query.getConnection().prepareCall("call calcDifference(?,?)"); - callFinishConjunctionFilter.setString(1, query.getSourceSet()); + query.getConnection().prepareCall("call calcComplementUnion(?,?,?,?)"); + callFinishConjunctionFilter.setString(1, query.getTargetSet()); callFinishConjunctionFilter.setString(2, this.targetSet); + callFinishConjunctionFilter.setString(3, query.getSourceSet()); + callFinishConjunctionFilter.setBoolean(4, this.isVersioned()); callFinishConjunctionFilter.execute(); } } catch (final SQLException e) { @@ -169,7 +173,6 @@ public class Negation implements EntityFilterInterface, QueryInterface { @Override public boolean isVersioned() { - // TODO Auto-generated method stub - return false; + return this.query.isVersioned(); } } diff --git a/src/main/java/org/caosdb/server/query/POV.java b/src/main/java/org/caosdb/server/query/POV.java index 0d6e0e64f49c48f437e11b1313c10d4809a2cc1d..01860ba518df4453ff17012e75641e6e6a05a446 100644 --- a/src/main/java/org/caosdb/server/query/POV.java +++ b/src/main/java/org/caosdb/server/query/POV.java @@ -26,6 +26,8 @@ import static java.sql.Types.DOUBLE; import static java.sql.Types.INTEGER; import static java.sql.Types.VARCHAR; import static org.caosdb.server.database.DatabaseUtils.bytes2UTF8; + +import de.timmfitschen.easyunits.parser.ParserException; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.PreparedStatement; @@ -47,7 +49,6 @@ import org.caosdb.unit.Unit; import org.jdom2.Element; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import de.timmfitschen.easyunits.parser.ParserException; public class POV implements EntityFilterInterface { private SubProperty subp = null; @@ -420,7 +421,9 @@ public class POV implements EntityFilterInterface { if (hasSubProperty() && this.targetSet != null) { try (PreparedStatement stmt = - query.getConnection().prepareStatement("call initEmptyTargetSet(NULL)")) { + query.getConnection().prepareStatement("call initEmptyTargetSet(?, ?)")) { + stmt.setNull(1, VARCHAR); + stmt.setBoolean(2, query.isVersioned()); // generate new targetSet final ResultSet rs = stmt.executeQuery(); if (rs.next()) { diff --git a/src/main/java/org/caosdb/server/query/Query.java b/src/main/java/org/caosdb/server/query/Query.java index 2425f874c772f3568b83ea76e0c3d35e63d599ab..e8c4f9d352aded34322eaaed594b165cd7406d0c 100644 --- a/src/main/java/org/caosdb/server/query/Query.java +++ b/src/main/java/org/caosdb/server/query/Query.java @@ -23,6 +23,7 @@ package org.caosdb.server.query; import static org.caosdb.server.database.DatabaseUtils.bytes2UTF8; + import java.sql.CallableStatement; import java.sql.Connection; import java.sql.PreparedStatement; @@ -167,12 +168,13 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac super(t); } } - + public static class IdVersionPair { public IdVersionPair(Integer id, String version) { this.id = id; this.version = version; } + public Integer id; public String version; } @@ -463,16 +465,24 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac } } - private List<IdVersionPair> getResultSet(final String resultSetTableName, boolean versioned) throws QueryException { + private List<IdVersionPair> getResultSet(final String resultSetTableName, boolean versioned) + throws QueryException { ResultSet finishResultSet = null; try { - final String sql = "Select results.id AS id" + (versioned?", ev.version AS version": "") +" from `" + resultSetTableName + "` AS results" + (versioned ? " JOIN entity_version AS ev ON (results.id = ev.entity_id AND results._iversion = ev._iversion)": ""); - final PreparedStatement finish = - getConnection().prepareStatement(sql); + final String sql = + "Select results.id AS id" + + (versioned ? ", ev.version AS version" : "") + + " from `" + + resultSetTableName + + "` AS results" + + (versioned + ? " JOIN entity_version AS ev ON (results.id = ev.entity_id AND results._iversion = ev._iversion)" + : ""); + final PreparedStatement finish = getConnection().prepareStatement(sql); finishResultSet = finish.executeQuery(); final List<IdVersionPair> rs = new LinkedList<>(); while (finishResultSet.next()) { - final String version = versioned ? finishResultSet.getString("version"): null; + final String version = versioned ? finishResultSet.getString("version") : null; rs.add(new IdVersionPair(finishResultSet.getInt("id"), version)); } return rs; diff --git a/src/main/java/org/caosdb/server/query/RoleFilter.java b/src/main/java/org/caosdb/server/query/RoleFilter.java index b51c55e2823218e81656c2ddb082187cb98df6dc..c29ea88398ec1ee316dbf51e206c7e859cff1df0 100644 --- a/src/main/java/org/caosdb/server/query/RoleFilter.java +++ b/src/main/java/org/caosdb/server/query/RoleFilter.java @@ -91,32 +91,31 @@ public class RoleFilter implements EntityFilterInterface { final String targetSet, final boolean versioned) throws SQLException { - final String sql = ("INSERT IGNORE INTO `" - + targetSet - + (sourceSet.equals("entities") - ? (versioned - ? "` (id, _iversion) SELECT e.id, _get_head_iversion(e.id) FROM `entities` AS e WHERE e.role " - + operator - + " ? UNION SELECT a.id, a._iversion FROM `archive_entities` AS a WHERE a.role" - + operator + "?" - : "` (id) SELECT e.id FROM `entities` AS e WHERE e.role" - + operator - + "?") - : (versioned - ? "` (id, _iversion) SELECT s.id, s._iversion FROM `" - + sourceSet - + "` LEFT JOIN archive_entities AS a ON (s.id = a.id AND s._iversion = a._iversion) WHERE a.role" - + operator - + "? UNION SELECT s.id, s._iversion FROM `" - + sourceSet - + "` LEFT JOIN entities AS e ON (s.id = e.id) WHERE e.role" - + operator - + "? AND a._iversion = _get_head_iversion(s.id)" - : "` (id) SELECT e.id FROM `entities` AS e WHERE e.role = ?"))); - final PreparedStatement filterRoleStmt = - connection.prepareCall(sql); - int params = (versioned ? 2: 1); - while(params>0) { + final String sql = + ("INSERT IGNORE INTO `" + + targetSet + + (sourceSet.equals("entities") + ? (versioned + ? "` (id, _iversion) SELECT e.id, _get_head_iversion(e.id) FROM `entities` AS e WHERE e.role " + + operator + + " ? UNION SELECT a.id, a._iversion FROM `archive_entities` AS a WHERE a.role" + + operator + + "?" + : "` (id) SELECT e.id FROM `entities` AS e WHERE e.role" + operator + "?") + : (versioned + ? "` (id, _iversion) SELECT s.id, s._iversion FROM `" + + sourceSet + + "` LEFT JOIN archive_entities AS a ON (s.id = a.id AND s._iversion = a._iversion) WHERE a.role" + + operator + + "? UNION SELECT s.id, s._iversion FROM `" + + sourceSet + + "` LEFT JOIN entities AS e ON (s.id = e.id) WHERE e.role" + + operator + + "? AND a._iversion = _get_head_iversion(s.id)" + : "` (id) SELECT e.id FROM `entities` AS e WHERE e.role = ?"))); + final PreparedStatement filterRoleStmt = connection.prepareCall(sql); + int params = (versioned ? 2 : 1); + while (params > 0) { filterRoleStmt.setString(params, role); params--; } diff --git a/src/main/java/org/caosdb/server/query/SubProperty.java b/src/main/java/org/caosdb/server/query/SubProperty.java index 5e3dc8c36e304d8ee776ffe638c55d24e46d0b3d..2f2311851ec83ad756bd7482f88976497a218573 100644 --- a/src/main/java/org/caosdb/server/query/SubProperty.java +++ b/src/main/java/org/caosdb/server/query/SubProperty.java @@ -24,6 +24,7 @@ package org.caosdb.server.query; import static java.sql.Types.VARCHAR; import static org.caosdb.server.database.DatabaseUtils.bytes2UTF8; + import java.sql.CallableStatement; import java.sql.Connection; import java.sql.ResultSet; @@ -89,18 +90,15 @@ public class SubProperty implements QueryInterface, EntityFilterInterface { getQuery().filterEntitiesWithoutRetrievePermission(this, this.sourceSet); final CallableStatement callFinishSubProperty = - getConnection().prepareCall("call finishSubProperty(?,?,?)"); - callFinishSubProperty.setString(1, query.getSourceSet()); // sourceSet - // of - // parent - // query + getConnection().prepareCall("call finishSubProperty(?,?,?,?)"); + callFinishSubProperty.setString(1, query.getSourceSet()); // sourceSet of parent query if (query.getTargetSet() != null) { // targetSet callFinishSubProperty.setString(2, query.getTargetSet()); } else { callFinishSubProperty.setNull(2, VARCHAR); } - callFinishSubProperty.setString(3, this.sourceSet); // sub query - // sourceSet + callFinishSubProperty.setString(3, this.sourceSet); // sub query sourceSet + callFinishSubProperty.setBoolean(4, this.isVersioned()); callFinishSubProperty.execute(); callFinishSubProperty.close(); } else { diff --git a/src/main/java/org/caosdb/server/query/VersionFilter.java b/src/main/java/org/caosdb/server/query/VersionFilter.java index 1ec31980d724d0c719b8bf39ef94d24c352ca758..aa391778ce20c089a9fa6dae88caf77e0f797703 100644 --- a/src/main/java/org/caosdb/server/query/VersionFilter.java +++ b/src/main/java/org/caosdb/server/query/VersionFilter.java @@ -4,5 +4,4 @@ public class VersionFilter { public static final VersionFilter ANY_VERSION = new VersionFilter(); public static final VersionFilter UNVERSIONED = new VersionFilter(); - } diff --git a/src/test/java/org/caosdb/server/query/TestCQL.java b/src/test/java/org/caosdb/server/query/TestCQL.java index a6c181b34e83eb6f79c2c0cb3b8dbab0fdb6b82a..2f6651cc81a2614b63f1314f35052fe2096758b0 100644 --- a/src/test/java/org/caosdb/server/query/TestCQL.java +++ b/src/test/java/org/caosdb/server/query/TestCQL.java @@ -28,6 +28,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; + import java.io.IOException; import java.sql.SQLException; import java.util.LinkedList; @@ -241,7 +242,7 @@ public class TestCQL { String emptyTextValue = "FIND ENTITY WITH prop=''"; String queryMR56 = "FIND ENTITY WITH ((p0 = v0 OR p1=v1) AND p2=v2)"; - + String versionedQuery1 = "FIND ANY VERSION OF ENTITY e1"; @Test @@ -6451,10 +6452,8 @@ public class TestCQL { final ParseTree pov = conjunction.getChild(4); assertEquals("p2=v2", pov.getText()); } - - /** - * String versionedQuery1 = "FIND ANY VERSION OF ENTITY e1"; - */ + + /** String versionedQuery1 = "FIND ANY VERSION OF ENTITY e1"; */ @Test public void testVersionedQuery1() { CQLLexer lexer; @@ -6471,6 +6470,5 @@ public class TestCQL { assertEquals(VersionFilter.ANY_VERSION, sfq.v); assertEquals(Query.Role.ENTITY, sfq.r); assertEquals("e1", sfq.e.toString()); - } }