[
https://issues.apache.org/jira/browse/PHOENIX-514?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14278302#comment-14278302
]
ASF GitHub Bot commented on PHOENIX-514:
----------------------------------------
Github user JamesRTaylor commented on a diff in the pull request:
https://github.com/apache/phoenix/pull/34#discussion_r22992211
--- Diff:
phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ExpressionIndexIT.java
---
@@ -0,0 +1,632 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.end2end.index;
+
+import static org.apache.phoenix.util.TestUtil.INDEX_DATA_SCHEMA;
+import static org.apache.phoenix.util.TestUtil.INDEX_DATA_TABLE;
+import static org.apache.phoenix.util.TestUtil.MUTABLE_INDEX_DATA_TABLE;
+import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.math.BigDecimal;
+import java.sql.Connection;
+import java.sql.Date;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Properties;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.phoenix.end2end.BaseHBaseManagedTimeIT;
+import org.apache.phoenix.exception.SQLExceptionCode;
+import org.apache.phoenix.query.QueryConstants;
+import org.apache.phoenix.util.DateUtil;
+import org.apache.phoenix.util.PropertiesUtil;
+import org.apache.phoenix.util.QueryUtil;
+import org.junit.Test;
+
+public class ExpressionIndexIT extends BaseHBaseManagedTimeIT {
+
+ private static final int NUM_MILLIS_IN_DAY = 86400000;
+
+ @Test
+ public void testImmutableIndexCreationAndUpdate() throws Exception {
+ helpTestCreateAndUpdate(false, false);
+ }
+
+ @Test
+ public void testImmutableLocalIndexCreationAndUpdate() throws Exception
{
+ helpTestCreateAndUpdate(false, true);
+ }
+
+ @Test
+ public void testMutableIndexCreationAndUpdate() throws Exception {
+ helpTestCreateAndUpdate(true, false);
+ }
+
+ @Test
+ public void testMutableLocalIndexCreationAndUpdate() throws Exception {
+ helpTestCreateAndUpdate(true, true);
+ }
+
+ /**
+ * Adds a row to the index data table
+ *
+ * @param i
+ * row number
+ */
+ private void insertRow(PreparedStatement stmt, int i) throws
SQLException {
+ // insert row
+ stmt.setString(1, "varchar" + String.valueOf(i));
+ stmt.setString(2, "char" + String.valueOf(i));
+ stmt.setInt(3, i);
+ stmt.setLong(4, i);
+ stmt.setBigDecimal(5, new BigDecimal(Double.valueOf(i)));
+ Date date = new Date(DateUtil.parseDate("2015-01-01
00:00:00").getTime()+(i-1)*NUM_MILLIS_IN_DAY);
+ stmt.setDate(6, date);
+ stmt.setString(7, "a.varchar" + String.valueOf(i));
+ stmt.setString(8, "a.char" + String.valueOf(i));
+ stmt.setInt(9, i);
+ stmt.setLong(10, i);
+ stmt.setBigDecimal(11, new BigDecimal((double) i));
+ stmt.setDate(12, date);
+ stmt.setString(13, "b.varchar" + String.valueOf(i));
+ stmt.setString(14, "b.char" + String.valueOf(i));
+ stmt.setInt(15, i);
+ stmt.setLong(16, i);
+ stmt.setBigDecimal(17, new BigDecimal((double) i));
+ stmt.setDate(18, date);
+ stmt.executeUpdate();
+ }
+
+ private void verifyResult(ResultSet rs, int i) throws SQLException {
+ assertTrue(rs.next());
+ assertEquals(
+ "VARCHAR"+ String.valueOf(i)+ "_"
+ + StringUtils.rightPad("CHAR" +
String.valueOf(i), 6,' ')
+ + "_A.VARCHAR"+ String.valueOf(i)
+ + "_"+ StringUtils.rightPad("B.CHAR" +
String.valueOf(i),10, ' '), rs.getString(1));
+ assertEquals(i * 4, rs.getInt(2));
+ Date date = new Date(DateUtil.parseDate("2015-01-01
00:00:00").getTime()+(i)*NUM_MILLIS_IN_DAY);
+ assertEquals(date, rs.getDate(3));
+ assertEquals(date, rs.getDate(4));
+ assertEquals(date, rs.getDate(5));
+ assertEquals("varchar" + String.valueOf(i), rs.getString(6));
+ assertEquals("char" + String.valueOf(i), rs.getString(7));
+ assertEquals(i, rs.getInt(8));
+ assertEquals(i, rs.getLong(9));
+ assertEquals(i, rs.getDouble(10), 0.000001);
+ assertEquals(i, rs.getLong(11));
+ assertEquals(i, rs.getLong(12));
+ }
+
+ protected void helpTestCreateAndUpdate(boolean mutable, boolean
localIndex)
+ throws Exception {
+ String dataTableName = mutable ? MUTABLE_INDEX_DATA_TABLE :
INDEX_DATA_TABLE;
+ String fullDataTableName = INDEX_DATA_SCHEMA +
QueryConstants.NAME_SEPARATOR + dataTableName;
+ Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+ Connection conn = DriverManager.getConnection(getUrl(), props);
+ try
+ {
+ conn.setAutoCommit(false);
+ populateDataTable(conn, dataTableName);
+
+ // create an expression index
+ String ddl = "CREATE " + (localIndex ? "LOCAL" : "") +
" INDEX IDX ON " + fullDataTableName
+ + " ((UPPER(varchar_pk) || '_' ||
UPPER(char_pk) || '_' || UPPER(varchar_col1) || '_' || UPPER(char_col2)),"
+ + " (decimal_pk+int_pk+decimal_col2+int_col1),"
+ + " date_pk+1, date1+1, date2+1 )"
+ + " INCLUDE (long_col1, long_col2)";
+ PreparedStatement stmt = conn.prepareStatement(ddl);
+ stmt.execute();
+
+ // run select query with expression in WHERE clause
+ String whereSql = "SELECT long_col1, long_col2 from " +
fullDataTableName +
+ " WHERE UPPER(varchar_pk) || '_' ||
UPPER(char_pk) || '_' || UPPER(varchar_col1) || '_' || UPPER(char_col2) = ?"
+ +" AND
decimal_pk+int_pk+decimal_col2+int_col1=?"
+ // since a.date1 and b.date2 are NULLABLE and
date is fixed width, these expressions are stored as DECIMAL in the index
(which is not fixed width)
+ +" AND date_pk+1=? AND cast (date1+1 as
DECIMAL) =? AND cast (date2+1 as DECIMAL)=?";
--- End diff --
Do you need to do this CAST here in order for the index to be used? Or if
you just had date1+1 and date2+1 would it still be used?
> Support functional indexes
> --------------------------
>
> Key: PHOENIX-514
> URL: https://issues.apache.org/jira/browse/PHOENIX-514
> Project: Phoenix
> Issue Type: Task
> Reporter: James Taylor
> Assignee: Thomas D'Silva
> Labels: enhancement
>
> Instead of only defining the set of columns from the data table that make up
> an index, you should be able to use expressions. For example:
> CREATE INDEX upper_last_name_idx ON person (UPPER(last_name))
> Then in queries that use UPPER(last_name), we can replace them with column
> references to the index table.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)