Skip to content

Commit

Permalink
Push simple ORDER clauses into the SQL
Browse files Browse the repository at this point in the history
  • Loading branch information
grahamtriggs committed Feb 15, 2019
1 parent bd09dcf commit dc3e823
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 8 deletions.
2 changes: 2 additions & 0 deletions jena-sdb/src/main/java/org/apache/jena/sdb/SDB.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ public class SDB
public static final Symbol annotateGeneratedSQL = SDBConstants.allocSymbol("annotateGeneratedSQL") ;

public static final Symbol optimizeSubqueryFragments = SDBConstants.allocSymbol("optimizeSubqueryFragments") ;

public static final Symbol optimizeOrderClause = SDBConstants.allocSymbol("optimizeOrderClause") ;
// ----------------------------------

// Global context is the ARQ context.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package org.apache.jena.sdb.compiler;

import org.apache.jena.atlas.io.IndentedWriter ;
import org.apache.jena.query.SortCondition;
import org.apache.jena.sdb.core.SDBRequest ;
import org.apache.jena.sdb.core.sqlnode.SqlNode ;
import org.apache.jena.sdb.store.SQLBridge ;
Expand All @@ -32,12 +33,15 @@
import org.apache.jena.sparql.serializer.SerializationContext ;
import org.apache.jena.sparql.util.NodeIsomorphismMap ;

import java.util.List;

