Skip to content

Commit

Permalink
Support for adding two UTF8StringValue
Browse files Browse the repository at this point in the history
  • Loading branch information
pontusmelke committed Oct 19, 2017
1 parent 1b4ab9f commit 723ead6
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 7 deletions.
Expand Up @@ -19,13 +19,15 @@
*/ */
package org.neo4j.cypher.internal.compatibility.v3_4.runtime.commands.expressions package org.neo4j.cypher.internal.compatibility.v3_4.runtime.commands.expressions


import org.neo4j.cypher.internal.util.v3_4.CypherTypeException
import org.neo4j.cypher.internal.compatibility.v3_4.runtime.ExecutionContext import org.neo4j.cypher.internal.compatibility.v3_4.runtime.ExecutionContext
import org.neo4j.cypher.internal.compatibility.v3_4.runtime.helpers.{IsList, TypeSafeMathSupport} import org.neo4j.cypher.internal.compatibility.v3_4.runtime.helpers.{IsList, TypeSafeMathSupport}
import org.neo4j.cypher.internal.compatibility.v3_4.runtime.pipes.QueryState import org.neo4j.cypher.internal.compatibility.v3_4.runtime.pipes.QueryState
import org.neo4j.cypher.internal.util.v3_4.CypherTypeException
import org.neo4j.cypher.internal.util.v3_4.symbols._ import org.neo4j.cypher.internal.util.v3_4.symbols._
import org.neo4j.values._ import org.neo4j.values._
import org.neo4j.values.storable.StringValue.UTF8StringValue
import org.neo4j.values.storable._ import org.neo4j.values.storable._
import org.neo4j.values.utils.UTF8Utils
import org.neo4j.values.virtual.VirtualValues import org.neo4j.values.virtual.VirtualValues


case class Add(a: Expression, b: Expression) extends Expression with TypeSafeMathSupport { case class Add(a: Expression, b: Expression) extends Expression with TypeSafeMathSupport {
Expand All @@ -37,6 +39,7 @@ case class Add(a: Expression, b: Expression) extends Expression with TypeSafeMat
case (x, y) if x == Values.NO_VALUE || y == Values.NO_VALUE => Values.NO_VALUE case (x, y) if x == Values.NO_VALUE || y == Values.NO_VALUE => Values.NO_VALUE
case (x: IntegralValue, y: IntegralValue) => Values.longValue(StrictMath.addExact(x.longValue(),y.longValue())) case (x: IntegralValue, y: IntegralValue) => Values.longValue(StrictMath.addExact(x.longValue(),y.longValue()))
case (x: NumberValue, y: NumberValue) => Values.doubleValue(x.doubleValue() + y.doubleValue()) case (x: NumberValue, y: NumberValue) => Values.doubleValue(x.doubleValue() + y.doubleValue())
case (x: UTF8StringValue, y: UTF8StringValue) => UTF8Utils.add(x, y)
case (x: TextValue, y: TextValue) => Values.stringValue(x.stringValue() + y.stringValue()) case (x: TextValue, y: TextValue) => Values.stringValue(x.stringValue() + y.stringValue())
case (IsList(x), IsList(y)) => VirtualValues.concat(x, y) case (IsList(x), IsList(y)) => VirtualValues.concat(x, y)
case (IsList(x), y) => VirtualValues.appendToList(x, y) case (IsList(x), y) => VirtualValues.appendToList(x, y)
Expand Down
Expand Up @@ -19,13 +19,18 @@
*/ */
package org.neo4j.cypher.internal.compatibility.v3_4.runtime.commands package org.neo4j.cypher.internal.compatibility.v3_4.runtime.commands


import org.neo4j.cypher.internal.util.v3_4.CypherTypeException import java.nio.charset.StandardCharsets

import org.neo4j.cypher.internal.compatibility.v3_4.runtime.ExecutionContext import org.neo4j.cypher.internal.compatibility.v3_4.runtime.ExecutionContext
import org.neo4j.cypher.internal.compatibility.v3_4.runtime.commands.expressions.{Add, Literal} import org.neo4j.cypher.internal.compatibility.v3_4.runtime.commands.expressions.{Add, Literal, ParameterExpression}
import org.neo4j.cypher.internal.compiler.v3_4._ import org.neo4j.cypher.internal.compiler.v3_4._
import org.neo4j.cypher.internal.util.v3_4.CypherTypeException
import org.neo4j.cypher.internal.util.v3_4.test_helpers.CypherFunSuite import org.neo4j.cypher.internal.util.v3_4.test_helpers.CypherFunSuite
import org.neo4j.values.AnyValue
import org.neo4j.values.storable.StringValue.UTF8StringValue
import org.neo4j.values.storable.Values import org.neo4j.values.storable.Values
import org.neo4j.values.storable.Values.{longValue, stringValue} import org.neo4j.values.storable.Values.{longValue, stringValue, utf8Value}
import org.neo4j.values.virtual.VirtualValues


class AddTest extends CypherFunSuite { class AddTest extends CypherFunSuite {


Expand Down Expand Up @@ -64,4 +69,21 @@ class AddTest extends CypherFunSuite {
val expr = Add(Literal("1"), Literal(true)) val expr = Add(Literal("1"), Literal(true))
intercept[CypherTypeException](expr(m, s)) intercept[CypherTypeException](expr(m, s))
} }

test("UTF8 value addition") {
import scala.collection.JavaConverters._
// Given
val hello = "hello".getBytes(StandardCharsets.UTF_8)
val world = "world".getBytes(StandardCharsets.UTF_8)
val params: Map[String, AnyValue] = Map("p1" -> utf8Value(hello), "p2" -> utf8Value(world))
val state = QueryStateHelper.newWith(params = VirtualValues.map(params.asJava))

// When
val result = Add(ParameterExpression("p1"), ParameterExpression("p2"))(m,state)

// Then
result shouldBe a[UTF8StringValue]
result should equal(utf8Value("helloworld".getBytes(StandardCharsets.UTF_8)))
result should equal(Values.stringValue("helloworld"))
}
} }
Expand Up @@ -183,6 +183,11 @@ public int length()
{ {
return value().length(); return value().length();
} }

public byte[] bytes()
{
return bytes;
}
} }
} }


