001/*
002// This software is subject to the terms of the Eclipse Public License v1.0
003// Agreement, available at the following URL:
004// http://www.eclipse.org/legal/epl-v10.html.
005// You must accept the terms of that agreement to use this software.
006//
007// Copyright (C) 2012-2013 Pentaho
008// All Rights Reserved.
009*/
010package mondrian.spi.impl;
011
012import mondrian.olap.Util;
013import mondrian.rolap.SqlStatement;
014
015import java.sql.Connection;
016import java.sql.ResultSetMetaData;
017import java.sql.SQLException;
018import java.sql.Types;
019
020/**
021 * Implementation of {@link mondrian.spi.Dialect} for the MonetDB database.
022 *
023 * @author pstoellberger
024 * @since Nov 10, 2012
025 */
026public class MonetDbDialect extends JdbcDialectImpl {
027
028    public static final JdbcDialectFactory FACTORY =
029        new JdbcDialectFactory(
030            MonetDbDialect.class,
031            DatabaseProduct.MONETDB);
032
033    /**
034     * Creates a MonetDbDialect.
035     *
036     * @param connection Connection
037     *
038     * @throws java.sql.SQLException on error
039     */
040    public MonetDbDialect(Connection connection) throws SQLException {
041        super(connection);
042    }
043
044    @Override
045    public boolean allowsMultipleDistinctSqlMeasures() {
046        return false;
047    }
048
049    @Override
050    public boolean allowsCountDistinct() {
051        return false;
052    }
053
054    @Override
055    public boolean requiresAliasForFromQuery() {
056        return true;
057    }
058
059    @Override
060    public boolean allowsCompoundCountDistinct() {
061        return false;
062    }
063
064    @Override
065    public boolean supportsGroupByExpressions() {
066        return false;
067    }
068
069    @Override
070    public void quoteStringLiteral(StringBuilder buf, String s) {
071        // Go beyond Util.singleQuoteString; also quote backslash, like MySQL.
072        buf.append('\'');
073        String s0 = Util.replace(s, "'", "''");
074        String s1 = Util.replace(s0, "\\", "\\\\");
075        buf.append(s1);
076        buf.append('\'');
077    }
078
079    @Override
080    public SqlStatement.Type getType(
081        ResultSetMetaData metaData, int columnIndex)
082        throws SQLException
083    {
084        final int columnType = metaData.getColumnType(columnIndex + 1);
085        final int precision = metaData.getPrecision(columnIndex + 1);
086        final int scale = metaData.getScale(columnIndex + 1);
087
088        if (columnType == Types.NUMERIC || columnType == Types.DECIMAL) {
089            if (scale == 0 && precision == 0) {
090                // MonetDB marks doesn't return precision and scale for agg
091                // decimal data types, so we'll assume it's a double.
092                logTypeInfo(metaData, columnIndex, SqlStatement.Type.DOUBLE);
093                return SqlStatement.Type.DOUBLE;
094            }
095        }
096        return super.getType(metaData, columnIndex);
097    }
098
099}
100
101// End MonetDbDialect.java