diff --git a/full/src/main/java/apoc/cypher/CypherExtended.java b/full/src/main/java/apoc/cypher/CypherExtended.java index c9e748102f..1943b284ac 100644 --- a/full/src/main/java/apoc/cypher/CypherExtended.java +++ b/full/src/main/java/apoc/cypher/CypherExtended.java @@ -250,7 +250,7 @@ private void runDataStatementsInTx( String fileName) { while (scanner.hasNext()) { String stmt = removeShellControlCommands(scanner.next()); - if (stmt.trim().isEmpty()) continue; + if (isCommentOrEmpty(stmt)) continue; // Periodic operations cannot be schema operations, so no need to check that here (will fail as invalid // query) @@ -303,7 +303,7 @@ private void collectError(BlockingQueue 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; } @@ -317,7 +317,7 @@ private void runSchemaStatementsInTx( 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); @@ -338,6 +338,11 @@ private void runSchemaStatementsInTx( } } + private static boolean isCommentOrEmpty(String stmt) { + String trimStatement = stmt.trim(); + return trimStatement.isEmpty() || trimStatement.startsWith("//"); + } + private static final Pattern shellControl = Pattern.compile("^:?\\b(begin|commit|rollback)\\b", Pattern.CASE_INSENSITIVE); diff --git a/full/src/test/java/apoc/cypher/CypherExtendedTest.java b/full/src/test/java/apoc/cypher/CypherExtendedTest.java index a75c8411e3..894053d5cd 100644 --- a/full/src/test/java/apoc/cypher/CypherExtendedTest.java +++ b/full/src/test/java/apoc/cypher/CypherExtendedTest.java @@ -200,6 +200,34 @@ public void testRunFile() throws Exception { }); } + @Test + public void testRunFileWithCommentsAndEmptyRows() throws Exception { + testResult(db, "CALL apoc.cypher.runFile('return.cypher', {statistics: false})", r -> { + Map 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 = 2000; @@ -640,6 +668,14 @@ 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 row = r.next(); Map result = (Map) row.get("result"); diff --git a/full/src/test/resources/return.cypher b/full/src/test/resources/return.cypher new file mode 100644 index 0000000000..65bf8c84aa --- /dev/null +++ b/full/src/test/resources/return.cypher @@ -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*/ \ No newline at end of file diff --git a/full/src/test/resources/schemaWithCommentsAndEmptyRows.cypher b/full/src/test/resources/schemaWithCommentsAndEmptyRows.cypher new file mode 100644 index 0000000000..8f20a6c436 --- /dev/null +++ b/full/src/test/resources/schemaWithCommentsAndEmptyRows.cypher @@ -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*/ \ No newline at end of file