Skip to content

Commit

Permalink
Fixes #3798: apoc.cypher.runFile() - Unexpected behaviour with commen…
Browse files Browse the repository at this point in the history
…ted ; (#3993)

* Fixes #3798: apoc.cypher.runFile() - Unexpected behaviour with commented ;

* removed unused imports
  • Loading branch information
vga91 committed Mar 14, 2024
1 parent fb01a29 commit 3389251
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 3 deletions.
11 changes: 8 additions & 3 deletions extended/src/main/java/apoc/cypher/CypherExtended.java
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ private <T> BlockingQueue<T> runInSeparateThreadAndSendTombstone(int queueCapaci
private void runDataStatementsInTx(Scanner scanner, 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;
if (isCommentOrEmpty(stmt)) continue;
boolean schemaOperation;
try {
schemaOperation = isSchemaOperation(stmt);
Expand Down Expand Up @@ -227,14 +227,14 @@ private void collectError(BlockingQueue<RowResult> queue, boolean reportError, E

private Scanner createScannerFor(Reader reader) {
Scanner scanner = new Scanner(reader);
scanner.useDelimiter(";\r?\n");
scanner.useDelimiter(";\s*\r?\n");
return scanner;
}

private void runSchemaStatementsInTx(Scanner scanner, 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;
if (isCommentOrEmpty(stmt)) continue;
boolean schemaOperation;
try {
schemaOperation = isSchemaOperation(stmt);
Expand All @@ -255,6 +255,11 @@ private void runSchemaStatementsInTx(Scanner scanner, BlockingQueue<RowResult> q
}
}

private static boolean isCommentOrEmpty(String stmt) {
String trimStatement = stmt.trim();
return trimStatement.isEmpty() || trimStatement.startsWith("//");
}

private final static Pattern shellControl = Pattern.compile("^:?\\b(begin|commit|rollback)\\b", Pattern.CASE_INSENSITIVE);

private Object consumeResult(Result result, BlockingQueue<RowResult> queue, boolean addStatistics, Transaction tx, String fileName) {
Expand Down
38 changes: 38 additions & 0 deletions extended/src/test/java/apoc/cypher/CypherExtendedTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,35 @@ public void testRunFile() throws Exception {
});
}

@Test
public void testRunFileWithCommentsAndEmptyRows() throws Exception {
testResult(db, "CALL apoc.cypher.runFile('return.cypher', {statistics: false})",
r -> {
Map<String, Object> row = r.next();
assertEquals(Map.of("\"Step 1\"", "Step 1"), row.get("result"));

row = r.next();
assertEquals(Map.of("row", "Step 3"), row.get("result"));

row = r.next();
assertEquals(Map.of("row", 6L), row.get("result"));

row = r.next();
assertEquals(Map.of("row", 7L), row.get("result"));

row = r.next();
assertEquals(Map.of("'8'", "8"), row.get("result"));

row = r.next();
assertEquals(Map.of("9", 9L), row.get("result"));

row = r.next();
assertEquals(Map.of("10", 10L), row.get("result"));

assertFalse(r.hasNext());
});
}

@Test
public void testRunFileWithAutoTransaction() {
final int expectedCount = 1000;
Expand Down Expand Up @@ -619,6 +648,15 @@ public void testSchemaRunFile() {
}
}

@Test
public void testRunSchemaFileWithCommentsAndEmptyRows() {
testResult(db, "CALL apoc.cypher.runSchemaFile('schemaWithCommentsAndEmptyRows.cypher')",
r -> {
assertSchemaCypherFile(r);
assertFalse(r.hasNext());
});
}

private void assertSchemaCypherFile(Result r) {
Map<String, Object> row = r.next();
Map result = (Map) row.get("result");
Expand Down
16 changes: 16 additions & 0 deletions extended/src/test/resources/return.cypher
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
RETURN "Step 1";
;
// RETURN "Step 2" as row;
RETURN "Step 3" AS row;
// RETURN "Step 4" as row;

// RETURN "Step 5" as row;

RETURN 6 as row;
// RETURN "Step 5" as row; // RETURN "Step 5" as row;
/*comment*/RETURN 7 /* comment*/ AS row;

/*comment*/RETURN '8'/*comment*/;
/*comment*/RETURN 9/*comment*/;
;
/*comment*/RETURN 10/*comment*/
13 changes: 13 additions & 0 deletions extended/src/test/resources/schemaWithCommentsAndEmptyRows.cypher
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
CREATE FULLTEXT INDEX CustomerIndex1 FOR (n:Customer1) ON EACH [n.name1];
;
// RETURN "Step 2" as row;
CREATE FULLTEXT INDEX CustomerIndex21 FOR (n:Customer21) ON EACH [n.name12];
// RETURN "Step 4" as row;

// RETURN "Step 5" as row;

// RETURN "Step 5" as row; // RETURN "Step 5" as row;
/*comment*/ CREATE FULLTEXT INDEX CustomerIndex231 FOR (n:Customer213) /* comment*/ ON EACH [n.name123];
;
/*comment*/RETURN '8'/*comment*/;
/*comment*/CREATE INDEX node_index_name FOR (n:Person) ON (n.surname);/*comment*/

0 comments on commit 3389251

Please sign in to comment.