From 14de8051d89ce11ee0e9105fd1d4584b7585a54e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louise=20S=C3=B6derstr=C3=B6m?= Date: Tue, 16 Jan 2018 17:33:18 +0100 Subject: [PATCH] Solve nested unwind bug in compiled runtime and add some feature tests. --- .../codegen/CompiledConversionUtils.java | 63 ++++++++++++------- .../resources/blacklists/compatibility-23.txt | 5 ++ .../cypher/features/UnwindAcceptance.feature | 54 ++++++++++++++++ 3 files changed, 101 insertions(+), 21 deletions(-) diff --git a/community/cypher/cypher/src/main/java/org/neo4j/cypher/internal/codegen/CompiledConversionUtils.java b/community/cypher/cypher/src/main/java/org/neo4j/cypher/internal/codegen/CompiledConversionUtils.java index 7149ab843cb0..b887bb6ca9ef 100644 --- a/community/cypher/cypher/src/main/java/org/neo4j/cypher/internal/codegen/CompiledConversionUtils.java +++ b/community/cypher/cypher/src/main/java/org/neo4j/cypher/internal/codegen/CompiledConversionUtils.java @@ -400,14 +400,26 @@ else if ( iterable instanceof PrimitiveEntityStream ) { return ((PrimitiveEntityStream) iterable).iterator(); } + else if ( iterable instanceof Long) + { + return (LongStream.of((Long) iterable)).iterator(); + } else if ( iterable instanceof LongStream ) { return ((LongStream) iterable).iterator(); } + else if ( iterable instanceof Double) + { + return (DoubleStream.of((Double) iterable)).iterator(); + } else if ( iterable instanceof DoubleStream ) { return ((DoubleStream) iterable).iterator(); } + else if ( iterable instanceof Integer) + { + return (IntStream.of((Integer) iterable)).iterator(); + } else if ( iterable instanceof IntStream ) { return ((IntStream) iterable).iterator(); @@ -416,30 +428,15 @@ else if ( iterable == null ) { return Collections.emptyIterator(); } + else if ( iterable instanceof String ) + { + String[] singleStringArray = {(String) iterable}; + return getIterator( singleStringArray, 1 ); + } else if ( iterable.getClass().isArray() ) { int len = Array.getLength( iterable ); - - return new Iterator() - { - private int position = 0; - - @Override - public boolean hasNext() - { - return position < len; - } - - @Override - public Object next() - { - if ( position >= len ) - { - throw new NoSuchElementException(); - } - return Array.get( iterable, position++ ); - } - }; + return getIterator( iterable, len ); } else { @@ -448,6 +445,30 @@ public Object next() } } + private static Iterator getIterator( Object iterable, int len ) + { + return new Iterator() + { + private int position = 0; + + @Override + public boolean hasNext() + { + return position < len; + } + + @Override + public Object next() + { + if ( position >= len ) + { + throw new NoSuchElementException(); + } + return Array.get( iterable, position++ ); + } + }; + } + @SuppressWarnings( "unchecked" ) public static LongStream toLongStream( Object list ) { diff --git a/enterprise/cypher/acceptance-spec-suite/src/test/resources/blacklists/compatibility-23.txt b/enterprise/cypher/acceptance-spec-suite/src/test/resources/blacklists/compatibility-23.txt index fa977abe7cba..cfe06213e636 100644 --- a/enterprise/cypher/acceptance-spec-suite/src/test/resources/blacklists/compatibility-23.txt +++ b/enterprise/cypher/acceptance-spec-suite/src/test/resources/blacklists/compatibility-23.txt @@ -65,3 +65,8 @@ Negative parameter for LIMIT should not generate errors //IndexAcceptance.feature STARTS WITH should handle null prefix + +//UnwindAcceptance.feature +Nested unwind with longs +Nested unwind with doubles +Nested unwind with strings diff --git a/enterprise/cypher/acceptance-spec-suite/src/test/resources/cypher/features/UnwindAcceptance.feature b/enterprise/cypher/acceptance-spec-suite/src/test/resources/cypher/features/UnwindAcceptance.feature index 6e2dcc247a63..d26272c4200d 100644 --- a/enterprise/cypher/acceptance-spec-suite/src/test/resources/cypher/features/UnwindAcceptance.feature +++ b/enterprise/cypher/acceptance-spec-suite/src/test/resources/cypher/features/UnwindAcceptance.feature @@ -228,3 +228,57 @@ Feature: UnwindAcceptance | 'c' | And no side effects + Scenario: Nested unwind with longs + Given an empty graph + When executing query: + """ + WITH [[1, 2], [3, 4], 5] AS nested + UNWIND nested AS x + UNWIND x AS y + RETURN y + """ + Then the result should be: + | y | + | 1 | + | 2 | + | 3 | + | 4 | + | 5 | + And no side effects + + Scenario: Nested unwind with doubles + Given an empty graph + When executing query: + """ + WITH [[1.5, 2.5], [3.5, 4.5], 5.5] AS nested + UNWIND nested AS x + UNWIND x AS y + RETURN y + """ + Then the result should be: + | y | + | 1.5 | + | 2.5 | + | 3.5 | + | 4.5 | + | 5.5 | + And no side effects + + Scenario: Nested unwind with strings + Given an empty graph + When executing query: + """ + WITH [['a', 'b'], ['c', 'd'], 'e'] AS nested + UNWIND nested AS x + UNWIND x AS y + RETURN y + """ + Then the result should be: + | y | + | 'a' | + | 'b' | + | 'c' | + | 'd' | + | 'e' | + And no side effects +