@Override public String toString() { List<String> columns = new ArrayList<>(attributes.size()); for (Attribute c : attributes) columns.add(c.getID().toString()); StringBuilder bf = new StringBuilder(); bf.append("ALTER TABLE ").append(attributes.get(0).getRelation().getID()) .append(" ADD CONSTRAINT ").append(name).append(isPK ? " PRIMARY KEY " : " UNIQUE ") .append("("); Joiner.on(", ").appendTo(bf, columns); bf.append(")"); return bf.toString(); } }
public String getColumnReference(Function atom, int column) { RelationID viewName = viewNames.get(atom); RelationDefinition def = dataDefinitions.get(atom); QuotedID columnname = def.getAttribute(column + 1).getID(); // indexes from 1 return new QualifiedAttributeID(viewName, columnname).getSQLRendering(); } }
private String generateSQLString(RelationDefinition table) { StringBuilder sb = new StringBuilder("select"); boolean needComma = false; for (Attribute attr : table.getAttributes()) { if (needComma) { sb.append(","); } sb.append(" "); sb.append(attr.getID()); needComma = true; } sb.append(" "); sb.append("from"); sb.append(" "); sb.append(table.getID()); return sb.toString(); }
private static ImmutableList<TermType> extractTypes(RelationDefinition relation) { return relation.getAttributes().stream() .map(Attribute::getTermType) .collect(ImmutableCollectors.toList()); }
private Stream<ForeignKeyConstraint> extractMatchedFKsForARelation( RelationDefinition leftRelation, Collection<ImmutableList<? extends VariableOrGroundTerm>> leftArgumentLists, ImmutableList<? extends VariableOrGroundTerm> rightArguments, RelationDefinition rightRelation) { return leftRelation.getForeignKeys().stream() .filter(fk -> fk.getReferencedRelation().equals(rightRelation)) .filter(fk -> leftArgumentLists.stream() .anyMatch(leftArguments -> isFkMatching(fk, leftArguments, rightArguments))); }
private ImmutableSet<UniqueConstraint> extractMatchedUCs( ImmutableMultimap<RelationDefinition, ImmutableList<? extends VariableOrGroundTerm>> leftRelationArgumentMultimap, ImmutableList<? extends VariableOrGroundTerm> rightArguments, RelationDefinition rightRelation) { /* * When the left and right relations are the same */ return leftRelationArgumentMultimap.get(rightRelation).stream() .flatMap(leftArguments -> rightRelation.getUniqueConstraints().stream() .filter(uc -> isUcMatching(uc, leftArguments, rightArguments))) .collect(ImmutableCollectors.toSet()); }
@Override protected Optional<PredicateLevelProposal> proposePerPredicate(InnerJoinNode joinNode, ImmutableCollection<ExtensionalDataNode> initialNodes, RelationPredicate predicate, DBMetadata dbMetadata, ImmutableList<Variable> priorityVariables, IntermediateQuery query) throws AtomUnificationException { if (initialNodes.size() < 2) return Optional.empty(); RelationDefinition relation = predicate.getRelationDefinition(); /* * Does nothing */ if (relation == null) return Optional.empty(); ImmutableMap<FunctionalDependency, ImmutableCollection<Collection<ExtensionalDataNode>>> constraintNodeMap = relation.getOtherFunctionalDependencies().stream() .collect(ImmutableCollectors.toMap( c -> c, c -> groupDataNodesPerConstraint(c, initialNodes))); ImmutableSet<Variable> requiredAndCooccuringVariables = extractRequiredAndCooccuringVariables(query, joinNode); ImmutableSet<ExtensionalDataNode> nodesToRemove = selectNodesToRemove(requiredAndCooccuringVariables, constraintNodeMap, predicate); ImmutableList<ImmutableSubstitution<VariableOrGroundTerm>> dependentUnifiers = extractDependentUnifiers( relation, constraintNodeMap, nodesToRemove); return (dependentUnifiers.isEmpty() && nodesToRemove.isEmpty()) ? Optional.empty() : Optional.of(new PredicateLevelProposal(dependentUnifiers, nodesToRemove)); }
public static Function getAtom(RelationDefinition r, List<Term> terms) { if (r.getAttributes().size() != terms.size()) throw new IllegalArgumentException("The number of terms does not match the arity of relation"); Predicate pred = createPredicateFromRelation(r); return TERM_FACTORY.getFunction(pred, terms); }
private ImmutableSet<DataNode> findRedundantNodes(IntermediateQuery query, InnerJoinNode joinNode, ImmutableMultimap<RelationDefinition, ExtensionalDataNode> dataNodeMap) { return dataNodeMap.keySet().stream() .flatMap(r -> r.getForeignKeys().stream() .flatMap(c -> selectRedundantNodesForConstraint(r, c, query, joinNode, dataNodeMap))) .collect(ImmutableCollectors.toSet()); }
/** * Inserts a new data definition to this metadata object. * * @param td * The data definition. It can be a {@link DatabaseRelationDefinition} or a * {@link ParserViewDefinition} object. */ protected <T extends RelationDefinition> void add(T td, Map<RelationID, T> schema) { if (!isStillMutable) { throw new IllegalStateException("Too late, cannot add a schema"); } schema.put(td.getID(), td); if (td.getID().hasSchema()) { RelationID noSchemaID = td.getID().getSchemalessID(); if (!schema.containsKey(noSchemaID)) { schema.put(noSchemaID, td); } else { LOGGER.warn("DUPLICATE TABLE NAMES, USE QUALIFIED NAMES:\n" + td + "\nAND\n" + schema.get(noSchemaID)); //schema.remove(noSchemaID); // TODO (ROMAN 8 Oct 2015): think of a better way of resolving ambiguities } } }
relationAlias, relation instanceof DatabaseRelationDefinition ? relation.getID().getSQLRendering() : inBrackets(((ParserViewDefinition)relation).getStatement()), relation.getAttributes().stream() .map(a -> new QualifiedAttributeID(relationAlias, a.getID())) .collect(ImmutableCollectors.toList()));
private void indexVariables(Function atom) { RelationDefinition def = dataDefinitions.get(atom); RelationID viewName = viewNames.get(atom); for (int index = 0; index < atom.getTerms().size(); index++) { Term term = atom.getTerms().get(index); if (term instanceof Variable) { Set<QualifiedAttributeID> references = columnReferences.get(term); if (references == null) { references = new LinkedHashSet<>(); columnReferences.put((Variable) term, references); } /* * the index of attributes of the definition starts from 1 */ Attribute column; if (ruleIndex.containsKey(atom.getFunctionSymbol())) { // If I am here it means that it is not a database table // but a view from an Ans predicate int attPos = 3 * (index + 1); column = def.getAttribute(attPos); } else { column = def.getAttribute(index + 1); } QualifiedAttributeID qualifiedId = new QualifiedAttributeID(viewName, column.getID()); references.add(qualifiedId); } } }
public static Predicate createPredicateFromRelation(RelationDefinition r) { Predicate pred = TERM_FACTORY.getPredicate(extractPredicateName(r), r.getAttributes().size()); return pred; }
@Override public String toString() { List<String> columns = new ArrayList<>(attributes.size()); for (Attribute c : attributes) columns.add(c.getID().toString()); StringBuilder bf = new StringBuilder(); bf.append("ALTER TABLE ").append(attributes.get(0).getRelation().getID()) .append(" ADD CONSTRAINT ").append(name).append(isPK ? " PRIMARY KEY " : " UNIQUE ") .append("("); Joiner.on(", ").appendTo(bf, columns); bf.append(")"); return bf.toString(); } }
relationAlias, relation instanceof DatabaseRelationDefinition ? relation.getID().getSQLRendering() : inBrackets(((ParserViewDefinition)relation).getStatement()), relation.getAttributes().stream() .map(a -> new QualifiedAttributeID(relationAlias, a.getID())) .collect(ImmutableCollectors.toList()));
@Override public VariableNullability getVariableNullability() { if (variableNullability == null) { DataAtom<RelationPredicate> atom = getProjectionAtom(); RelationDefinition relation = atom.getPredicate().getRelationDefinition(); ImmutableList<? extends VariableOrGroundTerm> arguments = atom.getArguments(); ImmutableMultiset<? extends VariableOrGroundTerm> argMultiset = ImmutableMultiset.copyOf(arguments); // NB: DB column indexes start at 1. ImmutableSet<ImmutableSet<Variable>> nullableGroups = IntStream.range(0, arguments.size()) .filter(i -> arguments.get(i) instanceof Variable) .filter(i -> relation.getAttribute(i + 1).canNull()) .mapToObj(arguments::get) .map(a -> (Variable) a) // An implicit filter condition makes them non-nullable .filter(a -> argMultiset.count(a) < 2) .map(ImmutableSet::of) .collect(ImmutableCollectors.toSet()); variableNullability = new VariableNullabilityImpl(nullableGroups); } return variableNullability; }
public static AtomPredicate createAtomPredicateFromRelation(RelationDefinition r) { return ATOM_FACTORY.getAtomPredicate(extractPredicateName(r), r.getAttributes().size()); }
/** * Inserts a new data definition to this metadata object. * * @param td * The data definition. It can be a {@link DatabaseRelationDefinition} or a * {@link ParserViewDefinition} object. */ protected <T extends RelationDefinition> void add(T td, Map<RelationID, T> schema) { if (!isStillMutable) { throw new IllegalStateException("Too late, cannot add a schema"); } schema.put(td.getID(), td); if (td.getID().hasSchema()) { RelationID noSchemaID = td.getID().getSchemalessID(); if (!schema.containsKey(noSchemaID)) { schema.put(noSchemaID, td); } else { LOGGER.warn("DUPLICATE TABLE NAMES, USE QUALIFIED NAMES:\n" + td + "\nAND\n" + schema.get(noSchemaID)); //schema.remove(noSchemaID); // TODO (ROMAN 8 Oct 2015): think of a better way of resolving ambiguities } } }
Attribute attribute = td.get().getAttribute(i+1);
/** * TODO: explain * * @throws AtomUnificationException */ private ImmutableList<ImmutableSubstitution<VariableOrGroundTerm>> extractDependentUnifiers( RelationDefinition databaseRelation, ImmutableMap<FunctionalDependency, ImmutableCollection<Collection<ExtensionalDataNode>>> constraintNodeMap, ImmutableSet<ExtensionalDataNode> nodesToRemove) throws AtomUnificationException { ImmutableSet<Integer> nullableIndexes = databaseRelation.getAttributes().stream() .filter(Attribute::canNull) .map(a -> a.getIndex() - 1) .collect(ImmutableCollectors.toSet()); ImmutableList.Builder<ImmutableSubstitution<VariableOrGroundTerm>> dependentUnifierBuilder = ImmutableList.builder(); for (Map.Entry<FunctionalDependency, ImmutableCollection<Collection<ExtensionalDataNode>>> constraintEntry : constraintNodeMap.entrySet()) { dependentUnifierBuilder.addAll(extractDependentUnifiers(constraintEntry.getKey(), constraintEntry.getValue(), nodesToRemove, nullableIndexes)); } return dependentUnifierBuilder.build(); }