diff --git a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v2_3/TransactionBoundQueryContext.scala b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v2_3/TransactionBoundQueryContext.scala
index d19b04a680350..8ce55efd5314c 100644
--- a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v2_3/TransactionBoundQueryContext.scala
+++ b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v2_3/TransactionBoundQueryContext.scala
@@ -716,7 +716,7 @@ final class TransactionBoundQueryContext(tc: TransactionalContextWrapper, val re
def addIndexRule(labelId: Int, propertyKeyId: Int): IdempotentResult[SchemaTypes.IndexDescriptor] = try {
IdempotentResult(
DefaultIndexReference.toDescriptor(
- tc.kernelTransaction.schemaWrite().indexCreate(SchemaDescriptorFactory.forLabel(labelId, propertyKeyId), null))
+ tc.kernelTransaction.schemaWrite().indexCreate(SchemaDescriptorFactory.forLabel(labelId, propertyKeyId)))
)
} catch {
case _: AlreadyIndexedException =>
diff --git a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_1/TransactionBoundQueryContext.scala b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_1/TransactionBoundQueryContext.scala
index e83cd35f5f327..859f659d4ae6f 100644
--- a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_1/TransactionBoundQueryContext.scala
+++ b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_1/TransactionBoundQueryContext.scala
@@ -731,7 +731,7 @@ final class TransactionBoundQueryContext(txContext: TransactionalContextWrapper,
override def addIndexRule(labelId: Int, propertyKeyId: Int): IdempotentResult[IndexDescriptor] = try {
IdempotentResult(
DefaultIndexReference.toDescriptor(
- txContext.kernelTransaction.schemaWrite().indexCreate(SchemaDescriptorFactory.forLabel(labelId, propertyKeyId), null))
+ txContext.kernelTransaction.schemaWrite().indexCreate(SchemaDescriptorFactory.forLabel(labelId, propertyKeyId)))
)
} catch {
case _: AlreadyIndexedException =>
diff --git a/community/cypher/interpreted-runtime/src/main/scala/org/neo4j/cypher/internal/runtime/interpreted/TransactionBoundQueryContext.scala b/community/cypher/interpreted-runtime/src/main/scala/org/neo4j/cypher/internal/runtime/interpreted/TransactionBoundQueryContext.scala
index 75c4796558928..77e899cdf6567 100644
--- a/community/cypher/interpreted-runtime/src/main/scala/org/neo4j/cypher/internal/runtime/interpreted/TransactionBoundQueryContext.scala
+++ b/community/cypher/interpreted-runtime/src/main/scala/org/neo4j/cypher/internal/runtime/interpreted/TransactionBoundQueryContext.scala
@@ -640,7 +640,7 @@ sealed class TransactionBoundQueryContext(val transactionalContext: Transactiona
override def addIndexRule(descriptor: IndexDescriptor): IdempotentResult[IndexReference] = {
val kernelDescriptor = cypherToKernelSchema(descriptor)
try {
- IdempotentResult(transactionalContext.kernelTransaction.schemaWrite().indexCreate(kernelDescriptor, null))
+ IdempotentResult(transactionalContext.kernelTransaction.schemaWrite().indexCreate(kernelDescriptor))
} catch {
case _: AlreadyIndexedException =>
val indexReference = transactionalContext.kernelTransaction.schemaRead().index(kernelDescriptor.getLabelId, kernelDescriptor.getPropertyIds: _*)
diff --git a/community/kernel-api/src/main/java/org/neo4j/internal/kernel/api/SchemaWrite.java b/community/kernel-api/src/main/java/org/neo4j/internal/kernel/api/SchemaWrite.java
index 0593a8ca9670f..b8a0acdf733e1 100644
--- a/community/kernel-api/src/main/java/org/neo4j/internal/kernel/api/SchemaWrite.java
+++ b/community/kernel-api/src/main/java/org/neo4j/internal/kernel/api/SchemaWrite.java
@@ -30,6 +30,16 @@
*/
public interface SchemaWrite
{
+ /**
+ * Create index from schema descriptor. Default configured index provider will be used.
+ *
+ * @param descriptor description of the index
+ */
+ default IndexReference indexCreate( SchemaDescriptor descriptor ) throws SchemaKernelException
+ {
+ return indexCreate( descriptor, null );
+ }
+
/**
* Create index from schema descriptor. Optionally a specific provider name can be specified.
*
@@ -47,18 +57,42 @@ public interface SchemaWrite
void indexDrop( IndexReference index ) throws SchemaKernelException;
/**
- * Create unique property constraint
+ * Create unique property constraint. Default configured index provider will be used.
*
* @param descriptor description of the constraint
*/
- ConstraintDescriptor uniquePropertyConstraintCreate( SchemaDescriptor descriptor ) throws SchemaKernelException;
+ default ConstraintDescriptor uniquePropertyConstraintCreate( SchemaDescriptor descriptor ) throws SchemaKernelException
+ {
+ return uniquePropertyConstraintCreate( descriptor, null );
+ }
/**
- * Create node key constraint
+ * Create unique property constraint. Optionally a specific provider name can be specified.
*
* @param descriptor description of the constraint
+ * @param providerName specific index provider this index will be created for. If {@code null} then the default configured will be used.
+ * @return the newly created index
+ */
+ ConstraintDescriptor uniquePropertyConstraintCreate( SchemaDescriptor descriptor, String providerName ) throws SchemaKernelException;
+
+ /**
+ * Create node key constraint. Default configured index provider will be used.
+ *
+ * @param descriptor description of the constraint
+ */
+ default ConstraintDescriptor nodeKeyConstraintCreate( LabelSchemaDescriptor descriptor ) throws SchemaKernelException
+ {
+ return nodeKeyConstraintCreate( descriptor, null );
+ }
+
+ /**
+ * Create node key constraint. Optionally a specific provider name can be specified.
+ *
+ * @param descriptor description of the constraint
+ * @param providerName specific index provider this index will be created for. If {@code null} then the default configured will be used.
+ * @return the newly created index
*/
- ConstraintDescriptor nodeKeyConstraintCreate( LabelSchemaDescriptor descriptor ) throws SchemaKernelException;
+ ConstraintDescriptor nodeKeyConstraintCreate( LabelSchemaDescriptor descriptor, String providerName ) throws SchemaKernelException;
/**
* Create node property existence constraint
diff --git a/community/kernel/src/main/java/org/neo4j/kernel/api/txstate/TransactionState.java b/community/kernel/src/main/java/org/neo4j/kernel/api/txstate/TransactionState.java
index 0f1fa46f78cec..0e6ea7f20f01d 100644
--- a/community/kernel/src/main/java/org/neo4j/kernel/api/txstate/TransactionState.java
+++ b/community/kernel/src/main/java/org/neo4j/kernel/api/txstate/TransactionState.java
@@ -19,6 +19,8 @@
*/
package org.neo4j.kernel.api.txstate;
+import javax.annotation.Nullable;
+
import org.neo4j.internal.kernel.api.schema.SchemaDescriptor;
import org.neo4j.internal.kernel.api.schema.constraints.ConstraintDescriptor;
import org.neo4j.kernel.api.index.IndexProvider;
@@ -85,7 +87,7 @@ public interface TransactionState extends ReadableTransactionState
* @param providerDescriptor specific {@link IndexProvider.Descriptor} to use for this index to be created.
* This provider descriptor is allowed to be null, which will be interpreted as simply using the default instead.
*/
- void indexRuleDoAdd( SchemaIndexDescriptor descriptor, IndexProvider.Descriptor providerDescriptor );
+ void indexRuleDoAdd( SchemaIndexDescriptor descriptor, @Nullable IndexProvider.Descriptor providerDescriptor );
void indexDoDrop( SchemaIndexDescriptor descriptor );
diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/index/IndexProviderDescriptorByName.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/index/IndexProviderDescriptorByName.java
deleted file mode 100644
index 0c13f6fdabc93..0000000000000
--- a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/index/IndexProviderDescriptorByName.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2002-2018 "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.kernel.impl.api.index;
-
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-import java.util.function.Consumer;
-
-import org.neo4j.kernel.api.index.IndexProvider;
-
-/**
- * Can visit an {@link IndexProviderMap} and extract {@link IndexProvider.Descriptor} matching a given name.
- */
-public class IndexProviderDescriptorByName implements Consumer, Iterable
-{
- private final Set hits = new HashSet<>();
- private final String name;
-
- public IndexProviderDescriptorByName( String name )
- {
- this.name = name;
- }
-
- @Override
- public void accept( IndexProvider indexProvider )
- {
- IndexProvider.Descriptor providerDescriptor = indexProvider.getProviderDescriptor();
- if ( providerDescriptor.name().equals( name ) )
- {
- hits.add( providerDescriptor );
- }
- }
-
- @Override
- public Iterator iterator()
- {
- return hits.iterator();
- }
-
- public IndexProvider.Descriptor single()
- {
- Iterator iterator = hits.iterator();
- if ( !iterator.hasNext() )
- {
- throw new IllegalArgumentException( "No index provider matching name '" + name + "'" );
- }
- IndexProvider.Descriptor single = iterator.next();
- if ( iterator.hasNext() )
- {
- throw new IllegalArgumentException( "Multiple index providers matching name '" + name + "'" );
- }
- return single;
- }
-}
diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/index/IndexProviderMap.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/index/IndexProviderMap.java
index 68cb1b6341caa..5ca7d54c24dcb 100644
--- a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/index/IndexProviderMap.java
+++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/index/IndexProviderMap.java
@@ -27,7 +27,9 @@
public interface IndexProviderMap extends Function
{
@Override
- IndexProvider apply( IndexProvider.Descriptor descriptor ) throws IndexProviderNotFoundException;
+ IndexProvider apply( IndexProvider.Descriptor providerDescriptor ) throws IndexProviderNotFoundException;
+
+ IndexProvider apply( String providerDescriptorName ) throws IndexProviderNotFoundException;
IndexProvider getDefaultProvider();
diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/state/ConstraintIndexCreator.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/state/ConstraintIndexCreator.java
index 2dc6b6ecc3f92..0447c02a08c9e 100644
--- a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/state/ConstraintIndexCreator.java
+++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/state/ConstraintIndexCreator.java
@@ -42,12 +42,14 @@
import org.neo4j.kernel.api.exceptions.schema.AlreadyIndexedException;
import org.neo4j.kernel.api.exceptions.schema.CreateConstraintFailureException;
import org.neo4j.kernel.api.exceptions.schema.UniquePropertyValueValidationException;
+import org.neo4j.kernel.api.index.IndexProvider;
import org.neo4j.kernel.api.index.PropertyAccessor;
import org.neo4j.kernel.api.schema.constaints.ConstraintDescriptorFactory;
import org.neo4j.kernel.api.schema.constaints.UniquenessConstraintDescriptor;
import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptor;
import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptor.Type;
import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptorFactory;
+import org.neo4j.kernel.api.txstate.TransactionState;
import org.neo4j.kernel.impl.api.KernelTransactionImplementation;
import org.neo4j.kernel.impl.api.index.IndexProxy;
import org.neo4j.kernel.impl.api.index.IndexingService;
@@ -91,9 +93,11 @@ public ConstraintIndexCreator( Supplier kernelSupplier, IndexingService
* Leave this method, knowing that the uniqueness constraint rule will be added to tx state
* and this tx committed, which will create the uniqueness constraint
*
+ *
+ * Btw providerDescriptor is allowed to be null, where default configured will be used.
*/
public long createUniquenessConstraintIndex( KernelTransactionImplementation transaction,
- SchemaDescriptor descriptor ) throws TransactionFailureException, CreateConstraintFailureException,
+ SchemaDescriptor descriptor, IndexProvider.Descriptor providerDescriptor ) throws TransactionFailureException, CreateConstraintFailureException,
UniquePropertyValueValidationException, AlreadyConstrainedException
{
UniquenessConstraintDescriptor constraint = ConstraintDescriptorFactory.uniqueForSchema( descriptor );
@@ -102,7 +106,7 @@ public long createUniquenessConstraintIndex( KernelTransactionImplementation tra
SchemaRead schemaRead = transaction.schemaRead();
try
{
- index = getOrCreateUniquenessConstraintIndex( schemaRead, transaction.tokenRead(), descriptor );
+ index = getOrCreateUniquenessConstraintIndex( schemaRead, transaction.tokenRead(), descriptor, providerDescriptor );
}
catch ( AlreadyConstrainedException e )
{
@@ -242,7 +246,7 @@ private void awaitConstrainIndexPopulation( UniquenessConstraintDescriptor const
}
private CapableIndexReference getOrCreateUniquenessConstraintIndex( SchemaRead schemaRead,
- TokenRead tokenRead, SchemaDescriptor schema )
+ TokenRead tokenRead, SchemaDescriptor schema, IndexProvider.Descriptor providerDescriptor )
throws SchemaKernelException, IndexNotFoundKernelException
{
CapableIndexReference descriptor = schemaRead.index( schema.keyId(), schema.getPropertyIds() );
@@ -265,21 +269,22 @@ private CapableIndexReference getOrCreateUniquenessConstraintIndex( SchemaRead s
// There's already an index for this schema descriptor, which isn't of the type we're after.
throw new AlreadyIndexedException( schema, CONSTRAINT_CREATION );
}
- SchemaIndexDescriptor indexDescriptor = createConstraintIndex( schema );
+ SchemaIndexDescriptor indexDescriptor = createConstraintIndex( schema, providerDescriptor );
IndexProxy indexProxy = indexingService.getIndexProxy( indexDescriptor.schema() );
return new DefaultCapableIndexReference( indexDescriptor.type() == Type.UNIQUE, indexProxy.getIndexCapability(),
indexProxy.getProviderDescriptor(), indexDescriptor.schema().keyId(),
indexDescriptor.schema().getPropertyIds() );
}
- public SchemaIndexDescriptor createConstraintIndex( final SchemaDescriptor schema )
+ public SchemaIndexDescriptor createConstraintIndex( final SchemaDescriptor schema, IndexProvider.Descriptor providerDescriptor )
{
try ( Session session = kernelSupplier.get().beginSession( AUTH_DISABLED );
Transaction transaction = session.beginTransaction( Transaction.Type.implicit );
Statement ignore = ((KernelTransaction)transaction).acquireStatement() )
{
SchemaIndexDescriptor index = SchemaIndexDescriptorFactory.uniqueForSchema( schema );
- ((KernelTransactionImplementation) transaction).txState().indexRuleDoAdd( index, null );
+ TransactionState transactionState = ((KernelTransactionImplementation) transaction).txState();
+ transactionState.indexRuleDoAdd( index, providerDescriptor );
transaction.success();
return index;
}
diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/state/TxState.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/state/TxState.java
index 133e8975eca7b..9e30160098dbc 100644
--- a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/state/TxState.java
+++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/state/TxState.java
@@ -810,6 +810,10 @@ public void indexRuleDoAdd( SchemaIndexDescriptor descriptor, IndexProvider.Desc
public void indexDoDrop( SchemaIndexDescriptor descriptor )
{
indexChangesDiffSets().remove( descriptor );
+ if ( specificIndexProviders != null )
+ {
+ specificIndexProviders.remove( descriptor );
+ }
changed();
}
diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/coreapi/schema/SchemaImpl.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/coreapi/schema/SchemaImpl.java
index 0d878259f8437..5bb12629c0760 100644
--- a/community/kernel/src/main/java/org/neo4j/kernel/impl/coreapi/schema/SchemaImpl.java
+++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/coreapi/schema/SchemaImpl.java
@@ -461,7 +461,7 @@ public IndexDefinition createIndexDefinition( Label label, String... propertyKey
int labelId = tokenWrite.labelGetOrCreateForName( indexDefinition.getLabel().name() );
int[] propertyKeyIds = getOrCreatePropertyKeyIds( tokenWrite, indexDefinition );
LabelSchemaDescriptor descriptor = forLabel( labelId, propertyKeyIds );
- transaction.schemaWrite().indexCreate( descriptor, null );
+ transaction.schemaWrite().indexCreate( descriptor );
return indexDefinition;
}
diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/Operations.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/Operations.java
index c113f471849a9..5fb294ce792c1 100644
--- a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/Operations.java
+++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/Operations.java
@@ -82,7 +82,6 @@
import org.neo4j.kernel.api.txstate.ExplicitIndexTransactionState;
import org.neo4j.kernel.api.txstate.TransactionState;
import org.neo4j.kernel.impl.api.KernelTransactionImplementation;
-import org.neo4j.kernel.impl.api.index.IndexProviderDescriptorByName;
import org.neo4j.kernel.impl.api.index.IndexProviderMap;
import org.neo4j.kernel.impl.api.state.ConstraintIndexCreator;
import org.neo4j.kernel.impl.api.store.DefaultIndexReference;
@@ -887,16 +886,7 @@ public IndexReference indexCreate( SchemaDescriptor descriptor, String providerN
assertIndexDoesNotExist( SchemaKernelException.OperationContext.INDEX_CREATION, descriptor );
SchemaIndexDescriptor indexDescriptor = SchemaIndexDescriptorFactory.forSchema( descriptor );
- IndexProvider.Descriptor providerDescriptor = null;
- if ( providerName != null )
- {
- IndexProviderDescriptorByName candidates = new IndexProviderDescriptorByName( providerName );
- indexProviderMap.accept( candidates );
-
- // We have to have a one-to-one mapping to the specified provider name, otherwise we can't be sure which.
- // Having this method fail if that's not the case is OK since that's a user error and way before commit.
- providerDescriptor = candidates.single();
- }
+ IndexProvider.Descriptor providerDescriptor = providerName != null ? indexProviderMap.apply( providerName ).getProviderDescriptor() : null;
ktx.txState().indexRuleDoAdd( indexDescriptor, providerDescriptor );
return DefaultIndexReference.fromDescriptor( indexDescriptor );
}
@@ -934,7 +924,7 @@ public void indexDrop( IndexReference index ) throws SchemaKernelException
}
@Override
- public ConstraintDescriptor uniquePropertyConstraintCreate( SchemaDescriptor descriptor )
+ public ConstraintDescriptor uniquePropertyConstraintCreate( SchemaDescriptor descriptor, String providerName )
throws SchemaKernelException
{
//Lock
@@ -949,12 +939,13 @@ public ConstraintDescriptor uniquePropertyConstraintCreate( SchemaDescriptor des
assertIndexDoesNotExist( SchemaKernelException.OperationContext.CONSTRAINT_CREATION, descriptor );
// Create constraints
- indexBackedConstraintCreate( constraint );
+ IndexProvider.Descriptor providerDescriptor = providerName != null ? indexProviderMap.apply( providerName ).getProviderDescriptor() : null;
+ indexBackedConstraintCreate( constraint, providerDescriptor );
return constraint;
}
@Override
- public ConstraintDescriptor nodeKeyConstraintCreate( LabelSchemaDescriptor descriptor ) throws SchemaKernelException
+ public ConstraintDescriptor nodeKeyConstraintCreate( LabelSchemaDescriptor descriptor, String providerName ) throws SchemaKernelException
{
//Lock
acquireExclusiveLabelLock( descriptor.getLabelId() );
@@ -975,7 +966,8 @@ public ConstraintDescriptor nodeKeyConstraintCreate( LabelSchemaDescriptor descr
}
//create constraint
- indexBackedConstraintCreate( constraint );
+ IndexProvider.Descriptor providerDescriptor = providerName != null ? indexProviderMap.apply( providerName ).getProviderDescriptor() : null;
+ indexBackedConstraintCreate( constraint, providerDescriptor );
return constraint;
}
@@ -1204,7 +1196,7 @@ private org.neo4j.kernel.api.schema.LabelSchemaDescriptor labelDescriptor( Index
return SchemaDescriptorFactory.forLabel( index.label(), index.properties() );
}
- private void indexBackedConstraintCreate( IndexBackedConstraintDescriptor constraint )
+ private void indexBackedConstraintCreate( IndexBackedConstraintDescriptor constraint, IndexProvider.Descriptor providerDescriptor )
throws CreateConstraintFailureException
{
SchemaDescriptor descriptor = constraint.schema();
@@ -1229,7 +1221,7 @@ private void indexBackedConstraintCreate( IndexBackedConstraintDescriptor constr
return;
}
}
- long indexId = constraintIndexCreator.createUniquenessConstraintIndex( ktx, descriptor );
+ long indexId = constraintIndexCreator.createUniquenessConstraintIndex( ktx, descriptor, providerDescriptor );
if ( !allStoreHolder.constraintExists( constraint ) )
{
// This looks weird, but since we release the label lock while awaiting population of the index
diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/state/DefaultIndexProviderMap.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/state/DefaultIndexProviderMap.java
index b35939a91cf15..1833d1b0320f8 100644
--- a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/state/DefaultIndexProviderMap.java
+++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/state/DefaultIndexProviderMap.java
@@ -28,11 +28,13 @@
import org.neo4j.kernel.api.index.IndexProvider;
import org.neo4j.kernel.api.index.IndexProvider.Descriptor;
import org.neo4j.kernel.impl.api.index.IndexProviderMap;
+import org.neo4j.kernel.impl.api.index.IndexProviderNotFoundException;
public class DefaultIndexProviderMap implements IndexProviderMap
{
private final IndexProvider defaultIndexProvider;
private final Map indexProviders = new HashMap<>();
+ private final Map indexProvidersByName = new HashMap<>();
public DefaultIndexProviderMap( IndexProvider defaultIndexProvider )
{
@@ -43,12 +45,12 @@ public DefaultIndexProviderMap( IndexProvider defaultIndexProvider,
Iterable additionalIndexProviders )
{
this.defaultIndexProvider = defaultIndexProvider;
- indexProviders.put( defaultIndexProvider.getProviderDescriptor(), defaultIndexProvider );
+ put( defaultIndexProvider.getProviderDescriptor(), defaultIndexProvider );
for ( IndexProvider provider : additionalIndexProviders )
{
Descriptor providerDescriptor = provider.getProviderDescriptor();
Objects.requireNonNull( providerDescriptor );
- IndexProvider existing = indexProviders.putIfAbsent( providerDescriptor, provider );
+ IndexProvider existing = put( providerDescriptor, provider );
if ( existing != null )
{
throw new IllegalArgumentException( "Tried to load multiple schema index providers with the same provider descriptor " +
@@ -57,6 +59,13 @@ public DefaultIndexProviderMap( IndexProvider defaultIndexProvider,
}
}
+ private IndexProvider put( Descriptor providerDescriptor, IndexProvider provider )
+ {
+ IndexProvider existing = indexProviders.putIfAbsent( providerDescriptor, provider );
+ indexProvidersByName.put( providerDescriptor.name(), provider );
+ return existing;
+ }
+
@Override
public IndexProvider getDefaultProvider()
{
@@ -64,17 +73,33 @@ public IndexProvider getDefaultProvider()
}
@Override
- public IndexProvider apply( IndexProvider.Descriptor descriptor )
+ public IndexProvider apply( IndexProvider.Descriptor providerDescriptor )
{
- IndexProvider provider = indexProviders.get( descriptor );
+ IndexProvider provider = indexProviders.get( providerDescriptor );
if ( provider != null )
{
return provider;
}
- throw new IllegalArgumentException( "Tried to get index provider for an existing index with provider " +
- descriptor + " whereas available providers in this session being " + indexProviders +
- ", and default being " + defaultIndexProvider );
+ throw notFound( providerDescriptor );
+ }
+
+ @Override
+ public IndexProvider apply( String providerDescriptorName ) throws IndexProviderNotFoundException
+ {
+ IndexProvider provider = indexProvidersByName.get( providerDescriptorName );
+ if ( provider != null )
+ {
+ return provider;
+ }
+
+ throw notFound( providerDescriptorName );
+ }
+
+ private IllegalArgumentException notFound( Object key )
+ {
+ return new IllegalArgumentException( "Tried to get index provider for an existing index with provider " + key +
+ " whereas available providers in this session being " + indexProviders + ", and default being " + defaultIndexProvider );
}
@Override
diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/constraints/ConstraintIndexCreatorTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/constraints/ConstraintIndexCreatorTest.java
index c119434ea0396..b35a74c6cd5d9 100644
--- a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/constraints/ConstraintIndexCreatorTest.java
+++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/constraints/ConstraintIndexCreatorTest.java
@@ -26,6 +26,7 @@
import org.neo4j.internal.kernel.api.CapableIndexReference;
import org.neo4j.internal.kernel.api.IndexCapability;
+import org.neo4j.internal.kernel.api.IndexReference;
import org.neo4j.internal.kernel.api.Kernel;
import org.neo4j.internal.kernel.api.Modes;
import org.neo4j.internal.kernel.api.SchemaRead;
@@ -54,6 +55,7 @@
import org.neo4j.kernel.impl.api.index.IndexingService;
import org.neo4j.kernel.impl.api.state.ConstraintIndexCreator;
import org.neo4j.kernel.impl.api.store.DefaultCapableIndexReference;
+import org.neo4j.kernel.impl.locking.Locks;
import org.neo4j.kernel.impl.locking.ResourceTypes;
import org.neo4j.kernel.impl.locking.SimpleStatementLocks;
import org.neo4j.kernel.impl.transaction.TransactionHeaderInformationFactory;
@@ -64,6 +66,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.doThrow;
@@ -104,7 +107,7 @@ public void shouldCreateIndexInAnotherTransaction() throws Exception
new ConstraintIndexCreator( () -> kernel, indexingService, propertyAccessor );
// when
- long indexId = creator.createUniquenessConstraintIndex( createTransaction(), descriptor );
+ long indexId = creator.createUniquenessConstraintIndex( createTransaction(), descriptor, null );
// then
assertEquals( INDEX_ID, indexId );
@@ -142,7 +145,7 @@ public void shouldDropIndexIfPopulationFails() throws Exception
KernelTransactionImplementation transaction = createTransaction();
try
{
- creator.createUniquenessConstraintIndex( transaction, descriptor );
+ creator.createUniquenessConstraintIndex( transaction, descriptor, null );
fail( "expected exception" );
}
@@ -206,7 +209,7 @@ public void shouldReleaseLabelLockWhileAwaitingIndexPopulation() throws Exceptio
// when
KernelTransactionImplementation transaction = createTransaction();
- creator.createUniquenessConstraintIndex( transaction, descriptor );
+ creator.createUniquenessConstraintIndex( transaction, descriptor, null );
// then
verify( transaction.statementLocks().pessimistic() )
@@ -236,7 +239,7 @@ public void shouldReuseExistingOrphanedConstraintIndex() throws Exception
// when
KernelTransactionImplementation transaction = createTransaction();
- long indexId = creator.createUniquenessConstraintIndex( transaction, descriptor );
+ long indexId = creator.createUniquenessConstraintIndex( transaction, descriptor, null );
// then
assertEquals( orphanedConstraintIndexId, indexId );
@@ -276,7 +279,7 @@ public void shouldFailOnExistingOwnedConstraintIndex() throws Exception
try
{
KernelTransactionImplementation transaction = createTransaction();
- creator.createUniquenessConstraintIndex( transaction, descriptor );
+ creator.createUniquenessConstraintIndex( transaction, descriptor, null );
fail( "Should've failed" );
}
catch ( AlreadyConstrainedException e )
@@ -292,6 +295,35 @@ public void shouldFailOnExistingOwnedConstraintIndex() throws Exception
verifyNoMoreInteractions( schemaRead );
}
+ @Test
+ public void shouldCreateConstraintIndexForSpecifiedProvider() throws Exception
+ {
+ // given
+ IndexingService indexingService = mock( IndexingService.class );
+ StubKernel kernel = new StubKernel();
+
+ long constraintIndexId = 111;
+ when( schemaRead.indexGetCommittedId( indexReference ) ).thenReturn( constraintIndexId );
+ IndexProxy indexProxy = mock( IndexProxy.class );
+ when( indexingService.getIndexProxy( constraintIndexId ) ).thenReturn( indexProxy );
+ when( indexingService.getIndexProxy( descriptor ) ).thenReturn( indexProxy );
+ PropertyAccessor propertyAccessor = mock( PropertyAccessor.class );
+ ConstraintIndexCreator creator = new ConstraintIndexCreator( () -> kernel, indexingService, propertyAccessor );
+ IndexProvider.Descriptor providerDescriptor = new IndexProvider.Descriptor( "Groovy", "1.2" );
+
+ // when
+ KernelTransactionImplementation transaction = createTransaction();
+ creator.createUniquenessConstraintIndex( transaction, descriptor, providerDescriptor );
+
+ // then
+ assertEquals( 1, kernel.transactions.size() );
+ TransactionState transactionState = kernel.transactions.get( 0 ).txState();
+ verify( transactionState ).indexRuleDoAdd( SchemaIndexDescriptorFactory.uniqueForSchema( descriptor ), providerDescriptor );
+ verify( schemaRead ).index( LABEL_ID, PROPERTY_KEY_ID );
+ verify( schemaRead ).indexGetCommittedId( any( IndexReference.class ) );
+ verifyNoMoreInteractions( schemaRead );
+ }
+
private class StubKernel implements Kernel, Session
{
private final List transactions = new ArrayList<>();
diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/IndexIT.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/IndexIT.java
index 6a5a07eaa8580..96393c1381350 100644
--- a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/IndexIT.java
+++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/IndexIT.java
@@ -181,7 +181,7 @@ public void shouldBeAbleToRemoveAConstraintIndexWithoutOwner() throws Exception
PropertyAccessor propertyAccessor = mock( PropertyAccessor.class );
ConstraintIndexCreator creator = new ConstraintIndexCreator( () -> kernel, indexingService, propertyAccessor );
- SchemaIndexDescriptor constraintIndex = creator.createConstraintIndex( descriptor );
+ SchemaIndexDescriptor constraintIndex = creator.createConstraintIndex( descriptor, null );
// then
Transaction transaction = newTransaction();
assertEquals( emptySet(), asSet( transaction.schemaRead().constraintsGetForLabel( labelId ) ) );
diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/state/TxStateTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/state/TxStateTest.java
index 34c390eaebfb1..31f48bc3ababa 100644
--- a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/state/TxStateTest.java
+++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/state/TxStateTest.java
@@ -312,6 +312,56 @@ public void visitAddedIndex( SchemaIndexDescriptor index, IndexProvider.Descript
assertEquals( specificProvider, visitedProviderDescriptor.get() );
}
+ @Test
+ public void shouldForgetSpecificallySetIndexProviderDescriptorOnDrop() throws ConstraintValidationException, CreateConstraintFailureException
+ {
+ // given
+ IndexProvider.Descriptor specificProvider = new IndexProvider.Descriptor( "myProvider", "9.9" );
+ state.indexRuleDoAdd( indexOn_1_1, specificProvider );
+ state.indexDoDrop( indexOn_1_1 );
+ state.indexRuleDoAdd( indexOn_1_1, null );
+
+ // when
+ MutableBoolean called = new MutableBoolean();
+ state.accept( new TxStateVisitor.Adapter()
+ {
+ @Override
+ public void visitAddedIndex( SchemaIndexDescriptor index, IndexProvider.Descriptor providerDescriptor )
+ {
+ assertNull( providerDescriptor );
+ called.setTrue();
+ }
+ } );
+
+ // then
+ assertTrue( called.booleanValue() );
+ }
+
+ @Test
+ public void shouldSpecificallySetIndexProviderDescriptorOnRecreate() throws ConstraintValidationException, CreateConstraintFailureException
+ {
+ // given
+ IndexProvider.Descriptor specificProvider = new IndexProvider.Descriptor( "myProvider", "9.9" );
+ IndexProvider.Descriptor specificProvider2 = new IndexProvider.Descriptor( "myOtherProvider", "7.7" );
+ state.indexRuleDoAdd( indexOn_1_1, specificProvider );
+ state.indexDoDrop( indexOn_1_1 );
+ state.indexRuleDoAdd( indexOn_1_1, specificProvider2 );
+
+ // when
+ AtomicReference visitedProviderDescriptor = new AtomicReference<>();
+ state.accept( new TxStateVisitor.Adapter()
+ {
+ @Override
+ public void visitAddedIndex( SchemaIndexDescriptor index, IndexProvider.Descriptor providerDescriptor )
+ {
+ visitedProviderDescriptor.set( providerDescriptor );
+ }
+ } );
+
+ // then
+ assertEquals( specificProvider2, visitedProviderDescriptor.get() );
+ }
+
@Test
public void shouldUseNullForUnspecifiedIndexProviderDescriptor() throws ConstraintValidationException, CreateConstraintFailureException
{
diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/newapi/OperationsLockTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/newapi/OperationsLockTest.java
index 9924b6735f2e2..f4bf38c637a66 100644
--- a/community/kernel/src/test/java/org/neo4j/kernel/impl/newapi/OperationsLockTest.java
+++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/newapi/OperationsLockTest.java
@@ -465,7 +465,7 @@ public void shouldAcquireSchemaWriteLockBeforeRemovingIndexRule() throws Excepti
public void shouldAcquireSchemaWriteLockBeforeCreatingUniquenessConstraint() throws Exception
{
// given
- when( constraintIndexCreator.createUniquenessConstraintIndex( transaction, descriptor ) ).thenReturn( 42L );
+ when( constraintIndexCreator.createUniquenessConstraintIndex( transaction, descriptor, null ) ).thenReturn( 42L );
when( storeReadLayer.constraintsGetForSchema( descriptor.schema() ) ).thenReturn( Collections.emptyIterator() );
// when