Added OrderBy.Order.NULL.
"order by null" can be used in a query with a "group by" in it to tell the database to suppress the overhead of sorting the results. (Supported in postgres and mysql.) Changed the build visitors to have a whitelist of supported Orders, and to NPE on a null value for the Order enum. Note that previously "order by null" could be accomplished by passing a null value to your OrderBy, but now the enum constant must be used. I can change that if this disrupts anything.
This commit is contained in:
@@ -20,6 +20,10 @@ public class OrderBy implements QueryClause
|
|||||||
/** Indicates the order of the clause. */
|
/** Indicates the order of the clause. */
|
||||||
public enum Order
|
public enum Order
|
||||||
{
|
{
|
||||||
|
/** Ordering by null can be used to suppress sorting in the database when using
|
||||||
|
* a GROUP BY in your query (postgres and mysql only). */
|
||||||
|
NULL,
|
||||||
|
|
||||||
/** Ascending (nulls last). */
|
/** Ascending (nulls last). */
|
||||||
ASC,
|
ASC,
|
||||||
|
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ import com.samskivert.depot.impl.operator.MultiOperator;
|
|||||||
import com.samskivert.depot.impl.operator.Not;
|
import com.samskivert.depot.impl.operator.Not;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static com.samskivert.Log.log;
|
import static com.samskivert.Log.log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -979,17 +980,27 @@ public abstract class BuildVisitor implements FragmentVisitor<Void>
|
|||||||
*/
|
*/
|
||||||
protected OrderBy.Order validateOrder (OrderBy.Order order)
|
protected OrderBy.Order validateOrder (OrderBy.Order order)
|
||||||
{
|
{
|
||||||
if ((order == OrderBy.Order.ASC_NULLS_FIRST) || (order == OrderBy.Order.DESC_NULLS_LAST)) {
|
checkNotNull(order);
|
||||||
if (false /*Boolean.getBoolean("com.samskivert.depot.massageOrderByNulls")*/) {
|
if (orderSupported(order)) {
|
||||||
order = (order == OrderBy.Order.ASC_NULLS_FIRST)
|
return order;
|
||||||
? OrderBy.Order.ASC : OrderBy.Order.DESC;
|
|
||||||
} else {
|
|
||||||
throw new RuntimeException(order + " is not supported on your database.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return order;
|
// Note: the following code was never "live". If needed it can be made so.
|
||||||
|
// The property name is up for debate.
|
||||||
|
// if (Boolean.getBoolean("com.samskivert.depot.massageNullOrders")) {
|
||||||
|
// switch (order) {
|
||||||
|
// case ASC_NULLS_FIRST: return OrderBy.Order.ASC;
|
||||||
|
// case DESC_NULLS_LAST: return OrderBy.Order.DESC;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Order '" + order.name() + "' is not supported by your database.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the specified order supported by this database?
|
||||||
|
*/
|
||||||
|
protected abstract boolean orderSupported (OrderBy.Order order);
|
||||||
|
|
||||||
protected BuildVisitor (DepotTypes types, boolean allowComplexIndices)
|
protected BuildVisitor (DepotTypes types, boolean allowComplexIndices)
|
||||||
{
|
{
|
||||||
_types = types;
|
_types = types;
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import com.samskivert.depot.Ops;
|
|||||||
import com.samskivert.depot.PersistentRecord;
|
import com.samskivert.depot.PersistentRecord;
|
||||||
import com.samskivert.depot.annotation.FullTextIndex;
|
import com.samskivert.depot.annotation.FullTextIndex;
|
||||||
import com.samskivert.depot.annotation.GeneratedValue;
|
import com.samskivert.depot.annotation.GeneratedValue;
|
||||||
|
import com.samskivert.depot.clause.OrderBy;
|
||||||
import com.samskivert.depot.expression.ColumnExp;
|
import com.samskivert.depot.expression.ColumnExp;
|
||||||
import com.samskivert.depot.expression.SQLExpression;
|
import com.samskivert.depot.expression.SQLExpression;
|
||||||
import com.samskivert.depot.impl.expression.AggregateFun;
|
import com.samskivert.depot.impl.expression.AggregateFun;
|
||||||
@@ -183,6 +184,15 @@ public class HSQLBuilder
|
|||||||
@Override protected void appendIdentifier (String field) {
|
@Override protected void appendIdentifier (String field) {
|
||||||
_builder.append("\"").append(field).append("\"");
|
_builder.append("\"").append(field).append("\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override protected boolean orderSupported (OrderBy.Order order)
|
||||||
|
{
|
||||||
|
switch (order) {
|
||||||
|
case ASC: case DESC:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public HSQLBuilder (DepotTypes types)
|
public HSQLBuilder (DepotTypes types)
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import com.samskivert.util.StringUtil;
|
|||||||
|
|
||||||
import com.samskivert.depot.PersistentRecord;
|
import com.samskivert.depot.PersistentRecord;
|
||||||
import com.samskivert.depot.annotation.FullTextIndex;
|
import com.samskivert.depot.annotation.FullTextIndex;
|
||||||
|
import com.samskivert.depot.clause.OrderBy;
|
||||||
import com.samskivert.depot.expression.ColumnExp;
|
import com.samskivert.depot.expression.ColumnExp;
|
||||||
import com.samskivert.depot.operator.FullText;
|
import com.samskivert.depot.operator.FullText;
|
||||||
|
|
||||||
@@ -162,6 +163,15 @@ public class MySQLBuilder
|
|||||||
{
|
{
|
||||||
_builder.append("() values ()");
|
_builder.append("() values ()");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override protected boolean orderSupported (OrderBy.Order order)
|
||||||
|
{
|
||||||
|
switch (order) {
|
||||||
|
case NULL: case ASC: case DESC:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static String massageFTQuery (FullText fullText)
|
protected static String massageFTQuery (FullText fullText)
|
||||||
|
|||||||
@@ -119,8 +119,13 @@ public class PostgreSQLBuilder
|
|||||||
_builder.append("\"").append(field).append("\"");
|
_builder.append("\"").append(field).append("\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override protected OrderBy.Order validateOrder (OrderBy.Order order) {
|
@Override protected boolean orderSupported (OrderBy.Order order)
|
||||||
return order;
|
{
|
||||||
|
switch (order) {
|
||||||
|
case NULL: case ASC: case DESC: case ASC_NULLS_FIRST: case DESC_NULLS_LAST:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected PGBuildVisitor (DepotTypes types)
|
protected PGBuildVisitor (DepotTypes types)
|
||||||
|
|||||||
Reference in New Issue
Block a user