Skip to content

Commit

Permalink
Expand the FTS cypher planner tests to cover all supported versions.
Browse files Browse the repository at this point in the history
Also, avoid generating data sets that contain values that the old planners do not know how to work with.
  • Loading branch information
chrisvest committed Oct 9, 2018
1 parent 2968f7e commit 99b3e7b
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 12 deletions.
Expand Up @@ -36,6 +36,8 @@
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
Expand All @@ -47,6 +49,7 @@
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.function.LongFunction;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

Expand Down Expand Up @@ -1977,7 +1980,7 @@ public void fulltextIndexMustNotBeAvailableForRegularIndexSeeks()
try ( Transaction tx = db.beginTx() )
{
awaitIndexesOnline();
List<Value> values = generateRandomNonStringValues();
List<Value> values = generateRandomSimpleValues();
for ( Value value : values )
{
db.createNode( LABEL ).setProperty( PROP, value.asObject() );
Expand All @@ -1989,10 +1992,23 @@ public void fulltextIndexMustNotBeAvailableForRegularIndexSeeks()
params.put( "prop", valueToQueryFor );
try ( Result result = db.execute( "profile match (n:" + LABEL.name() + ") where n." + PROP + " = {prop} return n", params ) )
{
assertThat( result.stream().count(), is( 1L ) );
String planDescription = result.getExecutionPlanDescription().toString();
assertThat( planDescription, containsString( "NodeByLabelScan" ) );
assertThat( planDescription, not( containsString( "IndexSeek" ) ) );
assertNoIndexSeeks( result );
}
try ( Result result = db.execute( "cypher planner=rule profile match (n:" + LABEL.name() + ") where n." + PROP + " = {prop} return n", params ) )
{
assertNoIndexSeeks( result );
}
try ( Result result = db.execute( "cypher 2.3 profile match (n:" + LABEL.name() + ") where n." + PROP + " = {prop} return n", params ) )
{
assertNoIndexSeeks( result );
}
try ( Result result = db.execute( "cypher 3.1 profile match (n:" + LABEL.name() + ") where n." + PROP + " = {prop} return n", params ) )
{
assertNoIndexSeeks( result );
}
try ( Result result = db.execute( "cypher 3.4 profile match (n:" + LABEL.name() + ") where n." + PROP + " = {prop} return n", params ) )
{
assertNoIndexSeeks( result );
}
}

Expand All @@ -2011,7 +2027,7 @@ public void fulltextIndexMustNotBeAvailableForRegularIndexSeeksAfterShutDown()
try ( Transaction tx = db.beginTx() )
{
awaitIndexesOnline();
List<Value> values = generateRandomNonStringValues();
List<Value> values = generateRandomSimpleValues();
for ( Value value : values )
{
db.createNode( LABEL ).setProperty( PROP, value.asObject() );
Expand All @@ -2023,11 +2039,32 @@ public void fulltextIndexMustNotBeAvailableForRegularIndexSeeksAfterShutDown()
params.put( "prop", valueToQueryFor );
try ( Result result = db.execute( "profile match (n:" + LABEL.name() + ") where n." + PROP + " = {prop} return n", params ) )
{
assertThat( result.stream().count(), is( 1L ) );
String planDescription = result.getExecutionPlanDescription().toString();
assertThat( planDescription, containsString( "NodeByLabelScan" ) );
assertThat( planDescription, not( containsString( "IndexSeek" ) ) );
assertNoIndexSeeks( result );
}
try ( Result result = db.execute( "cypher planner=rule profile match (n:" + LABEL.name() + ") where n." + PROP + " = {prop} return n", params ) )
{
assertNoIndexSeeks( result );
}
try ( Result result = db.execute( "cypher 2.3 profile match (n:" + LABEL.name() + ") where n." + PROP + " = {prop} return n", params ) )
{
assertNoIndexSeeks( result );
}
try ( Result result = db.execute( "cypher 3.1 profile match (n:" + LABEL.name() + ") where n." + PROP + " = {prop} return n", params ) )
{
assertNoIndexSeeks( result );
}
try ( Result result = db.execute( "cypher 3.4 profile match (n:" + LABEL.name() + ") where n." + PROP + " = {prop} return n", params ) )
{
assertNoIndexSeeks( result );
}
}

private void assertNoIndexSeeks( Result result )
{
assertThat( result.stream().count(), is( 1L ) );
String planDescription = result.getExecutionPlanDescription().toString();
assertThat( planDescription, containsString( "NodeByLabel" ) );
assertThat( planDescription, not( containsString( "IndexSeek" ) ) );
}

private GraphDatabaseAPI createDatabase()
Expand Down Expand Up @@ -2138,6 +2175,19 @@ static String array( String... args )
}

private List<Value> generateRandomNonStringValues()
{
Predicate<Value> nonString = v -> v.valueGroup() != ValueGroup.TEXT;
return generateRandomValues( nonString );
}

private List<Value> generateRandomSimpleValues()
{
EnumSet<ValueGroup> simpleTypes = EnumSet.of(
ValueGroup.BOOLEAN, ValueGroup.BOOLEAN_ARRAY, ValueGroup.NUMBER, ValueGroup.NUMBER_ARRAY );
return generateRandomValues( v -> simpleTypes.contains( v.valueGroup() ) );
}

private List<Value> generateRandomValues( Predicate<Value> predicate )
{
int valuesToGenerate = 1000;
RandomValues generator = RandomValues.create();
Expand All @@ -2149,7 +2199,7 @@ private List<Value> generateRandomNonStringValues()
{
value = generator.nextValue();
}
while ( value.valueGroup() == ValueGroup.TEXT );
while ( !predicate.test( value ) );
values.add( value );
}
return values;
Expand Down
Expand Up @@ -86,8 +86,8 @@ class TransactionBoundPlanContext(txSupplier: () => KernelTransaction, logger: I
private def getOnlineIndex(reference: IndexReference): Option[IndexDescriptor] =
txSupplier().schemaRead.indexGetState(reference) match {
case InternalIndexState.ONLINE => reference match {
case cir: CapableIndexDescriptor => Some(IndexDescriptor(cir.schema().getEntityTokenIds()(0), cir.properties, cir.limitations().map(kernelToCypher).toSet))
case ref if ref.isFulltextIndex || ref.isEventuallyConsistent => None
case cir: CapableIndexDescriptor => Some(IndexDescriptor(cir.schema().getEntityTokenIds()(0), cir.properties, cir.limitations().map(kernelToCypher).toSet))
case _ => Some(IndexDescriptor(reference.schema().getEntityTokenIds()(0), reference.properties))
}
case _ => None
Expand Down

0 comments on commit 99b3e7b

Please sign in to comment.