mondrian.spi.impl
Class JdbcDialectImpl

java.lang.Object
  extended by mondrian.spi.impl.JdbcDialectImpl
All Implemented Interfaces:
Dialect
Direct Known Subclasses:
AccessDialect, Db2Dialect, DerbyDialect, FirebirdDialect, HsqldbDialect, InformixDialect, IngresDialect, InterbaseDialect, LucidDbDialect, MicrosoftSqlServerDialect, MySqlDialect, OracleDialect, PostgreSqlDialect, SybaseDialect, TeradataDialect, VerticaDialect

public class JdbcDialectImpl
extends java.lang.Object
implements Dialect

Implementation of Dialect based on a JDBC connection and metadata.

If you are writing a class for a specific database dialect, we recommend that you use this as a base class, so your dialect class will be forwards-compatible. If methods are added to Dialect in future revisions, default implementations of those methods will be added to this class.

Mondrian uses JdbcDialectImpl as a fallback if it cannot find a more specific dialect. JdbcDialectImpl reads properties from the JDBC driver's metadata, so can deduce some of the dialect's behavior.

Since:
Oct 10, 2008
Version:
$Id: //open/mondrian/src/main/mondrian/spi/impl/JdbcDialectImpl.java#23 $
Author:
jhyde

Nested Class Summary
 
Nested classes/interfaces inherited from interface mondrian.spi.Dialect
Dialect.DatabaseProduct, Dialect.Datatype, Dialect.NullCollation
 
Field Summary
protected  Dialect.DatabaseProduct databaseProduct
          Major database product (or null if product is not a common one)
protected  boolean permitsSelectNotInGroupBy
          Indicates whether the database allows selection of columns not listed in the group by clause.
protected  java.lang.String productVersion
          Product version per JDBC driver.
 
Constructor Summary
JdbcDialectImpl(java.sql.Connection connection)
          Creates a JdbcDialectImpl.
 
Method Summary
 boolean allowsAs()
          Returns whether the SQL dialect allows "AS" in the FROM clause.
 boolean allowsCompoundCountDistinct()
          Returns whether this Dialect allows multiple arguments to the COUNT(DISTINCT ...) aggregate function, for example SELECT COUNT(DISTINCT x, y) FROM t
 boolean allowsCountDistinct()
          Returns whether this Dialect supports distinct aggregations.
 boolean allowsDdl()
          Returns whether this dialect supports common SQL Data Definition Language (DDL) statements such as CREATE TABLE and DROP INDEX.
 boolean allowsDialectSharing()
          Returns whether this Dialect object can be used for all connections from the same data source.
 boolean allowsFromQuery()
          Returns whether this Dialect allows a subquery in the from clause, for example SELECT * FROM (SELECT * FROM t) AS x
 boolean allowsMultipleCountDistinct()
          Returns whether this Dialect supports more than one distinct aggregation in the same query.
 boolean allowsMultipleDistinctSqlMeasures()
          Returns whether this Dialect has performant support of distinct SQL measures in the same query.
 boolean allowsOrderByAlias()
          Returns true if aliases defined in the SELECT clause can be used as expressions in the ORDER BY clause.
 boolean allowsSelectNotInGroupBy()
          Returns whether the database currently permits queries to include in the SELECT clause expressions that are not listed in the GROUP BY clause.
 void appendHintsAfterFromClause(java.lang.StringBuilder buf, java.util.Map<java.lang.String,java.lang.String> hints)
          Assembles and returns a string containing any hints that should be appended after the FROM clause in a SELECT statement, based on any hints provided.
 java.lang.String caseWhenElse(java.lang.String cond, java.lang.String thenExpr, java.lang.String elseExpr)
          Generates a conditional statement in this dialect's syntax.
protected  java.lang.String deduceIdentifierQuoteString(java.sql.DatabaseMetaData databaseMetaData)
           
protected  int deduceMaxColumnNameLength(java.sql.DatabaseMetaData databaseMetaData)
           
protected  java.lang.String deduceProductName(java.sql.DatabaseMetaData databaseMetaData)
           
protected  java.lang.String deduceProductVersion(java.sql.DatabaseMetaData databaseMetaData)
           
protected  boolean deduceReadOnly(java.sql.DatabaseMetaData databaseMetaData)
           
