Repository: marmotta Updated Branches: refs/heads/develop 228ab09f8 -> 3bd812477
bug fix in BIND expressions and JOINs bug fix in mixed ValueConstant and Var interpretation Project: http://git-wip-us.apache.org/repos/asf/marmotta/repo Commit: http://git-wip-us.apache.org/repos/asf/marmotta/commit/3bd81247 Tree: http://git-wip-us.apache.org/repos/asf/marmotta/tree/3bd81247 Diff: http://git-wip-us.apache.org/repos/asf/marmotta/diff/3bd81247 Branch: refs/heads/develop Commit: 3bd81247747aab6eefe7b72296cfef29fd27d40d Parents: 228ab09 Author: Sebastian Schaffert <[email protected]> Authored: Thu Sep 25 14:54:41 2014 +0200 Committer: Sebastian Schaffert <[email protected]> Committed: Thu Sep 25 14:54:41 2014 +0200 ---------------------------------------------------------------------- .../kiwi/sparql/builder/SQLBuilder.java | 109 +++++++++++++------ .../kiwi/sparql/builder/SQLVariable.java | 19 ++-- 2 files changed, 81 insertions(+), 47 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/marmotta/blob/3bd81247/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/SQLBuilder.java ---------------------------------------------------------------------- diff --git a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/SQLBuilder.java b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/SQLBuilder.java index 63b4661..a160806 100644 --- a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/SQLBuilder.java +++ b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/SQLBuilder.java @@ -21,7 +21,6 @@ import com.google.common.base.Preconditions; import org.apache.commons.lang3.StringUtils; import org.apache.marmotta.commons.collections.CollectionUtils; import org.apache.marmotta.commons.util.DateUtils; -import org.apache.marmotta.commons.vocabulary.XSD; import org.apache.marmotta.kiwi.model.rdf.KiWiNode; import org.apache.marmotta.kiwi.persistence.KiWiDialect; import org.apache.marmotta.kiwi.sail.KiWiValueFactory; @@ -218,22 +217,15 @@ public class SQLBuilder { sv.setProjectionType(ProjectionType.NODE); } - addVariable(sv); - } - - String pName = p.getName(); - String vName = sv.getName(); + String pName = p.getName(); + String vName = sv.getName(); - if (new ConditionFinder(v.getName(), query).found) { - sv.getAliases().add(pName + "_" + positions[i] + "_" + vName); - } + if (new ConditionFinder(v.getName(), query).found) { + sv.setAlias(pName + "_" + positions[i] + "_" + vName); + } - // if the variable has been used before, add a join condition to the first occurrence - if(sv.getExpressions().size() > 0) { - p.getConditions().add(sv.getExpressions().get(0) + " = " + pName + "." + positions[i]); + addVariable(sv); } - - sv.getExpressions().add(pName + "." + positions[i]); } } } @@ -251,23 +243,16 @@ public class SQLBuilder { sv.setProjectionType(sq_v.getProjectionType()); } - addVariable(sv); - } - - String sqName = sq.getAlias(); - String vName = sv.getName(); + String sqName = sq.getAlias(); + String vName = sv.getName(); - if (new ConditionFinder(sq_v.getSparqlName(), query).found) { - sv.getAliases().add(sqName + "_" + vName); - } + if (new ConditionFinder(sq_v.getSparqlName(), query).found) { + sv.setAlias(sqName + "_" + vName); + } - // if the variable has been used before, add a join condition to the first occurrence - if(sv.getExpressions().size() > 0) { - sq.getConditions().add(sv.getExpressions().get(0) + " = " + sqName + "." + sq_v.getName()); + addVariable(sv); } - sv.getExpressions().add(sqName + "." + sq_v.getName()); - } } } @@ -297,10 +282,55 @@ public class SQLBuilder { //sv.getAliases().add(evaluateExpression(ext.getExpr(), OPTypes.VALUE)); sv.getBindings().add(ext.getExpr()); } + sv.getExpressions().add(evaluateExpression(ext.getExpr(), OPTypes.ANY)); } + // calculate for each variable the SQL expressions representing them and any necessary JOIN conditions + + for(SQLFragment f : fragments) { + for (SQLPattern p : f.getPatterns()) { + // build pattern + Var[] fields = p.getFields(); + for (int i = 0; i < fields.length; i++) { + if (fields[i] != null && !fields[i].hasValue()) { + Var v = fields[i]; + + SQLVariable sv = variables.get(v.getName()); + + String pName = p.getName(); + + // if the variable has been used before, add a join condition to the first occurrence + if(sv.getExpressions().size() > 0) { + p.getConditions().add(sv.getExpressions().get(0) + " = " + pName + "." + positions[i]); + } + + sv.getExpressions().add(pName + "." + positions[i]); + } + } + } + + // subqueries: look up which variables are bound in the subqueries and add proper aliases + for(SQLAbstractSubquery sq : f.getSubqueries()) { + for(SQLVariable sq_v : sq.getQueryVariables()) { + SQLVariable sv = variables.get(sq_v.getSparqlName()); + + String sqName = sq.getAlias(); + + // if the variable has been used before, add a join condition to the first occurrence + if(sv.getExpressions().size() > 0) { + sq.getConditions().add(sv.getExpressions().get(0) + " = " + sqName + "." + sq_v.getName()); + } + + sv.getExpressions().add(sqName + "." + sq_v.getName()); + + } + } + } + + + // find context restrictions of patterns and match them with potential restrictions given in the // dataset (MARMOTTA-340) for(SQLFragment f : fragments) { @@ -691,7 +721,7 @@ public class SQLBuilder { Lang lang = (Lang)expr; if(lang.getArg() instanceof Var) { - return variables.get(((Var) lang.getArg()).getName()).getPrimaryAlias() + ".lang"; + return variables.get(((Var) lang.getArg()).getName()).getAlias() + ".lang"; } } else if(expr instanceof Compare) { Compare cmp = (Compare)expr; @@ -736,7 +766,7 @@ public class SQLBuilder { if(arg instanceof ValueConstant) { return Boolean.toString(((ValueConstant) arg).getValue() instanceof URI || ((ValueConstant) arg).getValue() instanceof BNode); } else if(arg instanceof Var) { - String var = variables.get(((Var) arg).getName()).getPrimaryAlias(); + String var = variables.get(((Var) arg).getName()).getAlias(); return "(" + var + ".ntype = 'uri' OR " + var + ".ntype = 'bnode')"; } @@ -747,7 +777,7 @@ public class SQLBuilder { if(arg instanceof ValueConstant) { return Boolean.toString(((ValueConstant) arg).getValue() instanceof URI); } else if(arg instanceof Var) { - String var = variables.get(((Var) arg).getName()).getPrimaryAlias(); + String var = variables.get(((Var) arg).getName()).getAlias(); return var + ".ntype = 'uri'"; } @@ -758,7 +788,7 @@ public class SQLBuilder { if(arg instanceof ValueConstant) { return Boolean.toString(((ValueConstant) arg).getValue() instanceof BNode); } else if(arg instanceof Var) { - String var = variables.get(((Var) arg).getName()).getPrimaryAlias(); + String var = variables.get(((Var) arg).getName()).getAlias(); return var + ".ntype = 'bnode'"; } @@ -769,7 +799,7 @@ public class SQLBuilder { if(arg instanceof ValueConstant) { return Boolean.toString(((ValueConstant) arg).getValue() instanceof Literal); } else if(arg instanceof Var) { - String var = variables.get(((Var) arg).getName()).getPrimaryAlias(); + String var = variables.get(((Var) arg).getName()).getAlias(); return "(" + var + ".ntype = 'string' OR " + var + ".ntype = 'int' OR " + var + ".ntype = 'double' OR " + var + ".ntype = 'date' OR " + var + ".ntype = 'boolean')"; } @@ -782,7 +812,7 @@ public class SQLBuilder { // variable occurrence with its value return evaluateExpression(sv.getBindings().get(0),optype); } else { - String var = sv.getPrimaryAlias(); + String var = sv.getAlias(); if(sv.getProjectionType() != ProjectionType.NODE && sv.getProjectionType() != ProjectionType.NONE) { // in case the variable represents a constructed or bound value instead of a node, we need to @@ -828,7 +858,12 @@ public class SQLBuilder { case INT: return "" + Integer.parseInt(val); case DOUBLE: return "" + Double.parseDouble(val); case DATE: return "'" + sqlDateFormat.format(DateUtils.parseDate(val)) + "'"; - case ANY: return "'" + val + "'"; + + // in this case we should return a node ID and also need to make sure it actually exists + case ANY: + KiWiNode n = converter.convert(((ValueConstant) expr).getValue()); + return "" + n.getId(); + default: throw new IllegalArgumentException("unsupported value type: " + optype); } } @@ -855,7 +890,8 @@ public class SQLBuilder { List<String> countVariables = new ArrayList<>(); for(SQLVariable v : variables.values()) { if(v.getProjectionType() == ProjectionType.NONE) { - countVariables.add(v.getExpressions().get(0)); + //countVariables.add(v.getExpressions().get(0)); + countVariables.add(v.getAlias()); } } countExp.append("ARRAY["); @@ -1062,6 +1098,8 @@ public class SQLBuilder { } else if(expr instanceof NAryValueOperator) { return getProjectionType(((NAryValueOperator) expr).getArguments().get(0)); } else if(expr instanceof ValueConstant) { + return ProjectionType.NODE; + /* if (((ValueConstant) expr).getValue() instanceof URI) { return ProjectionType.URI; } else if (((ValueConstant) expr).getValue() instanceof Literal) { @@ -1077,6 +1115,7 @@ public class SQLBuilder { } else { return ProjectionType.STRING; } + */ } else if(expr instanceof Var) { return ProjectionType.NODE; } else if(expr instanceof MathExpr) { http://git-wip-us.apache.org/repos/asf/marmotta/blob/3bd81247/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/SQLVariable.java ---------------------------------------------------------------------- diff --git a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/SQLVariable.java b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/SQLVariable.java index 42515da..bbcd153 100644 --- a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/SQLVariable.java +++ b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/SQLVariable.java @@ -45,7 +45,7 @@ public class SQLVariable implements Cloneable{ * depending on the number of patterns it occurs in; will look like * { ?x -> ["P1_V1", "P2_V1"], ?y -> ["P2_V2"], ... } */ - private List<String> aliases; + private String alias; /** @@ -72,7 +72,6 @@ public class SQLVariable implements Cloneable{ this.name = name; this.sparqlName = sparqlName; - this.aliases = new ArrayList<>(); this.bindings = new ArrayList<>(); this.expressions = new ArrayList<>(); } @@ -89,16 +88,12 @@ public class SQLVariable implements Cloneable{ return sparqlName; } - public List<String> getAliases() { - return aliases; + public String getAlias() { + return alias; } - /** - * Primary alias for a variable, used e.g. when projecting or evaluating in functions. All others are added with join conditions. - * @return - */ - public String getPrimaryAlias() { - return aliases.get(0); + public void setAlias(String alias) { + this.alias = alias; } public List<ValueExpr> getBindings() { @@ -139,7 +134,7 @@ public class SQLVariable implements Cloneable{ return "Variable{" + "SQL name='" + name + '\'' + ", SPARQL name=" + sparqlName + - ", aliases=" + aliases + + ", alias=" + alias + ", expressions=" + expressions + ", projectionType=" + projectionType + '}'; @@ -165,7 +160,7 @@ public class SQLVariable implements Cloneable{ SQLVariable clone = new SQLVariable(getName(), getSparqlName()); clone.projectionType = projectionType; clone.getExpressions().addAll(expressions); - clone.getAliases().addAll(aliases); + clone.alias = alias; clone.getBindings().addAll(bindings); return clone;
