Skip to content

Commit

Permalink
[aYPLiTQG] Remove isSchema check to be more performant (#4150)
Browse files Browse the repository at this point in the history
  • Loading branch information
gem-neo4j authored Aug 29, 2024
1 parent 8d4fa33 commit 7e6cf18
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 25 deletions.
53 changes: 30 additions & 23 deletions full/src/main/java/apoc/cypher/CypherExtended.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
Expand Down Expand Up @@ -207,8 +208,7 @@ private Stream<RowResult> runManyStatements(
runSchemaStatementsInTx(
scanner, internalQueue, params, addStatistics, timeout, reportError, fileName);
} else {
runDataStatementsInTx(
scanner, internalQueue, params, addStatistics, timeout, reportError, fileName);
runDataStatementsInTx(scanner, internalQueue, params, addStatistics, reportError, fileName);
}
},
RowResult.TOMBSTONE);
Expand Down Expand Up @@ -246,40 +246,47 @@ private void runDataStatementsInTx(
BlockingQueue<RowResult> queue,
Map<String, Object> params,
boolean addStatistics,
long timeout,
boolean reportError,
String fileName) {
while (scanner.hasNext()) {
String stmt = removeShellControlCommands(scanner.next());
if (stmt.trim().isEmpty()) continue;
boolean schemaOperation;
try {
schemaOperation = isSchemaOperation(stmt);
} catch (Exception e) {
collectError(queue, reportError, e, fileName);
return;
}

if (!schemaOperation) {
if (isPeriodicOperation(stmt)) {
Util.inThread(pools, () -> {
try {
return db.executeTransactionally(
stmt, params, result -> consumeResult(result, queue, addStatistics, tx, fileName));
} catch (Exception e) {
collectError(queue, reportError, e, fileName);
return null;
}
});
} else {
// Periodic operations cannot be schema operations, so no need to check that here (will fail as invalid
// query)
if (isPeriodicOperation(stmt)) {
Util.inThread(pools, () -> {
try {
return db.executeTransactionally(
stmt, params, result -> consumeResult(result, queue, addStatistics, tx, fileName));
} catch (Exception e) {
collectError(queue, reportError, e, fileName);
return null;
}
});
} else {
AtomicBoolean isSchemaError = new AtomicBoolean(false);
try {
Util.inTx(db, pools, threadTx -> {
try (Result result = threadTx.execute(stmt, params)) {
return consumeResult(result, queue, addStatistics, tx, fileName);
} catch (Exception e) {
collectError(queue, reportError, e, fileName);
// APOC historically skips schema operations
if (!(e.getMessage().contains("Schema operations on database")
&& e.getMessage().contains("are not allowed"))) {
collectError(queue, reportError, e, fileName);
return null;
}
isSchemaError.set(true);
return null;
}
});
} catch (Exception e) {
// An error thrown by a schema operation
if (isSchemaError.get()) {
continue;
}
throw e;
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion full/src/test/resources/wrong_statements.cypher
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
CREATE (n:Person{id:1);
CREATE INDEX ON :Node(id);
CREATE (n:Person{id:1);
CREATE (n:Person{id:1});
2 changes: 1 addition & 1 deletion full/src/test/resources/wrong_statements_runtime.cypher
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
CREATE (n:Fail {foo: 1});

CREATE (n:Fail {foo: 2});

0 comments on commit 7e6cf18

Please sign in to comment.