protected  java.util.Set<java.util.List<java.lang.Integer>> deduceSupportedResultSetStyles(java.sql.DatabaseMetaData databaseMetaData)
           
protected  boolean deduceSupportsSelectNotInGroupBy(java.sql.Connection conn)
          Detects whether the database is configured to permit queries that include columns in the SELECT that are not also in the GROUP BY.
 java.lang.String generateInline(java.util.List<java.lang.String> columnNames, java.util.List<java.lang.String> columnTypes, java.util.List<java.lang.String[]> valueList)
          Generates a SQL statement to represent an inline dataset.
 java.lang.String generateInlineForAnsi(java.lang.String alias, java.util.List<java.lang.String> columnNames, java.util.List<java.lang.String> columnTypes, java.util.List<java.lang.String[]> valueList, boolean cast)
          Generates inline values list using ANSI 'VALUES' syntax.
protected  java.lang.String generateInlineGeneric(java.util.List<java.lang.String> columnNames, java.util.List<java.lang.String> columnTypes, java.util.List<java.lang.String[]> valueList, java.lang.String fromClause, boolean cast)
          Generic algorithm to generate inline values list, using an optional FROM clause, specified by the caller of this method, appropriate to the dialect of SQL.
 java.lang.String generateOrderItem(java.lang.String expr, boolean nullable, boolean ascending)
          Generates an item for an ORDER BY clause, sorting in the required direction, and ensuring that NULL values collate after all non-NULL values.
 Dialect.DatabaseProduct getDatabaseProduct()
          Returns the database for this Dialect, or Dialect.DatabaseProduct.UNKNOWN if the database is not a common database.
 int getMaxColumnNameLength()
          Returns the maximum length of the name of a database column or query alias allowed by this dialect.
 Dialect.NullCollation getNullCollation()
          Returns the rule which determines whether NULL values appear first or last when sorted using ORDER BY.
static Dialect.DatabaseProduct getProduct(java.lang.String productName, java.lang.String productVersion)
          Converts a product name and version (per the JDBC driver) into a product enumeration.
 java.lang.String getQuoteIdentifierString()
          Returns the character which is used to quote identifiers, or null if quoting is not supported.
 boolean needsExponent(java.lang.Object value, java.lang.String valueString)
          If Double values need to include additional exponent in its string represenation.
 void quote(java.lang.StringBuilder buf, java.lang.Object value, Dialect.Datatype datatype)
          Appends to a buffer a value quoted for its type.
 void quoteBooleanLiteral(java.lang.StringBuilder buf, java.lang.String value)
          Appends to a buffer a boolean literal.
 void quoteDateLiteral(java.lang.StringBuilder buf, java.lang.String value)
          Appends to a buffer a date literal.
protected  void quoteDateLiteral(java.lang.StringBuilder buf, java.lang.String value, java.sql.Date date)
          Helper method for quoteDateLiteral(StringBuilder, String).
 java.lang.String quoteIdentifier(java.lang.String val)
          Encloses an identifier in quotation marks appropriate for this Dialect.
 void quoteIdentifier(java.lang.StringBuilder buf, java.lang.String... names)
          Appends to a buffer a list of identifiers, quoted appropriately for this Dialect.
 java.lang.String quoteIdentifier(java.lang.String qual, java.lang.String name)
          Encloses an identifier in quotation marks appropriate for the current SQL dialect.
 void quoteIdentifier(java.lang.String val, java.lang.StringBuilder buf)
          Appends to a buffer an identifier, quoted appropriately for this Dialect.
 void quoteNumericLiteral(java.lang.StringBuilder buf, java.lang.String value)
          Appends to a buffer a numeric literal.
 void quoteStringLiteral(java.lang.StringBuilder buf, java.lang.String s)
          Appends to a buffer a single-quoted SQL string.
 void quoteTimeLiteral(java.lang.StringBuilder buf, java.lang.String value)
          Appends to a buffer a time literal.
 void quoteTimestampLiteral(java.lang.StringBuilder buf, java.lang.String value)
          Appends to a buffer a timestamp literal.
 boolean requiresAliasForFromQuery()
          Returns whether this Dialect requires subqueries in the FROM clause to have an alias.
 boolean requiresGroupByAlias()
          Returns true if this Dialect can include expressions in the GROUP BY clause only by adding an expression to the SELECT clause and using its alias.
 boolean requiresOrderByAlias()
          Returns true if this Dialect can include expressions in the ORDER BY clause only by adding an expression to the SELECT clause and using its alias.
 boolean requiresUnionOrderByExprToBeInSelectClause()
          Returns true if this dialect allows an expression in the ORDER BY clause of a UNION (or other set operation) query only if it occurs in the SELECT clause.
 boolean requiresUnionOrderByOrdinal()
          Returns true if this dialect allows only integers in the ORDER BY clause of a UNION (or other set operation) query.
 boolean supportsGroupByExpressions()
          Returns whether this Dialect supports expressions in the GROUP BY clause.
 boolean supportsGroupingSets()
          Returns whether this Dialect allows the GROUPING SETS construct in the GROUP BY clause.
 boolean supportsMultiValueInExpr()
          Returns true if this dialect supports multi-value IN expressions.
 boolean supportsOrderByNullsLast()
          Returns whether this dialect supports "ASC NULLS LAST" and "DESC NULLS LAST" applied to an item in the ORDER BY clause.
 boolean supportsResultSetConcurrency(int type, int concurrency)
          Returns whether this Dialect supports the given concurrency type in combination with the given result set type.
 boolean supportsUnlimitedValueList()
          Returns whether this Dialect places no limit on the number of rows which can appear as elements of an IN or VALUES expression.
 java.lang.String toString()
           
 java.lang.String toUpper(java.lang.String expr)
          Converts an expression to upper case.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

