Skip to content

Commit 7e6cf18

Browse files
authored
[aYPLiTQG] Remove isSchema check to be more performant (#4150)
1 parent 8d4fa33 commit 7e6cf18

File tree

3 files changed

+34
-25
lines changed

3 files changed

+34
-25
lines changed

full/src/main/java/apoc/cypher/CypherExtended.java

+30-23
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
import java.util.concurrent.BlockingQueue;
5050
import java.util.concurrent.ExecutionException;
5151
import java.util.concurrent.Future;
52+
import java.util.concurrent.atomic.AtomicBoolean;
5253
import java.util.function.Consumer;
5354
import java.util.regex.Matcher;
5455
import java.util.regex.Pattern;
@@ -207,8 +208,7 @@ private Stream<RowResult> runManyStatements(
207208
runSchemaStatementsInTx(
208209
scanner, internalQueue, params, addStatistics, timeout, reportError, fileName);
209210
} else {
210-
runDataStatementsInTx(
211-
scanner, internalQueue, params, addStatistics, timeout, reportError, fileName);
211+
runDataStatementsInTx(scanner, internalQueue, params, addStatistics, reportError, fileName);
212212
}
213213
},
214214
RowResult.TOMBSTONE);
@@ -246,40 +246,47 @@ private void runDataStatementsInTx(
246246
BlockingQueue<RowResult> queue,
247247
Map<String, Object> params,
248248
boolean addStatistics,
249-
long timeout,
250249
boolean reportError,
251250
String fileName) {
252251
while (scanner.hasNext()) {
253252
String stmt = removeShellControlCommands(scanner.next());
254253
if (stmt.trim().isEmpty()) continue;
255-
boolean schemaOperation;
256-
try {
257-
schemaOperation = isSchemaOperation(stmt);
258-
} catch (Exception e) {
259-
collectError(queue, reportError, e, fileName);
260-
return;
261-
}
262254

263-
if (!schemaOperation) {
264-
if (isPeriodicOperation(stmt)) {
265-
Util.inThread(pools, () -> {
266-
try {
267-
return db.executeTransactionally(
268-
stmt, params, result -> consumeResult(result, queue, addStatistics, tx, fileName));
269-
} catch (Exception e) {
270-
collectError(queue, reportError, e, fileName);
271-
return null;
272-
}
273-
});
274-
} else {
255+
// Periodic operations cannot be schema operations, so no need to check that here (will fail as invalid
256+
// query)
257+
if (isPeriodicOperation(stmt)) {
258+
Util.inThread(pools, () -> {
259+
try {
260+
return db.executeTransactionally(
261+
stmt, params, result -> consumeResult(result, queue, addStatistics, tx, fileName));
262+
} catch (Exception e) {
263+
collectError(queue, reportError, e, fileName);
264+
return null;
265+
}
266+
});
267+
} else {
268+
AtomicBoolean isSchemaError = new AtomicBoolean(false);
269+
try {
275270
Util.inTx(db, pools, threadTx -> {
276271
try (Result result = threadTx.execute(stmt, params)) {
277272
return consumeResult(result, queue, addStatistics, tx, fileName);
278273
} catch (Exception e) {
279-
collectError(queue, reportError, e, fileName);
274+
// APOC historically skips schema operations
275+
if (!(e.getMessage().contains("Schema operations on database")
276+
&& e.getMessage().contains("are not allowed"))) {
277+
collectError(queue, reportError, e, fileName);
278+
return null;
279+
}
280+
isSchemaError.set(true);
280281
return null;
281282
}
282283
});
284+
} catch (Exception e) {
285+
// An error thrown by a schema operation
286+
if (isSchemaError.get()) {
287+
continue;
288+
}
289+
throw e;
283290
}
284291
}
285292
}
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
CREATE (n:Person{id:1);
1+
CREATE INDEX ON :Node(id);
2+
CREATE (n:Person{id:1);
3+
CREATE (n:Person{id:1});
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
CREATE (n:Fail {foo: 1});
2-
2+
CREATE (n:Fail {foo: 2});

0 commit comments

Comments
 (0)