diff --git a/src/main/java/com/samskivert/depot/clause/OrderBy.java b/src/main/java/com/samskivert/depot/clause/OrderBy.java index 56cc765..5932505 100644 --- a/src/main/java/com/samskivert/depot/clause/OrderBy.java +++ b/src/main/java/com/samskivert/depot/clause/OrderBy.java @@ -20,6 +20,10 @@ public class OrderBy implements QueryClause /** Indicates the order of the clause. */ 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). */ ASC, diff --git a/src/main/java/com/samskivert/depot/impl/BuildVisitor.java b/src/main/java/com/samskivert/depot/impl/BuildVisitor.java index fc0e495..1923d8f 100644 --- a/src/main/java/com/samskivert/depot/impl/BuildVisitor.java +++ b/src/main/java/com/samskivert/depot/impl/BuildVisitor.java @@ -84,6 +84,7 @@ import com.samskivert.depot.impl.operator.MultiOperator; import com.samskivert.depot.impl.operator.Not; import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; import static com.samskivert.Log.log; /** @@ -979,17 +980,27 @@ public abstract class BuildVisitor implements FragmentVisitor */ protected OrderBy.Order validateOrder (OrderBy.Order order) { - if ((order == OrderBy.Order.ASC_NULLS_FIRST) || (order == OrderBy.Order.DESC_NULLS_LAST)) { - if (false /*Boolean.getBoolean("com.samskivert.depot.massageOrderByNulls")*/) { - order = (order == OrderBy.Order.ASC_NULLS_FIRST) - ? OrderBy.Order.ASC : OrderBy.Order.DESC; - } else { - throw new RuntimeException(order + " is not supported on your database."); - } + checkNotNull(order); + if (orderSupported(order)) { + return order; } - 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) { _types = types; diff --git a/src/main/java/com/samskivert/depot/impl/HSQLBuilder.java b/src/main/java/com/samskivert/depot/impl/HSQLBuilder.java index c397453..05fba87 100644 --- a/src/main/java/com/samskivert/depot/impl/HSQLBuilder.java +++ b/src/main/java/com/samskivert/depot/impl/HSQLBuilder.java @@ -18,6 +18,7 @@ import com.samskivert.depot.Ops; import com.samskivert.depot.PersistentRecord; import com.samskivert.depot.annotation.FullTextIndex; import com.samskivert.depot.annotation.GeneratedValue; +import com.samskivert.depot.clause.OrderBy; import com.samskivert.depot.expression.ColumnExp; import com.samskivert.depot.expression.SQLExpression; import com.samskivert.depot.impl.expression.AggregateFun; @@ -183,6 +184,15 @@ public class HSQLBuilder @Override protected void appendIdentifier (String field) { _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) diff --git a/src/main/java/com/samskivert/depot/impl/MySQLBuilder.java b/src/main/java/com/samskivert/depot/impl/MySQLBuilder.java index 7d7f6f9..707a7f5 100644 --- a/src/main/java/com/samskivert/depot/impl/MySQLBuilder.java +++ b/src/main/java/com/samskivert/depot/impl/MySQLBuilder.java @@ -14,6 +14,7 @@ import com.samskivert.util.StringUtil; import com.samskivert.depot.PersistentRecord; import com.samskivert.depot.annotation.FullTextIndex; +import com.samskivert.depot.clause.OrderBy; import com.samskivert.depot.expression.ColumnExp; import com.samskivert.depot.operator.FullText; @@ -162,6 +163,15 @@ public class MySQLBuilder { _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) diff --git a/src/main/java/com/samskivert/depot/impl/PostgreSQLBuilder.java b/src/main/java/com/samskivert/depot/impl/PostgreSQLBuilder.java index f287840..4edd388 100644 --- a/src/main/java/com/samskivert/depot/impl/PostgreSQLBuilder.java +++ b/src/main/java/com/samskivert/depot/impl/PostgreSQLBuilder.java @@ -119,8 +119,13 @@ public class PostgreSQLBuilder _builder.append("\"").append(field).append("\""); } - @Override protected OrderBy.Order validateOrder (OrderBy.Order order) { - return order; + @Override protected boolean orderSupported (OrderBy.Order 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)