productVersion

protected final java.lang.String productVersion
Product version per JDBC driver.


permitsSelectNotInGroupBy

protected boolean permitsSelectNotInGroupBy
Indicates whether the database allows selection of columns not listed in the group by clause.


databaseProduct

protected final Dialect.DatabaseProduct databaseProduct
Major database product (or null if product is not a common one)

Constructor Detail

JdbcDialectImpl

public JdbcDialectImpl(java.sql.Connection connection)
                throws java.sql.SQLException
Creates a JdbcDialectImpl.

To prevent connection leaks, this constructor does not hold a reference to the connection after the call returns. It makes a copy of everything useful during the call. Derived classes must do the same.

Parameters:
connection - Connection
Throws:
java.sql.SQLException
Method Detail

getDatabaseProduct

public Dialect.DatabaseProduct getDatabaseProduct()
Description copied from interface: Dialect
Returns the database for this Dialect, or Dialect.DatabaseProduct.UNKNOWN if the database is not a common database.

Specified by:
getDatabaseProduct in interface Dialect
Returns:
Database

appendHintsAfterFromClause

public void appendHintsAfterFromClause(java.lang.StringBuilder buf,
                                       java.util.Map<java.lang.String,java.lang.String> hints)
Description copied from interface: Dialect
Assembles and returns a string containing any hints that should be appended after the FROM clause in a SELECT statement, based on any hints provided. Any unrecognized or unsupported hints will be ignored.

Specified by:
appendHintsAfterFromClause in interface Dialect
Parameters:
buf - The Stringbuffer to which the dialect-specific syntax for any relevant table hints may be appended. Must not be null.
hints - A map of table hints provided in the schema definition

allowsDialectSharing

public boolean allowsDialectSharing()
Description copied from interface: Dialect
Returns whether this Dialect object can be used for all connections from the same data source.

The default implementation returns true, and this allows dialects to be cached and reused in environments where connections are allocated from a pool based on the same data source.

Data sources are deemed 'equal' by the same criteria used by Java collections, namely the Object.equals(Object) and Object.hashCode() methods.

Specified by:
allowsDialectSharing in interface Dialect
Returns:
Whether this dialect can be used for other connections created from the same data source
See Also:
DialectFactory.createDialect(javax.sql.DataSource, java.sql.Connection)

deduceMaxColumnNameLength

protected int deduceMaxColumnNameLength(java.sql.DatabaseMetaData databaseMetaData)

deduceReadOnly

protected boolean deduceReadOnly(java.sql.DatabaseMetaData databaseMetaData)

deduceProductName

protected java.lang.String deduceProductName(java.sql.DatabaseMetaData databaseMetaData)

deduceIdentifierQuoteString

protected java.lang.String deduceIdentifierQuoteString(java.sql.DatabaseMetaData databaseMetaData)

deduceProductVersion

protected java.lang.String deduceProductVersion(java.sql.DatabaseMetaData databaseMetaData)