Expand Up @@ -23,6 +23,8 @@
import java.util.Arrays; import java.util.Arrays;
import java.util.Comparator; import java.util.Comparator;


import org.neo4j.values.storable.StringValue.UTF8StringValue;

import static java.lang.String.format; import static java.lang.String.format;


/** /**
Expand Down Expand Up @@ -107,14 +109,14 @@ public static double coerceToDouble( Value value )


public static final Value NO_VALUE = NoValue.NO_VALUE; public static final Value NO_VALUE = NoValue.NO_VALUE;


public static TextValue utf8Value( byte[] bytes ) public static UTF8StringValue utf8Value( byte[] bytes )
{ {
return utf8Value( bytes, 0, bytes.length ); return utf8Value( bytes, 0, bytes.length );
} }


public static TextValue utf8Value( byte[] bytes, int offset, int length ) public static UTF8StringValue utf8Value( byte[] bytes, int offset, int length )
{ {
return new StringValue.UTF8StringValue( bytes, offset, length ); return new UTF8StringValue( bytes, offset, length );
} }


public static TextValue stringValue( String value ) public static TextValue stringValue( String value )
Expand Down
@@ -0,0 +1,52 @@
/*
* Copyright (c) 2002-2017 "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 <http://www.gnu.org/licenses/>.
*/
package org.neo4j.values.utils;

import org.neo4j.values.storable.StringValue.UTF8StringValue;

import static org.neo4j.values.storable.Values.utf8Value;

/**
* Utility class for operations on utf-8 values.
*/
public final class UTF8Utils
{
private UTF8Utils()
{
throw new UnsupportedOperationException( "Do not instantiate" );
}

/**
* Add two values.
* @param a value to add
* @param b value to add
* @return the value a + b
*/
public static UTF8StringValue add( UTF8StringValue a, UTF8StringValue b )
{
byte[] bytesA = a.bytes();
byte[] bytesB = b.bytes();

byte[] bytes = new byte[bytesA.length + bytesB.length];
System.arraycopy( bytesA, 0, bytes, 0, bytesA.length );
System.arraycopy( bytesB, 0, bytes, bytesA.length, bytesB.length );
return utf8Value(bytes);
}
}

0 comments on commit 723ead6

Please sign in to comment.