PHOENIX-2720 Minor additions to PhoenixRuntime utils
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/PhoenixRuntimeIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/PhoenixRuntimeIT.java
index e748825..3cab7fa 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/PhoenixRuntimeIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/PhoenixRuntimeIT.java
@@ -133,6 +133,15 @@
Expression e6 = PhoenixRuntime.getTenantIdExpression(conn, "I2");
HTableInterface htable6 = conn.unwrap(PhoenixConnection.class).getQueryServices().getTable(Bytes.toBytes("I2"));
assertTenantIds(e6, htable6, new FirstKeyOnlyFilter(), new String[] {"t1", "t2"} );
+
+ tableName = "BAR_" + (isSalted ? "SALTED" : "UNSALTED");
+ conn.createStatement().execute("CREATE TABLE " + tableName + " (k1 VARCHAR NOT NULL, k2 VARCHAR, CONSTRAINT PK PRIMARY KEY(K1,K2)) " + (isSalted ? "SALT_BUCKETS=3" : ""));
+ conn.createStatement().execute("UPSERT INTO " + tableName + " VALUES('t1','x')");
+ conn.createStatement().execute("UPSERT INTO " + tableName + " VALUES('t2','y')");
+ Expression e7 = PhoenixRuntime.getFirstPKColumnExpression(conn, tableName);
+ HTableInterface htable7 = conn.unwrap(PhoenixConnection.class).getQueryServices().getTable(Bytes.toBytes(tableName));
+ assertTenantIds(e7, htable7, new FirstKeyOnlyFilter(), new String[] {"t1", "t2"} );
+
}
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/PhoenixRuntime.java b/phoenix-core/src/main/java/org/apache/phoenix/util/PhoenixRuntime.java
index fbf3d1b..508446c 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/PhoenixRuntime.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/PhoenixRuntime.java
@@ -89,6 +89,8 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
+import co.cask.tephra.util.TxUtils;
+
/**
*
* Collection of non JDBC compliant utility methods
@@ -985,6 +987,25 @@
if (!SchemaUtil.isMetaTable(table) && !SchemaUtil.isSequenceTable(table) && !table.isMultiTenant()) {
return null;
}
+ return getFirstPKColumnExpression(table);
+ }
+
+ /**
+ * Get expression that may be used to evaluate to the value of the first
+ * column of a given row in a Phoenix table.
+ * @param conn open Phoenix connection
+ * @param fullTableName full table name
+ * @return An expression that may be evaluated for a row in the provided table.
+ * @throws SQLException if the table name is not found, a TableNotFoundException
+ * is thrown. If a local index is supplied a SQLFeatureNotSupportedException
+ * is thrown.
+ */
+ public static Expression getFirstPKColumnExpression(Connection conn, String fullTableName) throws SQLException {
+ PTable table = getTable(conn, fullTableName);
+ return getFirstPKColumnExpression(table);
+ }
+
+ private static Expression getFirstPKColumnExpression(PTable table) throws SQLException {
if (table.getIndexType() == IndexType.LOCAL) {
/*
* With some hackery, we could deduce the tenant ID from a multi-tenant local index,
@@ -1159,4 +1180,14 @@
pConn.clearMetrics();
}
+ /**
+ * Use this utility function to ensure that a timestamp is in milliseconds across transactional and
+ * non transactional tables. This expects that the Cell timestamp is based either on wall clock
+ * time or transaction manager nanos wall clock time.
+ * @param tsOfCell Cell time stamp to be converted.
+ * @return wall clock time in milliseconds (i.e. Epoch time) of a given Cell time stamp.
+ */
+ public static long getWallClockTimeFromCellTimeStamp(long tsOfCell) {
+ return TxUtils.isPreExistingVersion(tsOfCell) ? tsOfCell : TransactionUtil.convertToMilliseconds(tsOfCell);
+ }
}
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/util/PhoenixRuntimeTest.java b/phoenix-core/src/test/java/org/apache/phoenix/util/PhoenixRuntimeTest.java
index 895e29e..fe81120 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/util/PhoenixRuntimeTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/util/PhoenixRuntimeTest.java
@@ -40,6 +40,7 @@
import org.apache.phoenix.expression.Expression;
import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
import org.apache.phoenix.query.BaseConnectionlessQueryTest;
+import org.apache.phoenix.query.QueryConstants;
import org.apache.phoenix.schema.PTable;
import org.apache.phoenix.schema.TableNotFoundException;
import org.apache.phoenix.schema.types.PDataType;
@@ -288,4 +289,14 @@
return "\"" + string + "\"";
}
+ @Test
+ public void testGetWallClockTimeFromCellTimeStamp() {
+ long ts = System.currentTimeMillis();
+ assertEquals(ts, PhoenixRuntime.getWallClockTimeFromCellTimeStamp(ts));
+ long nanoTs = TransactionUtil.convertToNanoseconds(ts);
+ assertEquals(ts, PhoenixRuntime.getWallClockTimeFromCellTimeStamp(nanoTs));
+ long skewedTs = ts + QueryConstants.MILLIS_IN_DAY; // skew of a day
+ // Even with a day of skew, we won't consider the ts a nanos timestamp
+ assertEquals(skewedTs, PhoenixRuntime.getWallClockTimeFromCellTimeStamp(skewedTs));
+ }
}