deduceSupportedResultSetStyles

protected java.util.Set<java.util.List<java.lang.Integer>> deduceSupportedResultSetStyles(java.sql.DatabaseMetaData databaseMetaData)

deduceSupportsSelectNotInGroupBy

protected boolean deduceSupportsSelectNotInGroupBy(java.sql.Connection conn)
                                            throws java.sql.SQLException

Detects whether the database is configured to permit queries that include columns in the SELECT that are not also in the GROUP BY. MySQL is an example of one that does, though this is configurable.

The expectation is that this will not change while Mondrian is running, though some databases (MySQL) allow changing it on the fly.

Parameters:
conn - The database connection
Returns:
Whether the feature is enabled.
Throws:
java.sql.SQLException

toUpper

public java.lang.String toUpper(java.lang.String expr)
Description copied from interface: Dialect
Converts an expression to upper case.

For example, for MySQL, toUpper("foo.bar") returns "UPPER(foo.bar)".

Specified by:
toUpper in interface Dialect
Parameters:
expr - SQL expression
Returns:
SQL syntax that converts expr into upper case.

caseWhenElse

public java.lang.String caseWhenElse(java.lang.String cond,
                                     java.lang.String thenExpr,
                                     java.lang.String elseExpr)
Description copied from interface: Dialect
Generates a conditional statement in this dialect's syntax.

For example, caseWhenElse("b", "1", "0") returns "case when b then 1 else 0 end" on Oracle, "Iif(b, 1, 0)" on Access.

Specified by:
caseWhenElse in interface Dialect
Parameters:
cond - Predicate expression
thenExpr - Expression if condition is true
elseExpr - Expression if condition is false
Returns:
Conditional expression

quoteIdentifier

public java.lang.String quoteIdentifier(java.lang.String val)
Description copied from interface: Dialect
Encloses an identifier in quotation marks appropriate for this Dialect.

For example, quoteIdentifier("emp") yields a string containing "emp" in Oracle, and a string containing [emp] in Access.

Specified by:
quoteIdentifier in interface Dialect
Parameters:
val - Identifier
Returns:
Quoted identifier

quoteIdentifier

public void quoteIdentifier(java.lang.String val,
                            java.lang.StringBuilder buf)
Description copied from interface: Dialect
Appends to a buffer an identifier, quoted appropriately for this Dialect.

Specified by:
quoteIdentifier in interface Dialect
Parameters:
val - identifier to quote (must not be null).
buf - Buffer

quoteIdentifier

public java.lang.String quoteIdentifier(java.lang.String qual,
                                        java.lang.String name)
Description copied from interface: Dialect
Encloses an identifier in quotation marks appropriate for the current SQL dialect. For example, in Oracle, where the identifiers are quoted using double-quotes, quoteIdentifier("schema","table") yields a string containing "schema"."table".

Specified by:
quoteIdentifier in interface Dialect
Parameters:
qual - Qualifier. If it is not null, "qual". is prepended.
name - Name to be quoted.
Returns:
Quoted identifier

quoteIdentifier

public void quoteIdentifier(java.lang.StringBuilder buf,
                            java.lang.String... names)
Description copied from interface: Dialect
Appends to a buffer a list of identifiers, quoted appropriately for this Dialect.

Names in the list may be null, but there must be at least one non-null name in the list.

Specified by:
quoteIdentifier in interface Dialect
Parameters:
buf - Buffer
names - List of names to be quoted

getQuoteIdentifierString

public java.lang.String getQuoteIdentifierString()
Description copied from interface: Dialect
Returns the character which is used to quote identifiers, or null if quoting is not supported.

Specified by:
getQuoteIdentifierString in interface Dialect
Returns:
identifier quote

quoteStringLiteral

public void quoteStringLiteral(java.lang.StringBuilder buf,
                               java.lang.String s)
Description copied from interface: Dialect
Appends to a buffer a single-quoted SQL string.

For example, in the default dialect, quoteStringLiteral(buf, "Can't") appends "'Can''t'" to buf.

Specified by:
quoteStringLiteral in interface Dialect
Parameters:
buf - Buffer to append to
s - Literal

quoteNumericLiteral

public void quoteNumericLiteral(java.lang.StringBuilder buf,
                                java.lang.String value)
Description copied from interface: Dialect
Appends to a buffer a numeric literal.

In the default dialect, numeric literals are printed as is.