public class OpSQL extends OpExt
{
private SqlNode sqlNode ;
private Op originalOp ;
private SQLBridge bridge = null ;
private SDBRequest request ;
private List<SortCondition> sortConditions;

public OpSQL(SqlNode sqlNode, Op original, SDBRequest request)
{
Expand Down Expand Up @@ -121,6 +125,9 @@ public void resetSqlNode(SqlNode sqlNode2)

public void setBridge(SQLBridge bridge) { this.bridge = bridge ; }

public List<SortCondition> getSortConditions() { return this.sortConditions; }
public void setSortConditions(List<SortCondition> sortConditions) { this.sortConditions = sortConditions; }

@Override
public void outputArgs(IndentedWriter out, SerializationContext sCxt)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,8 @@ public Op transformSliceProject(OpSlice opSlice, OpProject opProject)
// Put back project - as an OpProject to leave for the bridge.
OpSQL x = new OpSQL(n, opProject, request) ;
x.setBridge(opSQL.getBridge()) ;
// Ensure any sort conditions are copied to the new OpSQL
x.setSortConditions(opSQL.getSortConditions());
// Bridge will be set later.
// Is OpProject needed?
return new OpProject(x, pv) ;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,15 @@ public static Op compile(Store store, Op op, Binding binding, Context context, S
request.LimitOffsetTranslation = true ;
request.DistinctTranslation = true ;
}

if (context.isTrueOrUndef(SDB.optimizeOrderClause))
{
request.OrderTranslation = true;
}
else
{
request.OrderTranslation = false;
}

QueryCompiler queryCompiler = store.getQueryCompilerFactory().createQueryCompiler(request) ;
Op op2 = queryCompiler.compile(op) ;
Expand Down
13 changes: 13 additions & 0 deletions jena-sdb/src/main/java/org/apache/jena/sdb/compiler/SDB_QC.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import java.sql.SQLException;
import java.util.List;
import java.util.Set;

import org.apache.jena.sdb.core.sqlnode.SqlSelectBlock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.jena.query.Query ;
Expand Down Expand Up @@ -87,6 +89,17 @@ public static String toSqlString(OpSQL opSQL,
SDBRequest request)
{
SqlNode sqlNode = opSQL.getSqlNode() ;

// If any sort conditions have been set, pass them on to the SQL Node - ensuring the SQL Node is a select block
List<SortCondition> sortConditions = opSQL.getSortConditions();
if (sortConditions != null && sortConditions.size() > 0) {
if ( ! sqlNode.isSelectBlock() ) {
sqlNode = SqlSelectBlock.project(request, sqlNode) ;
}

sqlNode.asSelectBlock().setSortConditions(sortConditions);
}

String sqlStmt = request.getStore().getSQLGenerator().generateSQL(request, sqlNode) ;
return sqlStmt ;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

import org.apache.jena.atlas.iterator.Iter ;
import org.apache.jena.graph.Node ;
import org.apache.jena.query.SortCondition;
import org.apache.jena.sdb.core.AliasesSql ;
import org.apache.jena.sdb.core.SDBRequest ;
import org.apache.jena.sdb.core.ScopeEntry ;
Expand All @@ -43,6 +44,8 @@
import org.apache.jena.sparql.algebra.TransformCopy ;
import org.apache.jena.sparql.algebra.op.* ;
import org.apache.jena.sparql.core.Var ;
import org.apache.jena.sparql.expr.ExprAggregator;
import org.apache.jena.sparql.expr.ExprVar;
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;

Expand Down Expand Up @@ -190,24 +193,56 @@ public Op transform(OpDistinct opDistinct, Op subOp)

@Override
public Op transform(OpProject opProject, Op subOp)
{
{
// If the an OpOrder has been pushed onto an SQL Op
if (opProject.getSubOp() instanceof OpOrder && SDB_QC.isOpSQL(subOp) ) {
// Just return an update Project, without a bridge
return opProject.copy(subOp);
}

//request.getStore().getSQLBridgeFactory().create(request, null, null)
if ( ! SDB_QC.isOpSQL(subOp) )
return super.transform(opProject, subOp) ;

// Need to not do bridge elsewhere.
List<Var> vars = opProject.getVars() ;
return doBridge(request, (OpSQL)subOp, vars, opProject) ;
List<Var> vars = opProject.getVars();
return doBridge(request, (OpSQL) subOp, vars, opProject);
}


@Override
public Op transform(OpOrder opOrder, Op subOp) {
if (request.OrderTranslation) {
// If this Order has an OpSQL child
if (SDB_QC.isOpSQL(subOp)) {
// Check that all of the SortConditions are simple variable expressions
boolean orderInSQL = true;
for (SortCondition sc : opOrder.getConditions()) {
if (!(sc.getExpression() instanceof ExprVar)) {
orderInSQL = false;
}
}

// Simple sorts, so copy them on to the OpSQL and drop the OpOrder
// (Ordering is then applied in the database, not in memory
if (orderInSQL) {
OpSQL opSQL = (OpSQL) subOp;
opSQL.setSortConditions(opOrder.getConditions());
return opSQL;
}
}
}

return super.transform(opOrder, subOp);
}

@Override
public Op transform(OpService opService, Op subOp)
{
// Do not walk in any further.
// See ARQ Optimize class for a better way to do this.
return opService ;
}

// See QueryCompilerMain.SqlNodesFinisher.visit(OpExt op)
// Be careful about being done twice.
// XXX SHARE CODE!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ public class SDBRequest extends StoreHolder
public boolean LeftJoinTranslation = true ; // Does the DB support general join expressions?
public boolean LimitOffsetTranslation = false ; // Does the DB grok the Limit/Offset SQL?
public boolean DistinctTranslation = true ; // Some DBs can't do DISTINCT on CLOBS.

public boolean OrderTranslation = true ; // Allow translation of ORDER to SQL to be configurable

private Context context ;

public SDBRequest(Store store, Query query, Context context)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@
import org.apache.jena.atlas.io.IndentedWriter ;
import org.apache.jena.atlas.iterator.Iter ;
import org.apache.jena.atlas.lib.Lib ;
import org.apache.jena.query.Query;
import org.apache.jena.query.SortCondition;
import org.apache.jena.sdb.SDB ;
import org.apache.jena.sdb.core.Annotations ;
import org.apache.jena.sdb.core.ScopeEntry;
import org.apache.jena.sdb.core.sqlexpr.S_Equal ;
import org.apache.jena.sdb.core.sqlexpr.SqlColumn ;
import org.apache.jena.sdb.core.sqlexpr.SqlExpr ;
Expand Down Expand Up @@ -115,6 +118,10 @@ public void visit(SqlSelectBlock sqlSelectBlock)
if ( sqlSelectBlock.getConditions().size() > 0 )
genWHERE(sqlSelectBlock.getConditions()) ;

// ORDDER
out.ensureStartOfLine() ;
genOrder(sqlSelectBlock) ;

// LIMIT/OFFSET
out.ensureStartOfLine() ;
genLimitOffset(sqlSelectBlock) ;
Expand Down Expand Up @@ -147,6 +154,44 @@ protected void genSuffix(SqlSelectBlock sqlSelectBlock)
// By default, NOP.
}

protected void genOrder(SqlSelectBlock sqlSelectBlock) {
StringBuilder orderBuilder = new StringBuilder();

List<SortCondition> sortConditions = sqlSelectBlock.getSortConditions();
if (sortConditions != null && sortConditions.size() > 0) {
for (SortCondition sc : sortConditions) {
if (orderBuilder.length() > 0) {
orderBuilder.append(", ");
}

// Find the correct column for this condition
for (ColAlias ca : sqlSelectBlock.getCols()) {
if ("lex".equals(ca.getColumn().getColumnName())) {
ScopeEntry se = ca.getColumn().getTable().getNodeScope().findScopeForVar(sc.getExpression().asVar());
if (se != null) {
orderBuilder.append(ca.getColumn().getFullColumnName());
switch (sc.getDirection()) {
case Query.ORDER_DESCENDING:
orderBuilder.append(" DESC");
break;

case Query.ORDER_ASCENDING:
orderBuilder.append(" ASC");
break;
}
break;
}
}
}
}
}

if (orderBuilder.length() > 0) {
out.println("ORDER BY " + orderBuilder.toString());
}
}


protected void genLimitOffset(SqlSelectBlock sqlSelectBlock)
{
if ( sqlSelectBlock.getLength() >= 0 )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.util.Collection;
import java.util.List;

import org.apache.jena.query.SortCondition;
import org.apache.jena.sdb.core.* ;
import org.apache.jena.sdb.core.sqlexpr.SqlColumn ;
import org.apache.jena.sdb.core.sqlexpr.SqlExpr ;
Expand Down Expand Up @@ -62,7 +63,8 @@ public class SqlSelectBlock extends SqlNodeBase1
private SqlTable vTable ; // Naming base for renamed columns
private Scope idScope = null ; // Scopes are as the wrapped SqlNode unless explicitly changed.
private Scope nodeScope = null ;


private List<SortCondition> sortConditions = null;

static public SqlNode distinct(SDBRequest request, SqlNode sqlNode)
{
Expand Down Expand Up @@ -223,6 +225,9 @@ public boolean getDistinct()
return distinct ;
}

public List<SortCondition> getSortConditions() { return this.sortConditions; }
public void setSortConditions(List<SortCondition> sortConditions) { this.sortConditions = sortConditions; }

private void setDistinct(boolean isDistinct)
{
this.distinct = isDistinct ;
Expand Down

0 comments on commit dc3e823

Please sign in to comment.