|
From: <bir...@us...> - 2007-10-15 18:38:45
|
Revision: 114
http://mptstore.svn.sourceforge.net/mptstore/?rev=114&view=rev
Author: birkland
Date: 2007-10-15 11:38:38 -0700 (Mon, 15 Oct 2007)
Log Message:
-----------
Formatting changes (thanks, eclipse...), fixed some logic with non-mappable predicates in multiple optional clauses
Modified Paths:
--------------
trunk/src/java/org/nsdl/mptstore/query/provider/GraphQuerySQLProvider.java
Modified: trunk/src/java/org/nsdl/mptstore/query/provider/GraphQuerySQLProvider.java
===================================================================
--- trunk/src/java/org/nsdl/mptstore/query/provider/GraphQuerySQLProvider.java 2007-10-15 18:35:51 UTC (rev 113)
+++ trunk/src/java/org/nsdl/mptstore/query/provider/GraphQuerySQLProvider.java 2007-10-15 18:38:38 UTC (rev 114)
@@ -28,18 +28,18 @@
/**
* Translates a {@link GraphQuery} into a series of SQL statements.
* <p>
- * Produces ANSI SQL-92 queries by converting each {@link GraphPattern} leaf
- * of the query tree into a series of JOINs. Each join condition is formed
- * by matching variables between {@link TriplePattern}s in the appripriate
+ * Produces ANSI SQL-92 queries by converting each {@link GraphPattern} leaf of
+ * the query tree into a series of JOINs. Each join condition is formed by
+ * matching variables between {@link TriplePattern}s in the appripriate
* GraphPatterns.
* </p>
* <p>
* TODO:
* <ul>
- * <li> Truly handle nested subqueries (currently is set to barf if a
- * required or optional compomnent is not a GraphPattern). Things are
- * set up for doing so, just not finished yet</li>
- * <li> Implement a strategy for dealing with unbound predicates </li>
+ * <li> Truly handle nested subqueries (currently is set to barf if a required
+ * or optional compomnent is not a GraphPattern). Things are set up for doing
+ * so, just not finished yet</li>
+ * <li> Implement a strategy for dealing with unbound predicates </li>
* </ul>
* </p>
*
@@ -47,14 +47,15 @@
*/
public class GraphQuerySQLProvider implements SQLBuilder, SQLProvider {
- private static final Logger LOG =
- Logger.getLogger(GraphQuerySQLProvider.class.getName());
+ private static final Logger LOG = Logger
+ .getLogger(GraphQuerySQLProvider.class.getName());
private final GraphQuery query;
private final TableManager tableManager;
private MappingManager manager;
+
private List<String> targets;
private final boolean backslashEscape;
@@ -62,38 +63,39 @@
private Set<MappableTriplePattern> encounteredPatterns;
private String ordering;
+
private String orderingDirection;
private HashMap<String, Set<String>> valueBindings;
-
/**
* Create an instance.
*
- * @param tm the table manager to use for looking up table names.
- * @param graphQuery the graph query.
- * @param backslashIsEscape whether backslash should be escaped in SQL
- * (Database specific)
+ * @param tm
+ * the table manager to use for looking up table names.
+ * @param graphQuery
+ * the graph query.
+ * @param backslashIsEscape
+ * whether backslash should be escaped in SQL (Database specific)
*/
public GraphQuerySQLProvider(final TableManager tm,
- final GraphQuery graphQuery,
- final boolean backslashIsEscape) {
+ final GraphQuery graphQuery, final boolean backslashIsEscape) {
this.tableManager = tm;
this.query = graphQuery;
this.backslashEscape = backslashIsEscape;
}
-
- /** Choose the variables that define result tuples
+ /**
+ * Choose the variables that define result tuples
* <p>
- * The given list of variables are used for determining
- * which bound values are included in result tuples, and in
- * what order. If a variable is specified as a target, it
- * <em>must</em> be present somewhere in the query. Any
- * unmatched target will result in error
+ * The given list of variables are used for determining which bound values
+ * are included in result tuples, and in what order. If a variable is
+ * specified as a target, it <em>must</em> be present somewhere in the
+ * query. Any unmatched target will result in error
* </p>
*
- * @param targetList the list of query variables.
+ * @param targetList
+ * the list of query variables.
*/
public void setTargets(final List<String> targetList) {
this.targets = new ArrayList<String>(targetList);
@@ -104,15 +106,16 @@
/**
* Force an order on the results.
* <p>
- * Given the name of a target variable, results will be ordered by its
- * bound value. Results may be specified to return in ascending or
- * descending order.
+ * Given the name of a target variable, results will be ordered by its bound
+ * value. Results may be specified to return in ascending or descending
+ * order.
* </p>
*
- * @param target Name of the target variable whose value will be the sort
- * key.
- * @param desc True if results are to be in desceiding order, false
- * otherwise.
+ * @param target
+ * Name of the target variable whose value will be the sort key.
+ * @param desc
+ * True if results are to be in desceiding order, false
+ * otherwise.
*/
public void orderBy(final String target, final boolean desc) {
if (this.targets == null || !this.targets.contains(target)) {
@@ -129,29 +132,29 @@
}
}
- /** Returns a query in ANSI SQL
+ /**
+ * Returns a query in ANSI SQL
* <p>
- * Translates the GraphQuery defined in the constructor, along with
- * any specified orderings , into a set of SQL statements. The
- * union of all SQL statement results, executed in order, will
- * represent the entire result set.
+ * Translates the GraphQuery defined in the constructor, along with any
+ * specified orderings , into a set of SQL statements. The union of all SQL
+ * statement results, executed in order, will represent the entire result
+ * set.
* </p>
*
* @return list of SQL statements
- * @throws QueryException if there is some error translating the query
- * to SQL.
+ * @throws QueryException
+ * if there is some error translating the query to SQL.
*/
public List<String> getSQL() throws QueryException {
this.manager = new MappingManager(tableManager);
this.encounteredPatterns = new HashSet<MappableTriplePattern>();
- valueBindings =
- new HashMap<String, Set<String>>();
+ valueBindings = new HashMap<String, Set<String>>();
/* These are bindings of variables in the 'required' query portions */
HashMap<String, String> requiredBindings =
- new HashMap<String, String>();
+ new HashMap<String, String>();
/* All variable bindings, including optional */
HashMap<String, String> allBindings = new HashMap<String, String>();
@@ -162,6 +165,8 @@
/* Process required elements first */
for (QueryElement e : query.getRequired()) {
+ LOG.debug("Processing required element: " + e);
+
/* Disallow subqueries for the time being */
if (e.getType().equals(QueryElement.Type.GraphQuery)) {
throw new QueryException("Currently, we do not support "
@@ -174,12 +179,11 @@
/* All required elements of the query are inner joined */
if (joinSeq == null) {
- joinSeq = new JoinSequence(
- parseGraphPattern((GraphPattern) e, requiredBindings));
+ joinSeq = new JoinSequence(parseGraphPattern((GraphPattern) e,
+ requiredBindings));
} else {
- joinSeq.addJoin(JoinType.INNER_JOIN,
- parseGraphPattern((GraphPattern) e, requiredBindings),
- requiredBindings);
+ joinSeq.addJoin(JoinType.INNER_JOIN, parseGraphPattern(
+ (GraphPattern) e, requiredBindings), requiredBindings);
}
}
@@ -187,9 +191,10 @@
for (QueryElement e : query.getOptional()) {
- HashMap<String, String> optionalBindings =
- new HashMap<String, String>(requiredBindings);
+ LOG.debug("processing optional path: " + e);
+ HashMap<String, String> optionalBindings = requiredBindings;
+
/* Disallow subqueries for the time being */
if (e.getType().equals(QueryElement.Type.GraphQuery)) {
throw new QueryException("Currently, we do not support "
@@ -200,9 +205,8 @@
+ e.getType());
}
- joinSeq.addJoin(JoinType.LEFT_OUTER_JOIN,
- parseGraphPattern((GraphPattern) e, optionalBindings),
- requiredBindings);
+ joinSeq.addJoin(JoinType.LEFT_OUTER_JOIN, parseGraphPattern(
+ (GraphPattern) e, optionalBindings), requiredBindings);
addNewMappings(optionalBindings, allBindings);
@@ -214,24 +218,24 @@
/* No tables to join means no query parts submitted */
return Arrays.asList("SELECT 1 WHERE 1=0");
} else {
- sql.append("SELECT " + generateTargets(allBindings)
- + " FROM " + joinSeq);
+ sql.append("SELECT " + generateTargets(allBindings) + " FROM "
+ + joinSeq);
}
/*
- * If there are any values or constraints that remain to be added to
- * the query, add them in a WHERE clause. NB: They better not be from
- * an optional clause: It would probably be wise to either check
- * here, or prove that an exception would have been thrown already.
+ * If there are any values or constraints that remain to be added to the
+ * query, add them in a WHERE clause. NB: They better not be from an
+ * optional clause: It would probably be wise to either check here, or
+ * prove that an exception would have been thrown already.
*/
StringBuilder additional = new StringBuilder();
if (valueBindings.size() > 0) {
additional.append(" WHERE ");
- ArrayList<String> valueKeys =
- new ArrayList<String>(valueBindings.keySet());
+ ArrayList<String> valueKeys = new ArrayList<String>(valueBindings
+ .keySet());
for (int i = 0; i < valueKeys.size(); i++) {
- ArrayList<String> values = new ArrayList<String>(
- valueBindings.get(valueKeys.get(i)));
+ ArrayList<String> values = new ArrayList<String>(valueBindings
+ .get(valueKeys.get(i)));
for (int j = 0; j < values.size(); j++) {
if (i > 0 || j > 0) {
sql.append(" AND ");
@@ -264,18 +268,18 @@
return new ArrayList<String>(targets);
}
- private Joinable parseGraphPattern(
- final GraphPattern g,
+ private Joinable parseGraphPattern(final GraphPattern g,
final HashMap<String, String> variableBindings)
throws QueryException {
+ LOG.debug("parsing graph pattern " + g);
/* First, organize the filters by variable so that we can map them */
HashMap<String, Set<MappableNodeFilter>> filters =
- new HashMap<String, Set<MappableNodeFilter>>();
+ new HashMap<String, Set<MappableNodeFilter>>();
/* We're given NodeFilters, but need MappableNodeFilters. Convert. */
Set<MappableNodeFilter<Node>> givenFilters =
- new HashSet<MappableNodeFilter<Node>>();
+ new HashSet<MappableNodeFilter<Node>>();
for (NodeFilter<Node> filter : g.getFilters()) {
givenFilters.add(new MappableNodeFilter<Node>(filter));
}
@@ -295,17 +299,16 @@
filters.get(f.getNode().getVarName()).add(f);
}
if (f.getConstraint().isVariable()) {
- if (!filters.containsKey(f.getConstraint().getVarName())) {
+ if (!filters.containsKey(f.getConstraint().getVarName())) {
LOG.debug("Adding " + f.getConstraint().getVarName()
+ " To filter pool..\n");
filters.put(f.getConstraint().getVarName(),
new HashSet<MappableNodeFilter>());
}
- filters.get(f.getConstraint().getVarName()).add(f);
+ filters.get(f.getConstraint().getVarName()).add(f);
}
- if (!(f.getNode().isVariable()
- || f.getConstraint().isVariable())) {
+ if (!(f.getNode().isVariable() || f.getConstraint().isVariable())) {
throw new IllegalArgumentException("Triple filters must "
+ "contain a variable. Neither "
+ f.getNode().getVarName() + " nor "
@@ -313,22 +316,34 @@
}
}
-
/* Next, process each triple pattern in this graph pattern */
LinkedList<MappableTriplePattern> steps =
- new LinkedList<MappableTriplePattern>();
+ new LinkedList<MappableTriplePattern>();
for (TriplePattern p : g.getTriplePatterns()) {
steps.add(new MappableTriplePattern(p));
}
/*
- * We create an initial join sequence from the first triple pattern
- * NB: We require that all triple patterns in a graph pattern
- * can be joined, so it is OK to do this
+ * We create an initial join sequence from the first triple pattern NB:
+ * We require that all triple patterns in a graph pattern can be joined,
+ * so it is OK to do this
*/
- MappableTriplePattern step = steps.removeFirst();
- if (!bindPattern(step, variableBindings)) {
+ MappableTriplePattern step = null;
+ boolean successfullyBoundFirstStep = false;
+ while (!steps.isEmpty()) {
+ step = steps.removeFirst();
+
+ if (!bindPattern(step, variableBindings)) {
+ continue;
+ } else {
+ successfullyBoundFirstStep = true;
+ break;
+ }
+ }
+
+ if (!successfullyBoundFirstStep) {
+ LOG.info("Pattern is entirely redundant. Ignoring: " + g);
return null;
}
@@ -365,8 +380,8 @@
for (MappableNodePattern var : joinableVars) {
if (valueBindings.containsKey(var.boundTable().alias())) {
- for (String condition : valueBindings.get(
- var.boundTable().alias())) {
+ for (String condition : valueBindings.get(var.boundTable()
+ .alias())) {
LOG.debug("parseGraphPattern: Adding remaining "
+ "constant conditions " + condition + "\n");
conditions.addCondition(condition);
@@ -389,8 +404,8 @@
}
/* .. If so, then get that one pattern */
- MappableTriplePattern p = new MappableTriplePattern(
- g.getTriplePatterns().get(0));
+ MappableTriplePattern p = new MappableTriplePattern(g
+ .getTriplePatterns().get(0));
/* ... and Process any remaining filters */
for (String varName : filters.keySet()) {
@@ -401,17 +416,16 @@
return joins;
}
- private void addJoinConditions(
- final JoinConditions conditions,
+ private void addJoinConditions(final JoinConditions conditions,
final MappableTriplePattern step,
final HashMap<String, String> variableBindings) {
for (MappableNodePattern p : step.getNodes()) {
if (isBound(p, variableBindings)) {
/* Join this var's column w/the corresponding bound one */
- if (!p.mappedName().equals(
- getBoundValue(p, variableBindings))) {
+ if (!p.mappedName().equals(getBoundValue(
+ p, variableBindings))) {
LOG.debug("parseGraphPattern: Adding Join Condition "
- + p.mappedName() + " = "
+ + p.mappedName() + " = "
+ getBoundValue(p, variableBindings) + "\n");
conditions.addCondition(p.mappedName(), " = ",
getBoundValue(p, variableBindings));
@@ -422,15 +436,14 @@
+ getBoundValue(p, variableBindings) + "\n");
valueBindings.get(p.boundTable().alias()).remove(
p.mappedName() + " = "
- + getBoundValue(p, variableBindings));
+ + getBoundValue(p, variableBindings));
}
}
}
}
}
- private void addFilterConditions(
- final JoinConditions conditions,
+ private void addFilterConditions(final JoinConditions conditions,
final HashMap<String, Set<MappableNodeFilter>> filters,
final Set<MappableNodePattern> joinableVars,
final HashMap<String, String> variableBindings) {
@@ -442,38 +455,33 @@
String right;
String left;
- if (f.getNode().isVariable() && f.getNode()
- .getVarName().equals(filterVar)) {
- left = getBoundValue(joinableVar,
- variableBindings);
+ if (f.getNode().isVariable()
+ && f.getNode().getVarName().equals(filterVar)) {
+ left = getBoundValue(joinableVar, variableBindings);
} else if (f.getNode().isVariable()) {
- left = getBoundValue(f.getNode(),
- variableBindings);
+ left = getBoundValue(f.getNode(), variableBindings);
} else {
- left = DBUtil.quotedString(
- f.getNode().getNode().toString(),
- backslashEscape);
+ left = DBUtil.quotedString(f.getNode().getNode()
+ .toString(), backslashEscape);
}
if (f.getConstraint().isVariable()
- && f.getConstraint().getVarName()
- .equals(filterVar)) {
- right = getBoundValue(joinableVar,
- variableBindings);
+ && f.getConstraint().getVarName().equals(
+ filterVar)) {
+ right = getBoundValue(
+ joinableVar, variableBindings);
} else if (f.getConstraint().isVariable()) {
right = getBoundValue(f.getConstraint(),
variableBindings);
} else {
- right = DBUtil.quotedString(
- f.getConstraint().getNode().toString(),
- backslashEscape);
+ right = DBUtil.quotedString(f.getConstraint()
+ .getNode().toString(), backslashEscape);
}
- conditions.addCondition(left, f.getOperator(),
- right);
+ conditions.addCondition(left, f.getOperator(), right);
LOG.debug("parseGraphPattern: Adding filter "
- + "condition: " + left + " "
- + f.getOperator() + " " + right + "\n");
+ + "condition: " + left + " " + f.getOperator()
+ + " " + right + "\n");
}
removeFromMap(filters.get(filterVar), filters);
@@ -483,16 +491,15 @@
}
private void processFilter(final MappableTriplePattern p,
- final String varName,
- final MappableNodeFilter f)
+ final String varName, final MappableNodeFilter f)
throws QueryException {
String mappedName;
- if (p.getSubject().isVariable() && p.getSubject()
- .getVarName().equals(varName)) {
+ if (p.getSubject().isVariable()
+ && p.getSubject().getVarName().equals(varName)) {
mappedName = p.getSubject().mappedName();
- } else if (p.getObject().isVariable() && p.getObject()
- .getVarName().equals(varName)) {
+ } else if (p.getObject().isVariable()
+ && p.getObject().getVarName().equals(varName)) {
mappedName = p.getObject().mappedName();
} else {
throw new QueryException("Variable " + varName
@@ -503,21 +510,25 @@
valueBindings.put(mappedName, new HashSet<String>());
}
- if (f.getNode().isVariable() && f.getNode().getVarName()
- .equals(varName)) {
+ if (f.getNode().isVariable()
+ && f.getNode().getVarName().equals(varName)) {
if (f.getConstraint().isVariable()) {
/* XXX It's probably not legal to be here.. */
LOG.warn("Node filter constraint is variable? "
+ "It's probably not legal to be here...");
} else {
- valueBindings.get(mappedName).add(
- mappedName + " " + f.getOperator() + " "
- + DBUtil.quotedString(
- f.getConstraint().getNode().toString(),
- backslashEscape));
+ valueBindings.get(mappedName)
+ .add(
+ mappedName
+ + " "
+ + f.getOperator()
+ + " "
+ + DBUtil.quotedString(f.getConstraint()
+ .getNode().toString(),
+ backslashEscape));
LOG.debug("Remaining Filters: " + mappedName + " "
- + f.getOperator() + " '"
- + f.getConstraint().getNode() + "'" + "\n");
+ + f.getOperator() + " '" + f.getConstraint().getNode()
+ + "'" + "\n");
}
} else if (f.getConstraint().isVariable()
&& f.getConstraint().getVarName().equals(varName)) {
@@ -528,20 +539,19 @@
} else {
valueBindings.get(mappedName).add(
DBUtil.quotedString(f.getNode().getNode().toString(),
- backslashEscape) + " "
- + f.getOperator() + " " + mappedName);
- LOG.debug("Remaining Filters: " + "'"
- + f.getNode().getNode() + "' "
- + f.getOperator() + " " + mappedName + "\n");
+ backslashEscape)
+ + " " + f.getOperator() + " " + mappedName);
+ LOG.debug("Remaining Filters: " + "'" + f.getNode().getNode()
+ + "' " + f.getOperator() + " " + mappedName + "\n");
}
}
}
/*
- * From a list of mappable triple patterns, pick one that has a
- * variable that also occurs in variablebindings. This assures that
- * if the caller is looking for joins, it will find at least one.
+ * From a list of mappable triple patterns, pick one that has a variable
+ * that also occurs in variablebindings. This assures that if the caller is
+ * looking for joins, it will find at least one.
*/
private MappableTriplePattern getJoinablePattern(
final List<MappableTriplePattern> l,
@@ -556,11 +566,11 @@
}
/*
- * Determine if a variable has been apped to a literal or
- * specific column of a table
+ * Determine if a variable has been apped to a literal or specific column of
+ * a table
*/
private boolean isBound(final MappableNodePattern n,
- final HashMap<String, String> variableBindings) {
+ final HashMap<String, String> variableBindings) {
if (n.isVariable()) {
return variableBindings.containsKey(n.getVarName());
} else {
@@ -572,8 +582,7 @@
* Get either an explicit value or a column/table reference for a given
* mapped node pattern
*/
- private String getBoundValue(
- final MappableNodePattern n,
+ private String getBoundValue(final MappableNodePattern n,
final HashMap<String, String> variableBindings) {
if (n.isVariable()) {
return variableBindings.get(n.getVarName());
@@ -583,12 +592,12 @@
}
/*
- * Bind the variables/values of a triple pattern by:
- * - Placing any new variables into the master bings map,
- * - Placing any literal values into the literals map
+ * Bind the variables/values of a triple pattern by: - Placing any new
+ * variables into the master bings map, - Placing any literal values into
+ * the literals map
*/
private boolean bindPattern(final MappableTriplePattern t,
- final HashMap<String, String> variableBindings) {
+ final HashMap<String, String> variableBindings) {
if (!encounteredPatterns.contains(t)) {
encounteredPatterns.add(t);
@@ -596,7 +605,7 @@
t.bindTo(manager.mapPredicateTable(t.getPredicate()));
bindNode(t.getSubject(), variableBindings);
- //bindNode(t.predicate, variableBindings);
+ // bindNode(t.predicate, variableBindings);
bindNode(t.getObject(), variableBindings);
return true;
} else {
@@ -607,31 +616,42 @@
/* TODO: be able to bind a predicate node */
private void bindNode(final MappableNodePattern p,
- final HashMap<String, String>variableBindings) {
+ final HashMap<String, String> variableBindings) {
if (p.isVariable()) {
+ StringBuilder existing = new StringBuilder();
+ for (String variable : variableBindings.keySet()) {
+ existing.append(variable + " = "
+ + variableBindings.get(variable) + "\n");
+ }
+ LOG.debug("Considering " + p.getVarName()
+ + " with respect to \n" + existing);
if (!variableBindings.containsKey(p.getVarName())) {
- LOG.debug("Bound " + p.getVarName() + " to "
- + p.mappedName() + "\n");
+ LOG.debug("Bound " + p.getVarName() + " to " + p.mappedName()
+ + "\n");
variableBindings.put(p.getVarName(), p.mappedName());
}
} else {
if (!valueBindings.containsKey(p.boundTable().alias())) {
- valueBindings.put(p.boundTable().alias(),
- new HashSet<String>());
+ valueBindings
+ .put(p.boundTable().alias(), new HashSet<String>());
}
- LOG.debug("bindNode: adding valueBinding " + p.mappedName()
- + " = " + "'" + p.getNode() + "'\n");
- valueBindings.get(p.boundTable().alias()).add(p.mappedName()
- + " = " + DBUtil.quotedString(p.getNode().toString(),
- backslashEscape));
+ LOG.debug("bindNode: adding valueBinding " + p.mappedName() + " = "
+ + "'" + p.getNode() + "'\n");
+ valueBindings.get(p.boundTable().alias()).add(
+ p.mappedName()
+ + " = "
+ + DBUtil.quotedString(p.getNode().toString(),
+ backslashEscape));
}
}
-
- /** Removes a mapped value (and all associated keys) from a map.
+ /**
+ * Removes a mapped value (and all associated keys) from a map.
*
- * @param value mapped value to remove
- * @param m map to remove the value from
+ * @param value
+ * mapped value to remove
+ * @param m
+ * map to remove the value from
*/
private <K, V> void removeFromMap(final V value, final Map<K, V> m) {
Set<K> toRemove = new HashSet<K>();
@@ -658,8 +678,8 @@
return selects;
}
- private <K, V> void addNewMappings(final Map<K, V> from,
- final Map<K, V> to) {
+ private <K, V> void addNewMappings(
+ final Map<K, V> from, final Map<K, V> to) {
for (K key : from.keySet()) {
if (!to.containsKey(key)) {
to.put(key, from.get(key));
@@ -669,19 +689,21 @@
private interface Joinable {
Set<MappableNodePattern> joinVars();
+
String alias();
+
String declaration();
}
private class JoinTable implements Joinable {
private final MappableTriplePattern t;
+
public JoinTable(final MappableTriplePattern tPattern) {
this.t = tPattern;
}
public Set<MappableNodePattern> joinVars() {
- HashSet<MappableNodePattern> s =
- new HashSet<MappableNodePattern>();
+ HashSet<MappableNodePattern> s = new HashSet<MappableNodePattern>();
if (t.getSubject().isVariable()) {
s.add(t.getSubject());
}
@@ -706,22 +728,27 @@
return (name + " AS " + alias);
}
}
+
+ public String toString() {
+ return declaration();
+ }
}
private class JoinSequence implements Joinable {
private final StringBuilder join;
+
private int joinCount = 0;
private final List<Joinable> joined = new ArrayList<Joinable>();
+
public JoinSequence(final Joinable start) {
this.join = new StringBuilder(start.declaration());
joined.add(start);
joinCount = 1;
}
- public void addJoin(final String joinType,
- final Joinable j,
- final String joinConstraints) {
+ public void addJoin(final String joinType, final Joinable j,
+ final String joinConstraints) {
if (j == null) {
LOG.info("Skipping join");
return;
@@ -734,15 +761,13 @@
joinCount++;
}
- public void addJoin(final String joinType,
- final Joinable j,
- final JoinConditions conditions) {
+ public void addJoin(final String joinType, final Joinable j,
+ final JoinConditions conditions) {
addJoin(joinType, j, conditions.toString());
}
- public void addJoin(final String joinType,
- final Joinable j,
- final HashMap<String, String> variableBindings) {
+ public void addJoin(final String joinType, final Joinable j,
+ final HashMap<String, String> variableBindings) {
if (j == null) {
LOG.info("Skipping join");
@@ -750,16 +775,19 @@
}
JoinConditions conditions = new JoinConditions();
-
for (MappableNodePattern existingVar : this.joinVars()) {
for (MappableNodePattern candidateVar : j.joinVars()) {
- if (existingVar.getVarName().equals(
- candidateVar.getVarName())
- && variableBindings.get(
- candidateVar.getVarName())
- .equals(existingVar.mappedName())) {
- conditions.addCondition(existingVar.mappedName(),
- "=", candidateVar.mappedName());
+
+ String existingVarName = existingVar.getVarName();
+ String candidateVarName = candidateVar.getVarName();
+ String candidateBinding = variableBindings.get(candidateVar
+ .getVarName());
+ String existingBinding = existingVar.mappedName();
+
+ if (existingVarName.equals(candidateVarName)
+ && existingBinding.equals(candidateBinding)) {
+ conditions.addCondition(existingBinding, " = ",
+ candidateVar.mappedName());
}
}
}
@@ -769,7 +797,7 @@
public Set<MappableNodePattern> joinVars() {
HashSet<MappableNodePattern> joinVars =
- new HashSet<MappableNodePattern>();
+ new HashSet<MappableNodePattern>();
for (Joinable joinable : joined) {
joinVars.addAll(joinable.joinVars());
@@ -799,10 +827,9 @@
private Set<String> conditions = new HashSet<String>();
public void addCondition(final String leftOperand,
- final String operator,
- final String rightOperand) {
- addCondition(leftOperand.trim() + " " + operator.trim()
- + " " + rightOperand.trim());
+ final String operator, final String rightOperand) {
+ addCondition(leftOperand.trim() + " " + operator.trim() + " "
+ + rightOperand.trim());
}
public void addCondition(final String condition) {
@@ -822,17 +849,22 @@
return joinClause.toString();
}
}
+
private class JoinType {
public static final String LEFT_OUTER_JOIN = "LEFT OUTER JOIN";
+
public static final String INNER_JOIN = "JOIN";
}
private class MappingManager {
- private HashMap<String, List<String>> predicateMap
- = new HashMap<String, List<String>>();
+ private HashMap<String, List<String>> predicateMap =
+ new HashMap<String, List<String>>();
+
private HashMap<PredicateNode, MPTable> nonexistantMappings =
new HashMap<PredicateNode, MPTable>();
+
private final TableManager adaptor;
+
private int allMap = 0;
public MappingManager(final TableManager mgr) {
@@ -858,22 +890,39 @@
if (tableName == null) {
/* No predicate found.. create table that returns no results */
+ alias = "np_" + nonexistantMappings.size();
+ tableName = "(SELECT p AS s, p AS o from tmap where 1=0)";
if (!nonexistantMappings.containsKey(predicate.getNode())) {
alias = "np_" + nonexistantMappings.size();
LOG.debug("No table for '" + predicate.getNode()
+ "'. Using empty table as " + alias);
tableName = "(SELECT p AS s, p AS o from tmap where 1=0)";
- nonexistantMappings.put(
- predicate.getNode(), new MPTable(tableName, alias));
+ nonexistantMappings.put(predicate.getNode(), new MPTable(
+ tableName, alias));
+ predicateMap.put(predicate.getNode().toString(),
+ new ArrayList<String>());
+ return nonexistantMappings.get(predicate.getNode());
+ } else {
+ List<String> aliases = predicateMap.get(predicate.getNode()
+ .toString());
+ String primaryAlias = nonexistantMappings.get(
+ predicate.getNode()).alias();
+ alias = primaryAlias + "_" + aliases.size();
+ LOG.debug("Nonexistant predicate already encountered. "
+ + " Using alias " + alias);
+ return new MPTable(tableName, alias);
}
- return nonexistantMappings.get(predicate.getNode());
- } else if (predicateMap
- .containsKey(predicate.getNode().toString())) {
- List<String> aliases = predicateMap.get(
- predicate.getNode().toString());
+ } else if (predicateMap.containsKey(
+ predicate.getNode().toString())) {
+ LOG.debug("Predicate already encountered. "
+ + "Making new table alias");
+ List<String> aliases = predicateMap.get(predicate.getNode()
+ .toString());
alias = tableName + "_" + aliases.size();
aliases.add(alias);
} else {
+ LOG.debug("Predicate never encountered. "
+ + "Will refer to it by its own name");
ArrayList<String> aliases = new ArrayList<String>();
aliases.add(tableName);
predicateMap.put(predicate.getNode().toString(), aliases);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|