Specified by:
quoteNumericLiteral in interface Dialect
Parameters:
buf - Buffer to append to
value - Literal

quoteBooleanLiteral

public void quoteBooleanLiteral(java.lang.StringBuilder buf,
                                java.lang.String value)
Description copied from interface: Dialect
Appends to a buffer a boolean literal.

In the default dialect, boolean literals are printed as is.

Specified by:
quoteBooleanLiteral in interface Dialect
Parameters:
buf - Buffer to append to
value - Literal

quoteDateLiteral

public void quoteDateLiteral(java.lang.StringBuilder buf,
                             java.lang.String value)
Description copied from interface: Dialect
Appends to a buffer a date literal.

For example, in the default dialect, quoteStringLiteral(buf, "1969-03-17") appends DATE '1969-03-17'.

Specified by:
quoteDateLiteral in interface Dialect
Parameters:
buf - Buffer to append to
value - Literal

quoteDateLiteral

protected void quoteDateLiteral(java.lang.StringBuilder buf,
                                java.lang.String value,
                                java.sql.Date date)
Helper method for quoteDateLiteral(StringBuilder, String).

Parameters:
buf - Buffer to append to
value - Value as string
date - Value as date

quoteTimeLiteral

public void quoteTimeLiteral(java.lang.StringBuilder buf,
                             java.lang.String value)
Description copied from interface: Dialect
Appends to a buffer a time literal.

For example, in the default dialect, quoteStringLiteral(buf, "12:34:56") appends TIME '12:34:56'.

Specified by:
quoteTimeLiteral in interface Dialect
Parameters:
buf - Buffer to append to
value - Literal

quoteTimestampLiteral

public void quoteTimestampLiteral(java.lang.StringBuilder buf,
                                  java.lang.String value)
Description copied from interface: Dialect
Appends to a buffer a timestamp literal.

For example, in the default dialect, quoteStringLiteral(buf, "1969-03-17 12:34:56") appends TIMESTAMP '1969-03-17 12:34:56'.

Specified by:
quoteTimestampLiteral in interface Dialect
Parameters:
buf - Buffer to append to
value - Literal

requiresAliasForFromQuery

public boolean requiresAliasForFromQuery()
Description copied from interface: Dialect
Returns whether this Dialect requires subqueries in the FROM clause to have an alias.

Specified by:
requiresAliasForFromQuery in interface Dialect
Returns:
whether dialewct requires subqueries to have an alias
See Also:
Dialect.allowsFromQuery()

allowsAs

public boolean allowsAs()
Description copied from interface: Dialect
Returns whether the SQL dialect allows "AS" in the FROM clause. If so, "SELECT * FROM t AS alias" is a valid query.

Specified by:
allowsAs in interface Dialect
Returns:
whether dialect allows AS in FROM clause

allowsFromQuery

public boolean allowsFromQuery()
Description copied from interface: Dialect
Returns whether this Dialect allows a subquery in the from clause, for example
SELECT * FROM (SELECT * FROM t) AS x

Specified by:
allowsFromQuery in interface Dialect
Returns:
whether Dialect allows subquery in FROM clause
See Also:
Dialect.requiresAliasForFromQuery()

allowsCompoundCountDistinct

public boolean allowsCompoundCountDistinct()
Description copied from interface: Dialect
Returns whether this Dialect allows multiple arguments to the COUNT(DISTINCT ...) aggregate function, for example
SELECT COUNT(DISTINCT x, y) FROM t

Specified by:
allowsCompoundCountDistinct in interface Dialect
Returns:
whether Dialect allows multiple arguments to COUNT DISTINCT
See Also:
Dialect.allowsCountDistinct(), Dialect.allowsMultipleCountDistinct()

allowsCountDistinct

public boolean allowsCountDistinct()
Description copied from interface: Dialect
Returns whether this Dialect supports distinct aggregations.

For example, Access does not allow

select count(distinct x) from t

Specified by:
allowsCountDistinct in interface Dialect
Returns:
whether Dialect allows COUNT DISTINCT

allowsMultipleCountDistinct

public boolean allowsMultipleCountDistinct()
Description copied from interface: Dialect
Returns whether this Dialect supports more than one distinct aggregation in the same query.

In Derby 10.1,

select couunt(distinct x) from t
is OK, but
select couunt(distinct x), count(distinct y) from t
gives "Multiple DISTINCT aggregates are not supported at this time."

