diff --git a/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/BuiltInProcedures.java b/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/BuiltInProcedures.java index 294577e6cdd11..1a87e631b3e25 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/BuiltInProcedures.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/BuiltInProcedures.java @@ -204,11 +204,17 @@ public void resampleOutdatedIndexes() } } - @Procedure( name = "okapi.schema", mode = READ ) - @Description( "Show the derived property schema of the data in tabular form." ) - public Stream propertySchema() + @Procedure( name = "db.schema.nodeTypeProperties", mode = READ ) + @Description( "Show the derived property schema of the nodes in tabular form." ) + public Stream nodePropertySchema() { - return new SchemaCalculator( tx ).calculateTabularResultStream(); + return new SchemaCalculator( tx ).calculateTabularResultStreamForNodes(); + } + @Procedure( name = "db.schema.relTypeProperties", mode = READ ) + @Description( "Show the derived property schema of the relationships in tabular form." ) + public Stream relationshipPropertySchema() + { + return new SchemaCalculator( tx ).calculateTabularResultStreamForRels(); } @Description( "Show the schema of the data." ) diff --git a/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/SchemaInfoResult.java b/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/NodePropertySchemaInfoResult.java similarity index 51% rename from community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/SchemaInfoResult.java rename to community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/NodePropertySchemaInfoResult.java index 73799828f1da9..94d92ef89f37b 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/SchemaInfoResult.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/NodePropertySchemaInfoResult.java @@ -21,39 +21,38 @@ import java.util.List; -public class SchemaInfoResult +public class NodePropertySchemaInfoResult { /** - * Indicates whether the entry is a node or a relationship + * A combination of escaped label names interleaved by ":" */ - public final String type; + public final String nodeType; /** - * A combination of labels or a relationship + * A list of label names */ - public final List nodeLabelsOrRelType; - + public final List nodeLabels; /** - * A property that occurs on the given label combination / relationship type or null + * A property name that occurs on the given label combination or null */ - public final String property; + public final String propertyName; /** - * A List containing all CypherTypes of the given property on the given label combination / relationship type or null + * A List containing all types of the given property on the given label combination or null */ - public final List cypherTypes; + public final List propertyTypes; /** - * Indicates whether the property is present on all similar nodes / relationships (= false) or not (= true) + * Indicates whether the property is present on all similar nodes (= true) or not (= false) */ - public final boolean nullable; + public final boolean mandatory; - public SchemaInfoResult( String type, List nodeLabelsOrRelType, String property, List cypherTypes, boolean nullable ) + public NodePropertySchemaInfoResult( String nodeType, List nodeLabelsList, String propertyName, List cypherTypes, boolean mandatory ) { - this.type = type; - this.nodeLabelsOrRelType = nodeLabelsOrRelType; - this.property = property; - this.cypherTypes = cypherTypes; - this.nullable = nullable; + this.nodeType = nodeType; + this.nodeLabels = nodeLabelsList; + this.propertyName = propertyName; + this.propertyTypes = cypherTypes; + this.mandatory = mandatory; } } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/RelationshipPropertySchemaInfoResult.java b/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/RelationshipPropertySchemaInfoResult.java new file mode 100644 index 0000000000000..37abf79b5e74c --- /dev/null +++ b/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/RelationshipPropertySchemaInfoResult.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2002-2018 "Neo4j," + * Neo4j Sweden AB [http://neo4j.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.builtinprocs; + +import java.util.List; + +public class RelationshipPropertySchemaInfoResult +{ + /** + * A relationship type + */ + public final String relType; + + /** + * A property name that occurs on the given relationship type or null + */ + public final String propertyName; + + /** + * A List containing all types of the given property on the given relationship type or null + */ + public final List propertyTypes; + + /** + * Indicates whether the property is present on all similar relationships (= true) or not (= false) + */ + public final boolean mandatory; + + public RelationshipPropertySchemaInfoResult( String relType, String propertyName, List cypherTypes, boolean mandatory ) + { + this.relType = relType; + this.propertyName = propertyName; + this.propertyTypes = cypherTypes; + this.mandatory = mandatory; + } +} diff --git a/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/SchemaCalculator.java b/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/SchemaCalculator.java index 83e92b6aa7ea9..7b5a197faef07 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/SchemaCalculator.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/SchemaCalculator.java @@ -42,19 +42,9 @@ public class SchemaCalculator { - private Map> labelSetToPropertyKeysMapping; - private Map,ValueTypeListHelper> labelSetANDNodePropertyKeyIdToValueTypeMapping; - private Set nullableLabelSets; // used for label combinations without properties -> all properties are viewed as nullable - private Map labelIdToLabelNameMapping; - private Map propertyIdToPropertylNameMapping; - private Map relationshipTypIdToRelationshipNameMapping; - private Map> relationshipTypeIdToPropertyKeysMapping; - private Map,ValueTypeListHelper> relationshipTypeIdANDPropertyTypeIdToValueTypeMapping; - private Set nullableRelationshipTypes; // used for types without properties -> all properties are viewed as nullable + private Map propertyIdToPropertyNameMapping; private final Set emptyPropertyIdSet = Collections.unmodifiableSet( Collections.emptySet() ); - private static final String NODE = "Node"; - private static final String RELATIONSHIP = "Relationship"; private final Read dataRead; private final TokenRead tokenRead; @@ -62,64 +52,81 @@ public class SchemaCalculator SchemaCalculator( Transaction ktx ) { - dataRead = ktx.dataRead(); - tokenRead = ktx.tokenRead(); - cursors = ktx.cursors(); + this.dataRead = ktx.dataRead(); + this.tokenRead = ktx.tokenRead(); + this.cursors = ktx.cursors(); - // setup mappings + // the only one that is common for both nodes and rels so thats why we can do it here + propertyIdToPropertyNameMapping = new HashMap<>( tokenRead.propertyKeyCount() ); + addNamesToCollection( tokenRead.propertyKeyGetAllTokens(), propertyIdToPropertyNameMapping ); + } + + private NodeMappings initializeMappingsForNodes() + { int labelCount = tokenRead.labelCount(); + return new NodeMappings( labelCount ); + } + + private RelationshipMappings initializeMappingsForRels() + { int relationshipTypeCount = tokenRead.relationshipTypeCount(); - labelSetToPropertyKeysMapping = new HashMap<>( labelCount ); - labelIdToLabelNameMapping = new HashMap<>( labelCount ); - propertyIdToPropertylNameMapping = new HashMap<>( tokenRead.propertyKeyCount() ); - relationshipTypIdToRelationshipNameMapping = new HashMap<>( relationshipTypeCount ); - relationshipTypeIdToPropertyKeysMapping = new HashMap<>( relationshipTypeCount ); - labelSetANDNodePropertyKeyIdToValueTypeMapping = new HashMap<>(); - relationshipTypeIdANDPropertyTypeIdToValueTypeMapping = new HashMap<>(); - nullableLabelSets = new HashSet<>( ); - nullableRelationshipTypes = new HashSet<>( ); + return new RelationshipMappings( relationshipTypeCount ); + } + + // If we would have this schema information in the count store (or somewhere), this could be super fast + public Stream calculateTabularResultStreamForNodes() + { + NodeMappings nodeMappings = initializeMappingsForNodes(); + scanEverythingBelongingToNodes(nodeMappings); + + // go through all labels to get actual names + addNamesToCollection( tokenRead.labelsGetAllTokens(), nodeMappings.labelIdToLabelName ); + + return produceResultsForNodes( nodeMappings ).stream(); } - public Stream calculateTabularResultStream() + public Stream calculateTabularResultStreamForRels() { - calculateSchema(); + RelationshipMappings relMappings = initializeMappingsForRels(); + scanEverythingBelongingToRelationships( relMappings ); - List results = new ArrayList<>(); - results.addAll( produceResultsForNodes() ); - results.addAll( produceResultsForRelationships() ); + // go through all relationshipTypes to get actual names + addNamesToCollection( tokenRead.relationshipTypesGetAllTokens(), relMappings.relationshipTypIdToRelationshipName ); - return results.stream(); + return produceResultsForRelationships( relMappings ).stream(); } - private List produceResultsForRelationships() + private List produceResultsForRelationships( RelationshipMappings relMappings ) { - List results = new ArrayList<>(); - for ( Integer typeId : relationshipTypeIdToPropertyKeysMapping.keySet() ) + List results = new ArrayList<>(); + for ( Integer typeId : relMappings.relationshipTypeIdToPropertyKeys.keySet() ) { // lookup typ name - String name = relationshipTypIdToRelationshipNameMapping.get( typeId ); + String name = relMappings.relationshipTypIdToRelationshipName.get( typeId ); + name = ":`" + name + "`"; // escaping // lookup property value types - Set propertyIds = relationshipTypeIdToPropertyKeysMapping.get( typeId ); + Set propertyIds = relMappings.relationshipTypeIdToPropertyKeys.get( typeId ); if ( propertyIds.size() == 0 ) { - results.add( new SchemaInfoResult( RELATIONSHIP, Collections.singletonList( name ), null, null, true ) ); + results.add( new RelationshipPropertySchemaInfoResult( name, null, null, false ) ); } else { + String finalName = name; propertyIds.forEach( propId -> { // lookup propId name and valueGroup - String propName = propertyIdToPropertylNameMapping.get( propId ); - ValueTypeListHelper valueTypeListHelper = relationshipTypeIdANDPropertyTypeIdToValueTypeMapping.get( Pair.of( typeId, propId ) ); - if ( nullableRelationshipTypes.contains( typeId ) ) + String propName = propertyIdToPropertyNameMapping.get( propId ); + ValueTypeListHelper valueTypeListHelper = relMappings.relationshipTypeIdANDPropertyTypeIdToValueType.get( Pair.of( typeId, propId ) ); + if ( relMappings.nullableRelationshipTypes.contains( typeId ) ) { - results.add( new SchemaInfoResult( RELATIONSHIP, Collections.singletonList( name ), propName, valueTypeListHelper.getCypherTypesList(), - true ) ); + results.add( new RelationshipPropertySchemaInfoResult( finalName, propName, valueTypeListHelper.getCypherTypesList(), + false ) ); } else { - results.add( new SchemaInfoResult( RELATIONSHIP, Collections.singletonList( name ), propName, valueTypeListHelper.getCypherTypesList(), - valueTypeListHelper.isNullable() ) ); + results.add( new RelationshipPropertySchemaInfoResult( finalName, propName, valueTypeListHelper.getCypherTypesList(), + valueTypeListHelper.isMandatory() ) ); } } ); } @@ -127,39 +134,46 @@ private List produceResultsForRelationships() return results; } - private List produceResultsForNodes() + private List produceResultsForNodes( NodeMappings nodeMappings ) { - List results = new ArrayList<>(); - for ( SortedLabels labelSet : labelSetToPropertyKeysMapping.keySet() ) + List results = new ArrayList<>(); + for ( SortedLabels labelSet : nodeMappings.labelSetToPropertyKeys.keySet() ) { - // lookup label names and produce list of names + // lookup label names and produce list of names and produce String out of them List labelNames = new ArrayList<>(); for ( int i = 0; i < labelSet.numberOfLabels(); i++ ) { - String name = labelIdToLabelNameMapping.get( labelSet.label( i ) ); + String name = nodeMappings.labelIdToLabelName.get( labelSet.label( i ) ); labelNames.add( name ); } + Collections.sort( labelNames ); // this is optional but waaaaay nicer + StringBuilder labelsConcatenator = new StringBuilder(); + for ( String item : labelNames ) + { + labelsConcatenator.append( ":`" ).append( item ).append( "`" ); + } + String labels = labelsConcatenator.toString(); // lookup property value types - Set propertyIds = labelSetToPropertyKeysMapping.get( labelSet ); + Set propertyIds = nodeMappings.labelSetToPropertyKeys.get( labelSet ); if ( propertyIds.size() == 0 ) { - results.add( new SchemaInfoResult( NODE, labelNames, null, null, true ) ); + results.add( new NodePropertySchemaInfoResult( labels, labelNames, null, null, false ) ); } else { propertyIds.forEach( propId -> { // lookup propId name and valueGroup - String propName = propertyIdToPropertylNameMapping.get( propId ); - ValueTypeListHelper valueTypeListHelper = labelSetANDNodePropertyKeyIdToValueTypeMapping.get( Pair.of( labelSet, propId ) ); - if ( nullableLabelSets.contains( labelSet ) ) + String propName = propertyIdToPropertyNameMapping.get( propId ); + ValueTypeListHelper valueTypeListHelper = nodeMappings.labelSetANDNodePropertyKeyIdToValueType.get( Pair.of( labelSet, propId ) ); + if ( nodeMappings.nullableLabelSets.contains( labelSet ) ) { - results.add( new SchemaInfoResult( NODE, labelNames, propName, valueTypeListHelper.getCypherTypesList(), true ) ); + results.add( new NodePropertySchemaInfoResult( labels, labelNames, propName, valueTypeListHelper.getCypherTypesList(), false ) ); } else { - results.add( new SchemaInfoResult( NODE, labelNames, propName, valueTypeListHelper.getCypherTypesList(), - valueTypeListHelper.isNullable() ) ); + results.add( new NodePropertySchemaInfoResult( labels, labelNames, propName, valueTypeListHelper.getCypherTypesList(), + valueTypeListHelper.isMandatory() ) ); } } ); } @@ -167,22 +181,7 @@ private List produceResultsForNodes() return results; } - //TODO: If we would have this schema information in the count store (or somewhere), this could be super fast - private void calculateSchema() - { - scanEverythingBelongingToNodes(); - scanEverythingBelongingToRelationships(); - - // OTHER: - // go through all labels - addNamesToCollection( tokenRead.labelsGetAllTokens(), labelIdToLabelNameMapping ); - // go through all propertyKeys - addNamesToCollection( tokenRead.propertyKeyGetAllTokens(), propertyIdToPropertylNameMapping ); - // go through all relationshipTypes - addNamesToCollection( tokenRead.relationshipTypesGetAllTokens(), relationshipTypIdToRelationshipNameMapping ); - } - - private void scanEverythingBelongingToRelationships() + private void scanEverythingBelongingToRelationships( RelationshipMappings relMappings ) { try ( RelationshipScanCursor relationshipScanCursor = cursors.allocateRelationshipScanCursor(); PropertyCursor propertyCursor = cursors.allocatePropertyCursor() ) @@ -200,13 +199,13 @@ private void scanEverythingBelongingToRelationships() Value currentValue = propertyCursor.propertyValue(); Pair key = Pair.of( typeId, propertyKey ); - updateValueTypeInMapping( currentValue, key, relationshipTypeIdANDPropertyTypeIdToValueTypeMapping ); + updateValueTypeInMapping( currentValue, key, relMappings.relationshipTypeIdANDPropertyTypeIdToValueType ); propertyIds.add( propertyKey ); } propertyCursor.close(); - Set oldPropertyKeySet = relationshipTypeIdToPropertyKeysMapping.getOrDefault( typeId, emptyPropertyIdSet ); + Set oldPropertyKeySet = relMappings.relationshipTypeIdToPropertyKeys.getOrDefault( typeId, emptyPropertyIdSet ); // find out which old properties we did not visited and mark them as nullable if ( oldPropertyKeySet == emptyPropertyIdSet ) @@ -214,7 +213,7 @@ private void scanEverythingBelongingToRelationships() if ( propertyIds.size() == 0 ) { // Even if we find property key on other rels with this type, set all of them nullable - nullableRelationshipTypes.add( typeId ); + relMappings.nullableRelationshipTypes.add( typeId ); } propertyIds.addAll( oldPropertyKeySet ); @@ -222,25 +221,26 @@ private void scanEverythingBelongingToRelationships() else { Set currentPropertyIdsHelperSet = new HashSet( propertyIds ); + currentPropertyIdsHelperSet.addAll( propertyIds ); propertyIds.removeAll( oldPropertyKeySet ); // only the brand new ones in propIds now oldPropertyKeySet.removeAll( currentPropertyIdsHelperSet ); // only the old ones that are not on the new rel propertyIds.addAll( oldPropertyKeySet ); propertyIds.forEach( id -> { Pair key = Pair.of( typeId, id ); - relationshipTypeIdANDPropertyTypeIdToValueTypeMapping.get( key ).setNullable(); + relMappings.relationshipTypeIdANDPropertyTypeIdToValueType.get( key ).setNullable(); } ); propertyIds.addAll( currentPropertyIdsHelperSet ); } - relationshipTypeIdToPropertyKeysMapping.put( typeId, propertyIds ); + relMappings.relationshipTypeIdToPropertyKeys.put( typeId, propertyIds ); } relationshipScanCursor.close(); } } - private void scanEverythingBelongingToNodes() + private void scanEverythingBelongingToNodes( NodeMappings nodeMappings ) { try ( NodeCursor nodeCursor = cursors.allocateNodeCursor(); PropertyCursor propertyCursor = cursors.allocatePropertyCursor() ) @@ -258,13 +258,13 @@ private void scanEverythingBelongingToNodes() Value currentValue = propertyCursor.propertyValue(); int propertyKeyId = propertyCursor.propertyKey(); Pair key = Pair.of( labels, propertyKeyId ); - updateValueTypeInMapping( currentValue, key, labelSetANDNodePropertyKeyIdToValueTypeMapping ); + updateValueTypeInMapping( currentValue, key, nodeMappings.labelSetANDNodePropertyKeyIdToValueType ); propertyIds.add( propertyKeyId ); } propertyCursor.close(); - Set oldPropertyKeySet = labelSetToPropertyKeysMapping.getOrDefault( labels, emptyPropertyIdSet ); + Set oldPropertyKeySet = nodeMappings.labelSetToPropertyKeys.getOrDefault( labels, emptyPropertyIdSet ); // find out which old properties we did not visited and mark them as nullable if ( oldPropertyKeySet == emptyPropertyIdSet ) @@ -272,7 +272,7 @@ private void scanEverythingBelongingToNodes() if ( propertyIds.size() == 0 ) { // Even if we find property key on other nodes with those labels, set all of them nullable - nullableLabelSets.add( labels ); + nodeMappings.nullableLabelSets.add( labels ); } propertyIds.addAll( oldPropertyKeySet ); @@ -280,19 +280,20 @@ private void scanEverythingBelongingToNodes() else { Set currentPropertyIdsHelperSet = new HashSet( propertyIds ); + currentPropertyIdsHelperSet.addAll( propertyIds ); propertyIds.removeAll( oldPropertyKeySet ); // only the brand new ones in propIds now oldPropertyKeySet.removeAll( currentPropertyIdsHelperSet ); // only the old ones that are not on the new node propertyIds.addAll( oldPropertyKeySet ); propertyIds.forEach( id -> { Pair key = Pair.of( labels, id ); - labelSetANDNodePropertyKeyIdToValueTypeMapping.get( key ).setNullable(); + nodeMappings.labelSetANDNodePropertyKeyIdToValueType.get( key ).setNullable(); } ); propertyIds.addAll( currentPropertyIdsHelperSet ); } - labelSetToPropertyKeysMapping.put( labels, propertyIds ); + nodeMappings.labelSetToPropertyKeys.put( labels, propertyIds ); } nodeCursor.close(); } @@ -324,7 +325,7 @@ private void addNamesToCollection( Iterator labelIterator, Map seenValueTypes; - private boolean isNullable; + private boolean isMandatory = true; ValueTypeListHelper( Value v ) { @@ -332,14 +333,14 @@ private class ValueTypeListHelper updateValueTypesWith( v ); } - private void setNullable( ) + private void setNullable() { - isNullable = true; + isMandatory = false; } - public boolean isNullable() + public boolean isMandatory() { - return isNullable; + return isMandatory; } List getCypherTypesList() @@ -356,4 +357,42 @@ void updateValueTypesWith( Value newValue ) seenValueTypes.add( newValue.getTypeName() ); } } + + /* + All mappings needed to describe Nodes except for property infos + */ + private class NodeMappings + { + final Map> labelSetToPropertyKeys; + final Map,ValueTypeListHelper> labelSetANDNodePropertyKeyIdToValueType; + final Set nullableLabelSets; // used for label combinations without properties -> all properties are viewed as nullable + final Map labelIdToLabelName; + + NodeMappings( int labelCount ) + { + labelSetToPropertyKeys = new HashMap<>( labelCount ); + labelIdToLabelName = new HashMap<>( labelCount ); + labelSetANDNodePropertyKeyIdToValueType = new HashMap<>(); + nullableLabelSets = new HashSet<>(); + } + } + + /* + All mappings needed to describe Rels except for property infos + */ + private class RelationshipMappings + { + final Map relationshipTypIdToRelationshipName; + final Map> relationshipTypeIdToPropertyKeys; + final Map,ValueTypeListHelper> relationshipTypeIdANDPropertyTypeIdToValueType; + final Set nullableRelationshipTypes; // used for types without properties -> all properties are viewed as nullable + + RelationshipMappings( int relationshipTypeCount ) + { + relationshipTypIdToRelationshipName = new HashMap<>( relationshipTypeCount ); + relationshipTypeIdToPropertyKeys = new HashMap<>( relationshipTypeCount ); + relationshipTypeIdANDPropertyTypeIdToValueType = new HashMap<>(); + nullableRelationshipTypes = new HashSet<>(); + } + } } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/builtinprocs/BuiltInProceduresTest.java b/community/kernel/src/test/java/org/neo4j/kernel/builtinprocs/BuiltInProceduresTest.java index 464307fa1c341..b63cb3b216d51 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/builtinprocs/BuiltInProceduresTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/builtinprocs/BuiltInProceduresTest.java @@ -229,10 +229,14 @@ public void shouldListCorrectBuiltinProcedures() throws Throwable "Schedule resampling of an index (for example: CALL db.resampleIndex(\":Person(name)\")).", "READ" ), record( "db.resampleOutdatedIndexes", "db.resampleOutdatedIndexes() :: VOID", "Schedule resampling of all outdated indexes.", "READ" ), - record( "okapi.schema", - "okapi.schema() :: (type :: STRING?, nodeLabelsOrRelType :: LIST? OF STRING?, property :: STRING?, " + - "cypherTypes :: LIST? OF STRING?, nullable :: BOOLEAN?)", - "Show the derived property schema of the data in tabular form.", "READ" ), + record( "db.schema.nodeTypeProperties", + "db.schema.nodeTypeProperties() :: (nodeType :: STRING?, nodeLabels :: LIST? OF STRING?, propertyName :: STRING?, " + + "propertyTypes :: LIST? OF STRING?, mandatory :: BOOLEAN?)", + "Show the derived property schema of the nodes in tabular form.", "READ" ), + record( "db.schema.relTypeProperties", + "db.schema.relTypeProperties() :: (relType :: STRING?, propertyName :: STRING?, propertyTypes :: LIST? OF STRING?," + + " mandatory :: BOOLEAN?)", + "Show the derived property schema of the relationships in tabular form.", "READ" ), record( "db.schema", "db.schema() :: (nodes :: LIST? OF NODE?, relationships :: LIST? OF RELATIONSHIP?)", "Show the schema of the data.", "READ" ), diff --git a/community/kernel/src/test/java/org/neo4j/kernel/builtinprocs/BuiltInSchemaProceduresIT.java b/community/kernel/src/test/java/org/neo4j/kernel/builtinprocs/BuiltInSchemaProceduresIT.java index f7ef697181bb3..2eb6ccee2d19a 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/builtinprocs/BuiltInSchemaProceduresIT.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/builtinprocs/BuiltInSchemaProceduresIT.java @@ -43,8 +43,27 @@ public class BuiltInSchemaProceduresIT extends KernelIntegrationTest { - private final String prefix = "okapi"; - private final String procedure = "schema"; + private final String[] nodesProcedureName = {"db", "schema", "nodeTypeProperties"}; + private final String[] relsProcedureName = {"db", "schema", "relTypeProperties"}; + + @Test + public void testWeirdLabelName() throws Throwable + { + // Given + + // Node1: (:`This:is_a:label` {color: "red"}) + + createNode( Arrays.asList( "`This:is_a:label`" ), Arrays.asList( "color" ), Arrays.asList( Values.stringValue( "red" ) ) ); + + // When + RawIterator stream = + procs().procedureCallRead( procs().procedureGet( procedureName( nodesProcedureName ) ).id(), new Object[0] ); + + // Then + assertThat( asList( stream ), containsInAnyOrder( + equalTo( nodeEntry(":``This:is_a:label``", Arrays.asList( "`This:is_a:label`" ), "color", Arrays.asList( "String" ), true) ) ) ); +// printStream( stream ); + } @Test public void testNodePropertiesRegardlessOfCreationOrder1() throws Throwable @@ -59,13 +78,13 @@ public void testNodePropertiesRegardlessOfCreationOrder1() throws Throwable // When RawIterator stream = - procs().procedureCallRead( procs().procedureGet( procedureName( prefix, procedure ) ).id(), new Object[0] ); + procs().procedureCallRead( procs().procedureGet( procedureName( nodesProcedureName ) ).id(), new Object[0] ); // Then assertThat( asList( stream ), containsInAnyOrder( - equalTo( entry("Node", Arrays.asList( "A" ), "color", Arrays.asList( "String" ), true) ), - equalTo( entry("Node", Arrays.asList( "A" ), "size", Arrays.asList( "String" ), true) ), - equalTo( entry("Node", Arrays.asList( "A" ), "origin", Arrays.asList( "String" ), true) ) ) ); + equalTo( nodeEntry(":`A`", Arrays.asList( "A" ), "color", Arrays.asList( "String" ), false) ), + equalTo( nodeEntry(":`A`", Arrays.asList( "A" ), "size", Arrays.asList( "String" ), false) ), + equalTo( nodeEntry(":`A`", Arrays.asList( "A" ), "origin", Arrays.asList( "String" ), false) ) ) ); // printStream( stream ); } @@ -82,13 +101,13 @@ public void testNodePropertiesRegardlessOfCreationOrder2() throws Throwable // When RawIterator stream = - procs().procedureCallRead( procs().procedureGet( procedureName( prefix, procedure ) ).id(), new Object[0] ); + procs().procedureCallRead( procs().procedureGet( procedureName( nodesProcedureName ) ).id(), new Object[0] ); // Then assertThat( asList( stream ), containsInAnyOrder( - equalTo( entry("Node", Arrays.asList( "B" ), "color", Arrays.asList( "String" ), true) ), - equalTo( entry("Node", Arrays.asList( "B" ), "size", Arrays.asList( "String" ), true) ), - equalTo( entry("Node", Arrays.asList( "B" ), "origin", Arrays.asList( "String" ), true) ) ) ); + equalTo( nodeEntry(":`B`", Arrays.asList( "B" ), "color", Arrays.asList( "String" ), false) ), + equalTo( nodeEntry(":`B`", Arrays.asList( "B" ), "size", Arrays.asList( "String" ), false) ), + equalTo( nodeEntry(":`B`", Arrays.asList( "B" ), "origin", Arrays.asList( "String" ), false) ) ) ); // printStream( stream ); } @@ -106,14 +125,14 @@ public void testNodePropertiesRegardlessOfCreationOrder3() throws Throwable // When RawIterator stream = - procs().procedureCallRead( procs().procedureGet( procedureName( prefix, procedure ) ).id(), new Object[0] ); + procs().procedureCallRead( procs().procedureGet( procedureName( nodesProcedureName ) ).id(), new Object[0] ); // Then - assertThat( asList( stream ), containsInAnyOrder( - equalTo( entry("Node", Arrays.asList( "C" ), "color", Arrays.asList( "String" ), true) ), - equalTo( entry("Node", Arrays.asList( "C" ), "size", Arrays.asList( "String" ), true) ), - equalTo( entry("Node", Arrays.asList( "C" ), "origin", Arrays.asList( "String" ), true) ), - equalTo( entry("Node", Arrays.asList( "C" ), "active", Arrays.asList( "Boolean" ), true) ) ) ); + assertThat( asList( stream ), containsInAnyOrder( + equalTo( nodeEntry(":`C`", Arrays.asList( "C" ), "color", Arrays.asList( "String" ), false) ), + equalTo( nodeEntry(":`C`", Arrays.asList( "C" ), "size", Arrays.asList( "String" ), false) ), + equalTo( nodeEntry(":`C`", Arrays.asList( "C" ), "origin", Arrays.asList( "String" ), false) ), + equalTo( nodeEntry(":`C`", Arrays.asList( "C" ), "active", Arrays.asList( "Boolean" ), false) ) ) ); // printStream( stream ); } @@ -134,14 +153,13 @@ public void testRelsPropertiesRegardlessOfCreationOrder1() throws Throwable // When RawIterator stream = - procs().procedureCallRead( procs().procedureGet( procedureName( prefix, procedure ) ).id(), new Object[0] ); + procs().procedureCallRead( procs().procedureGet( procedureName( relsProcedureName ) ).id(), new Object[0] ); // Then assertThat( asList( stream ), containsInAnyOrder( - equalTo( entry("Node", Arrays.asList(), null, null, true) ), - equalTo( entry("Relationship", Arrays.asList( "R" ), "color", Arrays.asList( "String" ), true) ), - equalTo( entry("Relationship", Arrays.asList( "R" ), "size", Arrays.asList( "String" ), true) ), - equalTo( entry("Relationship", Arrays.asList( "R" ), "origin", Arrays.asList( "String" ), true) ) ) ); + equalTo( relEntry(":`R`", "color", Arrays.asList( "String" ), false) ), + equalTo( relEntry(":`R`", "size", Arrays.asList( "String" ), false) ), + equalTo( relEntry(":`R`", "origin", Arrays.asList( "String" ), false) ) ) ); // printStream( stream ); } @@ -161,14 +179,13 @@ public void testRelsPropertiesRegardlessOfCreationOrder2() throws Throwable // When RawIterator stream = - procs().procedureCallRead( procs().procedureGet( procedureName( prefix, procedure ) ).id(), new Object[0] ); + procs().procedureCallRead( procs().procedureGet( procedureName( relsProcedureName ) ).id(), new Object[0] ); // Then assertThat( asList( stream ), containsInAnyOrder( - equalTo( entry("Node", Arrays.asList(), null, null, true) ), - equalTo( entry("Relationship", Arrays.asList( "R" ), "color", Arrays.asList( "String" ), true) ), - equalTo( entry("Relationship", Arrays.asList( "R" ), "size", Arrays.asList( "String" ), true) ), - equalTo( entry("Relationship", Arrays.asList( "R" ), "origin", Arrays.asList( "String" ), true) ) ) ); + equalTo( relEntry(":`R`", "color", Arrays.asList( "String" ), false) ), + equalTo( relEntry(":`R`", "size", Arrays.asList( "String" ), false) ), + equalTo( relEntry(":`R`", "origin", Arrays.asList( "String" ), false) ) ) ); // printStream( stream ); } @@ -190,15 +207,14 @@ public void testRelsPropertiesRegardlessOfCreationOrder3() throws Throwable // When RawIterator stream = - procs().procedureCallRead( procs().procedureGet( procedureName( prefix, procedure ) ).id(), new Object[0] ); + procs().procedureCallRead( procs().procedureGet( procedureName( relsProcedureName ) ).id(), new Object[0] ); // Then assertThat( asList( stream ), containsInAnyOrder( - equalTo( entry("Node", Arrays.asList(), null, null, true) ), - equalTo( entry("Relationship", Arrays.asList( "R" ), "color", Arrays.asList( "String" ), true) ), - equalTo( entry("Relationship", Arrays.asList( "R" ), "size", Arrays.asList( "String" ), true) ), - equalTo( entry("Relationship", Arrays.asList( "R" ), "origin", Arrays.asList( "String" ), true) ), - equalTo( entry("Relationship", Arrays.asList( "R" ), "active", Arrays.asList( "Boolean" ), true))) ); + equalTo( relEntry(":`R`", "color", Arrays.asList( "String" ), false) ), + equalTo( relEntry(":`R`", "size", Arrays.asList( "String" ), false) ), + equalTo( relEntry(":`R`", "origin", Arrays.asList( "String" ), false) ), + equalTo( relEntry(":`R`", "active", Arrays.asList( "Boolean" ), false))) ); // printStream( stream ); } @@ -216,11 +232,12 @@ public void testNodesShouldNotDependOnOrderOfCreationWithOverlap() throws Throwa // When RawIterator stream = - procs().procedureCallRead( procs().procedureGet( procedureName( prefix, procedure ) ).id(), new Object[0] ); + procs().procedureCallRead( procs().procedureGet( procedureName( nodesProcedureName ) ).id(), new Object[0] ); // Then - assertThat( asList( stream ), containsInAnyOrder( equalTo( new Object[]{"Node", Arrays.asList( "B" ), "type", Arrays.asList( "String" ), false} ), - equalTo( entry("Node", Arrays.asList( "B" ), "size", Arrays.asList( "Integer" ), true) ) ) ); + assertThat( asList( stream ), containsInAnyOrder( + equalTo( nodeEntry(":`B`", Arrays.asList( "B" ), "type", Arrays.asList( "String" ), true) ), + equalTo( nodeEntry(":`B`", Arrays.asList( "B" ), "size", Arrays.asList( "Integer" ), false) ) ) ); // printStream( stream ); } @@ -238,11 +255,12 @@ public void testNodesShouldNotDependOnOrderOfCreationWithOverlap2() throws Throw // When RawIterator stream = - procs().procedureCallRead( procs().procedureGet( procedureName( prefix, procedure ) ).id(), new Object[0] ); + procs().procedureCallRead( procs().procedureGet( procedureName( nodesProcedureName ) ).id(), new Object[0] ); // Then - assertThat( asList( stream ), containsInAnyOrder( equalTo( new Object[]{"Node", Arrays.asList( "B" ), "type", Arrays.asList( "String" ), false} ), - equalTo( entry("Node", Arrays.asList( "B" ), "size", Arrays.asList( "Integer" ), true) ) ) ); + assertThat( asList( stream ), containsInAnyOrder( + equalTo( nodeEntry(":`B`", Arrays.asList( "B" ), "type", Arrays.asList( "String" ), true) ), + equalTo( nodeEntry(":`B`", Arrays.asList( "B" ), "size", Arrays.asList( "Integer" ), false) ) ) ); // printStream( stream ); } @@ -262,12 +280,12 @@ public void testRelsShouldNotDependOnOrderOfCreationWithOverlap() throws Throwab // When RawIterator stream = - procs().procedureCallRead( procs().procedureGet( procedureName( prefix, procedure ) ).id(), new Object[0] ); + procs().procedureCallRead( procs().procedureGet( procedureName( relsProcedureName ) ).id(), new Object[0] ); // Then - assertThat( asList( stream ), containsInAnyOrder( equalTo( entry("Node", Arrays.asList(), null, null, true) ), - equalTo( entry("Relationship", Arrays.asList( "B" ), "type", Arrays.asList( "String" ), false) ), - equalTo( entry("Relationship", Arrays.asList( "B" ), "size", Arrays.asList( "Integer" ), true) ) ) ); + assertThat( asList( stream ), containsInAnyOrder( + equalTo( relEntry(":`B`", "type", Arrays.asList( "String" ), true) ), + equalTo( relEntry(":`B`", "size", Arrays.asList( "Integer" ), false) ) ) ); // printStream( stream ); } @@ -287,18 +305,18 @@ public void testRelsShouldNotDependOnOrderOfCreationWithOverlap2() throws Throwa // When RawIterator stream = - procs().procedureCallRead( procs().procedureGet( procedureName( prefix, procedure ) ).id(), new Object[0] ); + procs().procedureCallRead( procs().procedureGet( procedureName( relsProcedureName ) ).id(), new Object[0] ); // Then - assertThat( asList( stream ), containsInAnyOrder( equalTo( entry("Node", Arrays.asList(), null, null, true) ), - equalTo( entry("Relationship", Arrays.asList( "B" ), "type", Arrays.asList( "String" ), false) ), - equalTo( entry("Relationship", Arrays.asList( "B" ), "size", Arrays.asList( "Integer" ), true) ) ) ); + assertThat( asList( stream ), containsInAnyOrder( + equalTo( relEntry(":`B`", "type", Arrays.asList( "String" ), true) ), + equalTo( relEntry(":`B`", "size", Arrays.asList( "Integer" ), false) ) ) ); // printStream( stream ); } @Test - public void testWithNodes() throws Throwable + public void testWithAllDifferentNodes() throws Throwable { // Given @@ -314,14 +332,15 @@ public void testWithNodes() throws Throwable // When RawIterator stream = - procs().procedureCallRead( procs().procedureGet( procedureName( prefix, procedure ) ).id(), new Object[0] ); + procs().procedureCallRead( procs().procedureGet( procedureName( nodesProcedureName ) ).id(), new Object[0] ); // Then - assertThat( asList( stream ), containsInAnyOrder( equalTo( entry("Node", Arrays.asList( "A", "B" ), "prop1", Arrays.asList( "String" ), false) ), - equalTo( entry("Node", Arrays.asList( "A", "B" ), "prop2", Arrays.asList( "Integer" ), false) ), - equalTo( entry("Node", Arrays.asList( "B" ), "prop1", Arrays.asList( "Boolean" ), false) ), - equalTo( entry("Node", Arrays.asList( "C" ), "prop1", Arrays.asList( "StringArray" ), false) ), - equalTo( entry("Node", Arrays.asList(), null, null, true) ) ) ); + assertThat( asList( stream ), containsInAnyOrder( + equalTo( nodeEntry(":`A`:`B`", Arrays.asList( "A", "B" ), "prop1", Arrays.asList( "String" ), true) ), + equalTo( nodeEntry(":`A`:`B`", Arrays.asList( "A", "B" ), "prop2", Arrays.asList( "Integer" ), true) ), + equalTo( nodeEntry(":`B`", Arrays.asList( "B" ), "prop1", Arrays.asList( "Boolean" ), true) ), + equalTo( nodeEntry(":`C`", Arrays.asList( "C" ), "prop1", Arrays.asList( "StringArray" ), true) ), + equalTo( nodeEntry("", Arrays.asList(), null, null, false) ) ) ); // printStream( stream ); } @@ -339,10 +358,11 @@ public void testWithSimilarNodes() throws Throwable // When RawIterator stream = - procs().procedureCallRead( procs().procedureGet( procedureName( prefix, procedure ) ).id(), new Object[0] ); + procs().procedureCallRead( procs().procedureGet( procedureName( nodesProcedureName ) ).id(), new Object[0] ); // Then - assertThat( asList( stream ), contains( equalTo( entry("Node", Arrays.asList( "A" ), "prop1", Arrays.asList( "String" ), false) ) ) ); + assertThat( asList( stream ), contains( + equalTo( nodeEntry(":`A`", Arrays.asList("A"), "prop1", Arrays.asList( "String" ), true) ) ) ); // printStream( stream ); } @@ -364,12 +384,13 @@ public void testWithSimilarNodesHavingDifferentPropertyValueTypes() throws Throw // When RawIterator stream = - procs().procedureCallRead( procs().procedureGet( procedureName( prefix, procedure ) ).id(), new Object[0] ); + procs().procedureCallRead( procs().procedureGet( procedureName( nodesProcedureName ) ).id(), new Object[0] ); // Then - assertThat( asList( stream ), containsInAnyOrder( equalTo( entry("Node", Arrays.asList(), "prop1", Arrays.asList( "String" ), false) ), - equalTo( entry("Node", Arrays.asList(), "prop2", Arrays.asList( "Integer", "Float" ), true) ), - equalTo( entry("Node", Arrays.asList(), "prop3", Arrays.asList( "String", "Boolean" ), true) ) ) ); + assertThat( asList( stream ), containsInAnyOrder( + equalTo( nodeEntry("", Arrays.asList(), "prop1", Arrays.asList( "String" ), true) ), + equalTo( nodeEntry("", Arrays.asList(), "prop2", Arrays.asList( "Integer", "Float" ), false) ), + equalTo( nodeEntry("", Arrays.asList(), "prop3", Arrays.asList( "String", "Boolean" ), false) ) ) ); // printStream( stream ); } @@ -391,18 +412,19 @@ public void testWithSimilarNodesShouldNotDependOnOrderOfCreation() throws Throwa // When RawIterator stream = - procs().procedureCallRead( procs().procedureGet( procedureName( prefix, procedure ) ).id(), new Object[0] ); + procs().procedureCallRead( procs().procedureGet( procedureName( nodesProcedureName ) ).id(), new Object[0] ); // Then - assertThat( asList( stream ), containsInAnyOrder( equalTo( entry("Node", Arrays.asList(), "prop1", Arrays.asList( "String" ), true) ), - equalTo( entry("Node", Arrays.asList(), "prop2", Arrays.asList( "Integer", "Float" ), true) ), - equalTo( entry("Node", Arrays.asList(), "prop3", Arrays.asList( "String", "Boolean" ), true) ) ) ); + assertThat( asList( stream ), containsInAnyOrder( + equalTo( nodeEntry("", Arrays.asList(), "prop1", Arrays.asList( "String" ), false) ), + equalTo( nodeEntry("", Arrays.asList(), "prop2", Arrays.asList( "Integer", "Float" ), false) ), + equalTo( nodeEntry("", Arrays.asList(), "prop3", Arrays.asList( "String", "Boolean" ), false) ) ) ); // printStream( stream ); } @Test - public void testWithRelationships() throws Throwable + public void testWithAllDifferentRelationships() throws Throwable { // Given @@ -418,15 +440,15 @@ public void testWithRelationships() throws Throwable // When RawIterator stream = - procs().procedureCallRead( procs().procedureGet( procedureName( prefix, procedure ) ).id(), new Object[0] ); + procs().procedureCallRead( procs().procedureGet( procedureName( relsProcedureName ) ).id(), new Object[0] ); // Then assertThat( asList( stream ), - containsInAnyOrder( equalTo( entry("Relationship", Arrays.asList( "R" ), "prop1", Arrays.asList( "String" ), false) ), - equalTo( entry("Relationship", Arrays.asList( "R" ), "prop2", Arrays.asList( "Integer" ), false) ), - equalTo( entry("Relationship", Arrays.asList( "X" ), "prop1", Arrays.asList( "Boolean" ), false) ), - equalTo( entry("Relationship", Arrays.asList( "Z" ), null, null, true) ), - equalTo( entry("Node", Arrays.asList(), null, null, true) ) ) ); + containsInAnyOrder( + equalTo( relEntry(":`R`", "prop1", Arrays.asList( "String" ), true) ), + equalTo( relEntry(":`R`", "prop2", Arrays.asList( "Integer" ), true) ), + equalTo( relEntry(":`X`", "prop1", Arrays.asList( "Boolean" ), true) ), + equalTo( relEntry(":`Z`", null, null, false) ) ) ); // printStream( stream ); } @@ -446,12 +468,12 @@ public void testWithSimilarRelationships() throws Throwable // When RawIterator stream = - procs().procedureCallRead( procs().procedureGet( procedureName( prefix, procedure ) ).id(), new Object[0] ); + procs().procedureCallRead( procs().procedureGet( procedureName( relsProcedureName ) ).id(), new Object[0] ); // Then assertThat( asList( stream ), - containsInAnyOrder( equalTo( entry("Relationship", Arrays.asList( "R" ), "prop1", Arrays.asList( "String" ), false) ), - equalTo( entry("Node", Arrays.asList(), null, null, true) ) ) ); + containsInAnyOrder( + equalTo( relEntry(":`R`", "prop1", Arrays.asList( "String" ), true ) ) ) ); //printStream( stream ); } @@ -472,13 +494,13 @@ public void testSchemaWithRelationshipWithoutProperties() throws Throwable // When RawIterator stream = - procs().procedureCallRead( procs().procedureGet( procedureName( prefix, procedure ) ).id(), new Object[0] ); + procs().procedureCallRead( procs().procedureGet( procedureName( relsProcedureName ) ).id(), new Object[0] ); // Then - assertThat( asList( stream ), containsInAnyOrder( equalTo( entry("Node", Arrays.asList(), null, null, true) ), - equalTo( entry("Relationship", Arrays.asList( "R" ), "prop1", Arrays.asList( "String" ), true) ), - equalTo( entry("Relationship", Arrays.asList( "R" ), "prop2", Arrays.asList( "Integer" ), true) ), - equalTo( entry("Relationship", Arrays.asList( "R" ), "prop3", Arrays.asList( "Boolean" ), true) ) ) ); + assertThat( asList( stream ), containsInAnyOrder( + equalTo( relEntry(":`R`", "prop1", Arrays.asList( "String" ), false) ), + equalTo( relEntry(":`R`", "prop2", Arrays.asList( "Integer" ), false) ), + equalTo( relEntry(":`R`", "prop3", Arrays.asList( "Boolean" ), false) ) ) ); //printStream( stream ); } @@ -502,13 +524,13 @@ public void testWithSimilarRelationshipsHavingDifferentPropertyValueTypes() thro // When RawIterator stream = - procs().procedureCallRead( procs().procedureGet( procedureName( prefix, procedure ) ).id(), new Object[0] ); + procs().procedureCallRead( procs().procedureGet( procedureName( relsProcedureName ) ).id(), new Object[0] ); // Then - assertThat( asList( stream ), containsInAnyOrder( equalTo( entry("Node", Arrays.asList(), null, null, true) ), - equalTo( entry("Relationship", Arrays.asList( "R" ), "prop1", Arrays.asList( "String" ), false) ), - equalTo( entry("Relationship", Arrays.asList( "R" ), "prop2", Arrays.asList( "Integer", "Float" ), true) ), - equalTo( entry("Relationship", Arrays.asList( "R" ), "prop3", Arrays.asList( "String", "Boolean" ), true) ) ) ); + assertThat( asList( stream ), containsInAnyOrder( + equalTo( relEntry(":`R`", "prop1", Arrays.asList( "String" ), true) ), + equalTo( relEntry(":`R`", "prop2", Arrays.asList( "Integer", "Float" ), false) ), + equalTo( relEntry(":`R`", "prop3", Arrays.asList( "String", "Boolean" ), false) ) ) ); //printStream( stream ); } @@ -533,13 +555,13 @@ public void testWithSimilarRelationshipsShouldNotDependOnOrderOfCreation() throw // When RawIterator stream = - procs().procedureCallRead( procs().procedureGet( procedureName( prefix, procedure ) ).id(), new Object[0] ); + procs().procedureCallRead( procs().procedureGet( procedureName( relsProcedureName ) ).id(), new Object[0] ); // Then - assertThat( asList( stream ), containsInAnyOrder( equalTo( entry("Node", Arrays.asList(), null, null, true) ), - equalTo( entry("Relationship", Arrays.asList( "R" ), "prop1", Arrays.asList( "String" ), true) ), - equalTo( entry("Relationship", Arrays.asList( "R" ), "prop2", Arrays.asList( "Integer", "Float" ), true) ), - equalTo( entry("Relationship", Arrays.asList( "R" ), "prop3", Arrays.asList( "String", "Boolean" ), true) ) ) ); + assertThat( asList( stream ), containsInAnyOrder( + equalTo( relEntry(":`R`", "prop1", Arrays.asList( "String" ), false) ), + equalTo( relEntry(":`R`", "prop2", Arrays.asList( "Integer", "Float" ), false) ), + equalTo( relEntry(":`R`", "prop3", Arrays.asList( "String", "Boolean" ), false) ) ) ); //printStream( stream ); } @@ -564,21 +586,27 @@ public void testWithNullableProperties() throws Throwable // When RawIterator stream = - procs().procedureCallRead( procs().procedureGet( procedureName( prefix, procedure ) ).id(), new Object[0] ); + procs().procedureCallRead( procs().procedureGet( procedureName( nodesProcedureName ) ).id(), new Object[0] ); // Then - assertThat( asList( stream ), containsInAnyOrder( equalTo( entry("Node", Arrays.asList( "A" ), "prop1", Arrays.asList( "String" ), false) ), - equalTo( entry("Node", Arrays.asList( "A" ), "prop2", Arrays.asList( "Integer" ), true) ), - equalTo( entry("Node", Arrays.asList( "A" ), "prop3", Arrays.asList( "Boolean" ), true) ), - equalTo( entry("Node", Arrays.asList( "B" ), "prop1", Arrays.asList( "String" ), true) ), - equalTo( entry("Node", Arrays.asList( "B" ), "prop2", Arrays.asList( "Integer" ), true) ) ) ); + assertThat( asList( stream ), containsInAnyOrder( + equalTo( nodeEntry(":`A`", Arrays.asList("A"), "prop1", Arrays.asList( "String" ), true) ), + equalTo( nodeEntry(":`A`", Arrays.asList("A"), "prop2", Arrays.asList( "Integer" ), false) ), + equalTo( nodeEntry(":`A`", Arrays.asList("A"), "prop3", Arrays.asList( "Boolean" ), false) ), + equalTo( nodeEntry(":`B`", Arrays.asList("B"), "prop1", Arrays.asList( "String" ), false) ), + equalTo( nodeEntry(":`B`", Arrays.asList("B"), "prop2", Arrays.asList( "Integer" ), false) ) ) ); //printStream( stream ); } - private Object[] entry( String entityType, List labelsOrRelType, String propertyName, List propertyValueTypes, Boolean nullable ) + private Object[] nodeEntry( String escapedLabels, List labels, String propertyName, List propertyValueTypes, Boolean mandatory ) + { + return new Object[]{escapedLabels, labels, propertyName, propertyValueTypes, mandatory}; + } + + private Object[] relEntry( String labelsOrRelType, String propertyName, List propertyValueTypes, Boolean mandatory ) { - return new Object[]{entityType, labelsOrRelType, propertyName, propertyValueTypes, nullable}; + return new Object[]{labelsOrRelType, propertyName, propertyValueTypes, mandatory}; } private long createEmptyNode() throws Throwable diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/integrationtest/BuiltInProceduresIT.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/integrationtest/BuiltInProceduresIT.java index 44a68537cf4bc..20f65574275b4 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/integrationtest/BuiltInProceduresIT.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/integrationtest/BuiltInProceduresIT.java @@ -174,11 +174,13 @@ public void listProcedures() throws Throwable equalTo( new Object[]{"db.schema", "db.schema() :: (nodes :: LIST? OF NODE?, relationships :: LIST? " + "OF " + "RELATIONSHIP?)", "Show the schema of the data.", "READ"} ), - equalTo( new Object[]{"okapi.schema", - "okapi.schema() :: (type :: STRING?, nodeLabelsOrRelType :: LIST? OF STRING?, property :: STRING?, " + - "cypherTypes :: LIST? OF STRING?, nullable :: BOOLEAN?)", - "Show the derived property schema of the data in tabular form.", - "READ"} ), + equalTo( new Object[]{ "db.schema.nodeTypeProperties", + "db.schema.nodeTypeProperties() :: (nodeType :: STRING?, nodeLabels :: LIST? OF STRING?, propertyName :: STRING?, " + + "propertyTypes :: LIST? OF STRING?, mandatory :: BOOLEAN?)", + "Show the derived property schema of the nodes in tabular form.", "READ"} ), + equalTo( new Object[]{ "db.schema.relTypeProperties", "db.schema.relTypeProperties() :: (relType :: STRING?, " + + "propertyName :: STRING?, propertyTypes :: LIST? OF STRING?, mandatory :: BOOLEAN?)", + "Show the derived property schema of the relationships in tabular form.", "READ"} ), equalTo( new Object[]{"db.relationshipTypes", "db.relationshipTypes() :: (relationshipType :: " + "STRING?)", "List all relationship types in the database.", "READ"} ),