/** * Thrown when changing the super of a {@link Type} will result in a {@link Role} disconnection which is in use. */ public static GraknTxOperationException changingSuperWillDisconnectRole(Type oldSuper, Type newSuper, Role role){ return create(String.format("Cannot change the super type {%s} to {%s} because {%s} is connected to role {%s} which {%s} is not connected to.", oldSuper.label(), newSuper.label(), oldSuper.label(), role.label(), newSuper.label())); }
/** * * @param type The type of this concept */ private void setInternalType(Type type){ cachedInternalType.set(type.label()); vertex().property(Schema.VertexProperty.THING_TYPE_LABEL_ID, type.labelId().getValue()); }
/** * Helper method to get implicit relationship types of attributes * * @param types * @return a set of type Labels */ private static Set<Label> getAttributeImplicitRelationTypeLabes(Set<Type> types) { // If the sub graph contains attributes, we may need to add implicit relations to the path return types.stream() .filter(Concept::isAttributeType) .map(attributeType -> Schema.ImplicitType.HAS.getLabel(attributeType.label())) .collect(Collectors.toSet()); }
public static GraqlQueryException createInstanceOfMetaConcept(Var var, Type type) { return new GraqlQueryException(var + " cannot be an instance of meta-type " + type.label()); }
/** * Helper method to get the label IDs of role players in a relationship * * @return a set of type label IDs */ private Set<LabelId> getRolePlayerLabelIds() { return scopeTypes() .filter(Concept::isRelationshipType) .map(Concept::asRelationshipType) .filter(RelationshipType::isImplicit) .flatMap(RelationshipType::roles) .flatMap(Role::players) .map(type -> tx.convertToId(type.label())) .filter(LabelId::isValid) .collect(Collectors.toSet()); }
/** * Throw when trying to add instances to an abstract Type */ public static GraknTxOperationException addingInstancesToAbstractType(Type type){ return create(ErrorMessage.IS_ABSTRACT.getMessage(type.label())); }
public Multimap<Role, Type> getRoleTypeMap(boolean inferTypes) { ImmutableMultimap.Builder<Role, Type> builder = ImmutableMultimap.builder(); Multimap<Role, Var> roleMap = getRoleVarMap(); Map<Var, Type> varTypeMap = getParentQuery().getVarTypeMap(); roleMap.entries().stream() .filter(e -> varTypeMap.containsKey(e.getValue())) .filter(e -> { return inferTypes || getParentQuery().getAtoms(TypeAtom.class) .filter(t -> t.getVarName().equals(e.getValue())) .filter(t -> Objects.nonNull(t.getSchemaConcept())) .anyMatch(t -> t.getSchemaConcept().equals(varTypeMap.get(e.getValue()))); }) .sorted(Comparator.comparing(e -> varTypeMap.get(e.getValue()).label())) .forEach(e -> builder.put(e.getKey(), varTypeMap.get(e.getValue()))); return builder.build(); }
/** * Helper method to check if concept instances exist in the query scope * * @param ids * @return true if they exist, false if they don't */ private boolean scopeContainsInstances(ConceptId... ids) { for (ConceptId id : ids) { Thing thing = tx.getConcept(id); if (thing == null || !scopeTypeLabels().contains(thing.type().label())) return false; } return true; }
/** * @param typedVar variable of interest * @param parentType to be checked * @return true if typing the typeVar with type is compatible with role configuration of this query */ @Override public boolean isTypeRoleCompatible(Var typedVar, Type parentType){ if (parentType == null || Schema.MetaSchema.isMetaLabel(parentType.label())) return true; Set<Type> parentTypes = parentType.subs().collect(Collectors.toSet()); return getAtoms(RelationshipAtom.class) .filter(ra -> ra.getVarNames().contains(typedVar)) .noneMatch(ra -> ra.getRoleVarMap().entries().stream() //get roles this type needs to play .filter(e -> e.getValue().equals(typedVar)) .filter(e -> !Schema.MetaSchema.isMetaLabel(e.getKey().label())) //check if it can play it .anyMatch(e -> e.getKey().players().noneMatch(parentTypes::contains))); }
/** * Thrown when {@code type} has {@code attributeType} as a {@link Type#key(AttributeType)} and a {@link Type#has(AttributeType)} */ public static GraknTxOperationException duplicateHas(Type type, AttributeType attributeType){ return create(ErrorMessage.CANNOT_BE_KEY_AND_ATTRIBUTE.getMessage(type.label(), attributeType.label())); }
@Override Label transform(MatchableConcept item) { Concept concept = item.get(); return concept.isType() ? concept.asType().label() : null; } };
/** * Helper method to get the types to be included in the query target * * @return a set of Types */ private ImmutableSet<Type> targetTypes() { if (!query.of().isPresent() || query.of().get().isEmpty()) { throw GraqlQueryException.statisticsAttributeTypesNotSpecified(); } return query.of().get().stream() .map((label) -> { Type type = tx.getSchemaConcept(label); if (type == null) throw GraqlQueryException.labelNotFound(label); if (!type.isAttributeType()) throw GraqlQueryException.mustBeAttributeType(type.label()); return type; }) .flatMap(Type::subs) .collect(CommonUtil.toImmutableSet()); }
@Override public Set<String> validateOntologically() { SchemaConcept type = getSchemaConcept(); Set<String> errors = new HashSet<>(); if (type == null) return errors; if (!type.isAttributeType()){ errors.add(ErrorMessage.VALIDATION_RULE_INVALID_ATTRIBUTE_TYPE.getMessage(type.label())); return errors; } Type ownerType = getParentQuery().getVarTypeMap().get(getVarName()); if (ownerType != null && ownerType.attributes().noneMatch(rt -> rt.equals(type.asAttributeType()))){ errors.add(ErrorMessage.VALIDATION_RULE_ATTRIBUTE_OWNER_CANNOT_HAVE_ATTRIBUTE.getMessage(type.label(), ownerType.label())); } return errors; }
@Override public Set<String> validateOntologically() { Set<String> errors = new HashSet<>(); SchemaConcept type = getSchemaConcept(); if (type != null && !type.isRelationshipType()){ errors.add(ErrorMessage.VALIDATION_RULE_INVALID_RELATION_TYPE.getMessage(type.label())); return errors; } //check role-type compatibility Map<Var, Type> varTypeMap = getParentQuery().getVarTypeMap(); for (Map.Entry<Role, Collection<Var>> e : getRoleVarMap().asMap().entrySet() ){ Role role = e.getKey(); if (!Schema.MetaSchema.isMetaLabel(role.label())) { //check whether this role can be played in this relation if (type != null && type.asRelationshipType().roles().noneMatch(r -> r.equals(role))) { errors.add(ErrorMessage.VALIDATION_RULE_ROLE_CANNOT_BE_PLAYED.getMessage(role.label(), type.label())); } //check whether the role player's type allows playing this role for (Var player : e.getValue()) { Type playerType = varTypeMap.get(player); if (playerType != null && playerType.playing().noneMatch(plays -> plays.equals(role))) { errors.add(ErrorMessage.VALIDATION_RULE_TYPE_CANNOT_PLAY_ROLE.getMessage(playerType.label(), role.label(), type == null? "" : type.label())); } } } } return errors; }
/** * Thrown when a {@link Thing} is not allowed to have {@link Attribute} of that {@link AttributeType} */ public static GraknTxOperationException hasNotAllowed(Thing thing, Attribute attribute){ return create(HAS_INVALID.getMessage(thing.type().label(), attribute.type().label())); }
/** * Helper method to validate that the target types are of one data type, and get that data type * * @return the DataType of the target types */ @Nullable private AttributeType.DataType<?> validateAndGetTargetDataType() { AttributeType.DataType<?> dataType = null; for (Type type : targetTypes()) { // check if the selected type is a attribute type if (!type.isAttributeType()) throw GraqlQueryException.mustBeAttributeType(type.label()); AttributeType<?> attributeType = type.asAttributeType(); if (dataType == null) { // check if the attribute type has data-type LONG or DOUBLE dataType = attributeType.dataType(); if (!dataType.equals(AttributeType.DataType.LONG) && !dataType.equals(AttributeType.DataType.DOUBLE)) { throw GraqlQueryException.attributeMustBeANumber(dataType, attributeType.label()); } } else { // check if all the attribute types have the same data-type if (!dataType.equals(attributeType.dataType())) { throw GraqlQueryException.attributesWithDifferentDataTypes(query.of().get()); } } } return dataType; }
@Override public String toString() { if (concept.isAttribute()) { return "hasValue(" + valueToString(concept.asAttribute().value()) + ")"; } else if (concept.isThing()) { Thing thing = concept.asThing(); Stream<Attribute<?>> resources = thing.attributes(); Optional<?> value = resources .filter(resource -> NAME_TYPES.contains(resource.type().label())) .map(Attribute::value).findFirst(); return "instance(" + value.map(StringUtil::valueToString).orElse("") + ") isa " + thing.type().label(); } else if (concept.isType()) { return "type(" + concept.asType().label() + ")"; } else if (concept.isRole()) { return "role(" + concept.asRole().label() + ")"; } else if (concept.isRule()) { return "rule(" + concept.asRule().label() + ")"; } else { throw CommonUtil.unreachableStatement("Unrecognised concept " + concept); } }
public static HasAtom create(Var var, Var predicateVar, ConceptId predicateId, ReasonerQuery parent) { Label label = parent.tx().getConcept(predicateId).asType().label(); return create(var.has(Graql.label(label)), predicateVar, predicateId, parent); }
/** * Given an thing, return a var with the type. * @param thing thing to map * @return var patterns representing given thing */ private static VarPattern base(Thing thing){ VarPattern var = var(thing.id().getValue()).isa(Graql.label(thing.type().label())); return hasResources(var, thing); }
private Thing putInstance() { Type type = use(TYPE); if (type.isEntityType()) { return type.asEntityType().create(); } else if (type.isRelationshipType()) { return type.asRelationshipType().create(); } else if (type.isAttributeType()) { return type.asAttributeType().create(use(VALUE)); } else if (type.label().equals(Schema.MetaSchema.THING.getLabel())) { throw GraqlQueryException.createInstanceOfMetaConcept(var, type); } else { throw CommonUtil.unreachableStatement("Can't recognize type " + type); } }