How to implement Kylin dialect for Mondrian

In this post I will explain, how to implement Kylin dialect in Mondrian.

First of all you need to download last version of Mondrian and source code for it .

Our plan consists of the following steps:
We will change the following classes for mondrian:
mondrian.spi.impl.JdbcDialectImpl
mondrian.spi.Dialect

And we will implement new dialect as
mondrian.spi.impl.KylinDialect

After changes are done you can compile the classes (with mondrian jar in the class path) and replace them in the mondrian jar.

First of all we need to explain mondrian, that there is new dialect available. For this we will do:

Step 1: Add two lines in getProduct method in mondrian.spi.impl.JdbcDialectImpl

} else if (productName.equals("Interbase")) {
return DatabaseProduct.INTERBASE;
} else if (upperProductName.equals("KYLIN")) {  //LINE 1
return DatabaseProduct.KYLIN;                   //LINE 2
} else if (upperProductName.equals("LUCIDDB") || upperProductName.equals("OPTIQ")) {
return DatabaseProduct.LUCIDDB;

Step 2: Add constant in mondrian.spi.Dialect

    enum DatabaseProduct {
        ACCESS,
        UNKNOWN,
        DERBY,
        DB2_OLD_AS400,
        DB2_AS400,
        DB2,
        FIREBIRD,
        GREENPLUM,
        HIVE,
        HSQLDB,
        IMPALA,
        INFORMIX,
        INFOBRIGHT,
        INGRES,
        INTERBASE,
        KYLIN,                             //KYLIN Constant
        LUCIDDB,

The last step is to implement Kylin Dialect. We need to extend JdbcDialectImpl class and says mondrian, which options are supported and not supported by Kylin JDBC implementation:

  • Kylin does not support allowsCountDistinct => false
  • Kylin supports allowsJoinOn => true
  • Mondrian should use Ansi Syntax by generating order by nulls SQL requests (generateOrderByNulls)
  • We should turn off the quoting of numbers. Sometimes mondrian does not recorgnize them correctly. (quoteStringLiteral)
  • We should turn off to Upper function for numbers. Sometimes mondrian does not recorgnize them correctly (toUpper)

public class KylinDialect extends JdbcDialectImpl {
    public static final JdbcDialectFactory FACTORY = new JdbcDialectFactory(KylinDialect.class, DatabaseProduct.KYLIN) {
                protected boolean acceptsConnection(Connection connection) {
                    return super.acceptsConnection(connection);
                }
            };

    public KylinDialect(Connection connection) throws SQLException {
        super(connection);
    }

    public boolean allowsCountDistinct() {
        return false;
    }

    public boolean allowsJoinOn() {
        return true;
    }
	
    protected String generateOrderByNulls(String expr, boolean ascending, boolean collateNullsLast) {
        return generateOrderByNullsAnsi(expr, ascending, collateNullsLast);
    }

    public void quoteStringLiteral(StringBuilder buf, String s) {
        try {
            Double.parseDouble(s);
            buf.append(s);
        } catch (Exception ex) {
            super.quoteStringLiteral(buf, s);
        }
    }

    public String toUpper(String expr) {
        try {
            Double.parseDouble(expr);
        } catch (Exception ex) {
            return super.toUpper(expr);
        }
        return expr;
    }
}

Next you can read how to use Kylin Cubes with Excel Pivot.