Skip to content

Commit

Permalink
MONDRIAN: Reinstate support for "ORDER BY ... NULLS LAST" per MONDRIA…
Browse files Browse the repository at this point in the history
…N-618.

    This implementation is more conservative; it assumes that a database does
    not support the syntax unless JdbcDialectImpl.supportsOrderByNullsLast()
    is overridden.

[git-p4: depot-paths = "//open/mondrian-release/3.1/": change = 13068]
  • Loading branch information
julianhyde committed Sep 29, 2009
1 parent 385ce83 commit 1b5fb05
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 18 deletions.
4 changes: 4 additions & 0 deletions src/main/mondrian/spi/impl/FirebirdDialect.java
Expand Up @@ -37,6 +37,10 @@ public FirebirdDialect(Connection connection) throws SQLException {
public boolean allowsAs() {
return false;
}

public boolean supportsOrderByNullsLast() {
return true;
}
}

// End FirebirdDialect.java
78 changes: 60 additions & 18 deletions src/main/mondrian/spi/impl/JdbcDialectImpl.java
Expand Up @@ -9,7 +9,6 @@
package mondrian.spi.impl;

import mondrian.olap.Util;
import mondrian.olap.MondrianDef;
import mondrian.spi.*;

import java.util.*;
Expand Down Expand Up @@ -704,13 +703,55 @@ public String generateOrderItem(
boolean nullable,
boolean ascending)
{
if (ascending) {
return expr + " ASC";
if (nullable) {
NullCollation collateLast = getNullCollation();
switch (collateLast) {
case NEGINF:
// For DESC, NULLs already appear last.
// For ASC, we need to reverse the order.
// Use the SQL standard syntax 'ORDER BY x ASC NULLS LAST'.
if (ascending) {
return expr + " ASC"
+ (supportsOrderByNullsLast() ? " NULLS LAST" : "");
} else {
return expr + " DESC";
}
case POSINF:
if (ascending) {
return expr + " ASC";
} else {
return expr + " DESC"
+ (supportsOrderByNullsLast() ? " NULLS LAST" : "");
}
default:
throw Util.unexpected(collateLast);
}
} else {
return expr + " DESC";
if (ascending) {
return expr + " ASC";
} else {
return expr + " DESC";
}
}
}

/**
* Returns whether this dialect supports "ASC NULLS LAST" and "DESC NULLS
* LAST" applied to an item in the ORDER BY clause.
*
* <p>This feature is in standard SQL but is not supported by many
* databases, therefore the default implementation returns {@code false}.
*
* <p>This method is only called from
* {@link #generateOrderItem(String, boolean, boolean)}. Some dialects
* override that method and therefore never call this method.
*
* @return Whether this dialect supports "ORDER BY ... NULLS LAST".
*/
public boolean supportsOrderByNullsLast() {
return false;
}

public boolean supportsGroupByExpressions() {
return true;
}
Expand Down Expand Up @@ -779,11 +820,12 @@ public static DatabaseProduct getProduct(
String productName,
String productVersion)
{
final String upperProductName = productName.toUpperCase();
if (productName.equals("ACCESS")) {
return DatabaseProduct.ACCESS;
} else if (productName.trim().toUpperCase().equals("APACHE DERBY")) {
} else if (upperProductName.trim().equals("APACHE DERBY")) {
return DatabaseProduct.DERBY;
} else if (productName.trim().toUpperCase().equals("DBMS:CLOUDSCAPE")) {
} else if (upperProductName.trim().equals("DBMS:CLOUDSCAPE")) {
return DatabaseProduct.DERBY;
} else if (productName.startsWith("DB2")) {
if (productName.startsWith("DB2 UDB for AS/400")) {
Expand All @@ -808,37 +850,37 @@ public static DatabaseProduct getProduct(
// DB2 on NT returns "DB2/NT"
return DatabaseProduct.DB2;
}
} else if (productName.toUpperCase().indexOf("FIREBIRD") >= 0) {
} else if (upperProductName.indexOf("FIREBIRD") >= 0) {
return DatabaseProduct.FIREBIRD;
} else if (productName.startsWith("Informix")) {
return DatabaseProduct.INFORMIX;
} else if (productName.toUpperCase().equals("INGRES")) {
} else if (upperProductName.equals("INGRES")) {
return DatabaseProduct.INGRES;
} else if (productName.equals("Interbase")) {
return DatabaseProduct.INTERBASE;
} else if (productName.toUpperCase().equals("LUCIDDB")) {
} else if (upperProductName.equals("LUCIDDB")) {
return DatabaseProduct.LUCIDDB;
} else if (productName.toUpperCase().indexOf("SQL SERVER") >= 0) {
} else if (upperProductName.indexOf("SQL SERVER") >= 0) {
return DatabaseProduct.MSSQL;
} else if (productName.equals("Oracle")) {
return DatabaseProduct.ORACLE;
} else if (productName.toUpperCase().indexOf("POSTGRE") >= 0) {
} else if (upperProductName.indexOf("POSTGRE") >= 0) {
return DatabaseProduct.POSTGRESQL;
} else if (productName.toUpperCase().indexOf("NETEZZA") >= 0) {
} else if (upperProductName.indexOf("NETEZZA") >= 0) {
return DatabaseProduct.NETEZZA;
} else if (productName.toUpperCase().equals("MYSQL (INFOBRIGHT)")) {
} else if (upperProductName.equals("MYSQL (INFOBRIGHT)")) {
return DatabaseProduct.INFOBRIGHT;
} else if (productName.toUpperCase().equals("MYSQL")) {
} else if (upperProductName.equals("MYSQL")) {
return DatabaseProduct.MYSQL;
} else if (productName.startsWith("HP Neoview")) {
return DatabaseProduct.NEOVIEW;
} else if (productName.toUpperCase().indexOf("SYBASE") >= 0) {
} else if (upperProductName.indexOf("SYBASE") >= 0) {
return DatabaseProduct.SYBASE;
} else if (productName.toUpperCase().indexOf("TERADATA") >= 0) {
} else if (upperProductName.indexOf("TERADATA") >= 0) {
return DatabaseProduct.TERADATA;
} else if (productName.toUpperCase().indexOf("HSQL") >= 0) {
} else if (upperProductName.indexOf("HSQL") >= 0) {
return DatabaseProduct.HSQLDB;
} else if (productName.toUpperCase().indexOf("VERTICA") >= 0) {
} else if (upperProductName.indexOf("VERTICA") >= 0) {
return DatabaseProduct.VERTICA;
} else {
return DatabaseProduct.UNKNOWN;
Expand Down
4 changes: 4 additions & 0 deletions src/main/mondrian/spi/impl/OracleDialect.java
Expand Up @@ -52,6 +52,10 @@ public String generateInline(
public boolean supportsGroupingSets() {
return true;
}

public boolean supportsOrderByNullsLast() {
return true;
}
}

// End OracleDialect.java
5 changes: 5 additions & 0 deletions src/main/mondrian/spi/impl/PostgreSqlDialect.java
Expand Up @@ -37,6 +37,11 @@ public PostgreSqlDialect(Connection connection) throws SQLException {
public boolean requiresAliasForFromQuery() {
return true;
}

public boolean supportsOrderByNullsLast() {
// Support for "ORDER BY ... NULLS LAST" was introduced in Postgres 8.3.
return productVersion.compareTo("8.3") >= 0;
}
}

// End PostgreSqlDialect.java

0 comments on commit 1b5fb05

Please sign in to comment.