Specified by:
allowsMultipleCountDistinct in interface Dialect
Returns:
whether this Dialect supports more than one distinct aggregation in the same query

allowsMultipleDistinctSqlMeasures

public boolean allowsMultipleDistinctSqlMeasures()
Description copied from interface: Dialect
Returns whether this Dialect has performant support of distinct SQL measures in the same query.

Specified by:
allowsMultipleDistinctSqlMeasures in interface Dialect
Returns:
whether this dialect supports multiple count(distinct subquery) measures in one query.

generateInline

public java.lang.String generateInline(java.util.List<java.lang.String> columnNames,
                                       java.util.List<java.lang.String> columnTypes,
                                       java.util.List<java.lang.String[]> valueList)
Description copied from interface: Dialect
Generates a SQL statement to represent an inline dataset.

For example, for Oracle, generates

 SELECT 1 AS FOO, 'a' AS BAR FROM dual
 UNION ALL
 SELECT 2 AS FOO, 'b' AS BAR FROM dual
 

For ANSI SQL, generates:

 VALUES (1, 'a'), (2, 'b')
 

Specified by:
generateInline in interface Dialect
Parameters:
columnNames - List of column names
columnTypes - List of column types ("String" or "Numeric")
valueList - List of rows values
Returns:
SQL string

generateInlineGeneric

protected java.lang.String generateInlineGeneric(java.util.List<java.lang.String> columnNames,
                                                 java.util.List<java.lang.String> columnTypes,
                                                 java.util.List<java.lang.String[]> valueList,
                                                 java.lang.String fromClause,
                                                 boolean cast)
Generic algorithm to generate inline values list, using an optional FROM clause, specified by the caller of this method, appropriate to the dialect of SQL.

Parameters:
columnNames - Column names
columnTypes - Column types
valueList - List rows
fromClause - FROM clause, or null
cast - Whether to cast the values in the first row
Returns:
Expression that returns the given values

generateInlineForAnsi

public java.lang.String generateInlineForAnsi(java.lang.String alias,
                                              java.util.List<java.lang.String> columnNames,
                                              java.util.List<java.lang.String> columnTypes,
                                              java.util.List<java.lang.String[]> valueList,
                                              boolean cast)
Generates inline values list using ANSI 'VALUES' syntax. For example,
SELECT * FROM (VALUES (1, 'a'), (2, 'b')) AS t(x, y)

If NULL values are present, we use a CAST to ensure that they have the same type as other columns:

SELECT * FROM (VALUES (1, 'a'), (2, CASE(NULL AS VARCHAR(1)))) AS t(x, y)

This syntax is known to work on Derby, but not Oracle 10 or Access.

Parameters:
alias - Table alias
columnNames - Column names
columnTypes - Column types
valueList - List rows
cast - Whether to generate casts
Returns:
Expression that returns the given values

needsExponent

public boolean needsExponent(java.lang.Object value,
                             java.lang.String valueString)
Description copied from interface: Dialect
If Double values need to include additional exponent in its string represenation. This is to make sure that Double literals will be interpreted as doubles by LucidDB.

Specified by:
needsExponent in interface Dialect
Parameters:
value - Double value to generate string for
valueString - java string representation for this value.
Returns:
whether an additional exponent "E0" needs to be appended

quote

public void quote(java.lang.StringBuilder buf,
                  java.lang.Object value,
                  Dialect.Datatype datatype)
Description copied from interface: Dialect
Appends to a buffer a value quoted for its type.

Specified by:
quote in interface Dialect
Parameters:
buf - Buffer to append to
value - Value
datatype - Datatype of value

allowsDdl

public boolean allowsDdl()
Description copied from interface: Dialect
Returns whether this dialect supports common SQL Data Definition Language (DDL) statements such as CREATE TABLE and DROP INDEX.

Access seems to allow DDL iff the .mdb file is writeable.

Specified by:
allowsDdl in interface Dialect
Returns:
whether this Dialect supports DDL
See Also:
DatabaseMetaData.isReadOnly()

getNullCollation

public Dialect.NullCollation getNullCollation()
Description copied from interface: Dialect
Returns the rule which determines whether NULL values appear first or last when sorted using ORDER BY.

According to the SQL standard, this is implementation-specific. The default behavior is Dialect.NullCollation.POSINF.

