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) 2011-2013 Pentaho and others 008// All Rights Reserved. 009*/ 010package mondrian.spi.impl; 011 012import mondrian.olap.Util; 013 014import java.sql.*; 015import java.sql.Date; 016import java.util.*; 017 018/** 019 * Implementation of {@link mondrian.spi.Dialect} for the Hive database. 020 * 021 * @author Hongwei Fu 022 * @since Jan 10, 2011 023 */ 024public class HiveDialect extends JdbcDialectImpl { 025 private static final int MAX_COLUMN_NAME_LENGTH = 128; 026 027 public static final JdbcDialectFactory FACTORY = 028 new JdbcDialectFactory( 029 HiveDialect.class, 030 DatabaseProduct.HIVE) 031 { 032 protected boolean acceptsConnection(Connection connection) { 033 return super.acceptsConnection(connection) 034 && !isDatabase(DatabaseProduct.IMPALA, connection); 035 } 036 }; 037 038 /** 039 * Creates a HiveDialect. 040 * 041 * @param connection Connection 042 * 043 * @throws SQLException on error 044 */ 045 public HiveDialect(Connection connection) throws SQLException { 046 super(connection); 047 } 048 049 protected String deduceIdentifierQuoteString( 050 DatabaseMetaData databaseMetaData) 051 { 052 try { 053 final String quoteIdentifierString = 054 databaseMetaData.getIdentifierQuoteString(); 055 return "".equals(quoteIdentifierString) 056 // quoting not supported 057 ? null 058 : quoteIdentifierString; 059 } catch (SQLException e) { 060 // Not supported by HiveDatabaseMetaData; do nothing if catch an 061 // Exception 062 return "`"; 063 } 064 } 065 066 protected Set<List<Integer>> deduceSupportedResultSetStyles( 067 DatabaseMetaData databaseMetaData) 068 { 069 // Hive don't support this, so just return an empty set. 070 return Collections.emptySet(); 071 } 072 073 protected boolean deduceReadOnly(DatabaseMetaData databaseMetaData) { 074 try { 075 return databaseMetaData.isReadOnly(); 076 } catch (SQLException e) { 077 // Hive is read only (as of release 0.7) 078 return true; 079 } 080 } 081 082 protected int deduceMaxColumnNameLength(DatabaseMetaData databaseMetaData) { 083 try { 084 return databaseMetaData.getMaxColumnNameLength(); 085 } catch (SQLException e) { 086 return MAX_COLUMN_NAME_LENGTH; 087 } 088 } 089 090 public boolean allowsCompoundCountDistinct() { 091 return true; 092 } 093 094 public boolean requiresAliasForFromQuery() { 095 return true; 096 } 097 098 public boolean requiresOrderByAlias() { 099 return true; 100 } 101 102 public boolean requiresUnionOrderByExprToBeInSelectClause() { 103 return false; 104 } 105 106 public String generateInline( 107 List<String> columnNames, 108 List<String> columnTypes, 109 List<String[]> valueList) 110 { 111 return "select * from (" 112 + generateInlineGeneric( 113 columnNames, columnTypes, valueList, " from dual", false) 114 + ") x limit " + valueList.size(); 115 } 116 117 protected void quoteDateLiteral( 118 StringBuilder buf, 119 String value, 120 Date date) 121 { 122 // Hive doesn't support Date type; treat date as a string '2008-01-23' 123 Util.singleQuoteString(value, buf); 124 } 125 126 @Override 127 protected String generateOrderByNulls( 128 String expr, 129 boolean ascending, 130 boolean collateNullsLast) 131 { 132 // In Hive, Null values are worth negative infinity. 133 if (collateNullsLast) { 134 if (ascending) { 135 return "ISNULL(" + expr + ") ASC, " + expr + " ASC"; 136 } else { 137 return expr + " DESC"; 138 } 139 } else { 140 if (ascending) { 141 return expr + " ASC"; 142 } else { 143 return "ISNULL(" + expr + ") DESC, " + expr + " DESC"; 144 } 145 } 146 } 147 148 public boolean allowsAs() { 149 return false; 150 } 151 152 public boolean allowsJoinOn() { 153 return false; 154 } 155} 156 157// End HiveDialect.java