From cf32135ffe0b871b0150693ed57b79f88a9771c6 Mon Sep 17 00:00:00 2001 From: Satia Herfert Date: Thu, 1 Mar 2018 08:30:11 +0100 Subject: [PATCH] Fix NullPointerException and forbid assigning both datetime and epoch --- .../neo4j/values/storable/TemporalValue.java | 40 ++++++++++++++----- .../acceptance/TemporalAcceptanceTest.scala | 3 +- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/community/values/src/main/java/org/neo4j/values/storable/TemporalValue.java b/community/values/src/main/java/org/neo4j/values/storable/TemporalValue.java index 4a28e6da37309..39c4ac7b51db2 100644 --- a/community/values/src/main/java/org/neo4j/values/storable/TemporalValue.java +++ b/community/values/src/main/java/org/neo4j/values/storable/TemporalValue.java @@ -628,7 +628,7 @@ DateTimeBuilder assign( Field field, AnyValue value ) { if ( field == Field.datetime || field == Field.epoch ) { - return new SelectDateTimeDTBuilder( date, time ); + return new SelectDateTimeDTBuilder( date, time ).assign( field, value ); } else if ( field == Field.time || field == Field.date ) { @@ -636,13 +636,13 @@ else if ( field == Field.time || field == Field.date ) } else { - return assignNonComposite( field, value ); + return assignToSubBuilders( field, value ); } } - DateTimeBuilder assignNonComposite( Field field, AnyValue value ) + DateTimeBuilder assignToSubBuilders( Field field, AnyValue value ) { - if ( field.field.isDateBased() ) + if ( field == Field.date || field.field != null && field.field.isDateBased() ) { if ( date == null ) { @@ -650,7 +650,7 @@ DateTimeBuilder assignNonComposite( Field field, AnyValue value ) } date = date.assign( field, value ); } - else + else if ( field == Field.time || field.field != null && field.field.isTimeBased() ) { if ( time == null ) { @@ -658,12 +658,19 @@ DateTimeBuilder assignNonComposite( Field field, AnyValue value ) } time.assign( field, value ); } + else + { + throw new IllegalStateException( "This method should not be used for any fields the DateBuilder or TimeBuilder can't handle" ); + } return this; } } private static class SelectDateTimeDTBuilder extends DateTimeBuilder { + private AnyValue datetime; + private AnyValue epoch; + SelectDateTimeDTBuilder( DateBuilder date, ConstructTime time ) { super( date, time ); @@ -680,16 +687,29 @@ DateTimeBuilder assign( Field field, AnyValue value ) { if ( field == Field.date || field == Field.time ) { - throw new IllegalArgumentException( field.name() + " cannot be selected together with datetime." ); + throw new IllegalArgumentException( field.name() + " cannot be selected together with datetime or epoch." ); } else if ( field == Field.datetime ) { - throw new IllegalArgumentException( "cannot re-assign " + field ); + if ( epoch != null ) + { + throw new IllegalArgumentException( field.name() + " cannot be selected together with epoch." ); + } + datetime = assignment( Field.datetime, datetime, value ); + } + else if ( field == Field.epoch ) + { + if ( datetime != null ) + { + throw new IllegalArgumentException( field.name() + " cannot be selected together with datetime." ); + } + epoch = assignment( Field.epoch, epoch, value ); } else { - return assignNonComposite( field, value ); + return assignToSubBuilders( field, value ); } + return this; } } @@ -703,13 +723,13 @@ private static class SelectDateOrTimeDTBuilder extends DateTimeBuilder @Override DateTimeBuilder assign( Field field, AnyValue value ) { - if ( field == Field.datetime ) + if ( field == Field.datetime || field == Field.epoch ) { throw new IllegalArgumentException( field.name() + " cannot be selected together with date or time." ); } else { - return assignNonComposite( field, value ); + return assignToSubBuilders( field, value ); } } } diff --git a/enterprise/cypher/acceptance-spec-suite/src/test/scala/org/neo4j/internal/cypher/acceptance/TemporalAcceptanceTest.scala b/enterprise/cypher/acceptance-spec-suite/src/test/scala/org/neo4j/internal/cypher/acceptance/TemporalAcceptanceTest.scala index 50b9753c71124..b4f2137b4ac06 100644 --- a/enterprise/cypher/acceptance-spec-suite/src/test/scala/org/neo4j/internal/cypher/acceptance/TemporalAcceptanceTest.scala +++ b/enterprise/cypher/acceptance-spec-suite/src/test/scala/org/neo4j/internal/cypher/acceptance/TemporalAcceptanceTest.scala @@ -113,7 +113,8 @@ class TemporalAcceptanceTest extends ExecutionEngineFunSuite with QueryStatistic "{year:1984, month: 2, quarter:11}", "{year:1984, month: 2, dayOfQuarter:11}", "{year:1984, week: 2, day:11}", "{year:1984, week: 2, quarter:11}", "{year:1984, week: 2, dayOfQuarter:11}", "{year:1984, quarter: 2, day:11}", "{year:1984, quarter: 2, dayOfWeek:6}", "{datetime: datetime(), date: date()}", - "{datetime: datetime(), time: time()}") + "{datetime: datetime(), time: time()}", "{datetime: datetime(), epoch: timestamp()}", "{date: date(), epoch: timestamp()}", + "{time: time(), epoch: timestamp()}") shouldNotConstructWithArg("datetime", queries) }