Specified by:
getNullCollation in interface Dialect
Returns:
Rule which determines whether NULL values collate first or last

generateOrderItem

public java.lang.String generateOrderItem(java.lang.String expr,
                                          boolean nullable,
                                          boolean ascending)
Description copied from interface: Dialect
Generates an item for an ORDER BY clause, sorting in the required direction, and ensuring that NULL values collate after all non-NULL values.

By default, generateOrderItem(expr, true) generates "expr ASC" and generateOrderItem(expr, false) generates "expr DESC". But depending on Dialect.getNullCollation() and ascending, there may need to be additional code.

For example, on Oracle, where NULLs collate higher than all other values, generateOrderItem(expr, true) generates "expr ASC" and generateOrderItem(expr, false) generates "expr DESC NULLS LAST".

On MySQL, where NULLs collate lower than all other values, generateOrderItem(expr, true) generates "ISNULL(expr), expr ASC" and generateOrderItem(expr, false) generates "expr DESC".

Specified by:
generateOrderItem in interface Dialect
Parameters:
expr - Expression
nullable - Whether expression may have NULL values
ascending - Whether to sort expression ascending
Returns:
Expression modified so that NULL values collate last

supportsOrderByNullsLast

public boolean supportsOrderByNullsLast()
Returns whether this dialect supports "ASC NULLS LAST" and "DESC NULLS LAST" applied to an item in the ORDER BY clause.

This feature is in standard SQL but is not supported by many databases, therefore the default implementation returns false.

This method is only called from generateOrderItem(String, boolean, boolean). Some dialects override that method and therefore never call this method.

Returns:
Whether this dialect supports "ORDER BY ... NULLS LAST".

supportsGroupByExpressions

public boolean supportsGroupByExpressions()
Description copied from interface: Dialect
Returns whether this Dialect supports expressions in the GROUP BY clause. Derby/Cloudscape and Infobright do not.

Specified by:
supportsGroupByExpressions in interface Dialect
Returns:
Whether this Dialect allows expressions in the GROUP BY clause

allowsSelectNotInGroupBy

public boolean allowsSelectNotInGroupBy()
Description copied from interface: Dialect
Returns whether the database currently permits queries to include in the SELECT clause expressions that are not listed in the GROUP BY clause. The SQL standard allows this if the database can deduce that the expression is functionally dependent on columns in the GROUP BY clause.

For example, SELECT empno, first_name || ' ' || last_name FROM emps GROUP BY empno is valid because empno is the primary key of the emps table, and therefore all columns are dependent on it. For a given value of empno, first_name || ' ' || last_name has a unique value.

Most databases do not, MySQL is an example of one that does (if the functioality is enabled).

Specified by:
allowsSelectNotInGroupBy in interface Dialect
Returns:
Whether this Dialect allows SELECT clauses to contain columns that are not in the GROUP BY clause

supportsGroupingSets

public boolean supportsGroupingSets()
Description copied from interface: Dialect
Returns whether this Dialect allows the GROUPING SETS construct in the GROUP BY clause. Currently Oracle, DB2 and Teradata.

Specified by:
supportsGroupingSets in interface Dialect
Returns:
Whether this Dialect allows GROUPING SETS clause

supportsUnlimitedValueList

public boolean supportsUnlimitedValueList()
Description copied from interface: Dialect
Returns whether this Dialect places no limit on the number of rows which can appear as elements of an IN or VALUES expression.

Specified by:
supportsUnlimitedValueList in interface Dialect
Returns:
whether value list length is unlimited

requiresGroupByAlias

public boolean requiresGroupByAlias()
Description copied from interface: Dialect
Returns true if this Dialect can include expressions in the GROUP BY clause only by adding an expression to the SELECT clause and using its alias.

For example, in such a dialect,

SELECT x, x FROM t GROUP BY x
would be illegal, but
SELECT x AS a, x AS b FROM t ORDER BY a, b
would be legal.

Infobright is the only such dialect.

Specified by:
requiresGroupByAlias in interface Dialect
Returns:
Whether this Dialect can include expressions in the GROUP BY clause only by adding an expression to the SELECT clause and using its alias

requiresOrderByAlias

public boolean requiresOrderByAlias()
Description copied from interface: Dialect
Returns true if this Dialect can include expressions in the ORDER BY clause only by adding an expression to the SELECT clause and using its alias.

