From 0769be6f304d952810c4d2f634061eca2477ad14 Mon Sep 17 00:00:00 2001 From: Pontus Melke Date: Thu, 28 Apr 2016 18:49:33 +0100 Subject: [PATCH] Clean up and comments --- .../neo4j/codegen/BaseExpressionVisitor.java | 2 +- .../java/org/neo4j/codegen/Expression.java | 4 +- .../org/neo4j/codegen/ExpressionToString.java | 8 +- .../org/neo4j/codegen/ExpressionVisitor.java | 2 +- .../bytecode/ByteCodeExpressionVisitor.java | 2 +- .../bytecode/MethodByteCodeEmitter.java | 1 - .../codegen/source/MethodSourceWriter.java | 10 +- .../org/neo4j/codegen/CodeGenerationTest.java | 67 +-- .../acceptance/MatchAcceptanceTest.scala | 4 - .../compiler/v3_1/CompilationPhaseTracer.java | 7 +- .../v3_1/codegen/CodeGenConfiguration.scala | 4 +- .../compiler/v3_1/codegen/CodeGenerator.scala | 2 +- .../compiler/v3_1/codegen/CodeStructure.scala | 34 +- .../v3_1/codegen/ir/MethodInvocation.scala | 2 +- .../v3_1/codegen/ir/NullingInstruction.scala | 2 +- .../v3_1/codegen/ir/expressions/Equals.scala | 14 +- .../v3_1/codegen/ir/expressions/Literal.scala | 2 +- .../codegen/ir/expressions/LoadVariable.scala | 2 +- .../v3_1/codegen/ir/expressions/Modulo.scala | 2 +- .../codegen/ir/expressions/NodeProperty.scala | 2 +- .../v3_1/codegen/ir/expressions/Not.scala | 4 +- .../v3_1/codegen/ir/expressions/Or.scala | 6 +- .../codegen/ir/expressions/Parameter.scala | 2 +- .../v3_1/codegen/ir/expressions/TypeOf.scala | 4 +- .../ir/functions/CodeGenFunction1.scala | 2 +- .../cypher/internal/ExecutionEngine.scala | 3 +- .../spi/v2_3/GeneratedQueryStructure.scala | 34 +- .../spi/v3_0/GeneratedQueryStructure.scala | 26 +- .../codegen/GeneratedMethodStructure.scala | 528 +++++++++--------- .../codegen/GeneratedQueryStructure.scala | 145 +---- .../internal/spi/v3_1/codegen/Methods.scala | 6 +- .../internal/spi/v3_1/codegen/Templates.scala | 152 +++++ ...ianProductNotificationAcceptanceTest.scala | 1 - .../GeneratedMethodStructureTest.scala | 4 +- 34 files changed, 555 insertions(+), 535 deletions(-) create mode 100644 community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_1/codegen/Templates.scala diff --git a/community/codegen/src/main/java/org/neo4j/codegen/BaseExpressionVisitor.java b/community/codegen/src/main/java/org/neo4j/codegen/BaseExpressionVisitor.java index a73af80a774bd..72c2d1f6f219c 100644 --- a/community/codegen/src/main/java/org/neo4j/codegen/BaseExpressionVisitor.java +++ b/community/codegen/src/main/java/org/neo4j/codegen/BaseExpressionVisitor.java @@ -97,7 +97,7 @@ public void ternaryOnNonNull( Expression test, Expression onTrue, Expression onF } @Override - public void eq( Expression lhs, Expression rhs, TypeReference type ) + public void equal( Expression lhs, Expression rhs, TypeReference type ) { } diff --git a/community/codegen/src/main/java/org/neo4j/codegen/Expression.java b/community/codegen/src/main/java/org/neo4j/codegen/Expression.java index 7409e106fc27f..5b07d6e4588a5 100644 --- a/community/codegen/src/main/java/org/neo4j/codegen/Expression.java +++ b/community/codegen/src/main/java/org/neo4j/codegen/Expression.java @@ -58,14 +58,14 @@ public void accept( ExpressionVisitor visitor ) }; } - public static Expression eq( final Expression lhs, final Expression rhs, TypeReference type ) + public static Expression equal( final Expression lhs, final Expression rhs, TypeReference type ) { return new Expression() { @Override public void accept( ExpressionVisitor visitor ) { - visitor.eq( lhs, rhs, type ); + visitor.equal( lhs, rhs, type ); } }; } diff --git a/community/codegen/src/main/java/org/neo4j/codegen/ExpressionToString.java b/community/codegen/src/main/java/org/neo4j/codegen/ExpressionToString.java index 469d538908786..985e040cacb11 100644 --- a/community/codegen/src/main/java/org/neo4j/codegen/ExpressionToString.java +++ b/community/codegen/src/main/java/org/neo4j/codegen/ExpressionToString.java @@ -135,7 +135,7 @@ public void ternary( Expression test, Expression onTrue, Expression onFalse ) @Override public void ternaryOnNull( Expression test, Expression onTrue, Expression onFalse ) { - ternary( Expression.eq( test, Expression.constant( null ), TypeReference.OBJECT ), + ternary( Expression.equal( test, Expression.constant( null ), TypeReference.OBJECT ), onTrue, onFalse ); } @@ -143,14 +143,14 @@ public void ternaryOnNull( Expression test, Expression onTrue, Expression onFals public void ternaryOnNonNull( Expression test, Expression onTrue, Expression onFalse ) { ternary( Expression.not( - Expression.eq( test, Expression.constant( null ), TypeReference.OBJECT )), + Expression.equal( test, Expression.constant( null ), TypeReference.OBJECT )), onTrue, onFalse ); } @Override - public void eq( Expression lhs, Expression rhs, TypeReference ignored ) + public void equal( Expression lhs, Expression rhs, TypeReference ignored ) { - result.append( "eq(" ); + result.append( "equal(" ); lhs.accept( this ); result.append( ", " ); rhs.accept( this ); diff --git a/community/codegen/src/main/java/org/neo4j/codegen/ExpressionVisitor.java b/community/codegen/src/main/java/org/neo4j/codegen/ExpressionVisitor.java index c2433c2c66c88..e13f7683bd14e 100644 --- a/community/codegen/src/main/java/org/neo4j/codegen/ExpressionVisitor.java +++ b/community/codegen/src/main/java/org/neo4j/codegen/ExpressionVisitor.java @@ -45,7 +45,7 @@ public interface ExpressionVisitor void ternaryOnNonNull( Expression test, Expression onTrue, Expression onFalse ); - void eq( Expression lhs, Expression rhs, TypeReference type ); + void equal( Expression lhs, Expression rhs, TypeReference type ); void or( Expression lhs, Expression rhs ); diff --git a/community/codegen/src/main/java/org/neo4j/codegen/bytecode/ByteCodeExpressionVisitor.java b/community/codegen/src/main/java/org/neo4j/codegen/bytecode/ByteCodeExpressionVisitor.java index 7dffc3eac29d1..09e40e7b9e6b1 100644 --- a/community/codegen/src/main/java/org/neo4j/codegen/bytecode/ByteCodeExpressionVisitor.java +++ b/community/codegen/src/main/java/org/neo4j/codegen/bytecode/ByteCodeExpressionVisitor.java @@ -215,7 +215,7 @@ public void ternaryOnNonNull( Expression test, Expression onTrue, Expression onF } @Override - public void eq( Expression lhs, Expression rhs, TypeReference type ) + public void equal( Expression lhs, Expression rhs, TypeReference type ) { switch ( type.simpleName() ) { diff --git a/community/codegen/src/main/java/org/neo4j/codegen/bytecode/MethodByteCodeEmitter.java b/community/codegen/src/main/java/org/neo4j/codegen/bytecode/MethodByteCodeEmitter.java index 0e294d6e96ecd..74b3594dd5b57 100644 --- a/community/codegen/src/main/java/org/neo4j/codegen/bytecode/MethodByteCodeEmitter.java +++ b/community/codegen/src/main/java/org/neo4j/codegen/bytecode/MethodByteCodeEmitter.java @@ -316,7 +316,6 @@ private boolean needsToCallSuperConstructor() return declaration.isConstructor() && !calledSuper; } - private boolean loadsSuper( Expression expression ) { final boolean[] loadsSuper = new boolean[]{false}; diff --git a/community/codegen/src/main/java/org/neo4j/codegen/source/MethodSourceWriter.java b/community/codegen/src/main/java/org/neo4j/codegen/source/MethodSourceWriter.java index 3cbea3f74f81d..49e2dfbd5c876 100644 --- a/community/codegen/src/main/java/org/neo4j/codegen/source/MethodSourceWriter.java +++ b/community/codegen/src/main/java/org/neo4j/codegen/source/MethodSourceWriter.java @@ -161,13 +161,13 @@ public void beginIfNot( Expression test ) @Override public void beginIfNull( Expression test ) { - beginIf(Expression.eq(test, Expression.constant( null ), TypeReference.OBJECT)); + beginIf(Expression.equal(test, Expression.constant( null ), TypeReference.OBJECT)); } @Override public void beginIfNonNull( Expression test ) { - beginIfNot(Expression.eq(test, Expression.constant( null ), TypeReference.OBJECT)); + beginIfNot(Expression.equal(test, Expression.constant( null ), TypeReference.OBJECT)); } @Override @@ -329,7 +329,7 @@ public void ternary( Expression test, Expression onTrue, Expression onFalse ) @Override public void ternaryOnNull( Expression test, Expression onTrue, Expression onFalse ) { - ternary( Expression.eq( test, Expression.constant( null ), TypeReference.OBJECT ), + ternary( Expression.equal( test, Expression.constant( null ), TypeReference.OBJECT ), onTrue, onFalse ); } @@ -337,12 +337,12 @@ public void ternaryOnNull( Expression test, Expression onTrue, Expression onFals public void ternaryOnNonNull( Expression test, Expression onTrue, Expression onFalse ) { ternary( Expression.not( - Expression.eq( test, Expression.constant( null ), TypeReference.OBJECT )), + Expression.equal( test, Expression.constant( null ), TypeReference.OBJECT )), onTrue, onFalse ); } @Override - public void eq( Expression lhs, Expression rhs, TypeReference ignored ) + public void equal( Expression lhs, Expression rhs, TypeReference ignored ) { lhs.accept( this ); append( " == " ); diff --git a/community/codegen/src/test/java/org/neo4j/codegen/CodeGenerationTest.java b/community/codegen/src/test/java/org/neo4j/codegen/CodeGenerationTest.java index e231b7899d9d2..09e8eac4d159c 100644 --- a/community/codegen/src/test/java/org/neo4j/codegen/CodeGenerationTest.java +++ b/community/codegen/src/test/java/org/neo4j/codegen/CodeGenerationTest.java @@ -384,7 +384,6 @@ public void shouldGenerateStaticParameterizedTypeField() throws Throwable assertEquals( Arrays.asList( "FOO", "BAR", "BAZ" ), foo ); } - public interface Thrower { void doThrow() throws E; @@ -545,7 +544,6 @@ public void shouldGenerateNestedWhileLoop() throws Throwable methodReference( Iterator.class, boolean.class, "hasNext" ) ) ) ) { - inner.expression( invoke( Expression.cast( Runnable.class, invoke( callEach.load( "targets" ), @@ -1005,7 +1003,6 @@ public void shouldHandleTernaryOperator() throws Throwable assertTrue( checker1.ranOnTrue ); assertFalse( checker1.ranOnFalse ); - TernaryChecker checker2 = new TernaryChecker(); assertThat( ternary.invoke( false, checker2 ), equalTo( "on false" ) ); assertFalse( checker2.ranOnTrue ); @@ -1043,7 +1040,6 @@ public void shouldHandleTernaryOnNullOperator() throws Throwable assertTrue( checker1.ranOnTrue ); assertFalse( checker1.ranOnFalse ); - TernaryChecker checker2 = new TernaryChecker(); assertThat( ternary.invoke( new Object(), checker2 ), equalTo( "on false" ) ); assertFalse( checker2.ranOnTrue ); @@ -1081,7 +1077,6 @@ public void shouldHandleTernaryOnNonNullOperator() throws Throwable assertTrue( checker1.ranOnTrue ); assertFalse( checker1.ranOnFalse ); - TernaryChecker checker2 = new TernaryChecker(); assertThat( ternary.invoke( null, checker2 ), equalTo( "on false" ) ); assertFalse( checker2.ranOnTrue ); @@ -1093,79 +1088,79 @@ public void shouldHandleEquality() throws Throwable { // boolean assertTrue( compareForType( boolean.class, true, true, - ( a, b ) -> Expression.eq( a, b, typeReference( boolean.class ) ) ) ); + ( a, b ) -> Expression.equal( a, b, typeReference( boolean.class ) ) ) ); assertTrue( compareForType( boolean.class, false, false, - ( a, b ) -> Expression.eq( a, b, typeReference( boolean.class ) ) ) ); + ( a, b ) -> Expression.equal( a, b, typeReference( boolean.class ) ) ) ); assertFalse( compareForType( boolean.class, true, false, - ( a, b ) -> Expression.eq( a, b, typeReference( boolean.class ) ) ) ); + ( a, b ) -> Expression.equal( a, b, typeReference( boolean.class ) ) ) ); assertFalse( compareForType( boolean.class, false, true, - ( a, b ) -> Expression.eq( a, b, typeReference( boolean.class ) ) ) ); + ( a, b ) -> Expression.equal( a, b, typeReference( boolean.class ) ) ) ); // byte assertTrue( compareForType( byte.class, (byte) 42, (byte) 42, - ( a, b ) -> Expression.eq( a, b, typeReference( byte.class ) ) ) ); + ( a, b ) -> Expression.equal( a, b, typeReference( byte.class ) ) ) ); assertFalse( compareForType( byte.class, (byte) 43, (byte) 42, - ( a, b ) -> Expression.eq( a, b, typeReference( byte.class ) ) ) ); + ( a, b ) -> Expression.equal( a, b, typeReference( byte.class ) ) ) ); assertFalse( compareForType( byte.class, (byte) 42, (byte) 43, - ( a, b ) -> Expression.eq( a, b, typeReference( byte.class ) ) ) ); + ( a, b ) -> Expression.equal( a, b, typeReference( byte.class ) ) ) ); // short assertTrue( compareForType( short.class, (short) 42, (short) 42, - ( a, b ) -> Expression.eq( a, b, typeReference( short.class ) ) ) ); + ( a, b ) -> Expression.equal( a, b, typeReference( short.class ) ) ) ); assertFalse( compareForType( short.class, (short) 43, (short) 42, - ( a, b ) -> Expression.eq( a, b, typeReference( short.class ) ) ) ); + ( a, b ) -> Expression.equal( a, b, typeReference( short.class ) ) ) ); assertFalse( compareForType( short.class, (short) 42, (short) 43, - ( a, b ) -> Expression.eq( a, b, typeReference( short.class ) ) ) ); + ( a, b ) -> Expression.equal( a, b, typeReference( short.class ) ) ) ); // char assertTrue( compareForType( char.class, (char) 42, (char) 42, - ( a, b ) -> Expression.eq( a, b, typeReference( char.class ) ) ) ); + ( a, b ) -> Expression.equal( a, b, typeReference( char.class ) ) ) ); assertFalse( compareForType( char.class, (char) 43, (char) 42, - ( a, b ) -> Expression.eq( a, b, typeReference( char.class ) ) ) ); + ( a, b ) -> Expression.equal( a, b, typeReference( char.class ) ) ) ); assertFalse( compareForType( char.class, (char) 42, (char) 43, - ( a, b ) -> Expression.eq( a, b, typeReference( char.class ) ) ) ); + ( a, b ) -> Expression.equal( a, b, typeReference( char.class ) ) ) ); //int assertTrue( compareForType( int.class, 42, 42, - ( a, b ) -> Expression.eq( a, b, typeReference( int.class ) ) ) ); + ( a, b ) -> Expression.equal( a, b, typeReference( int.class ) ) ) ); assertFalse( compareForType( int.class, 43, 42, - ( a, b ) -> Expression.eq( a, b, typeReference( int.class ) ) ) ); + ( a, b ) -> Expression.equal( a, b, typeReference( int.class ) ) ) ); assertFalse( compareForType( int.class, 42, 43, - ( a, b ) -> Expression.eq( a, b, typeReference( int.class ) ) ) ); + ( a, b ) -> Expression.equal( a, b, typeReference( int.class ) ) ) ); //long assertTrue( compareForType( long.class, 42L, 42L, - ( a, b ) -> Expression.eq( a, b, typeReference( long.class ) ) ) ); + ( a, b ) -> Expression.equal( a, b, typeReference( long.class ) ) ) ); assertFalse( compareForType( long.class, 43L, 42L, - ( a, b ) -> Expression.eq( a, b, typeReference( long.class ) ) ) ); + ( a, b ) -> Expression.equal( a, b, typeReference( long.class ) ) ) ); assertFalse( compareForType( long.class, 42L, 43L, - ( a, b ) -> Expression.eq( a, b, typeReference( long.class ) ) ) ); + ( a, b ) -> Expression.equal( a, b, typeReference( long.class ) ) ) ); //float assertTrue( compareForType( float.class, 42F, 42F, - ( a, b ) -> Expression.eq( a, b, typeReference( float.class ) ) ) ); + ( a, b ) -> Expression.equal( a, b, typeReference( float.class ) ) ) ); assertFalse( compareForType( float.class, 43F, 42F, - ( a, b ) -> Expression.eq( a, b, typeReference( float.class ) ) ) ); + ( a, b ) -> Expression.equal( a, b, typeReference( float.class ) ) ) ); assertFalse( compareForType( float.class, 42F, 43F, - ( a, b ) -> Expression.eq( a, b, typeReference( float.class ) ) ) ); + ( a, b ) -> Expression.equal( a, b, typeReference( float.class ) ) ) ); //double assertTrue( compareForType( double.class, 42D, 42D, - ( a, b ) -> Expression.eq( a, b, typeReference( double.class ) ) ) ); + ( a, b ) -> Expression.equal( a, b, typeReference( double.class ) ) ) ); assertFalse( compareForType( double.class, 43D, 42D, - ( a, b ) -> Expression.eq( a, b, typeReference( double.class ) ) ) ); + ( a, b ) -> Expression.equal( a, b, typeReference( double.class ) ) ) ); assertFalse( compareForType( double.class, 42D, 43D, - ( a, b ) -> Expression.eq( a, b, typeReference( double.class ) ) ) ); + ( a, b ) -> Expression.equal( a, b, typeReference( double.class ) ) ) ); //reference Object obj1 = new Object(); Object obj2 = new Object(); assertTrue( compareForType( Object.class, obj1, obj1, - ( a, b ) -> Expression.eq( a, b, typeReference( Object.class ) ) ) ); + ( a, b ) -> Expression.equal( a, b, typeReference( Object.class ) ) ) ); assertFalse( compareForType( Object.class, obj1, obj2, - ( a, b ) -> Expression.eq( a, b, typeReference( Object.class ) ) ) ); + ( a, b ) -> Expression.equal( a, b, typeReference( Object.class ) ) ) ); assertFalse( compareForType( Object.class, obj2, obj1, - ( a, b ) -> Expression.eq( a, b, typeReference( Object.class ) ) ) ); + ( a, b ) -> Expression.equal( a, b, typeReference( Object.class ) ) ) ); } @Test @@ -1410,7 +1405,6 @@ public void shouldGenerateTryCatch() throws Throwable doThrow( theFailure ).when( failBody ).run(); MethodHandle run = instanceMethod( handle.newInstance(), "run", Runnable.class, Runnable.class ); - //success run.invoke( successBody, successCatch ); verify( successBody ).run(); @@ -1454,7 +1448,6 @@ public void shouldGenerateTryCatchWithNestedBlock() throws Throwable Runnable runnable = mock( Runnable.class ); MethodHandle run = instanceMethod( handle.newInstance(), "run", Runnable.class, Runnable.class, boolean.class ); - // then run.invoke( runnable, mock( Runnable.class ), false ); verify( runnable, never() ).run(); @@ -1489,7 +1482,6 @@ public void shouldGenerateTryAndMultipleCatch() throws Throwable } // when - Runnable body1 = mock( Runnable.class ), body2 = mock( Runnable.class ), catcher11 = mock( Runnable.class ), catcher12 = mock( Runnable.class ), catcher21 = mock( Runnable.class ), catcher22 = mock( Runnable.class ); @@ -1499,20 +1491,17 @@ public void shouldGenerateTryAndMultipleCatch() throws Throwable MethodHandle run = instanceMethod( handle.newInstance(), "run", Runnable.class, Runnable.class, Runnable.class ); - run.invoke( body1, catcher11, catcher12 ); verify( body1 ).run(); verify( catcher11 ).run(); verify( catcher12, never() ).run(); - run.invoke( body2, catcher21, catcher22 ); verify( body2 ).run(); verify( catcher22 ).run(); verify( catcher21, never() ).run(); } - @Test public void shouldThrowException() throws Throwable { diff --git a/community/cypher/acceptance/src/test/scala/org/neo4j/internal/cypher/acceptance/MatchAcceptanceTest.scala b/community/cypher/acceptance/src/test/scala/org/neo4j/internal/cypher/acceptance/MatchAcceptanceTest.scala index 4a486bd399770..8c53c49aefc72 100644 --- a/community/cypher/acceptance/src/test/scala/org/neo4j/internal/cypher/acceptance/MatchAcceptanceTest.scala +++ b/community/cypher/acceptance/src/test/scala/org/neo4j/internal/cypher/acceptance/MatchAcceptanceTest.scala @@ -28,10 +28,6 @@ import scala.collection.JavaConverters._ class MatchAcceptanceTest extends ExecutionEngineFunSuite with QueryStatisticsTestSupport with NewPlannerTestSupport { - test("foo") { - println(executeWithAllPlanners("EXPLAIN RETURN 1 + 2").executionPlanDescription()) - println(executeWithAllPlannersAndRuntimesAndCompatibilityMode("RETURN 1 + 2").dumpToString()) - } test("make sure non-existing nodes are not returned") { executeWithAllPlannersAndCompatibilityMode("match (n) where id(n) = 10 return n") should be(empty) executeWithAllPlannersAndCompatibilityMode("match ()-[r]->() where id(r) = 10 return r") should be(empty) diff --git a/community/cypher/cypher-compiler-3.1/src/main/java/org/neo4j/cypher/internal/compiler/v3_1/CompilationPhaseTracer.java b/community/cypher/cypher-compiler-3.1/src/main/java/org/neo4j/cypher/internal/compiler/v3_1/CompilationPhaseTracer.java index d0bfd98925828..c85a1b4b8ac53 100644 --- a/community/cypher/cypher-compiler-3.1/src/main/java/org/neo4j/cypher/internal/compiler/v3_1/CompilationPhaseTracer.java +++ b/community/cypher/cypher-compiler-3.1/src/main/java/org/neo4j/cypher/internal/compiler/v3_1/CompilationPhaseTracer.java @@ -47,11 +47,6 @@ public CompilationPhaseEvent beginPhase( CompilationPhase phase ) return NONE_PHASE; } }; - CompilationPhaseEvent NONE_PHASE = new CompilationPhaseEvent() - { - @Override - public void close() - { - } + CompilationPhaseEvent NONE_PHASE = () -> { }; } diff --git a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/CodeGenConfiguration.scala b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/CodeGenConfiguration.scala index c401b05b709d2..5f854aa52981f 100644 --- a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/CodeGenConfiguration.scala +++ b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/CodeGenConfiguration.scala @@ -19,7 +19,7 @@ */ package org.neo4j.cypher.internal.compiler.v3_1.codegen -import org.neo4j.helpers.Clock +import java.time.Clock /** * Configuration modes for code generation @@ -47,6 +47,6 @@ case object ByteCodeMode extends CodeGenMode */ case class CodeGenConfiguration(mode: CodeGenMode = ByteCodeMode, saveSource: Boolean = false, - clock: Clock = Clock.SYSTEM_CLOCK, + clock: Clock = Clock.systemUTC(), packageName: String = "org.neo4j.cypher.internal.compiler.v3_1.generated" ) diff --git a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/CodeGenerator.scala b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/CodeGenerator.scala index ee1511fd2c72a..4a9a433e90da7 100644 --- a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/CodeGenerator.scala +++ b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/CodeGenerator.scala @@ -51,7 +51,7 @@ class CodeGenerator(val structure: CodeStructure[GeneratedQuery], conf: CodeGenC val fp = planContext.statistics match { case igs: InstrumentedGraphStatistics => - Some(PlanFingerprint(conf.clock.currentTimeMillis(), planContext.txIdProvider(), igs.snapshot.freeze)) + Some(PlanFingerprint(conf.clock.millis(), planContext.txIdProvider(), igs.snapshot.freeze)) case _ => None } diff --git a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/CodeStructure.scala b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/CodeStructure.scala index 71af0bd859f11..c3d6a090d6f0b 100644 --- a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/CodeStructure.scala +++ b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/CodeStructure.scala @@ -45,6 +45,20 @@ case object LongsToCountTable extends CountingJoinTableType case class LongToListTable(structure: Map[String, CodeGenType], localMap: Map[String, String]) extends RecordingJoinTableType case class LongsToListTable(structure: Map[String, CodeGenType], localMap: Map[String, String]) extends RecordingJoinTableType +/** + * Describes the SPI for generating a method. + * + * In principle you can think of it as you have a method, e.g. + * + * {{{ + * public void foo + * { + * ... + * } + * }}} + * + * This SPI describes the operations that can be put in that method. + */ trait MethodStructure[E] { // misc @@ -60,14 +74,14 @@ trait MethodStructure[E] { def probe(tableVar: String, tableType: JoinTableType, keyVars: Seq[String])(block: MethodStructure[E]=>Unit): Unit def updateProbeTableCount(tableVar: String, tableType: CountingJoinTableType, keyVar: Seq[String]): Unit def allocateProbeTable(tableVar: String, tableType: JoinTableType): Unit - def method(resultType: JoinTableType, resultVar: String, methodName: String)(block: MethodStructure[E]=>Unit): Unit + def invokeMethod(resultType: JoinTableType, resultVar: String, methodName: String)(block: MethodStructure[E]=>Unit): Unit def coerceToBoolean(propertyExpression: E): E // expressions def decreaseCounterAndCheckForZero(name: String): E def counterEqualsZero(variableName: String): E def newTableValue(targetVar: String, structure: Map[String, CodeGenType]): E - def constant(value: Object): E + def constantExpression(value: Object): E def asMap(map: Map[String, E]): E def asList(values: Seq[E]): E @@ -75,22 +89,22 @@ trait MethodStructure[E] { def castToCollection(value: E): E - def load(varName: String): E + def loadVariable(varName: String): E // arithmetic def add(lhs: E, rhs: E): E def subtract(lhs: E, rhs: E): E def multiply(lhs: E, rhs: E): E def divide(lhs: E, rhs: E): E - def mod(lhs: E, rhs: E): E + def modulus(lhs: E, rhs: E): E // predicates - def threeValuedNot(value: E): E - def not(value: E): E - def threeValuedEquals(lhs: E, rhs: E): E - def eq(lhs: E, rhs: E, codeGenType: CodeGenType): E - def or(lhs: E, rhs: E): E - def threeValuedOr(lhs: E, rhs: E): E + def threeValuedNotExpression(value: E): E + def notExpression(value: E): E + def threeValuedEqualsExpression(lhs: E, rhs: E): E + def equalityExpression(lhs: E, rhs: E, codeGenType: CodeGenType): E + def orExpression(lhs: E, rhs: E): E + def threeValuedOrExpression(lhs: E, rhs: E): E // object handling def markAsNull(varName: String, codeGenType: CodeGenType): Unit diff --git a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/MethodInvocation.scala b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/MethodInvocation.scala index 5cb6c4f6a709c..f6c1cc3b0b6cd 100644 --- a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/MethodInvocation.scala +++ b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/MethodInvocation.scala @@ -29,7 +29,7 @@ case class MethodInvocation(override val operatorId: Set[String], override def init[E](generator: MethodStructure[E])(implicit context: CodeGenContext) = {} override def body[E](generator: MethodStructure[E])(implicit context: CodeGenContext) = { - generator.method(symbol.tableType, symbol.name, methodName) { body => + generator.invokeMethod(symbol.tableType, symbol.name, methodName) { body => statements.foreach(_.init(body)) statements.foreach(_.body(body)) } diff --git a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/NullingInstruction.scala b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/NullingInstruction.scala index a021e3d178de5..99f4249efd895 100644 --- a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/NullingInstruction.scala +++ b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/NullingInstruction.scala @@ -36,7 +36,7 @@ case class NullingInstruction(loop: Instruction, yieldedFlagVar: String, alterna override def body[E](generator: MethodStructure[E])(implicit context: CodeGenContext) = { generator.declareFlag(yieldedFlagVar, initialValue = false) loop.body(generator) - generator.ifNotStatement(generator.load(yieldedFlagVar)){ ifBody => + generator.ifNotStatement(generator.loadVariable(yieldedFlagVar)){ ifBody => //mark variables as null nullableVars.foreach(v => ifBody.markAsNull(v.name, deriveCodeGenType(v.cypherType))) alternativeAction.body(ifBody) diff --git a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/expressions/Equals.scala b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/expressions/Equals.scala index 0bd865705c265..85d0ea84da75b 100644 --- a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/expressions/Equals.scala +++ b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/expressions/Equals.scala @@ -41,18 +41,18 @@ case class Equals(lhs: CodeGenExpression, rhs: CodeGenExpression) extends CodeGe } override def generateExpression[E](structure: MethodStructure[E])(implicit context: CodeGenContext) = { - if (nullable) structure.threeValuedEquals(structure.box(lhs.generateExpression(structure), lhs.codeGenType), - structure.box(rhs.generateExpression(structure), rhs.codeGenType)) + if (nullable) structure.threeValuedEqualsExpression(structure.box(lhs.generateExpression(structure), lhs.codeGenType), + structure.box(rhs.generateExpression(structure), rhs.codeGenType)) else (lhs, rhs) match { - case (NodeExpression(v1), NodeExpression(v2)) => structure.eq(structure.load(v1.name), structure.load(v2.name), CodeGenType.primitiveNode) - case (RelationshipExpression(v1), RelationshipExpression(v2)) => structure.eq(structure.load(v1.name), structure.load(v2.name), - CodeGenType.primitiveRel) + case (NodeExpression(v1), NodeExpression(v2)) => structure.equalityExpression(structure.loadVariable(v1.name), structure.loadVariable(v2.name), CodeGenType.primitiveNode) + case (RelationshipExpression(v1), RelationshipExpression(v2)) => structure.equalityExpression(structure.loadVariable(v1.name), structure.loadVariable(v2.name), + CodeGenType.primitiveRel) case (NodeExpression(_), RelationshipExpression(_)) => throw new IncomparableValuesException(symbols.CTNode.toString, symbols.CTRelationship.toString) case (RelationshipExpression(_), NodeExpression(_)) => throw new IncomparableValuesException(symbols.CTNode.toString, symbols.CTRelationship.toString) - case _ => structure.threeValuedEquals(structure.box(lhs.generateExpression(structure), lhs. codeGenType), - structure.box(rhs.generateExpression(structure), rhs.codeGenType)) + case _ => structure.threeValuedEqualsExpression(structure.box(lhs.generateExpression(structure), lhs. codeGenType), + structure.box(rhs.generateExpression(structure), rhs.codeGenType)) } } } diff --git a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/expressions/Literal.scala b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/expressions/Literal.scala index 35bce18a2b537..abac429aa660e 100644 --- a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/expressions/Literal.scala +++ b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/expressions/Literal.scala @@ -27,7 +27,7 @@ case class Literal(value: Object) extends CodeGenExpression { override def init[E](generator: MethodStructure[E])(implicit context: CodeGenContext) = {} override def generateExpression[E](structure: MethodStructure[E])(implicit context: CodeGenContext) = - structure.constant(value) + structure.constantExpression(value) override def nullable(implicit context: CodeGenContext) = value == null diff --git a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/expressions/LoadVariable.scala b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/expressions/LoadVariable.scala index e28802e46c4cc..4b187ff2f2b49 100644 --- a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/expressions/LoadVariable.scala +++ b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/expressions/LoadVariable.scala @@ -27,7 +27,7 @@ case class LoadVariable(variable: Variable) extends CodeGenExpression { override def init[E](generator: MethodStructure[E])(implicit context: CodeGenContext) = {} override def generateExpression[E](structure: MethodStructure[E])(implicit context: CodeGenContext) = - structure.load(variable.name) + structure.loadVariable(variable.name) override def nullable(implicit context: CodeGenContext): Boolean = variable.nullable diff --git a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/expressions/Modulo.scala b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/expressions/Modulo.scala index cfe85b261282a..01ff82bae7c18 100644 --- a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/expressions/Modulo.scala +++ b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/expressions/Modulo.scala @@ -24,7 +24,7 @@ import org.neo4j.cypher.internal.frontend.v3_1.symbols._ case class Modulo(lhs: CodeGenExpression, rhs: CodeGenExpression) extends CodeGenExpression with BinaryOperator { - override protected def generator[E](structure: MethodStructure[E])(implicit context: CodeGenContext) = structure.mod + override protected def generator[E](structure: MethodStructure[E])(implicit context: CodeGenContext) = structure.modulus override def nullable(implicit context: CodeGenContext) = lhs.nullable || rhs.nullable override def codeGenType(implicit context: CodeGenContext) = CodeGenType(CTFloat, ReferenceType) diff --git a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/expressions/NodeProperty.scala b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/expressions/NodeProperty.scala index 5bda1d5c574b9..a0d203a65baae 100644 --- a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/expressions/NodeProperty.scala +++ b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/expressions/NodeProperty.scala @@ -34,7 +34,7 @@ abstract class ElementProperty(token: Option[Int], propName: String, elementIdVa else propertyById(structure, localName) structure.incrementDbHits() - structure.load(localName) + structure.loadVariable(localName) } def propertyByName[E](body: MethodStructure[E], localName: String): Unit diff --git a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/expressions/Not.scala b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/expressions/Not.scala index 6231a36c5a15a..3906bb4266865 100644 --- a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/expressions/Not.scala +++ b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/expressions/Not.scala @@ -29,8 +29,8 @@ case class Not(inner: CodeGenExpression) extends CodeGenExpression { } override def generateExpression[E](structure: MethodStructure[E])(implicit context: CodeGenContext) = - if (!nullable && inner.codeGenType.ct == CTBoolean) structure.not(inner.generateExpression(structure)) - else structure.threeValuedNot(structure.box(inner.generateExpression(structure), inner.codeGenType)) + if (!nullable && inner.codeGenType.ct == CTBoolean) structure.notExpression(inner.generateExpression(structure)) + else structure.threeValuedNotExpression(structure.box(inner.generateExpression(structure), inner.codeGenType)) override def nullable(implicit context: CodeGenContext) = inner.nullable diff --git a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/expressions/Or.scala b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/expressions/Or.scala index 99c58517798cf..ab2ecd4333d58 100644 --- a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/expressions/Or.scala +++ b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/expressions/Or.scala @@ -38,7 +38,7 @@ case class Or(lhs: CodeGenExpression, rhs: CodeGenExpression) extends CodeGenExp override def generateExpression[E](structure: MethodStructure[E])(implicit context: CodeGenContext): E = if (!nullable && lhs.codeGenType.ct == CTBoolean && rhs.codeGenType.ct == CTBoolean) - structure.or(lhs.generateExpression(structure), rhs.generateExpression(structure)) - else structure.threeValuedOr(structure.box(lhs.generateExpression(structure), lhs.codeGenType), - structure.box(rhs.generateExpression(structure), rhs.codeGenType)) + structure.orExpression(lhs.generateExpression(structure), rhs.generateExpression(structure)) + else structure.threeValuedOrExpression(structure.box(lhs.generateExpression(structure), lhs.codeGenType), + structure.box(rhs.generateExpression(structure), rhs.codeGenType)) } diff --git a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/expressions/Parameter.scala b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/expressions/Parameter.scala index e690b767786c0..6dbdaf7d2b56e 100644 --- a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/expressions/Parameter.scala +++ b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/expressions/Parameter.scala @@ -27,7 +27,7 @@ case class Parameter(key: String, variableName: String) extends CodeGenExpressio generator.expectParameter(key, variableName) override def generateExpression[E](structure: MethodStructure[E])(implicit context: CodeGenContext): E = - structure.load(variableName) + structure.loadVariable(variableName) override def nullable(implicit context: CodeGenContext) = true diff --git a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/expressions/TypeOf.scala b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/expressions/TypeOf.scala index d859bf4b13a2f..717fad25eb66e 100644 --- a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/expressions/TypeOf.scala +++ b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/expressions/TypeOf.scala @@ -34,11 +34,11 @@ case class TypeOf(relId: Variable) structure.ifNotStatement(structure.isNull(relId.name, CodeGenType.primitiveRel)) { body => body.relType(relId.name, typeName) } - structure.load(typeName) + structure.loadVariable(typeName) } else { structure.relType(relId.name, typeName) - structure.load(typeName) + structure.loadVariable(typeName) } } diff --git a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/functions/CodeGenFunction1.scala b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/functions/CodeGenFunction1.scala index 13e7c8b9492b4..8ddb8afb3ae5a 100644 --- a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/functions/CodeGenFunction1.scala +++ b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/codegen/ir/functions/CodeGenFunction1.scala @@ -39,7 +39,7 @@ case object IdCodeGenFunction extends CodeGenFunction1 { override def generateExpression[E](structure: MethodStructure[E]) (implicit context: CodeGenContext): E = - structure.load(variable) + structure.loadVariable(variable) override def init[E](generator: MethodStructure[E])(implicit context: CodeGenContext) = {} diff --git a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/ExecutionEngine.scala b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/ExecutionEngine.scala index 56bd64af40a89..dfddc0a36c4fe 100644 --- a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/ExecutionEngine.scala +++ b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/ExecutionEngine.scala @@ -19,7 +19,6 @@ */ package org.neo4j.cypher.internal -import java.lang.Boolean.FALSE import java.util.{Map => JavaMap} import org.neo4j.cypher._ @@ -54,7 +53,7 @@ class ExecutionEngine(val queryService: GraphDatabaseQueryService, logProvider: private val lastCommittedTxId = LastCommittedTxIdProvider(queryService) protected val kernelMonitors: monitoring.Monitors = queryService.getDependencyResolver.resolveDependency(classOf[org.neo4j.kernel.monitoring.Monitors]) private val compilationTracer: CompilationTracer = { - if(optGraphSetting(queryService, GraphDatabaseSettings.cypher_compiler_tracing, FALSE)) + if( true) //optGraphSetting(queryService, GraphDatabaseSettings.cypher_compiler_tracing, FALSE)) new TimingCompilationTracer(kernelMonitors.newMonitor(classOf[TimingCompilationTracer.EventListener])) else CompilationTracer.NO_COMPILATION_TRACING diff --git a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v2_3/GeneratedQueryStructure.scala b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v2_3/GeneratedQueryStructure.scala index b71d61d4fa153..0689f6fd7604d 100644 --- a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v2_3/GeneratedQueryStructure.scala +++ b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v2_3/GeneratedQueryStructure.scala @@ -24,11 +24,7 @@ import java.util.function.Consumer import org.neo4j.codegen import org.neo4j.codegen.CodeGeneratorOption._ -import org.neo4j.codegen.Expression._ -import org.neo4j.codegen.ExpressionTemplate._ -import org.neo4j.codegen.ExpressionTemplate.get -import org.neo4j.codegen.ExpressionTemplate.invoke -import org.neo4j.codegen.ExpressionTemplate.load +import org.neo4j.codegen.ExpressionTemplate.{get, invoke, load, _} import org.neo4j.codegen.MethodReference._ import org.neo4j.codegen.TypeReference._ import org.neo4j.codegen._ @@ -259,7 +255,7 @@ private case class Method(fields: Fields, generator: CodeBlock, aux:AuxGenerator generator.assign(typeRef[Long], toNodeVar, DirectionConverter.toGraphDb(direction) match { case Direction.INCOMING => startNode case Direction.OUTGOING => endNode - case Direction.BOTH => Expression.ternary(Expression.eq(startNode, generator.load(fromNodeVar), typeRef[Long]), endNode, startNode) + case Direction.BOTH => Expression.ternary(Expression.equal(startNode, generator.load(fromNodeVar), typeRef[Long]), endNode, startNode) }) generator.assign(typeRef[Long], relVar, Expression.invoke(generator.load("rel"), Methods.relationship)) } @@ -319,12 +315,12 @@ private case class Method(fields: Fields, generator: CodeBlock, aux:AuxGenerator override def decreaseCounterAndCheckForZero(name: String): Expression = { val local = locals(name) generator.assign(local, Expression.subtractInts(local, Expression.constant(1))) - Expression.eq(Expression.constant(0), local, typeRef[Int]) + Expression.equal(Expression.constant(0), local, typeRef[Int]) } override def counterEqualsZero(name: String): Expression = { val local = locals(name) - Expression.eq(Expression.constant(0), local, typeRef[Int]) + Expression.equal(Expression.constant(0), local, typeRef[Int]) } override def setInRow(column: String, value: Expression) = @@ -344,7 +340,7 @@ private case class Method(fields: Fields, generator: CodeBlock, aux:AuxGenerator override def nullable(varName: String, cypherType: CypherType, onSuccess: Expression) = { Expression.ternary( - Expression.eq(nullValue(cypherType), generator.load(varName), GeneratedQueryStructure.lowerType(cypherType)), + Expression.equal(nullValue(cypherType), generator.load(varName), GeneratedQueryStructure.lowerType(cypherType)), Expression.constant(null), onSuccess) } @@ -389,7 +385,7 @@ private case class Method(fields: Fields, generator: CodeBlock, aux:AuxGenerator override def ternaryEquals(lhs: Expression, rhs: Expression) = Expression.invoke(Methods.ternaryEquals, lhs, rhs) - override def eq(lhs: Expression, rhs: Expression) = Expression.eq(lhs, rhs, typeRef[Long]) + override def eq(lhs: Expression, rhs: Expression) = Expression.equal(lhs, rhs, typeRef[Long]) override def or(lhs: Expression, rhs: Expression) = Expression.or(lhs, rhs) @@ -399,8 +395,8 @@ private case class Method(fields: Fields, generator: CodeBlock, aux:AuxGenerator generator.assign(GeneratedQueryStructure.lowerType(cypherType), varName, nullValue(cypherType)) override def notNull(varName: String, cypherType: CypherType) = - Expression.not(Expression.eq(nullValue(cypherType), generator.load(varName), - GeneratedQueryStructure.lowerType(cypherType))) + Expression.not(Expression.equal(nullValue(cypherType), generator.load(varName), + GeneratedQueryStructure.lowerType(cypherType))) override def nodeGetAllRelationships(iterVar: String, nodeVar: String, direction: SemanticDirection) = { @@ -526,7 +522,7 @@ private case class Method(fields: Fields, generator: CodeBlock, aux:AuxGenerator Expression.invoke(generator.load(tableVar), Methods.countingTableGet, generator.load(keyVar))) generator.expression(Expression.invoke(generator.load(tableVar), Methods.countingTablePut, generator.load(keyVar), Expression.ternary( - Expression.eq(generator.load(countName), Expression + Expression.equal(generator.load(countName), Expression .get(GeneratedQueryStructure.staticField[LongKeyIntValueTable, Int]("NULL")), typeRef[Int]), Expression.constant(1), Expression.addInts(generator.load(countName), Expression.constant(1))))) @@ -537,7 +533,7 @@ private case class Method(fields: Fields, generator: CodeBlock, aux:AuxGenerator generator.assign(typeRef[java.lang.Integer], countName, Expression.invoke(generator.load(tableVar), Methods.countingTableCompositeKeyGet, generator.load(keyName))) generator.expression(Expression.invoke(generator.load(tableVar), Methods.countingTableCompositeKeyPut, generator.load(keyName), Expression.ternary( - Expression.eq(generator.load(countName), Expression.constant(null), typeRef[Int]), + Expression.equal(generator.load(countName), Expression.constant(null), typeRef[Int]), Expression.constant(1), Expression.addInts(generator.load(countName), Expression.constant(1))))) } @@ -560,7 +556,7 @@ private case class Method(fields: Fields, generator: CodeBlock, aux:AuxGenerator Expression.invoke(Methods.compositeKey, keyVars.map(generator.load): _*))) generator.assign(times, Expression.ternary( - Expression.eq(generator.load(intermediate.name()), Expression.constant(null), typeRef[Object]), + Expression.equal(generator.load(intermediate.name()), Expression.constant(null), typeRef[Object]), Expression.constant(-1), generator.load(intermediate.name()))) using(generator.whileLoop(Expression.gt(times, Expression.constant(0), typeRef[Int]))) { body => @@ -577,7 +573,7 @@ private case class Method(fields: Fields, generator: CodeBlock, aux:AuxGenerator val list = generator.declare(hashTable.listType, context.namer.newVarName()) val elementName = context.namer.newVarName() generator.assign(list, Expression.invoke(generator.load(tableVar), hashTable.get, generator.load(keyVar))) - using(generator.ifStatement(Expression.not(Expression.eq(list, Expression.constant(null), typeRef[Object])))) { onTrue => + using(generator.ifStatement(Expression.not(Expression.equal(list, Expression.constant(null), typeRef[Object])))) { onTrue => using(onTrue.forEach(Parameter.param(hashTable.valueType, elementName), list)) { forEach => localVars.foreach { case (local, field) => @@ -594,7 +590,7 @@ private case class Method(fields: Fields, generator: CodeBlock, aux:AuxGenerator val elementName = context.namer.newVarName() generator.assign(list, Expression.invoke(generator.load(tableVar),hashTable.get, Expression.invoke(Methods.compositeKey, keyVars.map(generator.load): _*))) - using(generator.ifStatement(Expression.not(Expression.eq(list, Expression.constant(null), typeRef[Object])))) { onTrue => + using(generator.ifStatement(Expression.not(Expression.equal(list, Expression.constant(null), typeRef[Object])))) { onTrue => using(onTrue.forEach(Parameter.param(hashTable.valueType, elementName), list)) { forEach => localVars.foreach { case (local, field) => @@ -622,7 +618,7 @@ private case class Method(fields: Fields, generator: CodeBlock, aux:AuxGenerator val list = generator.declare(hashTable.listType, listName) // ProbeTable list; generator.assign(list, Expression .invoke(generator.load(tableVar), hashTable.get, generator.load(keyVar))) // list = tableVar.get(keyVar); - using(generator.ifStatement(Expression.eq(Expression.constant(null), generator.load(listName), typeRef[Object]))) + using(generator.ifStatement(Expression.equal(Expression.constant(null), generator.load(listName), typeRef[Object]))) { onTrue => // if (null == list) onTrue.assign(list, Templates.newInstance(hashTable.listType)) // list = new ListType(); onTrue.expression(Expression.invoke(generator.load(tableVar), hashTable.put, generator.load(keyVar), @@ -640,7 +636,7 @@ private case class Method(fields: Fields, generator: CodeBlock, aux:AuxGenerator .assign(typeRef[CompositeKey], keyName, Expression.invoke(Methods.compositeKey, keyVars.map(generator.load): _*)) generator.assign(list, Expression .invoke(generator.load(tableVar), hashTable.get, generator.load(keyName))) // list = tableVar.get(keyVar); - using(generator.ifStatement(Expression.eq(Expression.constant(null), generator.load(listName), typeRef[Object]))) + using(generator.ifStatement(Expression.equal(Expression.constant(null), generator.load(listName), typeRef[Object]))) { onTrue => // if (null == list) onTrue.assign(list, Templates.newInstance(hashTable.listType)) // list = new ListType(); onTrue.expression(Expression.invoke(generator.load(tableVar), hashTable.put, generator.load(keyName), diff --git a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_0/GeneratedQueryStructure.scala b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_0/GeneratedQueryStructure.scala index 0db8475d02094..35c401931eaa0 100644 --- a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_0/GeneratedQueryStructure.scala +++ b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_0/GeneratedQueryStructure.scala @@ -263,7 +263,7 @@ private case class Method(fields: Fields, generator: CodeBlock, aux:AuxGenerator generator.assign(typeRef[Long], toNodeVar, DirectionConverter.toGraphDb(direction) match { case Direction.INCOMING => startNode case Direction.OUTGOING => endNode - case Direction.BOTH => Expression.ternary(Expression.eq(startNode, generator.load(fromNodeVar), typeRef[Long]), endNode, startNode) + case Direction.BOTH => Expression.ternary(Expression.equal(startNode, generator.load(fromNodeVar), typeRef[Long]), endNode, startNode) }) generator.assign(typeRef[Long], relVar, Expression.invoke(generator.load(extractor), Methods.relationship)) } @@ -329,12 +329,12 @@ private case class Method(fields: Fields, generator: CodeBlock, aux:AuxGenerator override def decreaseCounterAndCheckForZero(name: String): Expression = { val local = locals(name) generator.assign(local, Expression.subtractInts(local, Expression.constant(1))) - Expression.eq(Expression.constant(0), local, typeRef[Int]) + Expression.equal(Expression.constant(0), local, typeRef[Int]) } override def counterEqualsZero(name: String): Expression = { val local = locals(name) - Expression.eq(Expression.constant(0), local, typeRef[Int]) + Expression.equal(Expression.constant(0), local, typeRef[Int]) } override def setInRow(column: String, value: Expression) = @@ -354,7 +354,7 @@ private case class Method(fields: Fields, generator: CodeBlock, aux:AuxGenerator override def nullable(varName: String, cypherType: CypherType, onSuccess: Expression) = { Expression.ternary( - Expression.eq(nullValue(cypherType), generator.load(varName), typeRef[Object]), + Expression.equal(nullValue(cypherType), generator.load(varName), typeRef[Object]), Expression.constant(null), onSuccess) } @@ -399,7 +399,7 @@ private case class Method(fields: Fields, generator: CodeBlock, aux:AuxGenerator override def threeValuedEquals(lhs: Expression, rhs: Expression) = Expression.invoke(Methods.ternaryEquals, lhs, rhs) - override def eq(lhs: Expression, rhs: Expression) = Expression.eq(lhs, rhs, typeRef[Long]) + override def eq(lhs: Expression, rhs: Expression) = Expression.equal(lhs, rhs, typeRef[Long]) override def or(lhs: Expression, rhs: Expression) = Expression.or(lhs, rhs) @@ -409,7 +409,7 @@ private case class Method(fields: Fields, generator: CodeBlock, aux:AuxGenerator generator.assign(lowerType(cypherType), varName, nullValue(cypherType)) override def notNull(varName: String, cypherType: CypherType) = - Expression.not(Expression.eq(nullValue(cypherType), generator.load(varName), typeRef[Object])) + Expression.not(Expression.equal(nullValue(cypherType), generator.load(varName), typeRef[Object])) override def nodeGetAllRelationships(iterVar: String, nodeVar: String, direction: SemanticDirection) = { @@ -534,7 +534,7 @@ private case class Method(fields: Fields, generator: CodeBlock, aux:AuxGenerator Expression.invoke(generator.load(tableVar), Methods.countingTableGet, generator.load(keyVar))) generator.expression(Expression.invoke(generator.load(tableVar), Methods.countingTablePut, generator.load(keyVar), Expression.ternary( - Expression.eq(generator.load(countName), Expression + Expression.equal(generator.load(countName), Expression .get(staticField[LongKeyIntValueTable, Int]("NULL")), typeRef[Int]), Expression.constant(1), Expression.addInts(generator.load(countName), Expression.constant(1))))) @@ -545,7 +545,7 @@ private case class Method(fields: Fields, generator: CodeBlock, aux:AuxGenerator generator.assign(typeRef[java.lang.Integer], countName, Expression.invoke(generator.load(tableVar), Methods.countingTableCompositeKeyGet, generator.load(keyName))) generator.expression(Expression.invoke(generator.load(tableVar), Methods.countingTableCompositeKeyPut, generator.load(keyName), Expression.ternary( - Expression.eq(generator.load(countName), Expression.constant(null), typeRef[Int]), + Expression.equal(generator.load(countName), Expression.constant(null), typeRef[Int]), Expression.constant(1), Expression.addInts(generator.load(countName), Expression.constant(1))))) } @@ -568,7 +568,7 @@ private case class Method(fields: Fields, generator: CodeBlock, aux:AuxGenerator Expression.invoke(Methods.compositeKey, keyVars.map(generator.load): _*))) generator.assign(times, Expression.ternary( - Expression.eq(generator.load(intermediate.name()), Expression.constant(null), typeRef[Object]), + Expression.equal(generator.load(intermediate.name()), Expression.constant(null), typeRef[Object]), Expression.constant(-1), generator.load(intermediate.name()))) using(generator.whileLoop(Expression.gt(times, Expression.constant(0), typeRef[Int]))) { body => @@ -585,7 +585,7 @@ private case class Method(fields: Fields, generator: CodeBlock, aux:AuxGenerator val list = generator.declare(hashTable.listType, context.namer.newVarName()) val elementName = context.namer.newVarName() generator.assign(list, Expression.invoke(generator.load(tableVar), hashTable.get, generator.load(keyVar))) - using(generator.ifStatement(Expression.not(Expression.eq(list, Expression.constant(null), typeRef[Object])))) { onTrue => + using(generator.ifStatement(Expression.not(Expression.equal(list, Expression.constant(null), typeRef[Object])))) { onTrue => using(onTrue.forEach(Parameter.param(hashTable.valueType, elementName), list)) { forEach => localVars.foreach { case (local, field) => @@ -602,7 +602,7 @@ private case class Method(fields: Fields, generator: CodeBlock, aux:AuxGenerator val elementName = context.namer.newVarName() generator.assign(list, Expression.invoke(generator.load(tableVar),hashTable.get, Expression.invoke(Methods.compositeKey, keyVars.map(generator.load): _*))) - using(generator.ifStatement(Expression.not(Expression.eq(list, Expression.constant(null), typeRef[Object])))) { onTrue => + using(generator.ifStatement(Expression.not(Expression.equal(list, Expression.constant(null), typeRef[Object])))) { onTrue => using(onTrue.forEach(Parameter.param(hashTable.valueType, elementName), list)) { forEach => localVars.foreach { case (local, field) => @@ -630,7 +630,7 @@ private case class Method(fields: Fields, generator: CodeBlock, aux:AuxGenerator val list = generator.declare(hashTable.listType, listName) // ProbeTable list; generator.assign(list, Expression .invoke(generator.load(tableVar), hashTable.get, generator.load(keyVar))) // list = tableVar.get(keyVar); - using(generator.ifStatement(Expression.eq(Expression.constant(null), generator.load(listName), typeRef[Object]))) + using(generator.ifStatement(Expression.equal(Expression.constant(null), generator.load(listName), typeRef[Object]))) { onTrue => // if (null == list) onTrue.assign(list, Templates.newInstance(hashTable.listType)) // list = new ListType(); onTrue.expression(Expression.invoke(generator.load(tableVar), hashTable.put, generator.load(keyVar), @@ -648,7 +648,7 @@ private case class Method(fields: Fields, generator: CodeBlock, aux:AuxGenerator .assign(typeRef[CompositeKey], keyName, Expression.invoke(Methods.compositeKey, keyVars.map(generator.load): _*)) generator.assign(list, Expression .invoke(generator.load(tableVar), hashTable.get, generator.load(keyName))) // list = tableVar.get(keyVar); - using(generator.ifStatement(Expression.eq(Expression.constant(null), generator.load(listName), typeRef[Object]))) + using(generator.ifStatement(Expression.equal(Expression.constant(null), generator.load(listName), typeRef[Object]))) { onTrue => // if (null == list) onTrue.assign(list, Templates.newInstance(hashTable.listType)) // list = new ListType(); onTrue.expression(Expression.invoke(generator.load(tableVar), hashTable.put, generator.load(keyName), diff --git a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_1/codegen/GeneratedMethodStructure.scala b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_1/codegen/GeneratedMethodStructure.scala index a05c4ab3bc899..00385754ec8ea 100644 --- a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_1/codegen/GeneratedMethodStructure.scala +++ b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_1/codegen/GeneratedMethodStructure.scala @@ -21,17 +21,22 @@ package org.neo4j.cypher.internal.spi.v3_1.codegen import java.util +import org.neo4j.codegen.Expression.{not, or, _} +import org.neo4j.codegen.MethodReference.methodReference import org.neo4j.codegen._ import org.neo4j.collection.primitive.hopscotch.LongKeyIntValueTable import org.neo4j.collection.primitive.{PrimitiveLongIntMap, PrimitiveLongIterator, PrimitiveLongObjectMap} import org.neo4j.cypher.internal.codegen.CompiledConversionUtils.CompositeKey import org.neo4j.cypher.internal.codegen._ -import org.neo4j.cypher.internal.compiler.v3_1.ast.convert.commands.DirectionConverter +import org.neo4j.cypher.internal.compiler.v3_1.ast.convert.commands.DirectionConverter.toGraphDb import org.neo4j.cypher.internal.compiler.v3_1.codegen._ import org.neo4j.cypher.internal.compiler.v3_1.codegen.ir.expressions.{BoolType, CodeGenType, FloatType, IntType} import org.neo4j.cypher.internal.compiler.v3_1.helpers._ import org.neo4j.cypher.internal.compiler.v3_1.planDescription.Id +import org.neo4j.cypher.internal.frontend.v3_1.symbols.{CTNode, CTRelationship} import org.neo4j.cypher.internal.frontend.v3_1.{ParameterNotFoundException, SemanticDirection, symbols} +import org.neo4j.cypher.internal.spi.v3_1.codegen.Methods._ +import org.neo4j.cypher.internal.spi.v3_1.codegen.Templates.{createNewInstance, handleKernelExceptions, newRelationshipDataExtractor, tryCatch} import org.neo4j.graphdb.Direction import org.neo4j.kernel.api.index.IndexDescriptor import org.neo4j.kernel.impl.api.RelationshipDataExtractor @@ -40,11 +45,13 @@ import org.neo4j.kernel.impl.api.store.RelationshipIterator import scala.collection.mutable case class GeneratedMethodStructure(fields: Fields, generator: CodeBlock, aux: AuxGenerator, tracing: Boolean = true, - events: List[String] = List.empty, locals: mutable.Map[String, LocalVariable] = mutable.Map.empty) + events: List[String] = List.empty, + locals: mutable.Map[String, LocalVariable] = mutable.Map.empty) (implicit context: CodeGenContext) extends MethodStructure[Expression] { import GeneratedQueryStructure._ + import TypeReference.parameterizedType private case class HashTable(valueType: TypeReference, listType: TypeReference, tableType: TypeReference, get: MethodReference, put: MethodReference, add: MethodReference) @@ -55,54 +62,53 @@ case class GeneratedMethodStructure(fields: Fields, generator: CodeBlock, aux: A case LongToListTable(structure, localMap) => // compute the participating types val valueType = aux.typeReference(structure) - val listType = TypeReference.parameterizedType(classOf[util.ArrayList[_]], valueType) - val tableType = TypeReference.parameterizedType(classOf[PrimitiveLongObjectMap[_]], valueType) + val listType = parameterizedType(classOf[util.ArrayList[_]], valueType) + val tableType = parameterizedType(classOf[PrimitiveLongObjectMap[_]], valueType) // the methods we use on those types - val get = MethodReference.methodReference(tableType, typeRef[Object], "get", typeRef[Long]) - val put = MethodReference.methodReference(tableType, typeRef[Object], "put", typeRef[Long], typeRef[Object]) - val add = MethodReference.methodReference(listType, typeRef[Boolean], "add", typeRef[Object]) + val get = methodReference(tableType, typeRef[Object], "get", typeRef[Long]) + val put = methodReference(tableType, typeRef[Object], "put", typeRef[Long], typeRef[Object]) + val add = methodReference(listType, typeRef[Boolean], "add", typeRef[Object]) HashTable(valueType, listType, tableType, get, put, add) case LongsToListTable(structure, localMap) => // compute the participating types val valueType = aux.typeReference(structure) - val listType = TypeReference.parameterizedType(classOf[util.ArrayList[_]], valueType) - val tableType = TypeReference.parameterizedType(classOf[util.HashMap[_, _]], typeRef[CompositeKey], valueType) + val listType = parameterizedType(classOf[util.ArrayList[_]], valueType) + val tableType = parameterizedType(classOf[util.HashMap[_, _]], typeRef[CompositeKey], valueType) // the methods we use on those types - val get = MethodReference.methodReference(tableType, typeRef[Object], "get", typeRef[Object]) - val put = MethodReference.methodReference(tableType, typeRef[Object], "put", typeRef[Object], typeRef[Object]) - val add = MethodReference.methodReference(listType, typeRef[Boolean], "add", typeRef[Object]) + val get = methodReference(tableType, typeRef[Object], "get", typeRef[Object]) + val put = methodReference(tableType, typeRef[Object], "put", typeRef[Object], typeRef[Object]) + val add = methodReference(listType, typeRef[Boolean], "add", typeRef[Object]) HashTable(valueType, listType, tableType, get, put, add) } } override def nextNode(targetVar: String, iterVar: String) = - generator.assign(typeRef[Long], targetVar, Expression.invoke(generator.load(iterVar), Methods.nextLong)) + generator.assign(typeRef[Long], targetVar, invoke(generator.load(iterVar), nextLong)) override def createRelExtractor(relVar: String) = - generator.assign(typeRef[RelationshipDataExtractor], relExtractor(relVar), Templates.newRelationshipDataExtractor) + generator.assign(typeRef[RelationshipDataExtractor], relExtractor(relVar), newRelationshipDataExtractor) override def nextRelationshipAndNode(toNodeVar: String, iterVar: String, direction: SemanticDirection, fromNodeVar: String, relVar: String) = { val extractor = relExtractor(relVar) - val startNode = Expression.invoke(generator.load(extractor), Methods.startNode) - val endNode = Expression.invoke(generator.load(extractor), Methods.endNode) + val start = invoke(generator.load(extractor), startNode) + val end = invoke(generator.load(extractor), endNode) generator.expression( - Expression.pop( - Expression.invoke(generator.load(iterVar), Methods.relationshipVisit, - Expression.invoke(generator.load(iterVar), Methods.nextRelationship), - generator.load(extractor)))) - generator.assign(typeRef[Long], toNodeVar, DirectionConverter.toGraphDb(direction) match { - case Direction.INCOMING => startNode - case Direction.OUTGOING => endNode - case Direction.BOTH => Expression - .ternary(Expression.eq(startNode, generator.load(fromNodeVar), typeRef[Long]), endNode, startNode) + pop( + invoke(generator.load(iterVar), relationshipVisit, + invoke(generator.load(iterVar), fetchNextRelationship), + generator.load(extractor)))) + generator.assign(typeRef[Long], toNodeVar, toGraphDb(direction) match { + case Direction.INCOMING => start + case Direction.OUTGOING => end + case Direction.BOTH => ternary(equal(start, generator.load(fromNodeVar), typeRef[Long]), end, start) }) - generator.assign(typeRef[Long], relVar, Expression.invoke(generator.load(extractor), Methods.relationship)) + generator.assign(typeRef[Long], relVar, invoke(generator.load(extractor), getRelationship)) } private def relExtractor(relVar: String) = s"${relVar}Extractor" @@ -110,33 +116,32 @@ case class GeneratedMethodStructure(fields: Fields, generator: CodeBlock, aux: A override def nextRelationship(iterVar: String, ignored: SemanticDirection, relVar: String) = { val extractor = relExtractor(relVar) generator.expression( - Expression.pop( - Expression.invoke(generator.load(iterVar), Methods.relationshipVisit, - Expression.invoke(generator.load(iterVar), Methods.nextRelationship), - generator.load(extractor)))) - generator.assign(typeRef[Long], relVar, Expression.invoke(generator.load(extractor), Methods.relationship)) + pop( + invoke(generator.load(iterVar), relationshipVisit, + invoke(generator.load(iterVar), fetchNextRelationship), + generator.load(extractor)))) + generator.assign(typeRef[Long], relVar, invoke(generator.load(extractor), getRelationship)) } override def allNodesScan(iterVar: String) = - generator.assign(typeRef[PrimitiveLongIterator], iterVar, Expression.invoke(readOperations, Methods.nodesGetAll)) + generator.assign(typeRef[PrimitiveLongIterator], iterVar, invoke(readOperations, nodesGetAll)) override def labelScan(iterVar: String, labelIdVar: String) = generator.assign(typeRef[PrimitiveLongIterator], iterVar, - Expression.invoke(readOperations, Methods.nodesGetForLabel, generator.load(labelIdVar))) + invoke(readOperations, nodesGetForLabel, generator.load(labelIdVar))) override def lookupLabelId(labelIdVar: String, labelName: String) = generator.assign(typeRef[Int], labelIdVar, - Expression.invoke(readOperations, Methods.labelGetForName, Expression.constant(labelName))) + invoke(readOperations, labelGetForName, constant(labelName))) override def lookupRelationshipTypeId(typeIdVar: String, typeName: String) = - generator.assign(typeRef[Int], typeIdVar, Expression - .invoke(readOperations, Methods.relationshipTypeGetForName, Expression.constant(typeName))) + generator.assign(typeRef[Int], typeIdVar, invoke(readOperations, relationshipTypeGetForName, constant(typeName))) override def hasNextNode(iterVar: String) = - Expression.invoke(generator.load(iterVar), Methods.hasNextLong) + invoke(generator.load(iterVar), hasNextLong) override def hasNextRelationship(iterVar: String) = - Expression.invoke(generator.load(iterVar), Methods.hasNextRelationship) + invoke(generator.load(iterVar), hasMoreRelationship) override def whileLoop(test: Expression)(block: MethodStructure[Expression] => Unit) = using(generator.whileLoop(test)) { body => @@ -162,197 +167,196 @@ case class GeneratedMethodStructure(fields: Fields, generator: CodeBlock, aux: A } override def ternaryOperator(test: Expression, onTrue: Expression, onFalse: Expression): Expression = - Expression.ternary(test, onTrue, onFalse) + ternary(test, onTrue, onFalse) override def returnSuccessfully() { //close all outstanding events - for(event <- events) { - generator.expression(Expression.invoke(generator.load(event), - GeneratedQueryStructure.method[QueryExecutionEvent, Unit]("close"))) + for (event <- events) { + generator.expression( + invoke(generator.load(event), + method[QueryExecutionEvent, Unit]("close"))) } - generator.expression(Expression.invoke(generator.self(), fields.success)) - generator.expression(Expression.invoke(generator.self(), fields.close)) + generator.expression(invoke(generator.self(), fields.success)) + generator.expression(invoke(generator.self(), fields.close)) generator.returns() } override def declareCounter(name: String, initialValue: Expression): Unit = { val variable = generator.declare(typeRef[Int], name) locals += (name -> variable) - generator.assign(variable, Expression.invoke(Methods.mathCastToInt, initialValue)) + generator.assign(variable, invoke(mathCastToInt, initialValue)) } override def decreaseCounterAndCheckForZero(name: String): Expression = { val local = locals(name) - generator.assign(local, Expression.subtractInts(local, Expression.constant(1))) - Expression.eq(Expression.constant(0), local, typeRef[Int]) + generator.assign(local, subtractInts(local, constant(1))) + + equal(constant(0), local, typeRef[Int]) } override def counterEqualsZero(name: String): Expression = { val local = locals(name) - Expression.eq(Expression.constant(0), local, typeRef[Int]) + equal(constant(0), local, typeRef[Int]) } override def setInRow(column: String, value: Expression) = - generator.expression(Expression.invoke(resultRow, Methods.set, Expression.constant(column), value)) - - override def visitorAccept() = { - Templates.tryCatch(generator) { onSuccess => - using( - onSuccess.ifNotStatement(Expression.invoke(onSuccess.load("visitor"), - Methods.visit, onSuccess.load("row")))) { body => - // NOTE: we are in this if-block if the visitor decided to terminate early (by returning false) - //close all outstanding events - for(event <- events) { - body.expression(Expression.invoke(generator.load(event), - GeneratedQueryStructure.method[QueryExecutionEvent, Unit]("close"))) - } - body.expression(Expression.invoke(body.self(), fields.success)) - body.expression(Expression.invoke(body.self(), fields.close)) - body.returns() + generator.expression(invoke(resultRow, set, constant(column), value)) + + override def visitorAccept() = tryCatch(generator) { onSuccess => + using( + onSuccess.ifNotStatement( + invoke(onSuccess.load("visitor"), + visit, onSuccess.load("row")))) { body => + // NOTE: we are in this if-block if the visitor decided to terminate early (by returning false) + //close all outstanding events + for (event <- events) { + body.expression(invoke(generator.load(event), + method[QueryExecutionEvent, Unit]("close"))) } - }(exception = param[Throwable]("e")) { handle => - handle.expression(Expression.invoke(handle.self(), fields.close)) - handle.throwException(handle.load("e")) + body.expression(invoke(body.self(), fields.success)) + body.expression(invoke(body.self(), fields.close)) + body.returns() } + }(exception = param[Throwable]("e")) { onError => + onError.expression(invoke(onError.self(), fields.close)) + onError.throwException(onError.load("e")) } + override def materializeNode(nodeIdVar: String) = - Expression.invoke(nodeManager, Methods.newNodeProxyById, generator.load(nodeIdVar)) + invoke(nodeManager, newNodeProxyById, generator.load(nodeIdVar)) - override def node(nodeIdVar: String) = Templates.newInstance(typeRef[NodeIdWrapper], - (typeRef[Long], generator.load(nodeIdVar))) + override def node(nodeIdVar: String) = createNewInstance(typeRef[NodeIdWrapper], (typeRef[Long], generator.load(nodeIdVar))) override def nullablePrimitive(varName: String, codeGenType: CodeGenType, onSuccess: Expression) = codeGenType match { - case CodeGenType(symbols.CTNode, IntType) | CodeGenType(symbols.CTRelationship, IntType) => - Expression.ternary( - Expression.eq(nullValue(codeGenType), generator.load(varName), lowerType(codeGenType)), + case CodeGenType(CTNode, IntType) | CodeGenType(CTRelationship, IntType) => + ternary( + equal(nullValue(codeGenType), generator.load(varName), lowerType(codeGenType)), nullValue(codeGenType), onSuccess) - case _ => Expression.ternaryOnNull(generator.load(varName), Expression.constant(null), onSuccess) + case _ => ternaryOnNull(generator.load(varName), constant(null), onSuccess) } override def nullableReference(varName: String, codeGenType: CodeGenType, onSuccess: Expression) = codeGenType match { - case CodeGenType(symbols.CTNode, IntType) | CodeGenType(symbols.CTRelationship, IntType) => - Expression.ternary( - Expression.eq(nullValue(codeGenType), generator.load(varName), lowerType(codeGenType)), - Expression.constant(null), + case CodeGenType(CTNode, IntType) | CodeGenType(CTRelationship, IntType) => + ternary( + equal(nullValue(codeGenType), generator.load(varName), lowerType(codeGenType)), + constant(null), onSuccess) - case _ => Expression.ternaryOnNull(generator.load(varName), Expression.constant(null), onSuccess) + case _ => ternaryOnNull(generator.load(varName), constant(null), onSuccess) } override def materializeRelationship(relIdVar: String) = - Expression.invoke(nodeManager, Methods.newRelationshipProxyById, generator.load(relIdVar)) + invoke(nodeManager, newRelationshipProxyById, generator.load(relIdVar)) - override def relationship(relIdVar: String) = Templates.newInstance(typeRef[RelationshipIdWrapper], - (typeRef[Long], generator.load(relIdVar))) + override def relationship(relIdVar: String) = createNewInstance(typeRef[RelationshipIdWrapper], + (typeRef[Long], generator.load(relIdVar))) override def trace[V](planStepId: String)(block: MethodStructure[Expression] => V) = if (!tracing) block(this) else { val eventName = s"event_$planStepId" generator.assign(typeRef[QueryExecutionEvent], eventName, traceEvent(planStepId)) val result = block(copy(events = eventName :: events, generator = generator)) - generator.expression(Expression.invoke(generator.load(eventName), GeneratedQueryStructure.method[QueryExecutionEvent, Unit]("close"))) + generator.expression(invoke(generator.load(eventName), method[QueryExecutionEvent, Unit]("close"))) result } private def traceEvent(planStepId: String) = - Expression.invoke(tracer, Methods.executeOperator, - Expression.get(FieldReference.staticField(generator.owner(), typeRef[Id], planStepId))) + invoke(tracer, executeOperator, + get(FieldReference.staticField(generator.owner(), typeRef[Id], planStepId))) - override def incrementDbHits() = if (tracing) generator.expression(Expression.invoke(loadEvent, Methods.dbHit)) + override def incrementDbHits() = if (tracing) generator.expression(invoke(loadEvent, Methods.dbHit)) - override def incrementRows() = if (tracing) generator.expression(Expression.invoke(loadEvent, Methods.row)) + override def incrementRows() = if (tracing) generator.expression(invoke(loadEvent, Methods.row)) private def loadEvent = generator.load(events.headOption.getOrElse(throw new IllegalStateException("no current trace event"))) override def expectParameter(key: String, variableName: String) = { using( - generator.ifNotStatement(Expression.invoke(params, Methods.mapContains, Expression.constant(key)))) { block => + generator.ifNotStatement(invoke(params, mapContains, constant(key)))) { block => block.throwException(parameterNotFoundException(key)) } - generator.assign(typeRef[Object], variableName, Expression.invoke(Methods.loadParameter, - Expression.invoke(params, Methods.mapGet, - Expression.constant(key)))) + generator.assign(typeRef[Object], variableName, invoke(loadParameter, + invoke(params, mapGet, constantExpression(key)))) } - override def constant(value: Object) = value match { - case n: java.lang.Byte => Expression.constant(n.toLong) - case n: java.lang.Short => Expression.constant(n.toLong) - case n: java.lang.Character => Expression.constant(n.toLong) - case n: java.lang.Integer => Expression.constant(n.toLong) - case n: java.lang.Float => Expression.constant(n.toDouble) - case _ => Expression.constant(value) + override def constantExpression(value: Object) = value match { + case n: java.lang.Byte => constant(n.toLong) + case n: java.lang.Short => constant(n.toLong) + case n: java.lang.Character => constant(n.toLong) + case n: java.lang.Integer => constant(n.toLong) + case n: java.lang.Float => constant(n.toDouble) + case _ => constant(value) } - override def not(value: Expression): Expression = Expression.not(value) + override def notExpression(value: Expression): Expression = not(value) - override def threeValuedNot(value: Expression): Expression = Expression.invoke(Methods.not, value) + override def threeValuedNotExpression(value: Expression): Expression = invoke(Methods.not, value) - override def threeValuedEquals(lhs: Expression, rhs: Expression) = Expression.invoke(Methods.ternaryEquals, lhs, rhs) + override def threeValuedEqualsExpression(lhs: Expression, rhs: Expression) = invoke(Methods.ternaryEquals, lhs, rhs) - override def eq(lhs: Expression, rhs: Expression, codeGenType: CodeGenType) = Expression.eq(lhs, rhs, lowerType(codeGenType)) + override def equalityExpression(lhs: Expression, rhs: Expression, codeGenType: CodeGenType) = equal(lhs, rhs, lowerType(codeGenType)) - override def or(lhs: Expression, rhs: Expression) = Expression.or(lhs, rhs) + override def orExpression(lhs: Expression, rhs: Expression) = or(lhs, rhs) - override def threeValuedOr(lhs: Expression, rhs: Expression) = Expression.invoke(Methods.or, lhs, rhs) + override def threeValuedOrExpression(lhs: Expression, rhs: Expression) = invoke(Methods.or, lhs, rhs) override def markAsNull(varName: String, codeGenType: CodeGenType) = generator.assign(lowerType(codeGenType), varName, nullValue(codeGenType)) override def isNull(varName: String, codeGenType: CodeGenType) = - Expression.eq(nullValue(codeGenType), generator.load(varName), lowerType(codeGenType)) + equal(nullValue(codeGenType), generator.load(varName), lowerType(codeGenType)) - override def notNull(varName: String, codeGenType: CodeGenType) = Expression.not(isNull(varName, codeGenType)) + override def notNull(varName: String, codeGenType: CodeGenType) = not(isNull(varName, codeGenType)) override def box(expression: Expression, cType: CodeGenType) = cType match { - case CodeGenType(symbols.CTBoolean, BoolType) => Expression.invoke(Methods.boxBoolean, expression) - case CodeGenType(symbols.CTInteger, IntType) => Expression.invoke(Methods.boxLong, expression) - case CodeGenType(symbols.CTFloat, FloatType) => Expression.invoke(Methods.boxDouble, expression) + case CodeGenType(symbols.CTBoolean, BoolType) => invoke(Methods.boxBoolean, expression) + case CodeGenType(symbols.CTInteger, IntType) => invoke(Methods.boxLong, expression) + case CodeGenType(symbols.CTFloat, FloatType) => invoke(Methods.boxDouble, expression) case _ => expression } - override def toFloat(expression: Expression) = Expression.toDouble(expression) + override def toFloat(expression: Expression) = toDouble(expression) override def nodeGetAllRelationships(iterVar: String, nodeVar: String, direction: SemanticDirection) = { val local = generator.declare(typeRef[RelationshipIterator], iterVar) - Templates.handleKernelExceptions(generator, fields.ro, fields.close) { body => - body.assign(local, Expression - .invoke(readOperations, Methods.nodeGetAllRelationships, body.load(nodeVar), dir(direction))) + handleKernelExceptions(generator, fields.ro, fields.close) { body => + body.assign(local, invoke(readOperations, Methods.nodeGetAllRelationships, body.load(nodeVar), dir(direction))) } } override def nodeGetRelationships(iterVar: String, nodeVar: String, direction: SemanticDirection, typeVars: Seq[String]) = { val local = generator.declare(typeRef[RelationshipIterator], iterVar) - Templates.handleKernelExceptions(generator, fields.ro, fields.close) { body => - body.assign(local, Expression.invoke(readOperations, Methods.nodeGetRelationships, - body.load(nodeVar), dir(direction), - Expression.newArray(typeRef[Int], typeVars.map(body.load): _*))) + handleKernelExceptions(generator, fields.ro, fields.close) { body => + body.assign(local, invoke(readOperations, Methods.nodeGetRelationships, + body.load(nodeVar), dir(direction), + newArray(typeRef[Int], typeVars.map(body.load): _*))) } } override def connectingRelationships(iterVar: String, fromNode: String, direction: SemanticDirection, toNode: String) = { val local = generator.declare(typeRef[RelationshipIterator], iterVar) - Templates.handleKernelExceptions(generator, fields.ro, fields.close) { body => - body.assign(local, Expression.invoke(Methods.allConnectingRelationships, - readOperations, body.load(fromNode), dir(direction), - body.load(toNode))) + handleKernelExceptions(generator, fields.ro, fields.close) { body => + body.assign(local, invoke(Methods.allConnectingRelationships, + readOperations, body.load(fromNode), dir(direction), + body.load(toNode))) } } override def connectingRelationships(iterVar: String, fromNode: String, direction: SemanticDirection, typeVars: Seq[String], toNode: String) = { val local = generator.declare(typeRef[RelationshipIterator], iterVar) - Templates.handleKernelExceptions(generator, fields.ro, fields.close) { body => - body.assign(local, Expression.invoke(Methods.connectingRelationships, readOperations, body.load(fromNode), dir(direction), - body.load(toNode), - Expression.newArray(typeRef[Int], typeVars.map(body.load):_*))) + handleKernelExceptions(generator, fields.ro, fields.close) { body => + body.assign(local, invoke(Methods.connectingRelationships, readOperations, body.load(fromNode), dir(direction), + body.load(toNode), + newArray(typeRef[Int], typeVars.map(body.load): _*))) } } - override def load(varName: String) = generator.load(varName) + override def loadVariable(varName: String) = generator.load(varName) override def add(lhs: Expression, rhs: Expression) = math(Methods.mathAdd, lhs, rhs) @@ -362,25 +366,25 @@ case class GeneratedMethodStructure(fields: Fields, generator: CodeBlock, aux: A override def divide(lhs: Expression, rhs: Expression) = math(Methods.mathDiv, lhs, rhs) - override def mod(lhs: Expression, rhs: Expression) = math(Methods.mathMod, lhs, rhs) + override def modulus(lhs: Expression, rhs: Expression) = math(Methods.mathMod, lhs, rhs) private def math(method: MethodReference, lhs: Expression, rhs: Expression): Expression = - Expression.invoke(method, lhs, rhs) + invoke(method, lhs, rhs) - private def readOperations = Expression.get(generator.self(), fields.ro) + private def readOperations = get(generator.self(), fields.ro) - private def nodeManager = Expression.get(generator.self(), fields.entityAccessor) + private def nodeManager = get(generator.self(), fields.entityAccessor) private def resultRow = generator.load("row") - private def tracer = Expression.get(generator.self(), fields.tracer) + private def tracer = get(generator.self(), fields.tracer) - private def params = Expression.get(generator.self(), fields.params) + private def params = get(generator.self(), fields.params) private def parameterNotFoundException(key: String) = - Expression.invoke(Expression.newInstance(typeRef[ParameterNotFoundException]), - MethodReference.constructorReference(typeRef[ParameterNotFoundException], typeRef[String]), - Expression.constant(s"Expected a parameter named $key")) + invoke(newInstance(typeRef[ParameterNotFoundException]), + MethodReference.constructorReference(typeRef[ParameterNotFoundException], typeRef[String]), + constant(s"Expected a parameter named $key")) private def dir(dir: SemanticDirection): Expression = dir match { case SemanticDirection.INCOMING => Templates.incoming @@ -391,22 +395,22 @@ case class GeneratedMethodStructure(fields: Fields, generator: CodeBlock, aux: A override def asList(values: Seq[Expression]) = Templates.asList[Object](values) override def toSet(value: Expression) = - Templates.newInstance(typeRef[util.HashSet[Object]], (typeRef[util.Collection[_]], value)) + createNewInstance(typeRef[util.HashSet[Object]], (typeRef[util.Collection[_]], value)) - override def castToCollection(value: Expression) = Expression.invoke(Methods.toCollection, value) + override def castToCollection(value: Expression) = invoke(Methods.toCollection, value) override def asMap(map: Map[String, Expression]) = { - Expression.invoke(Methods.createMap, - Expression.newArray(typeRef[Object], map.flatMap { - case (key, value) => Seq(Expression.constant(key), value) - }.toSeq: _*)) + invoke(Methods.createMap, + newArray(typeRef[Object], map.flatMap { + case (key, value) => Seq(constant(key), value) + }.toSeq: _*)) } - override def method(resultType: JoinTableType, resultVar: String, methodName: String) - (block: MethodStructure[Expression] => Unit) = { + override def invokeMethod(resultType: JoinTableType, resultVar: String, methodName: String) + (block: MethodStructure[Expression] => Unit) = { val returnType: TypeReference = joinTableType(resultType) - generator.assign(returnType, resultVar, Expression - .invoke(generator.self(), MethodReference.methodReference(generator.owner(), returnType, methodName))) + generator.assign(returnType, resultVar, + invoke(generator.self(), methodReference(generator.owner(), returnType, methodName))) using(generator.classGenerator().generateMethod(returnType, methodName)) { body => block(copy(generator = body, events = List.empty)) body.returns(body.load(resultVar)) @@ -421,13 +425,13 @@ case class GeneratedMethodStructure(fields: Fields, generator: CodeBlock, aux: A case LongToCountTable => typeRef[PrimitiveLongIntMap] case LongsToCountTable => TypeReference .parameterizedType(classOf[util.HashMap[_, _]], classOf[CompositeKey], classOf[java.lang.Integer]) - case LongToListTable(structure, _) => TypeReference.parameterizedType(classOf[PrimitiveLongObjectMap[_]], - TypeReference.parameterizedType( - classOf[util.ArrayList[_]], - aux.typeReference(structure))) + case LongToListTable(structure, _) => parameterizedType(classOf[PrimitiveLongObjectMap[_]], + parameterizedType( + classOf[util.ArrayList[_]], + aux.typeReference(structure))) case LongsToListTable(structure, _) => TypeReference .parameterizedType(classOf[util.HashMap[_, _]], typeRef[CompositeKey], - TypeReference.parameterizedType(classOf[util.ArrayList[_]], aux.typeReference(structure))) + parameterizedType(classOf[util.ArrayList[_]], aux.typeReference(structure))) } returnType } @@ -435,8 +439,8 @@ case class GeneratedMethodStructure(fields: Fields, generator: CodeBlock, aux: A private def allocate(resultType: JoinTableType): Expression = resultType match { case LongToCountTable => Templates.newCountingMap case LongToListTable(_, _) => Templates.newLongObjectMap - case LongsToCountTable => Templates.newInstance(joinTableType(LongsToCountTable)) - case typ: LongsToListTable => Templates.newInstance(joinTableType(typ)) + case LongsToCountTable => createNewInstance(joinTableType(LongsToCountTable)) + case typ: LongsToListTable => createNewInstance(joinTableType(typ)) } override def updateProbeTableCount(tableVar: String, tableType: CountingJoinTableType, @@ -446,36 +450,37 @@ case class GeneratedMethodStructure(fields: Fields, generator: CodeBlock, aux: A val keyVar = keyVars.head val countName = context.namer.newVarName() generator.assign(typeRef[Int], countName, - Expression.invoke(generator.load(tableVar), Methods.countingTableGet, generator.load(keyVar))) + invoke(generator.load(tableVar), countingTableGet, generator.load(keyVar))) generator.expression( - Expression.pop( - Expression.invoke(generator.load(tableVar), Methods.countingTablePut, generator.load(keyVar), - Expression.ternary( - Expression.eq(generator.load(countName), Expression - .get(staticField[LongKeyIntValueTable, Int]("NULL")), typeRef[Int]), - Expression.constant(1), - Expression.addInts(generator.load(countName), Expression.constant(1)))))) + pop( + invoke(generator.load(tableVar), countingTablePut, generator.load(keyVar), + ternary( + equal(generator.load(countName), get(staticField[LongKeyIntValueTable, Int]("NULL")), typeRef[Int]), + constant(1), + addInts(generator.load(countName), constant(1)))))) + case LongsToCountTable => val countName = context.namer.newVarName() val keyName = context.namer.newVarName() generator.assign(typeRef[CompositeKey], keyName, - Expression.invoke(Methods.compositeKey, - Expression.newArray(typeRef[Long], keyVars.map(generator.load): _*))) + invoke(compositeKey, + newArray(typeRef[Long], keyVars.map(generator.load): _*))) generator.assign(typeRef[java.lang.Integer], countName, - Expression.cast(typeRef[java.lang.Integer], - Expression.invoke(generator.load(tableVar), Methods.countingTableCompositeKeyGet, - generator.load(keyName)) + cast(typeRef[java.lang.Integer], + invoke(generator.load(tableVar), countingTableCompositeKeyGet, + generator.load(keyName)) )) generator.expression( - Expression.pop( - Expression.invoke(generator.load(tableVar), Methods.countingTableCompositeKeyPut, - generator.load(keyName), - Expression.ternaryOnNull(generator.load(countName), - Expression.invoke(Methods.boxInteger, - Expression.constant(1)), Expression.invoke(Methods.boxInteger, - Expression.addInts( - Expression.invoke(generator.load(countName), Methods.unboxInteger), - Expression.constant(1))))))) + pop( + invoke(generator.load(tableVar), countingTableCompositeKeyPut, + generator.load(keyName), + ternaryOnNull(generator.load(countName), + invoke(boxInteger, + constant(1)), invoke(boxInteger, + addInts( + invoke(generator.load(countName), + unboxInteger), + constant(1))))))) } override def probe(tableVar: String, tableType: JoinTableType, keyVars: Seq[String]) @@ -484,31 +489,30 @@ case class GeneratedMethodStructure(fields: Fields, generator: CodeBlock, aux: A assert(keyVars.size == 1) val keyVar = keyVars.head val times = generator.declare(typeRef[Int], context.namer.newVarName()) - generator.assign(times, Expression - .invoke(generator.load(tableVar), Methods.countingTableGet, generator.load(keyVar))) - using(generator.whileLoop(Expression.gt(times, Expression.constant(0), typeRef[Int]))) { body => + generator.assign(times, invoke(generator.load(tableVar), countingTableGet, generator.load(keyVar))) + using(generator.whileLoop(gt(times, constant(0), typeRef[Int]))) { body => block(copy(generator = body)) - body.assign(times, Expression.subtractInts(times, Expression.constant(1))) + body.assign(times, subtractInts(times, constant(1))) } case LongsToCountTable => val times = generator.declare(typeRef[Int], context.namer.newVarName()) val intermediate = generator.declare(typeRef[java.lang.Integer], context.namer.newVarName()) generator.assign(intermediate, - Expression.cast(typeRef[Integer], - Expression.invoke(generator.load(tableVar), - Methods.countingTableCompositeKeyGet, - Expression.invoke(Methods.compositeKey, - Expression.newArray(typeRef[Long], - keyVars.map(generator.load): _*))))) + cast(typeRef[Integer], + invoke(generator.load(tableVar), + countingTableCompositeKeyGet, + invoke(compositeKey, + newArray(typeRef[Long], + keyVars.map(generator.load): _*))))) generator.assign(times, - Expression.ternaryOnNull( - intermediate, - Expression.constant(-1), - Expression.invoke(intermediate, Methods.unboxInteger))) + ternaryOnNull( + intermediate, + constant(-1), + invoke(intermediate, unboxInteger))) - using(generator.whileLoop(Expression.gt(times, Expression.constant(0), typeRef[Int]))) { body => + using(generator.whileLoop(gt(times, constant(0), typeRef[Int]))) { body => block(copy(generator = body)) - body.assign(times, Expression.subtractInts(times, Expression.constant(1))) + body.assign(times, subtractInts(times, constant(1))) } case tableType@LongToListTable(structure, localVars) => @@ -519,14 +523,14 @@ case class GeneratedMethodStructure(fields: Fields, generator: CodeBlock, aux: A // generate the code val list = generator.declare(hashTable.listType, context.namer.newVarName()) val elementName = context.namer.newVarName() - generator.assign(list, Expression.invoke(generator.load(tableVar), hashTable.get, generator.load(keyVar))) + generator.assign(list, invoke(generator.load(tableVar), hashTable.get, generator.load(keyVar))) using(generator.ifNonNullStatement(list)) { onTrue => using(onTrue.forEach(Parameter.param(hashTable.valueType, elementName), list)) { forEach => localVars.foreach { - case (local, field) => - val fieldType = lowerType(structure(field)) - forEach.assign(fieldType, local, Expression - .get(forEach.load(elementName), FieldReference.field(hashTable.valueType, fieldType, field))) + case (l, f) => + val fieldType = lowerType(structure(f)) + forEach.assign(fieldType, l, get(forEach.load(elementName), + field(structure, structure(f), f))) } block(copy(generator = forEach)) } @@ -538,32 +542,33 @@ case class GeneratedMethodStructure(fields: Fields, generator: CodeBlock, aux: A val elementName = context.namer.newVarName() generator.assign(list, - Expression.cast(hashTable.listType, - Expression.invoke(generator.load(tableVar), hashTable.get, - Expression.invoke(Methods.compositeKey, - Expression.newArray(typeRef[Long], - keyVars.map(generator.load): _*)) - ))) + cast(hashTable.listType, + invoke(generator.load(tableVar), hashTable.get, + invoke(compositeKey, + newArray(typeRef[Long], + keyVars.map(generator.load): _*)) + ))) using(generator.ifNonNullStatement(list)) { onTrue => using(onTrue.forEach(Parameter.param(hashTable.valueType, elementName), list)) { forEach => localVars.foreach { - case (local, field) => - val fieldType = lowerType(structure(field)) - forEach.assign(fieldType, local, Expression - .get(forEach.load(elementName), FieldReference.field(hashTable.valueType, fieldType, field))) + case (l, f) => + val fieldType = lowerType(structure(f)) + forEach.assign(fieldType, l, get(forEach.load(elementName), + field(structure, structure(f), f))) } block(copy(generator = forEach)) } } } - - override def putField(structure: Map[String, CodeGenType], value: Expression, fieldType: CodeGenType, fieldName: String, + override def putField(structure: Map[String, CodeGenType], value: Expression, fieldType: CodeGenType, + fieldName: String, localVar: String) = { generator.put(value, field(structure, fieldType, fieldName), generator.load(localVar)) } - override def updateProbeTable(structure: Map[String, CodeGenType], tableVar: String, tableType: RecordingJoinTableType, + override def updateProbeTable(structure: Map[String, CodeGenType], tableVar: String, + tableType: RecordingJoinTableType, keyVars: Seq[String], element: Expression) = tableType match { case _: LongToListTable => assert(keyVars.size == 1) @@ -574,23 +579,23 @@ case class GeneratedMethodStructure(fields: Fields, generator: CodeBlock, aux: A val list = generator.declare(hashTable.listType, listName) // ProbeTable list; // list = tableVar.get(keyVar); generator.assign(list, - Expression.cast(hashTable.listType, - Expression.invoke( - generator.load(tableVar), hashTable.get, - generator.load(keyVar)))) + cast(hashTable.listType, + invoke( + generator.load(tableVar), hashTable.get, + generator.load(keyVar)))) using(generator.ifNullStatement(list)) { onTrue => // if (null == list) // list = new ListType(); - onTrue.assign(list, Templates.newInstance(hashTable.listType)) + onTrue.assign(list, createNewInstance(hashTable.listType)) onTrue.expression( // tableVar.put(keyVar, list); - Expression.pop( - Expression.invoke( + pop( + invoke( generator.load(tableVar), hashTable.put, generator.load(keyVar), generator.load(listName)))) } // list.add( element ); generator.expression( - Expression.pop( - Expression.invoke(list, hashTable.add, element)) + pop( + invoke(list, hashTable.add, element)) ) case _: LongsToListTable => @@ -600,32 +605,31 @@ case class GeneratedMethodStructure(fields: Fields, generator: CodeBlock, aux: A val keyName = context.namer.newVarName() val list = generator.declare(hashTable.listType, listName) // ProbeTable list; generator.assign(typeRef[CompositeKey], keyName, - Expression.invoke(Methods.compositeKey, - Expression.newArray(typeRef[Long], keyVars.map(generator.load): _*))) + invoke(compositeKey, + newArray(typeRef[Long], keyVars.map(generator.load): _*))) // list = tableVar.get(keyVar); generator.assign(list, - Expression.cast(hashTable.listType, - Expression.invoke(generator.load(tableVar), hashTable.get, generator.load(keyName)))) - using(generator.ifNullStatement(generator.load(listName))) - { onTrue => // if (null == list) + cast(hashTable.listType, + invoke(generator.load(tableVar), hashTable.get, generator.load(keyName)))) + using(generator.ifNullStatement(generator.load(listName))) { onTrue => // if (null == list) // list = new ListType(); - onTrue.assign(list, Templates.newInstance(hashTable.listType)) + onTrue.assign(list, createNewInstance(hashTable.listType)) // tableVar.put(keyVar, list); onTrue.expression( - Expression.pop( - Expression.invoke(generator.load(tableVar), hashTable.put, generator.load(keyName), - generator.load(listName)))) + pop( + invoke(generator.load(tableVar), hashTable.put, generator.load(keyName), + generator.load(listName)))) } // list.add( element ); generator.expression( - Expression.pop( - Expression.invoke(list, hashTable.add, element))) + pop( + invoke(list, hashTable.add, element))) } override def declareProperty(propertyVar: String) = { val localVariable = generator.declare(typeRef[Object], propertyVar) locals += (propertyVar -> localVariable) - generator.assign(localVariable, Expression.constant(null)) + generator.assign(localVariable, constant(null)) } override def declare(varName: String, codeGenType: CodeGenType) = { @@ -637,8 +641,8 @@ case class GeneratedMethodStructure(fields: Fields, generator: CodeBlock, aux: A override def hasLabel(nodeVar: String, labelVar: String, predVar: String) = { val local = locals(predVar) - Templates.handleKernelExceptions(generator, fields.ro, fields.close) { inner => - val invoke = Expression.invoke(readOperations, Methods.nodeHasLabel, inner.load(nodeVar), inner.load(labelVar)) + handleKernelExceptions(generator, fields.ro, fields.close) { inner => + val invoke = Expression.invoke(readOperations, nodeHasLabel, inner.load(nodeVar), inner.load(labelVar)) inner.assign(local, invoke) generator.load(predVar) } @@ -646,10 +650,10 @@ case class GeneratedMethodStructure(fields: Fields, generator: CodeBlock, aux: A override def relType(relVar: String, typeVar: String) = { val variable = locals(typeVar) - val typeOfRel = Expression.invoke(generator.load(relExtractor(relVar)), Methods.typeOf) - Templates.handleKernelExceptions(generator, fields.ro, fields.close) { inner => - val invoke = Expression.invoke(readOperations, Methods.relationshipTypeGetName, typeOfRel) - inner.assign(variable, invoke) + val typeOfRel = invoke(generator.load(relExtractor(relVar)), typeOf) + handleKernelExceptions(generator, fields.ro, fields.close) { inner => + val res = invoke(readOperations, relationshipTypeGetName, typeOfRel) + inner.assign(variable, res) generator.load(variable.name()) } } @@ -664,11 +668,11 @@ case class GeneratedMethodStructure(fields: Fields, generator: CodeBlock, aux: A override def declareFlag(name: String, initialValue: Boolean) = { val localVariable = generator.declare(typeRef[Boolean], name) locals += (name -> localVariable) - generator.assign(localVariable, Expression.constant(initialValue)) + generator.assign(localVariable, constant(initialValue)) } override def updateFlag(name: String, newValue: Boolean) = { - generator.assign(locals(name), Expression.constant(newValue)) + generator.assign(locals(name), constant(newValue)) } override def declarePredicate(name: String) = { @@ -677,79 +681,71 @@ case class GeneratedMethodStructure(fields: Fields, generator: CodeBlock, aux: A override def nodeGetPropertyForVar(nodeIdVar: String, propIdVar: String, propValueVar: String) = { val local = locals(propValueVar) - Templates.handleKernelExceptions(generator, fields.ro, fields.close) { body => + handleKernelExceptions(generator, fields.ro, fields.close) { body => - body.assign(local, Expression - .invoke(readOperations, Methods.nodeGetProperty, body.load(nodeIdVar), body.load(propIdVar))) + body.assign(local, invoke(readOperations, nodeGetProperty, body.load(nodeIdVar), body.load(propIdVar))) } } override def nodeGetPropertyById(nodeIdVar: String, propId: Int, propValueVar: String) = { val local = locals(propValueVar) - Templates.handleKernelExceptions(generator, fields.ro, fields.close) { body => - body.assign(local, Expression - .invoke(readOperations, Methods.nodeGetProperty, body.load(nodeIdVar), Expression.constant(propId))) + handleKernelExceptions(generator, fields.ro, fields.close) { body => + body.assign(local, invoke(readOperations, nodeGetProperty, body.load(nodeIdVar), constant(propId))) } } override def relationshipGetPropertyForVar(relIdVar: String, propIdVar: String, propValueVar: String) = { val local = locals(propValueVar) - Templates.handleKernelExceptions(generator, fields.ro, fields.close) { body => - body.assign(local, Expression - .invoke(readOperations, Methods.relationshipGetProperty, body.load(relIdVar), body.load(propIdVar))) + handleKernelExceptions(generator, fields.ro, fields.close) { body => + body.assign(local, + invoke(readOperations, relationshipGetProperty, body.load(relIdVar), body.load(propIdVar))) } } override def relationshipGetPropertyById(relIdVar: String, propId: Int, propValueVar: String) = { val local = locals(propValueVar) - Templates.handleKernelExceptions(generator, fields.ro, fields.close) { body => - body.assign(local, Expression - .invoke(readOperations, Methods.relationshipGetProperty, body.load(relIdVar), Expression.constant(propId))) + handleKernelExceptions(generator, fields.ro, fields.close) { body => + body.assign(local, invoke(readOperations, relationshipGetProperty, body.load(relIdVar), constant(propId))) } } override def lookupPropertyKey(propName: String, propIdVar: String) = - generator.assign(typeRef[Int], propIdVar, Expression - .invoke(readOperations, Methods.propertyKeyGetForName, Expression.constant(propName))) + generator.assign(typeRef[Int], propIdVar, invoke(readOperations, propertyKeyGetForName, constant(propName))) override def newIndexDescriptor(descriptorVar: String, labelVar: String, propKeyVar: String) = { generator.assign(typeRef[IndexDescriptor], descriptorVar, - Templates - .newInstance(typeRef[IndexDescriptor], (typeRef[Int], generator.load(labelVar)), - (typeRef[Int], generator.load(propKeyVar))) + createNewInstance(typeRef[IndexDescriptor], (typeRef[Int], generator.load(labelVar)), + (typeRef[Int], generator.load(propKeyVar))) ) } override def indexSeek(iterVar: String, descriptorVar: String, value: Expression) = { val local = generator.declare(typeRef[PrimitiveLongIterator], iterVar) - Templates.handleKernelExceptions(generator, fields.ro, fields.close) { body => - body.assign(local, Expression - .invoke(readOperations, Methods.nodesGetFromIndexLookup, generator.load(descriptorVar), value)) + handleKernelExceptions(generator, fields.ro, fields.close) { body => + body.assign(local, invoke(readOperations, nodesGetFromIndexLookup, generator.load(descriptorVar), value)) } } override def indexUniqueSeek(nodeVar: String, descriptorVar: String, value: Expression) = { val local = generator.declare(typeRef[Long], nodeVar) - Templates.handleKernelExceptions(generator, fields.ro, fields.close) { body => - body.assign(local, Expression - .invoke(readOperations, Methods.nodeGetUniqueFromIndexLookup, generator.load(descriptorVar), value)) + handleKernelExceptions(generator, fields.ro, fields.close) { body => + body.assign(local, + invoke(readOperations, nodeGetUniqueFromIndexLookup, generator.load(descriptorVar), value)) } } override def coerceToBoolean(propertyExpression: Expression): Expression = - Expression.invoke(Methods.coerceToPredicate, propertyExpression) + invoke(coerceToPredicate, propertyExpression) override def newTableValue(targetVar: String, structure: Map[String, CodeGenType]) = { val valueType = aux.typeReference(structure) - generator.assign(valueType, targetVar, Templates.newInstance(valueType)) + generator.assign(valueType, targetVar, createNewInstance(valueType)) generator.load(targetVar) } - private def field(structure: Map[String, CodeGenType], fieldType: CodeGenType, fieldName: String) = { + private def field(structure: Map[String, CodeGenType], fieldType: CodeGenType, fieldName: String) = FieldReference.field(aux.typeReference(structure), lowerType(fieldType), fieldName) - } - } diff --git a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_1/codegen/GeneratedQueryStructure.scala b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_1/codegen/GeneratedQueryStructure.scala index a6b26899bb439..8ecb76008f917 100644 --- a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_1/codegen/GeneratedQueryStructure.scala +++ b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_1/codegen/GeneratedQueryStructure.scala @@ -21,33 +21,27 @@ package org.neo4j.cypher.internal.spi.v3_1.codegen import java.lang.reflect.Modifier import java.util -import java.util.function.Consumer import org.neo4j.codegen.CodeGeneratorOption._ -import org.neo4j.codegen.ExpressionTemplate._ -import org.neo4j.codegen.MethodReference._ import org.neo4j.codegen.TypeReference._ import org.neo4j.codegen.source.{SourceCode, SourceVisitor} import org.neo4j.codegen.{CodeGenerator, _} -import org.neo4j.collection.primitive.{Primitive, PrimitiveLongIntMap, PrimitiveLongObjectMap} import org.neo4j.cypher.internal.compiler.v3_1.codegen._ import org.neo4j.cypher.internal.compiler.v3_1.codegen.ir.expressions.{CodeGenType, FloatType, IntType, ReferenceType} import org.neo4j.cypher.internal.compiler.v3_1.executionplan._ import org.neo4j.cypher.internal.compiler.v3_1.helpers._ import org.neo4j.cypher.internal.compiler.v3_1.planDescription.{Id, InternalPlanDescription} import org.neo4j.cypher.internal.compiler.v3_1.planner.CantCompileQueryException -import org.neo4j.cypher.internal.compiler.v3_1.spi.{InternalResultVisitor, QueryContext, QueryTransactionalContext} +import org.neo4j.cypher.internal.compiler.v3_1.spi.{InternalResultVisitor, QueryContext} import org.neo4j.cypher.internal.compiler.v3_1.{ExecutionMode, TaskCloser} -import org.neo4j.cypher.internal.frontend.v3_1.{CypherExecutionException, symbols} -import org.neo4j.graphdb.Direction -import org.neo4j.kernel.api.exceptions.KernelException -import org.neo4j.kernel.api.{ReadOperations, StatementTokenNameLookup, TokenNameLookup} -import org.neo4j.kernel.impl.api.RelationshipDataExtractor +import org.neo4j.cypher.internal.frontend.v3_1.symbols +import org.neo4j.kernel.api.ReadOperations import org.neo4j.kernel.impl.core.NodeManager object GeneratedQueryStructure extends CodeStructure[GeneratedQuery] { import Expression.{constant, invoke, newInstance} + import MethodReference.constructorReference case class GeneratedQueryStructureResult(query: GeneratedQuery, source: Option[(String, String)]) extends CodeStructureResult[GeneratedQuery] @@ -66,7 +60,7 @@ object GeneratedQueryStructure extends CodeStructure[GeneratedQuery] { } try { - CodeGenerator.generateCode(classOf[CodeStructure[_]].getClassLoader, mode, option, SourceCode.PRINT_SOURCE) + CodeGenerator.generateCode(classOf[CodeStructure[_]].getClassLoader, mode, option) } catch { case e: Exception => throw new CantCompileQueryException(e.getMessage, e) } @@ -138,14 +132,16 @@ object GeneratedQueryStructure extends CodeStructure[GeneratedQuery] { param[Provider[InternalPlanDescription]]("description"), param[QueryExecutionTracer]("tracer"), param[util.Map[String, Object]]("params"))) { execute => - execute.returns(Expression - .invoke(newInstance(execution), MethodReference.constructorReference(execution, - typeRef[TaskCloser], - typeRef[QueryContext], - typeRef[ExecutionMode], - typeRef[Provider[InternalPlanDescription]], - typeRef[QueryExecutionTracer], - typeRef[util.Map[String, Object]]), + execute.returns( + invoke( + newInstance(execution), + constructorReference(execution, + typeRef[TaskCloser], + typeRef[QueryContext], + typeRef[ExecutionMode], + typeRef[Provider[InternalPlanDescription]], + typeRef[QueryExecutionTracer], + typeRef[util.Map[String, Object]]), execute.load("closer"), execute.load("queryContext"), execute.load("executionMode"), @@ -199,115 +195,4 @@ object GeneratedQueryStructure extends CodeStructure[GeneratedQuery] { case CodeGenType(symbols.CTRelationship, IntType) => constant(-1L) case _ => constant(null) } -} - -object Templates { - - import GeneratedQueryStructure.{method, param, staticField, typeRef} - - def newInstance(valueType: TypeReference, args: (TypeReference,Expression)*): Expression = { - val types: Seq[TypeReference] = args.map(_._1) - val exprs: Seq[Expression] = args.map(_._2) - Expression.invoke(Expression.newInstance(valueType), - MethodReference.constructorReference(valueType, types: _*), exprs:_*) - } - - val newLongObjectMap = Expression.invoke(method[Primitive, PrimitiveLongObjectMap[_]]("longObjectMap")) - val newCountingMap = Expression.invoke(method[Primitive, PrimitiveLongIntMap]("longIntMap")) - - def asList[T](values: Seq[Expression])(implicit manifest: Manifest[T]): Expression = Expression.invoke( - methodReference(typeRef[util.Arrays], typeRef[util.List[T]], "asList", typeRef[Array[Object]]), - Expression.newArray(typeRef[T], values: _*)) - - def handleKernelExceptions[V](generate: CodeBlock, ro: FieldReference, close: MethodReference) - (block: CodeBlock => V): V = { - var result = null.asInstanceOf[V] - - generate.tryCatch(new Consumer[CodeBlock] { - override def accept(body: CodeBlock) = { - result = block(body) - } - }, new Consumer[CodeBlock]() { - override def accept(handle: CodeBlock) = { - handle.expression(Expression.invoke(handle.self(), close)) - handle.throwException(Expression.invoke( - Expression.newInstance(typeRef[CypherExecutionException]), - MethodReference.constructorReference(typeRef[CypherExecutionException], typeRef[String], typeRef[Throwable]), - Expression - .invoke(handle.load("e"), method[KernelException, String]("getUserMessage", typeRef[TokenNameLookup]), - Expression.invoke( - Expression.newInstance(typeRef[StatementTokenNameLookup]), - MethodReference - .constructorReference(typeRef[StatementTokenNameLookup], typeRef[ReadOperations]), - Expression.get(handle.self(), ro))), handle.load("e") - )) - } - }, param[KernelException]("e")) - - result - } - - def tryCatch(generate: CodeBlock)(tryBlock :CodeBlock => Unit)(exception: Parameter)(catchBlock :CodeBlock => Unit): Unit = { - generate.tryCatch(new Consumer[CodeBlock] { - override def accept(body: CodeBlock) = tryBlock(body) - }, new Consumer[CodeBlock]() { - override def accept(handle: CodeBlock) = catchBlock(handle) - }, exception) - } - - val incoming = Expression.get(staticField[Direction, Direction](Direction.INCOMING.name())) - val outgoing = Expression.get(staticField[Direction, Direction](Direction.OUTGOING.name())) - val both = Expression.get(staticField[Direction, Direction](Direction.BOTH.name())) - val newResultRow = Expression - .invoke(Expression.newInstance(typeRef[ResultRowImpl]), - MethodReference.constructorReference(typeRef[ResultRowImpl])) - val newRelationshipDataExtractor = Expression - .invoke(Expression.newInstance(typeRef[RelationshipDataExtractor]), - MethodReference.constructorReference(typeRef[RelationshipDataExtractor])) - - val CONSTRUCTOR = MethodTemplate.constructor( - param[TaskCloser]("closer"), - param[QueryContext]("queryContext"), - param[ExecutionMode]("executionMode"), - param[Provider[InternalPlanDescription]]("description"), - param[QueryExecutionTracer]("tracer"), - - param[util.Map[String, Object]]("params")). - put(self(), typeRef[TaskCloser], "closer", load("closer")). - put(self(), typeRef[ReadOperations], "ro", - cast(classOf[ReadOperations], invoke( - invoke(load("queryContext"), method[QueryContext, QueryTransactionalContext]("transactionalContext")), - method[QueryTransactionalContext, Object]("readOperations")))). - put(self(), typeRef[ExecutionMode], "executionMode", load("executionMode")). - put(self(), typeRef[Provider[InternalPlanDescription]], "description", load("description")). - put(self(), typeRef[QueryExecutionTracer], "tracer", load("tracer")). - put(self(), typeRef[util.Map[String, Object]], "params", load("params")). - put(self(), typeRef[NodeManager], "nodeManager", - cast(typeRef[NodeManager], - invoke(load("queryContext"), method[QueryContext, Object]("entityAccessor")))). - build() - - val SET_SUCCESSFUL_CLOSEABLE = MethodTemplate.method(typeRef[Unit], "setSuccessfulCloseable", - param[SuccessfulCloseable]("closeable")). - put(self(), typeRef[SuccessfulCloseable], "closeable", load("closeable")). - build() - val SUCCESS = MethodTemplate.method(typeRef[Unit], "success"). - expression( - invoke(get(self(), typeRef[SuccessfulCloseable], "closeable"), method[SuccessfulCloseable, Unit]("success"))). - build() - val CLOSE = MethodTemplate.method(typeRef[Unit], "close"). - expression( - invoke(get(self(), typeRef[SuccessfulCloseable], "closeable"), method[SuccessfulCloseable, Unit]("close"))). - build() - val EXECUTION_MODE = MethodTemplate.method(typeRef[ExecutionMode], "executionMode"). - returns(get(self(), typeRef[ExecutionMode], "executionMode")). - build() - val EXECUTION_PLAN_DESCRIPTION = MethodTemplate.method(typeRef[InternalPlanDescription], "executionPlanDescription"). - returns(cast( typeRef[InternalPlanDescription], - invoke(get(self(), typeRef[Provider[InternalPlanDescription]], "description"), - method[Provider[InternalPlanDescription], Object]("get")))). - build() - val JAVA_COLUMNS = MethodTemplate.method(typeRef[util.List[String]], "javaColumns"). - returns(get(typeRef[util.List[String]], "COLUMNS")). - build() } \ No newline at end of file diff --git a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_1/codegen/Methods.scala b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_1/codegen/Methods.scala index 40535253ed99d..ddd150942b263 100644 --- a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_1/codegen/Methods.scala +++ b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_1/codegen/Methods.scala @@ -45,10 +45,10 @@ object Methods { val countingTableCompositeKeyGet = method[util.HashMap[CompositeKey, Integer], Object]("get", typeRef[Object]) val compositeKey = method[CompiledConversionUtils, CompositeKey]("compositeKey", typeRef[Array[Long]]) val hasNextLong = method[PrimitiveLongIterator, Boolean]("hasNext") - val hasNextRelationship = method[RelationshipIterator, Boolean]("hasNext") + val hasMoreRelationship = method[RelationshipIterator, Boolean]("hasNext") val createMap = method[MapUtil, util.Map[String, Object]]("map", typeRef[Array[Object]]) val relationshipVisit = method[RelationshipIterator, Boolean]("relationshipVisit", typeRef[Long], typeRef[RelationshipVisitor[RuntimeException]]) - val relationship = method[RelationshipDataExtractor, Long]("relationship") + val getRelationship = method[RelationshipDataExtractor, Long]("relationship") val startNode = method[RelationshipDataExtractor, Long]("startNode") val endNode = method[RelationshipDataExtractor, Long]("endNode") val typeOf = method[RelationshipDataExtractor, Int]("type") @@ -83,7 +83,7 @@ object Methods { val nodesGetForLabel = method[ReadOperations, PrimitiveLongIterator]("nodesGetForLabel", typeRef[Int]) val nodeHasLabel = method[ReadOperations, Boolean]("nodeHasLabel", typeRef[Long], typeRef[Int]) val nextLong = method[PrimitiveLongIterator, Long]("next") - val nextRelationship = method[RelationshipIterator, Long]("next") + val fetchNextRelationship = method[RelationshipIterator, Long]("next") val newNodeProxyById = method[NodeManager, NodeProxy]("newNodeProxyById", typeRef[Long]) val newRelationshipProxyById = method[NodeManager, RelationshipProxy]("newRelationshipProxyById", typeRef[Long]) val nodeId = method[NodeIdWrapper, Long]("id") diff --git a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_1/codegen/Templates.scala b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_1/codegen/Templates.scala new file mode 100644 index 0000000000000..0b58896d4351a --- /dev/null +++ b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_1/codegen/Templates.scala @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2002-2016 "Neo Technology," + * Network Engine for Objects in Lund AB [http://neotechnology.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.neo4j.cypher.internal.spi.v3_1.codegen +import java.util +import java.util.function.Consumer + +import org.neo4j.codegen.ExpressionTemplate._ +import org.neo4j.codegen.MethodReference._ +import org.neo4j.codegen._ +import org.neo4j.collection.primitive.{Primitive, PrimitiveLongIntMap, PrimitiveLongObjectMap} +import org.neo4j.cypher.internal.compiler.v3_1.codegen._ +import org.neo4j.cypher.internal.compiler.v3_1.executionplan._ +import org.neo4j.cypher.internal.compiler.v3_1.planDescription.InternalPlanDescription +import org.neo4j.cypher.internal.compiler.v3_1.spi.{QueryContext, QueryTransactionalContext} +import org.neo4j.cypher.internal.compiler.v3_1.{ExecutionMode, TaskCloser} +import org.neo4j.cypher.internal.frontend.v3_1.CypherExecutionException +import org.neo4j.graphdb.Direction +import org.neo4j.kernel.api.exceptions.KernelException +import org.neo4j.kernel.api.{ReadOperations, StatementTokenNameLookup, TokenNameLookup} +import org.neo4j.kernel.impl.api.RelationshipDataExtractor +import org.neo4j.kernel.impl.core.NodeManager + +/** + * Contains common code generation constructs. + */ +object Templates { + + import GeneratedQueryStructure.{method, param, staticField, typeRef} + + def createNewInstance(valueType: TypeReference, args: (TypeReference,Expression)*): Expression = { + val argTypes = args.map(_._1) + val argExpression = args.map(_._2) + Expression.invoke(Expression.newInstance(valueType), + MethodReference.constructorReference(valueType, argTypes: _*), argExpression:_*) + } + + val newLongObjectMap = Expression.invoke(method[Primitive, PrimitiveLongObjectMap[_]]("longObjectMap")) + val newCountingMap = Expression.invoke(method[Primitive, PrimitiveLongIntMap]("longIntMap")) + + def asList[T](values: Seq[Expression])(implicit manifest: Manifest[T]): Expression = Expression.invoke( + methodReference(typeRef[util.Arrays], typeRef[util.List[T]], "asList", typeRef[Array[Object]]), + Expression.newArray(typeRef[T], values: _*)) + + def handleKernelExceptions[V](generate: CodeBlock, ro: FieldReference, close: MethodReference) + (block: CodeBlock => V): V = { + var result = null.asInstanceOf[V] + + generate.tryCatch(new Consumer[CodeBlock] { + override def accept(body: CodeBlock) = { + result = block(body) + } + }, new Consumer[CodeBlock]() { + override def accept(handle: CodeBlock) = { + handle.expression(Expression.invoke(handle.self(), close)) + handle.throwException(Expression.invoke( + Expression.newInstance(typeRef[CypherExecutionException]), + MethodReference.constructorReference(typeRef[CypherExecutionException], typeRef[String], typeRef[Throwable]), + Expression + .invoke(handle.load("e"), method[KernelException, String]("getUserMessage", typeRef[TokenNameLookup]), + Expression.invoke( + Expression.newInstance(typeRef[StatementTokenNameLookup]), + MethodReference + .constructorReference(typeRef[StatementTokenNameLookup], typeRef[ReadOperations]), + Expression.get(handle.self(), ro))), handle.load("e") + )) + } + }, param[KernelException]("e")) + + result + } + + def tryCatch(generate: CodeBlock)(tryBlock :CodeBlock => Unit)(exception: Parameter)(catchBlock :CodeBlock => Unit): Unit = { + generate.tryCatch(new Consumer[CodeBlock] { + override def accept(body: CodeBlock) = tryBlock(body) + }, new Consumer[CodeBlock]() { + override def accept(handle: CodeBlock) = catchBlock(handle) + }, exception) + } + + val incoming = Expression.get(staticField[Direction, Direction](Direction.INCOMING.name())) + val outgoing = Expression.get(staticField[Direction, Direction](Direction.OUTGOING.name())) + val both = Expression.get(staticField[Direction, Direction](Direction.BOTH.name())) + val newResultRow = Expression + .invoke(Expression.newInstance(typeRef[ResultRowImpl]), + MethodReference.constructorReference(typeRef[ResultRowImpl])) + val newRelationshipDataExtractor = Expression + .invoke(Expression.newInstance(typeRef[RelationshipDataExtractor]), + MethodReference.constructorReference(typeRef[RelationshipDataExtractor])) + + val CONSTRUCTOR = MethodTemplate.constructor( + param[TaskCloser]("closer"), + param[QueryContext]("queryContext"), + param[ExecutionMode]("executionMode"), + param[Provider[InternalPlanDescription]]("description"), + param[QueryExecutionTracer]("tracer"), + + param[util.Map[String, Object]]("params")). + put(self(), typeRef[TaskCloser], "closer", load("closer")). + put(self(), typeRef[ReadOperations], "ro", + cast(classOf[ReadOperations], invoke( + invoke(load("queryContext"), method[QueryContext, QueryTransactionalContext]("transactionalContext")), + method[QueryTransactionalContext, Object]("readOperations")))). + put(self(), typeRef[ExecutionMode], "executionMode", load("executionMode")). + put(self(), typeRef[Provider[InternalPlanDescription]], "description", load("description")). + put(self(), typeRef[QueryExecutionTracer], "tracer", load("tracer")). + put(self(), typeRef[util.Map[String, Object]], "params", load("params")). + put(self(), typeRef[NodeManager], "nodeManager", + cast(typeRef[NodeManager], + invoke(load("queryContext"), method[QueryContext, Object]("entityAccessor")))). + build() + + val SET_SUCCESSFUL_CLOSEABLE = MethodTemplate.method(typeRef[Unit], "setSuccessfulCloseable", + param[SuccessfulCloseable]("closeable")). + put(self(), typeRef[SuccessfulCloseable], "closeable", load("closeable")). + build() + val SUCCESS = MethodTemplate.method(typeRef[Unit], "success"). + expression( + invoke(get(self(), typeRef[SuccessfulCloseable], "closeable"), method[SuccessfulCloseable, Unit]("success"))). + build() + val CLOSE = MethodTemplate.method(typeRef[Unit], "close"). + expression( + invoke(get(self(), typeRef[SuccessfulCloseable], "closeable"), method[SuccessfulCloseable, Unit]("close"))). + build() + val EXECUTION_MODE = MethodTemplate.method(typeRef[ExecutionMode], "executionMode"). + returns(get(self(), typeRef[ExecutionMode], "executionMode")). + build() + val EXECUTION_PLAN_DESCRIPTION = MethodTemplate.method(typeRef[InternalPlanDescription], "executionPlanDescription"). + returns(cast( typeRef[InternalPlanDescription], + invoke(get(self(), typeRef[Provider[InternalPlanDescription]], "description"), + method[Provider[InternalPlanDescription], Object]("get")))). + build() + val JAVA_COLUMNS = MethodTemplate.method(typeRef[util.List[String]], "javaColumns"). + returns(get(typeRef[util.List[String]], "COLUMNS")). + build() +} diff --git a/community/cypher/cypher/src/test/scala/org/neo4j/cypher/CartesianProductNotificationAcceptanceTest.scala b/community/cypher/cypher/src/test/scala/org/neo4j/cypher/CartesianProductNotificationAcceptanceTest.scala index 8ba23c67f1c56..ca3dcb2c01876 100644 --- a/community/cypher/cypher/src/test/scala/org/neo4j/cypher/CartesianProductNotificationAcceptanceTest.scala +++ b/community/cypher/cypher/src/test/scala/org/neo4j/cypher/CartesianProductNotificationAcceptanceTest.scala @@ -30,7 +30,6 @@ import org.neo4j.cypher.internal.frontend.v3_1.InputPosition import org.neo4j.cypher.internal.frontend.v3_1.notification.CartesianProductNotification import org.neo4j.cypher.internal.frontend.v3_1.test_helpers.CypherFunSuite import org.neo4j.cypher.internal.spi.v3_1.codegen.GeneratedQueryStructure -import org.neo4j.helpers.Clock import org.neo4j.logging.NullLog class CartesianProductNotificationAcceptanceTest extends CypherFunSuite with GraphDatabaseTestSupport { diff --git a/community/cypher/cypher/src/test/scala/org/neo4j/cypher/internal/spi/v3_1/codegen/GeneratedMethodStructureTest.scala b/community/cypher/cypher/src/test/scala/org/neo4j/cypher/internal/spi/v3_1/codegen/GeneratedMethodStructureTest.scala index 1c1bb6ae19857..a8be4fcee3b5a 100644 --- a/community/cypher/cypher/src/test/scala/org/neo4j/cypher/internal/spi/v3_1/codegen/GeneratedMethodStructureTest.scala +++ b/community/cypher/cypher/src/test/scala/org/neo4j/cypher/internal/spi/v3_1/codegen/GeneratedMethodStructureTest.scala @@ -60,7 +60,7 @@ class GeneratedMethodStructureTest extends CypherFunSuite { Operation("nullable node", m => { m.declare("foo", CodeGenType.primitiveNode) m.generator.assign(typeRef[Long], "bar", - m.nullablePrimitive("foo", CodeGenType.primitiveNode, m.load("foo"))) + m.nullablePrimitive("foo", CodeGenType.primitiveNode, m.loadVariable("foo"))) }), Operation("mark variables as null", m => { @@ -111,7 +111,7 @@ class GeneratedMethodStructureTest extends CypherFunSuite { } }), Operation("Method invocation", m => { - m.method(LongToCountTable, "v1", "inner") {inner => { + m.invokeMethod(LongToCountTable, "v1", "inner") { inner => { inner.allocateProbeTable("v1", LongToCountTable) }} }),