PHOENIX-3890 Disable EncodedQualifierCellsList optimization for tables with more than one column family
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/MultiCfQueryExecIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/MultiCfQueryExecIT.java
index ed87cb6..d94df6c 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/MultiCfQueryExecIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/MultiCfQueryExecIT.java
@@ -26,6 +26,7 @@
import java.math.BigDecimal;
import java.sql.Connection;
+import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@@ -337,4 +338,72 @@
conn.close();
}
}
+
+ @Test
+ public void testBug3890() throws Exception {
+ try (Connection conn = DriverManager.getConnection(getUrl())) {
+ String tableName = generateUniqueName();
+ String ddl =
+ "CREATE TABLE IF NOT EXISTS " + tableName + " (HOST CHAR(2) NOT NULL,"
+ + " DOMAIN VARCHAR NOT NULL," + " FEATURE VARCHAR NOT NULL,"
+ + " DATE DATE NOT NULL," + " USAGE.CORE BIGINT," + " USAGE.DB BIGINT,"
+ + " STATS.ACTIVE_VISITOR INTEGER"
+ + " CONSTRAINT PK PRIMARY KEY (HOST, DOMAIN, FEATURE, DATE))";
+ conn.createStatement().execute(ddl);
+ String upsert = "UPSERT INTO " + tableName + " VALUES (?, ?, ?, ?, ?, ?, ?)";
+ try (PreparedStatement stmt = conn.prepareStatement(upsert)) {
+ stmt.setString(1, "H1");
+ stmt.setString(2, "Salesforce");
+ stmt.setString(3, "F1");
+ stmt.setDate(4, new Date(100));
+ stmt.setLong(5, 100l);
+ stmt.setLong(6, 2000l);
+ stmt.setLong(7, 10);
+ stmt.executeUpdate();
+ stmt.setString(1, "H2");
+ stmt.setString(2, "Heroku");
+ stmt.setString(3, "F1");
+ stmt.setDate(4, new Date(100));
+ stmt.setLong(5, 100l);
+ stmt.setLong(6, 1000l);
+ stmt.setLong(7, 10);
+ stmt.executeUpdate();
+ conn.commit();
+ }
+ String query =
+ "SELECT DOMAIN, AVG(CORE) Average_CPU_Usage, AVG(DB) Average_DB_Usage FROM "
+ + tableName + " GROUP BY DOMAIN ORDER BY DOMAIN DESC";
+ ResultSet rs = conn.createStatement().executeQuery(query);
+ rs.next();
+ assertEquals("Salesforce", rs.getString(1));
+ assertEquals(0, Double.compare(100, rs.getDouble(2)));
+ assertEquals(0, Double.compare(2000, rs.getDouble(3)));
+ assertTrue(rs.next());
+ assertEquals("Heroku", rs.getString(1));
+ assertEquals(0, Double.compare(100, rs.getDouble(2)));
+ assertEquals(0, Double.compare(1000, rs.getDouble(3)));
+ assertFalse(rs.next());
+
+ query =
+ "SELECT TRUNC(DATE,'DAY') DAY, SUM(CORE) TOTAL_CPU_Usage, MIN(CORE) MIN_CPU_Usage, MAX(CORE) MAX_CPU_Usage"
+ + " FROM " + tableName + " WHERE DOMAIN LIKE 'Salesforce%'"
+ + " GROUP BY TRUNC(DATE,'DAY')";
+ rs = conn.createStatement().executeQuery(query);
+ rs.next();
+ assertEquals(0, rs.getLong(1));
+ assertEquals((Long) 100l, Long.valueOf(rs.getLong(2)));
+ assertEquals((Long) 100l, Long.valueOf(rs.getLong(3)));
+ assertEquals((Long) 100l, Long.valueOf(rs.getLong(4)));
+ assertFalse(rs.next());
+
+ query =
+ "SELECT HOST, SUM(ACTIVE_VISITOR) TOTAL_ACTIVE_VISITORS FROM " + tableName
+ + " WHERE DB > (CORE * 10)" + " GROUP BY HOST";
+ rs = conn.createStatement().executeQuery(query);
+ rs.next();
+ assertEquals("H1", rs.getString(1));
+ assertEquals(10, rs.getInt(2));
+ assertFalse(rs.next());
+ }
+ }
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/EncodedColumnsUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/util/EncodedColumnsUtil.java
index 0cf996a..e67ddeb 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/EncodedColumnsUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/EncodedColumnsUtil.java
@@ -129,8 +129,11 @@
/*
* HBase doesn't allow raw scans to have columns set. And we need columns to be set
* explicitly on the scan to use this optimization.
+ *
+ * Disabling this optimization for tables with more than one column family.
+ * See PHOENIX-3890.
*/
- return !scan.isRaw() && table.getImmutableStorageScheme() != null
+ return !scan.isRaw() && table.getColumnFamilies().size() <= 1 && table.getImmutableStorageScheme() != null
&& table.getImmutableStorageScheme() == ImmutableStorageScheme.ONE_CELL_PER_COLUMN
&& usesEncodedColumnNames(table) && !table.isTransactional()
&& !ScanUtil.hasDynamicColumns(table);