For example, in such a dialect,

SELECT x FROM t ORDER BY x + y
would be illegal, but
SELECT x, x + y AS z FROM t ORDER BY z
would be legal.

MySQL, DB2 and Ingres are examples of such dialects.

Specified by:
requiresOrderByAlias in interface Dialect
Returns:
Whether this Dialect can include expressions in the ORDER BY clause only by adding an expression to the SELECT clause and using its alias

allowsOrderByAlias

public boolean allowsOrderByAlias()
Description copied from interface: Dialect
Returns true if aliases defined in the SELECT clause can be used as expressions in the ORDER BY clause.

For example, in such a dialect,

SELECT x, x + y AS z FROM t ORDER BY z
would be legal.

MySQL, DB2 and Ingres are examples of dialects where this is true; Access is a dialect where this is false.

Specified by:
allowsOrderByAlias in interface Dialect
Returns:
Whether aliases defined in the SELECT clause can be used as expressions in the ORDER BY clause.

requiresUnionOrderByOrdinal

public boolean requiresUnionOrderByOrdinal()
Description copied from interface: Dialect
Returns true if this dialect allows only integers in the ORDER BY clause of a UNION (or other set operation) query.

For example, SELECT x, y + z FROM t
UNION ALL
SELECT x, y + z FROM t
ORDER BY 1, 2
is allowed but SELECT x, y, z FROM t
UNION ALL
SELECT x, y, z FROM t
ORDER BY x
is not.

Teradata is an example of a dialect with this restriction.

Specified by:
requiresUnionOrderByOrdinal in interface Dialect
Returns:
whether this dialect allows only integers in the ORDER BY clause of a UNION (or other set operation) query

requiresUnionOrderByExprToBeInSelectClause

public boolean requiresUnionOrderByExprToBeInSelectClause()
Description copied from interface: Dialect
Returns true if this dialect allows an expression in the ORDER BY clause of a UNION (or other set operation) query only if it occurs in the SELECT clause.

For example, SELECT x, y + z FROM t
UNION ALL
SELECT x, y + z FROM t
ORDER BY y + z
is allowed but SELECT x, y, z FROM t
UNION ALL
SELECT x, y, z FROM t
ORDER BY y + z
SELECT x, y, z FROM t ORDER BY y + z is not.

Access is an example of a dialect with this restriction.

Specified by:
requiresUnionOrderByExprToBeInSelectClause in interface Dialect
Returns:
whether this dialect allows an expression in the ORDER BY clause of a UNION (or other set operation) query only if it occurs in the SELECT clause

supportsMultiValueInExpr

public boolean supportsMultiValueInExpr()
Description copied from interface: Dialect
Returns true if this dialect supports multi-value IN expressions. E.g., WHERE (col1, col2) IN ((val1a, val2a), (val1b, val2b))

Specified by:
supportsMultiValueInExpr in interface Dialect
Returns:
true if the dialect supports multi-value IN expressions

supportsResultSetConcurrency

public boolean supportsResultSetConcurrency(int type,
                                            int concurrency)
Description copied from interface: Dialect
Returns whether this Dialect supports the given concurrency type in combination with the given result set type.

The result is similar to DatabaseMetaData.supportsResultSetConcurrency(int, int), except that the JdbcOdbc bridge in JDK 1.6 overstates its abilities. See bug 1690406.

Specified by:
supportsResultSetConcurrency in interface Dialect
Parameters:
type - defined in ResultSet
concurrency - type defined in ResultSet
Returns:
true if so; false otherwise

toString

public java.lang.String toString()
Overrides:
toString in class java.lang.Object

getMaxColumnNameLength

public int getMaxColumnNameLength()
Description copied from interface: Dialect
Returns the maximum length of the name of a database column or query alias allowed by this dialect.

Specified by:
getMaxColumnNameLength in interface Dialect
Returns:
maximum number of characters in a column name
See Also:
DatabaseMetaData.getMaxColumnNameLength()

getProduct

public static Dialect.DatabaseProduct getProduct(java.lang.String productName,
                                                 java.lang.String productVersion)
Converts a product name and version (per the JDBC driver) into a product enumeration.

Parameters:
productName - Product name
productVersion - Product version
Returns:
database product

Get Mondrian at SourceForge.net. Fast, secure and free Open Source software downloads