You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by ja...@apache.org on 2015/04/14 02:08:02 UTC
[1/5] phoenix git commit: PHOENIX-1749 ORDER BY should support
ordinal position as well as expression (Alicia Ying Shu)
Repository: phoenix
Updated Branches:
refs/heads/master 6b1818c09 -> 0d78e48b5
PHOENIX-1749 ORDER BY should support ordinal position as well as expression (Alicia Ying Shu)
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/795debfe
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/795debfe
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/795debfe
Branch: refs/heads/master
Commit: 795debfe568206bc9a90c15c6acf628c4f9460d4
Parents: 6b1818c
Author: James Taylor <jt...@salesforce.com>
Authored: Sat Apr 11 17:37:25 2015 -0700
Committer: James Taylor <jt...@salesforce.com>
Committed: Sat Apr 11 17:37:25 2015 -0700
----------------------------------------------------------------------
.../org/apache/phoenix/end2end/OrderByIT.java | 391 ++++++++++++++++++-
.../apache/phoenix/compile/OrderByCompiler.java | 34 +-
.../apache/phoenix/compile/QueryCompiler.java | 2 +-
.../phoenix/compile/QueryOptimizerTest.java | 14 +-
4 files changed, 431 insertions(+), 10 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/phoenix/blob/795debfe/phoenix-core/src/it/java/org/apache/phoenix/end2end/OrderByIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/OrderByIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/OrderByIT.java
index a8beb1e..74eb7fe 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/OrderByIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/OrderByIT.java
@@ -30,11 +30,14 @@ 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.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.phoenix.util.PhoenixRuntime;
@@ -80,7 +83,7 @@ public class OrderByIT extends BaseClientManagedTimeIT {
conn.close();
}
}
-
+
@Test
public void testDescMultiOrderByExpr() throws Exception {
@@ -118,4 +121,390 @@ public class OrderByIT extends BaseClientManagedTimeIT {
conn.close();
}
}
+
+ @Test
+ public void testOrderByWithPosition() throws Exception {
+ Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+ Connection conn = DriverManager.getConnection(getUrl(), props);
+ conn.setAutoCommit(false);
+
+ try {
+ String ddl = "CREATE TABLE t_table " +
+ " (a_string varchar not null, col1 integer" +
+ " CONSTRAINT pk PRIMARY KEY (a_string))\n";
+ createTestTable(getUrl(), ddl);
+
+ String dml = "UPSERT INTO t_table VALUES(?, ?)";
+ PreparedStatement stmt = conn.prepareStatement(dml);
+ stmt.setString(1, "a");
+ stmt.setInt(2, 40);
+ stmt.execute();
+ stmt.setString(1, "b");
+ stmt.setInt(2, 20);
+ stmt.execute();
+ stmt.setString(1, "c");
+ stmt.setInt(2, 30);
+ stmt.execute();
+ conn.commit();
+
+ String query = "select count(*), col1 from t_table group by col1 order by 2";
+ ResultSet rs = conn.createStatement().executeQuery(query);
+ assertTrue(rs.next());
+ assertEquals(1,rs.getInt(1));
+ assertTrue(rs.next());
+ assertEquals(1,rs.getInt(1));
+ assertTrue(rs.next());
+ assertEquals(1,rs.getInt(1));
+ assertFalse(rs.next());
+
+ query = "select a_string x, col1 y from t_table order by x";
+ rs = conn.createStatement().executeQuery(query);
+ assertTrue(rs.next());
+ assertEquals("a",rs.getString(1));
+ assertEquals(40,rs.getInt(2));
+ assertTrue(rs.next());
+ assertEquals("b",rs.getString(1));
+ assertEquals(20,rs.getInt(2));
+ assertTrue(rs.next());
+ assertEquals("c",rs.getString(1));
+ assertEquals(30,rs.getInt(2));
+ assertFalse(rs.next());
+
+ query = "select * from t_table order by 2";
+ rs = conn.createStatement().executeQuery(query);
+ assertTrue(rs.next());
+ assertEquals("b",rs.getString(1));
+ assertEquals(20,rs.getInt(2));
+ assertTrue(rs.next());
+ assertEquals("c",rs.getString(1));
+ assertEquals(30,rs.getInt(2));
+ assertTrue(rs.next());
+ assertEquals("a",rs.getString(1));
+ assertEquals(40,rs.getInt(2));
+ assertFalse(rs.next());
+ } finally {
+ conn.close();
+ }
+ }
+
+
+ @Test
+ public void testColumnFamily() throws Exception {
+ Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+ Connection conn = DriverManager.getConnection(getUrl(), props);
+ conn.setAutoCommit(false);
+
+ try {
+ String ddl = "CREATE TABLE x_table " +
+ " (a_string varchar not null, cf1.a integer, cf1.b varchar, col1 integer, cf2.c varchar, cf2.d integer, col2 integer" +
+ " CONSTRAINT pk PRIMARY KEY (a_string))\n";
+ createTestTable(getUrl(), ddl);
+ String dml = "UPSERT INTO x_table VALUES(?,?,?,?,?,?,?)";
+ PreparedStatement stmt = conn.prepareStatement(dml);
+ stmt.setString(1, "a");
+ stmt.setInt(2, 40);
+ stmt.setString(3, "aa");
+ stmt.setInt(4, 10);
+ stmt.setString(5, "bb");
+ stmt.setInt(6, 20);
+ stmt.setInt(7, 1);
+ stmt.execute();
+ stmt.setString(1, "c");
+ stmt.setInt(2, 30);
+ stmt.setString(3, "cc");
+ stmt.setInt(4, 50);
+ stmt.setString(5, "dd");
+ stmt.setInt(6, 60);
+ stmt.setInt(7, 3);
+ stmt.execute();
+ stmt.setString(1, "b");
+ stmt.setInt(2, 40);
+ stmt.setString(3, "bb");
+ stmt.setInt(4, 5);
+ stmt.setString(5, "aa");
+ stmt.setInt(6, 80);
+ stmt.setInt(7, 2);
+ stmt.execute();
+ conn.commit();
+
+ String query = "select * from x_table order by 2, 5";
+ ResultSet rs = conn.createStatement().executeQuery(query);
+ assertTrue(rs.next());
+ assertEquals("c",rs.getString(1));
+ assertEquals(30,rs.getInt(2));
+ assertEquals("cc",rs.getString(3));
+ assertEquals(50,rs.getInt(4));
+ assertEquals("dd",rs.getString(5));
+ assertEquals(60,rs.getInt(6));
+ assertEquals(3,rs.getInt(7));
+ assertTrue(rs.next());
+ assertEquals("b",rs.getString(1));
+ assertEquals(40,rs.getInt(2));
+ assertEquals("bb",rs.getString(3));
+ assertEquals(5,rs.getInt(4));
+ assertEquals("aa",rs.getString(5));
+ assertEquals(80,rs.getInt(6));
+ assertEquals(2,rs.getInt(7));
+ assertTrue(rs.next());
+ assertEquals("a",rs.getString(1));
+ assertEquals(40,rs.getInt(2));
+ assertEquals("aa",rs.getString(3));
+ assertEquals(10,rs.getInt(4));
+ assertEquals("bb",rs.getString(5));
+ assertEquals(20,rs.getInt(6));
+ assertEquals(1,rs.getInt(7));
+ assertFalse(rs.next());
+
+ query = "select * from x_table order by 7";
+ rs = conn.createStatement().executeQuery(query);
+ assertTrue(rs.next());
+ assertEquals("a",rs.getString(1));
+ assertEquals(40,rs.getInt(2));
+ assertEquals("aa",rs.getString(3));
+ assertEquals(10,rs.getInt(4));
+ assertEquals("bb",rs.getString(5));
+ assertEquals(20,rs.getInt(6));
+ assertEquals(1,rs.getInt(7));
+ assertTrue(rs.next());
+ assertEquals("b",rs.getString(1));
+ assertEquals(40,rs.getInt(2));
+ assertEquals("bb",rs.getString(3));
+ assertEquals(5,rs.getInt(4));
+ assertEquals("aa",rs.getString(5));
+ assertEquals(80,rs.getInt(6));
+ assertEquals(2,rs.getInt(7));
+ assertTrue(rs.next());
+ assertEquals("c",rs.getString(1));
+ assertEquals(30,rs.getInt(2));
+ assertEquals("cc",rs.getString(3));
+ assertEquals(50,rs.getInt(4));
+ assertEquals("dd",rs.getString(5));
+ assertEquals(60,rs.getInt(6));
+ assertEquals(3,rs.getInt(7));
+ assertFalse(rs.next());
+ } finally {
+ conn.close();
+ }
+ }
+
+ @Test
+ public void testOrderByWithJoin() throws Exception {
+ Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+ Connection conn = DriverManager.getConnection(getUrl(), props);
+ conn.setAutoCommit(false);
+
+ try {
+ String ddl = "CREATE TABLE s_table " +
+ " (a_string varchar not null, cf1.a integer, cf1.b varchar, col1 integer, cf2.c varchar, cf2.d integer " +
+ " CONSTRAINT pk PRIMARY KEY (a_string))\n";
+ createTestTable(getUrl(), ddl);
+ String dml = "UPSERT INTO s_table VALUES(?,?,?,?,?,?)";
+ PreparedStatement stmt = conn.prepareStatement(dml);
+ stmt.setString(1, "a");
+ stmt.setInt(2, 40);
+ stmt.setString(3, "aa");
+ stmt.setInt(4, 10);
+ stmt.setString(5, "bb");
+ stmt.setInt(6, 20);
+ stmt.execute();
+ stmt.setString(1, "c");
+ stmt.setInt(2, 30);
+ stmt.setString(3, "cc");
+ stmt.setInt(4, 50);
+ stmt.setString(5, "dd");
+ stmt.setInt(6, 60);
+ stmt.execute();
+ stmt.setString(1, "b");
+ stmt.setInt(2, 40);
+ stmt.setString(3, "bb");
+ stmt.setInt(4, 5);
+ stmt.setString(5, "aa");
+ stmt.setInt(6, 80);
+ stmt.execute();
+ conn.commit();
+
+ ddl = "CREATE TABLE t_table " +
+ " (a_string varchar not null, col1 integer" +
+ " CONSTRAINT pk PRIMARY KEY (a_string))\n";
+ createTestTable(getUrl(), ddl);
+
+ dml = "UPSERT INTO t_table VALUES(?, ?)";
+ stmt = conn.prepareStatement(dml);
+ stmt.setString(1, "a");
+ stmt.setInt(2, 40);
+ stmt.execute();
+ stmt.setString(1, "b");
+ stmt.setInt(2, 20);
+ stmt.execute();
+ stmt.setString(1, "c");
+ stmt.setInt(2, 30);
+ stmt.execute();
+ conn.commit();
+
+ String query = "select t1.* from s_table t1 join t_table t2 on t1.a_string = t2.a_string order by 3";
+ ResultSet rs = conn.createStatement().executeQuery(query);
+ assertTrue(rs.next());
+ assertEquals("a",rs.getString(1));
+ assertEquals(40,rs.getInt(2));
+ assertEquals("aa",rs.getString(3));
+ assertEquals(10,rs.getInt(4));
+ assertEquals("bb",rs.getString(5));
+ assertEquals(20,rs.getInt(6));
+ assertTrue(rs.next());
+ assertEquals("b",rs.getString(1));
+ assertEquals(40,rs.getInt(2));
+ assertEquals("bb",rs.getString(3));
+ assertEquals(5,rs.getInt(4));
+ assertEquals("aa",rs.getString(5));
+ assertEquals(80,rs.getInt(6));
+ assertTrue(rs.next());
+ assertEquals("c",rs.getString(1));
+ assertEquals(30,rs.getInt(2));
+ assertEquals("cc",rs.getString(3));
+ assertEquals(50,rs.getInt(4));
+ assertEquals("dd",rs.getString(5));
+ assertEquals(60,rs.getInt(6));
+ assertFalse(rs.next());
+
+ query = "select t1.a_string, t2.col1 from s_table t1 join t_table t2 on t1.a_string = t2.a_string order by 2";
+ rs = conn.createStatement().executeQuery(query);
+ assertTrue(rs.next());
+ assertEquals("b",rs.getString(1));
+ assertEquals(20,rs.getInt(2));
+ assertTrue(rs.next());
+ assertEquals("c",rs.getString(1));
+ assertEquals(30,rs.getInt(2));
+ assertTrue(rs.next());
+ assertEquals("a",rs.getString(1));
+ assertEquals(40,rs.getInt(2));
+ assertFalse(rs.next());
+ } catch (SQLException e) {
+ } finally {
+ conn.close();
+ }
+ }
+
+ @Test
+ public void testOrderByWithUnionAll() throws Exception {
+ Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+ Connection conn = DriverManager.getConnection(getUrl(), props);
+ conn.setAutoCommit(false);
+
+ try {
+ String ddl = "CREATE TABLE x_table " +
+ " (a_string varchar not null, cf1.a integer, cf1.b varchar, col1 integer, cf2.c varchar, cf2.d integer " +
+ " CONSTRAINT pk PRIMARY KEY (a_string))\n";
+ createTestTable(getUrl(), ddl);
+ String dml = "UPSERT INTO x_table VALUES(?,?,?,?,?,?)";
+ PreparedStatement stmt = conn.prepareStatement(dml);
+ stmt.setString(1, "a");
+ stmt.setInt(2, 40);
+ stmt.setString(3, "aa");
+ stmt.setInt(4, 10);
+ stmt.setString(5, "bb");
+ stmt.setInt(6, 20);
+ stmt.execute();
+ stmt.setString(1, "c");
+ stmt.setInt(2, 30);
+ stmt.setString(3, "cc");
+ stmt.setInt(4, 50);
+ stmt.setString(5, "dd");
+ stmt.setInt(6, 60);
+ stmt.execute();
+ stmt.setString(1, "b");
+ stmt.setInt(2, 40);
+ stmt.setString(3, "bb");
+ stmt.setInt(4, 5);
+ stmt.setString(5, "aa");
+ stmt.setInt(6, 80);
+ stmt.execute();
+ conn.commit();
+
+ ddl = "CREATE TABLE y_table " +
+ " (a_string varchar not null, col1 integer" +
+ " CONSTRAINT pk PRIMARY KEY (a_string))\n";
+ createTestTable(getUrl(), ddl);
+
+ dml = "UPSERT INTO y_table VALUES(?, ?)";
+ stmt = conn.prepareStatement(dml);
+ stmt.setString(1, "aa");
+ stmt.setInt(2, 40);
+ stmt.execute();
+ stmt.setString(1, "bb");
+ stmt.setInt(2, 10);
+ stmt.execute();
+ stmt.setString(1, "cc");
+ stmt.setInt(2, 30);
+ stmt.execute();
+ conn.commit();
+
+ String query = "select a_string, cf2.d from x_table union all select * from y_table order by 2";
+ ResultSet rs = conn.createStatement().executeQuery(query);
+ assertTrue(rs.next());
+ assertEquals("bb",rs.getString(1));
+ assertEquals(10,rs.getInt(2));
+ assertTrue(rs.next());
+ assertEquals("a",rs.getString(1));
+ assertEquals(20,rs.getInt(2));
+ assertTrue(rs.next());
+ assertEquals("cc",rs.getString(1));
+ assertEquals(30,rs.getInt(2));
+ assertTrue(rs.next());
+ assertEquals("aa",rs.getString(1));
+ assertEquals(40,rs.getInt(2));
+ assertTrue(rs.next());
+ assertEquals("c",rs.getString(1));
+ assertEquals(60,rs.getInt(2));
+ assertTrue(rs.next());
+ assertEquals("b",rs.getString(1));
+ assertEquals(80,rs.getInt(2));
+ assertFalse(rs.next());
+ } finally {
+ conn.close();
+ }
+ }
+
+ @Test
+ public void testOrderByWithExpression() throws Exception {
+ Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+ Connection conn = DriverManager.getConnection(getUrl(), props);
+ conn.setAutoCommit(false);
+
+ try {
+ String ddl = "CREATE TABLE e_table " +
+ " (a_string varchar not null, col1 integer, col2 integer, col3 timestamp, col4 varchar" +
+ " CONSTRAINT pk PRIMARY KEY (a_string))\n";
+ createTestTable(getUrl(), ddl);
+
+ Date date = new Date(System.currentTimeMillis());
+ String dml = "UPSERT INTO e_table VALUES(?, ?, ?, ?, ?)";
+ PreparedStatement stmt = conn.prepareStatement(dml);
+ stmt.setString(1, "a");
+ stmt.setInt(2, 40);
+ stmt.setInt(3, 20);
+ stmt.setDate(4, new Date(date.getTime()));
+ stmt.setString(5, "xxyy");
+ stmt.execute();
+ stmt.setString(1, "b");
+ stmt.setInt(2, 50);
+ stmt.setInt(3, 30);
+ stmt.setDate(4, new Date(date.getTime()-500));
+ stmt.setString(5, "yyzz");
+ stmt.execute();
+ stmt.setString(1, "c");
+ stmt.setInt(2, 60);
+ stmt.setInt(3, 20);
+ stmt.setDate(4, new Date(date.getTime()-300));
+ stmt.setString(5, "ddee");
+ stmt.execute();
+ conn.commit();
+
+ String query = "SELECT col1+col2, col4, TRUNC(col3, 'HOUR') FROM e_table ORDER BY 1, 2";
+ conn.createStatement().executeQuery(query);
+ fail();
+ } catch (SQLException e) {
+ } finally {
+ conn.close();
+ }
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/phoenix/blob/795debfe/phoenix-core/src/main/java/org/apache/phoenix/compile/OrderByCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/OrderByCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/OrderByCompiler.java
index 215f59e..d8e86ad 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/OrderByCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/OrderByCompiler.java
@@ -29,12 +29,17 @@ import org.apache.phoenix.exception.SQLExceptionCode;
import org.apache.phoenix.exception.SQLExceptionInfo;
import org.apache.phoenix.expression.Expression;
import org.apache.phoenix.expression.OrderByExpression;
-import org.apache.phoenix.parse.FilterableStatement;
+import org.apache.phoenix.parse.ColumnParseNode;
+import org.apache.phoenix.parse.LiteralParseNode;
import org.apache.phoenix.parse.OrderByNode;
+import org.apache.phoenix.parse.ParseNode;
+import org.apache.phoenix.parse.SelectStatement;
+import org.apache.phoenix.parse.TableName;
import org.apache.phoenix.query.QueryServices;
import org.apache.phoenix.query.QueryServicesOptions;
import org.apache.phoenix.schema.PTableType;
import org.apache.phoenix.schema.SortOrder;
+import org.apache.phoenix.schema.types.PInteger;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
@@ -77,8 +82,9 @@ public class OrderByCompiler {
* @throws SQLException
*/
public static OrderBy compile(StatementContext context,
- FilterableStatement statement,
+ SelectStatement statement,
GroupBy groupBy, Integer limit,
+ RowProjector projector,
boolean isInRowKeyOrder) throws SQLException {
List<OrderByNode> orderByNodes = statement.getOrderBy();
if (orderByNodes.isEmpty()) {
@@ -91,7 +97,28 @@ public class OrderByCompiler {
LinkedHashSet<OrderByExpression> orderByExpressions = Sets.newLinkedHashSetWithExpectedSize(orderByNodes.size());
for (OrderByNode node : orderByNodes) {
boolean isAscending = node.isAscending();
- Expression expression = node.getNode().accept(visitor);
+ ParseNode parseNode = node.getNode();
+ Expression expression = null;
+ if (parseNode instanceof LiteralParseNode && ((LiteralParseNode)parseNode).getType() == PInteger.INSTANCE){
+ Integer index = (Integer)((LiteralParseNode)parseNode).getValue();
+ int size = projector.getColumnProjectors().size();
+ if (index > size || index <= 0 ) {
+ throw new SQLExceptionInfo.Builder(SQLExceptionCode.PARAM_INDEX_OUT_OF_BOUND)
+ .setMessage("").build().buildException();
+ }
+ ColumnProjector colProj = projector.getColumnProjector(index-1);
+ TableName tableName = null;
+ if (statement.getSelects().size() > 0 )
+ tableName = TableName.create(context.getCurrentTable().getTable().getName().toString(), null);
+ else {
+ tableName = TableName.create(context.getResolver().getTables().get(0).getTable().getSchemaName().toString(),
+ context.getResolver().getTables().get(0).getTable().getTableName().toString());
+ }
+ ColumnParseNode colParseNode = new ColumnParseNode(tableName, colProj.getName(), null);
+ expression = colParseNode.accept(visitor);
+ } else {
+ expression = node.getNode().accept(visitor);
+ }
if (!expression.isStateless() && visitor.addEntry(expression, isAscending ? SortOrder.ASC : SortOrder.DESC)) {
// Detect mix of aggregate and non aggregates (i.e. ORDER BY txns, SUM(txns)
if (!visitor.isAggregate()) {
@@ -135,7 +162,6 @@ public class OrderByCompiler {
return new OrderBy(Lists.newArrayList(orderByExpressions.iterator()));
}
-
private OrderByCompiler() {
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/phoenix/blob/795debfe/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java
index 16a7a33..3100664 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java
@@ -532,8 +532,8 @@ public class QueryCompiler {
Set<SubqueryParseNode> subqueries = Sets.<SubqueryParseNode> newHashSet();
Expression where = WhereCompiler.compile(context, select, viewWhere, subqueries);
context.setResolver(resolver); // recover resolver
- OrderBy orderBy = OrderByCompiler.compile(context, select, groupBy, limit, isInRowKeyOrder);
RowProjector projector = ProjectionCompiler.compile(context, select, groupBy, asSubquery ? Collections.<PDatum>emptyList() : targetColumns);
+ OrderBy orderBy = OrderByCompiler.compile(context, select, groupBy, limit, projector, isInRowKeyOrder);
// Final step is to build the query plan
if (!asSubquery) {
int maxRows = statement.getMaxRows();
http://git-wip-us.apache.org/repos/asf/phoenix/blob/795debfe/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryOptimizerTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryOptimizerTest.java b/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryOptimizerTest.java
index 9e37451..67c44bd 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryOptimizerTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryOptimizerTest.java
@@ -33,6 +33,7 @@ import java.util.Properties;
import org.apache.hadoop.hbase.util.Pair;
import org.apache.phoenix.compile.OrderByCompiler.OrderBy;
+import org.apache.phoenix.exception.SQLExceptionCode;
import org.apache.phoenix.jdbc.PhoenixPreparedStatement;
import org.apache.phoenix.jdbc.PhoenixStatement;
import org.apache.phoenix.query.BaseConnectionlessQueryTest;
@@ -80,10 +81,15 @@ public class QueryOptimizerTest extends BaseConnectionlessQueryTest {
@Test
public void testOrderByDropped() throws Exception {
Connection conn = DriverManager.getConnection(getUrl());
- conn.createStatement().execute("CREATE TABLE foo (k VARCHAR NOT NULL PRIMARY KEY, v VARCHAR) IMMUTABLE_ROWS=true");
- PhoenixStatement stmt = conn.createStatement().unwrap(PhoenixStatement.class);
- QueryPlan plan = stmt.optimizeQuery("SELECT * FROM foo ORDER BY 1,2,3");
- assertEquals(OrderBy.EMPTY_ORDER_BY,plan.getOrderBy());
+ try{
+ conn.createStatement().execute("CREATE TABLE foo (k VARCHAR NOT NULL PRIMARY KEY, v VARCHAR) IMMUTABLE_ROWS=true");
+ PhoenixStatement stmt = conn.createStatement().unwrap(PhoenixStatement.class);
+ QueryPlan plan = stmt.optimizeQuery("SELECT * FROM foo ORDER BY 1,2,3");
+ } catch (SQLException e) {
+ assertEquals(SQLExceptionCode.PARAM_INDEX_OUT_OF_BOUND.getErrorCode(), e.getErrorCode());
+ } finally {
+ conn.close();
+ }
}
@Test
[5/5] phoenix git commit: PHOENIX-1765 Add DAYOFMONTH built-in
function (Alicia Ying Shu)
Posted by ja...@apache.org.
PHOENIX-1765 Add DAYOFMONTH built-in function (Alicia Ying Shu)
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/0d78e48b
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/0d78e48b
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/0d78e48b
Branch: refs/heads/master
Commit: 0d78e48b579739fb85a64fe7258f1838dc1af2c8
Parents: 8975fc1
Author: James Taylor <jt...@salesforce.com>
Authored: Mon Apr 13 17:05:45 2015 -0700
Committer: James Taylor <jt...@salesforce.com>
Committed: Mon Apr 13 17:05:45 2015 -0700
----------------------------------------------------------------------
.../org/apache/phoenix/end2end/DateTimeIT.java | 281 +++++++++++++++++-
.../end2end/YearMonthSecondFunctionIT.java | 287 -------------------
.../phoenix/expression/ExpressionType.java | 4 +-
.../expression/function/DayOfMonthFunction.java | 83 ++++++
4 files changed, 365 insertions(+), 290 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/phoenix/blob/0d78e48b/phoenix-core/src/it/java/org/apache/phoenix/end2end/DateTimeIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/DateTimeIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/DateTimeIT.java
index 371d82e..0db36df 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/DateTimeIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/DateTimeIT.java
@@ -42,12 +42,15 @@ import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
+import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.text.Format;
import java.util.Calendar;
import org.apache.phoenix.util.DateUtil;
+import org.junit.After;
+import org.junit.Before;
import org.junit.Test;
@@ -59,12 +62,21 @@ public class DateTimeIT extends BaseHBaseManagedTimeIT {
public DateTimeIT() throws Exception {
super();
- conn = DriverManager.getConnection(getUrl());
date = new Date(System.currentTimeMillis());
+ }
+
+ @Before
+ public void setUp() throws SQLException {
+ conn = DriverManager.getConnection(getUrl());
initAtable();
}
- protected void initAtable() throws Exception {
+ @After
+ public void tearDown() throws SQLException {
+ conn.close();
+ }
+
+ private void initAtable() throws SQLException {
ensureTableCreated(getUrl(), ATABLE_NAME, (byte[][])null);
PreparedStatement stmt = conn.prepareStatement(
"upsert into " + ATABLE_NAME +
@@ -357,4 +369,269 @@ public class DateTimeIT extends BaseHBaseManagedTimeIT {
assertEquals(ROW1, rs.getString(1));
assertFalse(rs.next());
}
+
+ private static int callYearFunction(Connection conn, String invocation) throws SQLException {
+ Statement stmt = conn.createStatement();
+ ResultSet rs =
+ stmt.executeQuery(String
+ .format("SELECT %s FROM SYSTEM.CATALOG LIMIT 1", invocation));
+ assertTrue(rs.next());
+ int returnValue = rs.getInt(1);
+ assertFalse(rs.next());
+ rs.close();
+ stmt.close();
+ return returnValue;
+ }
+
+ private int callYearFunction(String invocation) throws SQLException {
+ return callYearFunction(conn, invocation);
+ }
+
+ @Test
+ public void testYearFunctionDate() throws SQLException {
+
+ assertEquals(2015, callYearFunction("YEAR(current_date())"));
+
+ assertEquals(2015, callYearFunction("YEAR(now())"));
+
+ assertEquals(2008, callYearFunction("YEAR(TO_DATE('2008-01-01', 'yyyy-MM-dd', 'local'))"));
+
+ assertEquals(2004,
+ callYearFunction("YEAR(TO_DATE('2004-12-13 10:13:18', 'yyyy-MM-dd hh:mm:ss'))"));
+
+ assertEquals(2015, callYearFunction("YEAR(TO_DATE('2015-01-27T16:17:57+00:00'))"));
+
+ assertEquals(2005, callYearFunction("YEAR(TO_DATE('2005-12-13 10:13:18'))"));
+
+ assertEquals(2006, callYearFunction("YEAR(TO_DATE('2006-12-13'))"));
+
+ assertEquals(2015, callYearFunction("YEAR(TO_DATE('2015-W05'))"));
+
+ assertEquals(
+ 2008,
+ callYearFunction("YEAR(TO_DATE('Sat, 3 Feb 2008 03:05:06 GMT', 'EEE, d MMM yyyy HH:mm:ss z', 'UTC'))"));
+ }
+
+ @Test
+ public void testYearFunctionTimestamp() throws SQLException {
+
+ assertEquals(2015, callYearFunction("YEAR(TO_TIMESTAMP('2015-01-27T16:17:57+00:00'))"));
+
+ assertEquals(2015, callYearFunction("YEAR(TO_TIMESTAMP('2015-01-27T16:17:57Z'))"));
+
+ assertEquals(2015, callYearFunction("YEAR(TO_TIMESTAMP('2015-W10-3'))"));
+
+ assertEquals(2015, callYearFunction("YEAR(TO_TIMESTAMP('2015-W05'))"));
+
+ assertEquals(2015, callYearFunction("YEAR(TO_TIMESTAMP('2015-063'))"));
+
+ assertEquals(2006, callYearFunction("YEAR(TO_TIMESTAMP('2006-12-13'))"));
+
+ assertEquals(2004,
+ callYearFunction("YEAR(TO_TIMESTAMP('2004-12-13 10:13:18', 'yyyy-MM-dd hh:mm:ss'))"));
+
+ assertEquals(
+ 2008,
+ callYearFunction("YEAR(TO_TIMESTAMP('Sat, 3 Feb 2008 03:05:06 GMT', 'EEE, d MMM yyyy HH:mm:ss z', 'UTC'))"));
+ }
+
+ @Test
+ public void testYearFuncAgainstColumns() throws Exception {
+ String ddl =
+ "CREATE TABLE IF NOT EXISTS T1 (k1 INTEGER NOT NULL, dates DATE, timestamps TIMESTAMP, times TIME, " +
+ "unsignedDates UNSIGNED_DATE, unsignedTimestamps UNSIGNED_TIMESTAMP, unsignedTimes UNSIGNED_TIME CONSTRAINT pk PRIMARY KEY (k1))";
+ conn.createStatement().execute(ddl);
+ String dml = "UPSERT INTO T1 VALUES (1, TO_DATE('2004-03-01 00:00:00'), TO_TIMESTAMP('2006-02-01 00:00:00'), TO_TIME('2008-02-01 00:00:00'), " +
+ "TO_DATE('2010-03-01 00:00:00:896', 'yyyy-MM-dd HH:mm:ss:SSS'), TO_TIMESTAMP('2012-02-01'), TO_TIME('2015-02-01 00:00:00'))";
+ conn.createStatement().execute(dml);
+ dml = "UPSERT INTO T1 VALUES (2, TO_DATE('2005-03-01 00:00:00'), TO_TIMESTAMP('2006-02-01 00:00:00'), TO_TIME('2008-02-01 00:00:00'), " +
+ "TO_DATE('2010-03-01 00:00:00:896', 'yyyy-MM-dd HH:mm:ss:SSS'), TO_TIMESTAMP('2012-02-01'), TO_TIME('2015-02-01 00:00:00'))";
+ conn.createStatement().execute(dml);
+ dml = "UPSERT INTO T1 VALUES (3, TO_DATE('2006-03-01 00:00:00'), TO_TIMESTAMP('2006-02-01 00:00:00'), TO_TIME('2008-02-01 00:00:00'), " +
+ "TO_DATE('2010-03-01 00:00:00:896', 'yyyy-MM-dd HH:mm:ss:SSS'), TO_TIMESTAMP('2012-02-01'), TO_TIME('2015-02-01 00:00:00'))";
+ conn.createStatement().execute(dml);
+ conn.commit();
+
+ ResultSet rs = conn.createStatement().executeQuery("SELECT k1, YEAR(timestamps), YEAR(times), Year(unsignedDates), YEAR(unsignedTimestamps), " +
+ "YEAR(unsignedTimes) FROM T1 where YEAR(dates) = 2004");
+ assertTrue(rs.next());
+ assertEquals(1, rs.getInt(1));
+ assertEquals(2006, rs.getInt(2));
+ assertEquals(2008, rs.getInt(3));
+ assertEquals(2010, rs.getInt(4));
+ assertEquals(2012, rs.getInt(5));
+ assertEquals(2015, rs.getInt(6));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testMonthFuncAgainstColumns() throws Exception {
+ String ddl =
+ "CREATE TABLE IF NOT EXISTS T1 (k1 INTEGER NOT NULL, dates DATE, timestamps TIMESTAMP, times TIME, " +
+ "unsignedDates UNSIGNED_DATE, unsignedTimestamps UNSIGNED_TIMESTAMP, unsignedTimes UNSIGNED_TIME CONSTRAINT pk PRIMARY KEY (k1))";
+ conn.createStatement().execute(ddl);
+ String dml = "UPSERT INTO T1 VALUES (1, TO_DATE('2004-03-10 00:00:00'), TO_TIMESTAMP('2006-04-12 00:00:00'), TO_TIME('2008-05-16 00:00:00'), " +
+ "TO_DATE('2010-06-20 00:00:00:789', 'yyyy-MM-dd HH:mm:ss:SSS'), TO_TIMESTAMP('2012-07-28'), TO_TIME('2015-12-25 00:00:00'))";
+ conn.createStatement().execute(dml);
+ dml = "UPSERT INTO T1 VALUES (2, TO_DATE('2004-04-10 00:00:00'), TO_TIMESTAMP('2006-04-12 00:00:00'), TO_TIME('2008-05-16 00:00:00'), " +
+ "TO_DATE('2010-06-20 00:00:00:789', 'yyyy-MM-dd HH:mm:ss:SSS'), TO_TIMESTAMP('2012-07-28'), TO_TIME('2015-12-25 00:00:00'))";
+ conn.createStatement().execute(dml);
+ dml = "UPSERT INTO T1 VALUES (3, TO_DATE('2004-05-10 00:00:00'), TO_TIMESTAMP('2006-04-12 00:00:00'), TO_TIME('2008-05-16 00:00:00'), " +
+ "TO_DATE('2010-06-20 00:00:00:789', 'yyyy-MM-dd HH:mm:ss:SSS'), TO_TIMESTAMP('2012-07-28'), TO_TIME('2015-12-25 00:00:00'))";
+ conn.createStatement().execute(dml);
+ conn.commit();
+
+ ResultSet rs = conn.createStatement().executeQuery("SELECT k1, MONTH(timestamps), MONTH(times), MONTH(unsignedDates), MONTH(unsignedTimestamps), " +
+ "MONTH(unsignedTimes) FROM T1 where MONTH(dates) = 3");
+ assertTrue(rs.next());
+ assertEquals(1, rs.getInt(1));
+ assertEquals(4, rs.getInt(2));
+ assertEquals(5, rs.getInt(3));
+ assertEquals(6, rs.getInt(4));
+ assertEquals(7, rs.getInt(5));
+ assertEquals(12, rs.getInt(6));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testSecondFuncAgainstColumns() throws Exception {
+ String ddl =
+ "CREATE TABLE IF NOT EXISTS T1 (k1 INTEGER NOT NULL, dates DATE, timestamps TIMESTAMP, times TIME, " +
+ "unsignedDates UNSIGNED_DATE, unsignedTimestamps UNSIGNED_TIMESTAMP, unsignedTimes UNSIGNED_TIME CONSTRAINT pk PRIMARY KEY (k1))";
+ conn.createStatement().execute(ddl);
+ String dml = "UPSERT INTO T1 VALUES (1, TO_DATE('2004-03-01 00:00:10'), TO_TIMESTAMP('2006-04-12 00:00:20'), TO_TIME('2008-05-16 10:00:30'), " +
+ "TO_DATE('2010-06-20 00:00:40:789', 'yyyy-MM-dd HH:mm:ss:SSS'), TO_TIMESTAMP('2012-07-28'), TO_TIME('2015-12-25 00:00:50'))";
+ conn.createStatement().execute(dml);
+ dml = "UPSERT INTO T1 VALUES (2, TO_DATE('2004-03-01 00:00:10'), TO_TIMESTAMP('2006-04-12 00:20:30'), TO_TIME('2008-05-16 10:00:30'), " +
+ "TO_DATE('2010-06-20 00:00:40:789', 'yyyy-MM-dd HH:mm:ss:SSS'), TO_TIMESTAMP('2012-07-28'), TO_TIME('2015-12-25 00:00:50'))";
+ conn.createStatement().execute(dml);
+ dml = "UPSERT INTO T1 VALUES (3, TO_DATE('2004-03-01 00:00:10'), TO_TIMESTAMP('2006-04-12 00:50:30'), TO_TIME('2008-05-16 10:00:30'), " +
+ "TO_DATE('2010-06-20 00:00:40:789', 'yyyy-MM-dd HH:mm:ss:SSS'), TO_TIMESTAMP('2012-07-28'), TO_TIME('2015-12-25 00:00:50'))";
+ conn.createStatement().execute(dml);
+ conn.commit();
+
+ ResultSet rs = conn.createStatement().executeQuery("SELECT k1, SECOND(dates), SECOND(times), SECOND(unsignedDates), SECOND(unsignedTimestamps), " +
+ "SECOND(unsignedTimes) FROM T1 where SECOND(timestamps)=20");
+ assertTrue(rs.next());
+ assertEquals(1, rs.getInt(1));
+ assertEquals(10, rs.getInt(2));
+ assertEquals(30, rs.getInt(3));
+ assertEquals(40, rs.getInt(4));
+ assertEquals(0, rs.getInt(5));
+ assertEquals(50, rs.getInt(6));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testWeekFuncAgainstColumns() throws Exception {
+ String ddl =
+ "CREATE TABLE IF NOT EXISTS T1 (k1 INTEGER NOT NULL, dates DATE, timestamps TIMESTAMP, times TIME CONSTRAINT pk PRIMARY KEY (k1))";
+ conn.createStatement().execute(ddl);
+ String dml = "UPSERT INTO T1 VALUES (1, TO_DATE('2004-01-10 10:00:10'), TO_TIMESTAMP('2006-04-12 08:00:20'), TO_TIME('2008-05-16 10:00:30'))";
+ conn.createStatement().execute(dml);
+ dml = "UPSERT INTO T1 VALUES (2, TO_DATE('2004-01-10 10:00:10'), TO_TIMESTAMP('2006-05-18 08:00:20'), TO_TIME('2008-05-16 10:00:30'))";
+ conn.createStatement().execute(dml);
+ dml = "UPSERT INTO T1 VALUES (3, TO_DATE('2004-01-10 10:00:10'), TO_TIMESTAMP('2006-05-18 08:00:20'), TO_TIME('2008-05-16 10:00:30'))";
+ conn.createStatement().execute(dml);
+ conn.commit();
+
+ ResultSet rs = conn.createStatement().executeQuery("SELECT k1, WEEK(dates), WEEK(times) FROM T1 where WEEK(timestamps)=15");
+ assertTrue(rs.next());
+ assertEquals(1, rs.getInt(1));
+ assertEquals(2, rs.getInt(2));
+ assertEquals(20, rs.getInt(3));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testHourFuncAgainstColumns() throws Exception {
+ String ddl =
+ "CREATE TABLE IF NOT EXISTS T1 (k1 INTEGER NOT NULL, dates DATE, timestamps TIMESTAMP, times TIME CONSTRAINT pk PRIMARY KEY (k1))";
+ conn.createStatement().execute(ddl);
+ String dml = "UPSERT INTO T1 VALUES (1, TO_DATE('Sat, 3 Feb 2008 03:05:06 GMT', 'EEE, d MMM yyyy HH:mm:ss z', 'UTC'), TO_TIMESTAMP('2006-04-12 15:10:20'), " +
+ "TO_TIME('2008-05-16 20:40:30'))";
+ conn.createStatement().execute(dml);
+ dml = "UPSERT INTO T1 VALUES (2, TO_DATE('Sat, 3 Feb 2008 03:05:06 GMT', 'EEE, d MMM yyyy HH:mm:ss z', 'UTC'), TO_TIMESTAMP('2006-04-12 10:10:20'), " +
+ "TO_TIME('2008-05-16 20:40:30'))";
+ conn.createStatement().execute(dml);
+ dml = "UPSERT INTO T1 VALUES (3, TO_DATE('Sat, 3 Feb 2008 03:05:06 GMT', 'EEE, d MMM yyyy HH:mm:ss z', 'UTC'), TO_TIMESTAMP('2006-04-12 08:10:20'), " +
+ "TO_TIME('2008-05-16 20:40:30'))";
+ conn.createStatement().execute(dml);
+ conn.commit();
+
+ ResultSet rs = conn.createStatement().executeQuery("SELECT k1, HOUR(dates), HOUR(times) FROM T1 where HOUR(timestamps)=15");
+ assertTrue(rs.next());
+ assertEquals(1, rs.getInt(1));
+ assertEquals(3, rs.getInt(2));
+ assertEquals(20, rs.getInt(3));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testNowFunction() throws Exception {
+ Date date = new Date(System.currentTimeMillis());
+ String ddl =
+ "CREATE TABLE IF NOT EXISTS T1 (k1 INTEGER NOT NULL, timestamps TIMESTAMP CONSTRAINT pk PRIMARY KEY (k1))";
+ conn.createStatement().execute(ddl);
+ String dml = "UPSERT INTO T1 VALUES (?, ?)";
+ PreparedStatement stmt = conn.prepareStatement(dml);
+ stmt.setInt(1, 1);
+ stmt.setDate(2, new Date(date.getTime()-500));
+ stmt.execute();
+ stmt.setInt(1, 2);
+ stmt.setDate(2, new Date(date.getTime()+600000));
+ stmt.execute();
+ conn.commit();
+
+ ResultSet rs = conn.createStatement().executeQuery("SELECT * from T1 where now() > timestamps");
+ assertTrue(rs.next());
+ assertEquals(1, rs.getInt(1));
+ assertEquals(new Date(date.getTime()-500), rs.getDate(2));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testMinuteFuncAgainstColumns() throws Exception {
+ String ddl =
+ "CREATE TABLE IF NOT EXISTS T1 (k1 INTEGER NOT NULL, dates DATE, timestamps TIMESTAMP, times TIME, " +
+ "unsignedDates UNSIGNED_DATE, unsignedTimestamps UNSIGNED_TIMESTAMP, unsignedTimes UNSIGNED_TIME CONSTRAINT pk PRIMARY KEY (k1))";
+ conn.createStatement().execute(ddl);
+ String dml = "UPSERT INTO T1 VALUES (1, TO_DATE('2004-03-01 00:10:10'), TO_TIMESTAMP('2006-04-12 00:20:20'), TO_TIME('2008-05-16 10:30:30'), " +
+ "TO_DATE('2010-06-20 00:40:40:789', 'yyyy-MM-dd HH:mm:ss:SSS'), TO_TIMESTAMP('2012-07-28'), TO_TIME('2015-12-25 00:50:50'))";
+ conn.createStatement().execute(dml);
+ dml = "UPSERT INTO T1 VALUES (2, TO_DATE('2004-03-01 00:10:10'), TO_TIMESTAMP('2006-04-12 00:50:20'), TO_TIME('2008-05-16 10:30:30'), " +
+ "TO_DATE('2010-06-20 00:40:40:789', 'yyyy-MM-dd HH:mm:ss:SSS'), TO_TIMESTAMP('2012-07-28'), TO_TIME('2015-12-25 00:50:50'))";
+ conn.createStatement().execute(dml);
+ conn.commit();
+
+ ResultSet rs = conn.createStatement().executeQuery("SELECT k1, MINUTE(dates), MINUTE(times), MINUTE(unsignedDates), MINUTE(unsignedTimestamps), " +
+ "MINUTE(unsignedTimes) FROM T1 where MINUTE(timestamps)=20");
+ assertTrue(rs.next());
+ assertEquals(1, rs.getInt(1));
+ assertEquals(10, rs.getInt(2));
+ assertEquals(30, rs.getInt(3));
+ assertEquals(40, rs.getInt(4));
+ assertEquals(0, rs.getInt(5));
+ assertEquals(50, rs.getInt(6));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testDayOfMonthFuncAgainstColumns() throws Exception {
+ String ddl =
+ "CREATE TABLE IF NOT EXISTS T1 (k1 INTEGER NOT NULL, dates DATE, timestamps TIMESTAMP, times TIME CONSTRAINT pk PRIMARY KEY (k1))";
+ conn.createStatement().execute(ddl);
+ String dml = "UPSERT INTO T1 VALUES (1, TO_DATE('2004-01-08 10:00:10'), TO_TIMESTAMP('2006-04-12 08:00:20'), TO_TIME('2008-05-26 11:00:30'))";
+ conn.createStatement().execute(dml);
+ dml = "UPSERT INTO T1 VALUES (2, TO_DATE('2004-01-18 10:00:10'), TO_TIMESTAMP('2006-05-22 08:00:20'), TO_TIME('2008-12-30 11:00:30'))";
+ conn.createStatement().execute(dml);
+ conn.commit();
+
+ ResultSet rs = conn.createStatement().executeQuery("SELECT k1, DAYOFMONTH(dates), DAYOFMONTH(times) FROM T1 where DAYOFMONTH(timestamps)=12");
+ assertTrue(rs.next());
+ assertEquals(1, rs.getInt(1));
+ assertEquals(8, rs.getInt(2));
+ assertEquals(26, rs.getInt(3));
+ assertFalse(rs.next());
+ }
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/0d78e48b/phoenix-core/src/it/java/org/apache/phoenix/end2end/YearMonthSecondFunctionIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/YearMonthSecondFunctionIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/YearMonthSecondFunctionIT.java
deleted file mode 100644
index 1206ee4..0000000
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/YearMonthSecondFunctionIT.java
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * 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;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-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.sql.Statement;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class YearMonthSecondFunctionIT extends BaseHBaseManagedTimeIT {
- private Connection conn;
-
- @Before
- public void setUp() throws SQLException {
- conn = DriverManager.getConnection(getUrl());
- }
-
- @After
- public void tearDown() throws SQLException {
- conn.close();
- }
-
- private static int callYearFunction(Connection conn, String invocation) throws SQLException {
- Statement stmt = conn.createStatement();
- ResultSet rs =
- stmt.executeQuery(String
- .format("SELECT %s FROM SYSTEM.CATALOG LIMIT 1", invocation));
- assertTrue(rs.next());
- int returnValue = rs.getInt(1);
- assertFalse(rs.next());
- rs.close();
- stmt.close();
- return returnValue;
- }
-
- private int callYearFunction(String invocation) throws SQLException {
- return callYearFunction(conn, invocation);
- }
-
- @Test
- public void testYearFunctionDate() throws SQLException {
-
- assertEquals(2015, callYearFunction("YEAR(current_date())"));
-
- assertEquals(2015, callYearFunction("YEAR(now())"));
-
- assertEquals(2008, callYearFunction("YEAR(TO_DATE('2008-01-01', 'yyyy-MM-dd', 'local'))"));
-
- assertEquals(2004,
- callYearFunction("YEAR(TO_DATE('2004-12-13 10:13:18', 'yyyy-MM-dd hh:mm:ss'))"));
-
- assertEquals(2015, callYearFunction("YEAR(TO_DATE('2015-01-27T16:17:57+00:00'))"));
-
- assertEquals(2005, callYearFunction("YEAR(TO_DATE('2005-12-13 10:13:18'))"));
-
- assertEquals(2006, callYearFunction("YEAR(TO_DATE('2006-12-13'))"));
-
- assertEquals(2015, callYearFunction("YEAR(TO_DATE('2015-W05'))"));
-
- assertEquals(
- 2008,
- callYearFunction("YEAR(TO_DATE('Sat, 3 Feb 2008 03:05:06 GMT', 'EEE, d MMM yyyy HH:mm:ss z', 'UTC'))"));
- }
-
- @Test
- public void testYearFunctionTimestamp() throws SQLException {
-
- assertEquals(2015, callYearFunction("YEAR(TO_TIMESTAMP('2015-01-27T16:17:57+00:00'))"));
-
- assertEquals(2015, callYearFunction("YEAR(TO_TIMESTAMP('2015-01-27T16:17:57Z'))"));
-
- assertEquals(2015, callYearFunction("YEAR(TO_TIMESTAMP('2015-W10-3'))"));
-
- assertEquals(2015, callYearFunction("YEAR(TO_TIMESTAMP('2015-W05'))"));
-
- assertEquals(2015, callYearFunction("YEAR(TO_TIMESTAMP('2015-063'))"));
-
- assertEquals(2006, callYearFunction("YEAR(TO_TIMESTAMP('2006-12-13'))"));
-
- assertEquals(2004,
- callYearFunction("YEAR(TO_TIMESTAMP('2004-12-13 10:13:18', 'yyyy-MM-dd hh:mm:ss'))"));
-
- assertEquals(
- 2008,
- callYearFunction("YEAR(TO_TIMESTAMP('Sat, 3 Feb 2008 03:05:06 GMT', 'EEE, d MMM yyyy HH:mm:ss z', 'UTC'))"));
- }
-
- @Test
- public void testYearFuncAgainstColumns() throws Exception {
- String ddl =
- "CREATE TABLE IF NOT EXISTS T1 (k1 INTEGER NOT NULL, dates DATE, timestamps TIMESTAMP, times TIME, " +
- "unsignedDates UNSIGNED_DATE, unsignedTimestamps UNSIGNED_TIMESTAMP, unsignedTimes UNSIGNED_TIME CONSTRAINT pk PRIMARY KEY (k1))";
- conn.createStatement().execute(ddl);
- String dml = "UPSERT INTO T1 VALUES (1, TO_DATE('2004-03-01 00:00:00'), TO_TIMESTAMP('2006-02-01 00:00:00'), TO_TIME('2008-02-01 00:00:00'), " +
- "TO_DATE('2010-03-01 00:00:00:896', 'yyyy-MM-dd HH:mm:ss:SSS'), TO_TIMESTAMP('2012-02-01'), TO_TIME('2015-02-01 00:00:00'))";
- conn.createStatement().execute(dml);
- dml = "UPSERT INTO T1 VALUES (2, TO_DATE('2005-03-01 00:00:00'), TO_TIMESTAMP('2006-02-01 00:00:00'), TO_TIME('2008-02-01 00:00:00'), " +
- "TO_DATE('2010-03-01 00:00:00:896', 'yyyy-MM-dd HH:mm:ss:SSS'), TO_TIMESTAMP('2012-02-01'), TO_TIME('2015-02-01 00:00:00'))";
- conn.createStatement().execute(dml);
- dml = "UPSERT INTO T1 VALUES (3, TO_DATE('2006-03-01 00:00:00'), TO_TIMESTAMP('2006-02-01 00:00:00'), TO_TIME('2008-02-01 00:00:00'), " +
- "TO_DATE('2010-03-01 00:00:00:896', 'yyyy-MM-dd HH:mm:ss:SSS'), TO_TIMESTAMP('2012-02-01'), TO_TIME('2015-02-01 00:00:00'))";
- conn.createStatement().execute(dml);
- conn.commit();
-
- ResultSet rs = conn.createStatement().executeQuery("SELECT k1, YEAR(timestamps), YEAR(times), Year(unsignedDates), YEAR(unsignedTimestamps), " +
- "YEAR(unsignedTimes) FROM T1 where YEAR(dates) = 2004");
- assertTrue(rs.next());
- assertEquals(1, rs.getInt(1));
- assertEquals(2006, rs.getInt(2));
- assertEquals(2008, rs.getInt(3));
- assertEquals(2010, rs.getInt(4));
- assertEquals(2012, rs.getInt(5));
- assertEquals(2015, rs.getInt(6));
- assertFalse(rs.next());
- }
-
- @Test
- public void testMonthFuncAgainstColumns() throws Exception {
- String ddl =
- "CREATE TABLE IF NOT EXISTS T1 (k1 INTEGER NOT NULL, dates DATE, timestamps TIMESTAMP, times TIME, " +
- "unsignedDates UNSIGNED_DATE, unsignedTimestamps UNSIGNED_TIMESTAMP, unsignedTimes UNSIGNED_TIME CONSTRAINT pk PRIMARY KEY (k1))";
- conn.createStatement().execute(ddl);
- String dml = "UPSERT INTO T1 VALUES (1, TO_DATE('2004-03-10 00:00:00'), TO_TIMESTAMP('2006-04-12 00:00:00'), TO_TIME('2008-05-16 00:00:00'), " +
- "TO_DATE('2010-06-20 00:00:00:789', 'yyyy-MM-dd HH:mm:ss:SSS'), TO_TIMESTAMP('2012-07-28'), TO_TIME('2015-12-25 00:00:00'))";
- conn.createStatement().execute(dml);
- dml = "UPSERT INTO T1 VALUES (2, TO_DATE('2004-04-10 00:00:00'), TO_TIMESTAMP('2006-04-12 00:00:00'), TO_TIME('2008-05-16 00:00:00'), " +
- "TO_DATE('2010-06-20 00:00:00:789', 'yyyy-MM-dd HH:mm:ss:SSS'), TO_TIMESTAMP('2012-07-28'), TO_TIME('2015-12-25 00:00:00'))";
- conn.createStatement().execute(dml);
- dml = "UPSERT INTO T1 VALUES (3, TO_DATE('2004-05-10 00:00:00'), TO_TIMESTAMP('2006-04-12 00:00:00'), TO_TIME('2008-05-16 00:00:00'), " +
- "TO_DATE('2010-06-20 00:00:00:789', 'yyyy-MM-dd HH:mm:ss:SSS'), TO_TIMESTAMP('2012-07-28'), TO_TIME('2015-12-25 00:00:00'))";
- conn.createStatement().execute(dml);
- conn.commit();
-
- ResultSet rs = conn.createStatement().executeQuery("SELECT k1, MONTH(timestamps), MONTH(times), MONTH(unsignedDates), MONTH(unsignedTimestamps), " +
- "MONTH(unsignedTimes) FROM T1 where MONTH(dates) = 3");
- assertTrue(rs.next());
- assertEquals(1, rs.getInt(1));
- assertEquals(4, rs.getInt(2));
- assertEquals(5, rs.getInt(3));
- assertEquals(6, rs.getInt(4));
- assertEquals(7, rs.getInt(5));
- assertEquals(12, rs.getInt(6));
- assertFalse(rs.next());
- }
-
- @Test
- public void testSecondFuncAgainstColumns() throws Exception {
- String ddl =
- "CREATE TABLE IF NOT EXISTS T1 (k1 INTEGER NOT NULL, dates DATE, timestamps TIMESTAMP, times TIME, " +
- "unsignedDates UNSIGNED_DATE, unsignedTimestamps UNSIGNED_TIMESTAMP, unsignedTimes UNSIGNED_TIME CONSTRAINT pk PRIMARY KEY (k1))";
- conn.createStatement().execute(ddl);
- String dml = "UPSERT INTO T1 VALUES (1, TO_DATE('2004-03-01 00:00:10'), TO_TIMESTAMP('2006-04-12 00:00:20'), TO_TIME('2008-05-16 10:00:30'), " +
- "TO_DATE('2010-06-20 00:00:40:789', 'yyyy-MM-dd HH:mm:ss:SSS'), TO_TIMESTAMP('2012-07-28'), TO_TIME('2015-12-25 00:00:50'))";
- conn.createStatement().execute(dml);
- dml = "UPSERT INTO T1 VALUES (2, TO_DATE('2004-03-01 00:00:10'), TO_TIMESTAMP('2006-04-12 00:20:30'), TO_TIME('2008-05-16 10:00:30'), " +
- "TO_DATE('2010-06-20 00:00:40:789', 'yyyy-MM-dd HH:mm:ss:SSS'), TO_TIMESTAMP('2012-07-28'), TO_TIME('2015-12-25 00:00:50'))";
- conn.createStatement().execute(dml);
- dml = "UPSERT INTO T1 VALUES (3, TO_DATE('2004-03-01 00:00:10'), TO_TIMESTAMP('2006-04-12 00:50:30'), TO_TIME('2008-05-16 10:00:30'), " +
- "TO_DATE('2010-06-20 00:00:40:789', 'yyyy-MM-dd HH:mm:ss:SSS'), TO_TIMESTAMP('2012-07-28'), TO_TIME('2015-12-25 00:00:50'))";
- conn.createStatement().execute(dml);
- conn.commit();
-
- ResultSet rs = conn.createStatement().executeQuery("SELECT k1, SECOND(dates), SECOND(times), SECOND(unsignedDates), SECOND(unsignedTimestamps), " +
- "SECOND(unsignedTimes) FROM T1 where SECOND(timestamps)=20");
- assertTrue(rs.next());
- assertEquals(1, rs.getInt(1));
- assertEquals(10, rs.getInt(2));
- assertEquals(30, rs.getInt(3));
- assertEquals(40, rs.getInt(4));
- assertEquals(0, rs.getInt(5));
- assertEquals(50, rs.getInt(6));
- assertFalse(rs.next());
- }
-
- @Test
- public void testWeekFuncAgainstColumns() throws Exception {
- String ddl =
- "CREATE TABLE IF NOT EXISTS T1 (k1 INTEGER NOT NULL, dates DATE, timestamps TIMESTAMP, times TIME CONSTRAINT pk PRIMARY KEY (k1))";
- conn.createStatement().execute(ddl);
- String dml = "UPSERT INTO T1 VALUES (1, TO_DATE('2004-01-10 10:00:10'), TO_TIMESTAMP('2006-04-12 08:00:20'), TO_TIME('2008-05-16 10:00:30'))";
- conn.createStatement().execute(dml);
- dml = "UPSERT INTO T1 VALUES (2, TO_DATE('2004-01-10 10:00:10'), TO_TIMESTAMP('2006-05-18 08:00:20'), TO_TIME('2008-05-16 10:00:30'))";
- conn.createStatement().execute(dml);
- dml = "UPSERT INTO T1 VALUES (3, TO_DATE('2004-01-10 10:00:10'), TO_TIMESTAMP('2006-05-18 08:00:20'), TO_TIME('2008-05-16 10:00:30'))";
- conn.createStatement().execute(dml);
- conn.commit();
-
- ResultSet rs = conn.createStatement().executeQuery("SELECT k1, WEEK(dates), WEEK(times) FROM T1 where WEEK(timestamps)=15");
- assertTrue(rs.next());
- assertEquals(1, rs.getInt(1));
- assertEquals(2, rs.getInt(2));
- assertEquals(20, rs.getInt(3));
- assertFalse(rs.next());
- }
-
- @Test
- public void testHourFuncAgainstColumns() throws Exception {
- String ddl =
- "CREATE TABLE IF NOT EXISTS T1 (k1 INTEGER NOT NULL, dates DATE, timestamps TIMESTAMP, times TIME CONSTRAINT pk PRIMARY KEY (k1))";
- conn.createStatement().execute(ddl);
- String dml = "UPSERT INTO T1 VALUES (1, TO_DATE('Sat, 3 Feb 2008 03:05:06 GMT', 'EEE, d MMM yyyy HH:mm:ss z', 'UTC'), TO_TIMESTAMP('2006-04-12 15:10:20'), " +
- "TO_TIME('2008-05-16 20:40:30'))";
- conn.createStatement().execute(dml);
- dml = "UPSERT INTO T1 VALUES (2, TO_DATE('Sat, 3 Feb 2008 03:05:06 GMT', 'EEE, d MMM yyyy HH:mm:ss z', 'UTC'), TO_TIMESTAMP('2006-04-12 10:10:20'), " +
- "TO_TIME('2008-05-16 20:40:30'))";
- conn.createStatement().execute(dml);
- dml = "UPSERT INTO T1 VALUES (3, TO_DATE('Sat, 3 Feb 2008 03:05:06 GMT', 'EEE, d MMM yyyy HH:mm:ss z', 'UTC'), TO_TIMESTAMP('2006-04-12 08:10:20'), " +
- "TO_TIME('2008-05-16 20:40:30'))";
- conn.createStatement().execute(dml);
- conn.commit();
-
- ResultSet rs = conn.createStatement().executeQuery("SELECT k1, HOUR(dates), HOUR(times) FROM T1 where HOUR(timestamps)=15");
- assertTrue(rs.next());
- assertEquals(1, rs.getInt(1));
- assertEquals(3, rs.getInt(2));
- assertEquals(20, rs.getInt(3));
- assertFalse(rs.next());
- }
-
- @Test
- public void testNowFunction() throws Exception {
- Date date = new Date(System.currentTimeMillis());
- String ddl =
- "CREATE TABLE IF NOT EXISTS T1 (k1 INTEGER NOT NULL, timestamps TIMESTAMP CONSTRAINT pk PRIMARY KEY (k1))";
- conn.createStatement().execute(ddl);
- String dml = "UPSERT INTO T1 VALUES (?, ?)";
- PreparedStatement stmt = conn.prepareStatement(dml);
- stmt.setInt(1, 1);
- stmt.setDate(2, new Date(date.getTime()-500));
- stmt.execute();
- stmt.setInt(1, 2);
- stmt.setDate(2, new Date(date.getTime()+600000));
- stmt.execute();
- conn.commit();
-
- ResultSet rs = conn.createStatement().executeQuery("SELECT * from T1 where now() > timestamps");
- assertTrue(rs.next());
- assertEquals(1, rs.getInt(1));
- assertEquals(new Date(date.getTime()-500), rs.getDate(2));
- assertFalse(rs.next());
- }
-
- @Test
- public void testMinuteFuncAgainstColumns() throws Exception {
- String ddl =
- "CREATE TABLE IF NOT EXISTS T1 (k1 INTEGER NOT NULL, dates DATE, timestamps TIMESTAMP, times TIME, " +
- "unsignedDates UNSIGNED_DATE, unsignedTimestamps UNSIGNED_TIMESTAMP, unsignedTimes UNSIGNED_TIME CONSTRAINT pk PRIMARY KEY (k1))";
- conn.createStatement().execute(ddl);
- String dml = "UPSERT INTO T1 VALUES (1, TO_DATE('2004-03-01 00:10:10'), TO_TIMESTAMP('2006-04-12 00:20:20'), TO_TIME('2008-05-16 10:30:30'), " +
- "TO_DATE('2010-06-20 00:40:40:789', 'yyyy-MM-dd HH:mm:ss:SSS'), TO_TIMESTAMP('2012-07-28'), TO_TIME('2015-12-25 00:50:50'))";
- conn.createStatement().execute(dml);
- dml = "UPSERT INTO T1 VALUES (2, TO_DATE('2004-03-01 00:10:10'), TO_TIMESTAMP('2006-04-12 00:50:20'), TO_TIME('2008-05-16 10:30:30'), " +
- "TO_DATE('2010-06-20 00:40:40:789', 'yyyy-MM-dd HH:mm:ss:SSS'), TO_TIMESTAMP('2012-07-28'), TO_TIME('2015-12-25 00:50:50'))";
- conn.createStatement().execute(dml);
- conn.commit();
-
- ResultSet rs = conn.createStatement().executeQuery("SELECT k1, MINUTE(dates), MINUTE(times), MINUTE(unsignedDates), MINUTE(unsignedTimestamps), " +
- "MINUTE(unsignedTimes) FROM T1 where MINUTE(timestamps)=20");
- assertTrue(rs.next());
- assertEquals(1, rs.getInt(1));
- assertEquals(10, rs.getInt(2));
- assertEquals(30, rs.getInt(3));
- assertEquals(40, rs.getInt(4));
- assertEquals(0, rs.getInt(5));
- assertEquals(50, rs.getInt(6));
- assertFalse(rs.next());
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/phoenix/blob/0d78e48b/phoenix-core/src/main/java/org/apache/phoenix/expression/ExpressionType.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/ExpressionType.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/ExpressionType.java
index d42c5f2..d562d6a 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/ExpressionType.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/ExpressionType.java
@@ -31,6 +31,7 @@ import org.apache.phoenix.expression.function.CeilTimestampExpression;
import org.apache.phoenix.expression.function.CoalesceFunction;
import org.apache.phoenix.expression.function.ConvertTimezoneFunction;
import org.apache.phoenix.expression.function.CountAggregateFunction;
+import org.apache.phoenix.expression.function.DayOfMonthFunction;
import org.apache.phoenix.expression.function.DecodeFunction;
import org.apache.phoenix.expression.function.DistinctCountAggregateFunction;
import org.apache.phoenix.expression.function.DistinctValueAggregateFunction;
@@ -209,7 +210,8 @@ public enum ExpressionType {
HourFunction(HourFunction.class),
NowFunction(NowFunction.class),
InstrFunction(InstrFunction.class),
- MinuteFunction(MinuteFunction.class)
+ MinuteFunction(MinuteFunction.class),
+ DayOfMonthFunction(DayOfMonthFunction.class)
;
ExpressionType(Class<? extends Expression> clazz) {
http://git-wip-us.apache.org/repos/asf/phoenix/blob/0d78e48b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/DayOfMonthFunction.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/DayOfMonthFunction.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/DayOfMonthFunction.java
new file mode 100644
index 0000000..0c328cf
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/DayOfMonthFunction.java
@@ -0,0 +1,83 @@
+/*
+ * 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.expression.function;
+
+import java.sql.SQLException;
+import java.util.List;
+
+import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
+import org.apache.phoenix.expression.Expression;
+import org.apache.phoenix.parse.FunctionParseNode.Argument;
+import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
+import org.apache.phoenix.schema.tuple.Tuple;
+import org.apache.phoenix.schema.types.PDataType;
+import org.apache.phoenix.schema.types.PInteger;
+import org.apache.phoenix.schema.types.PTimestamp;
+import org.joda.time.DateTime;
+
+/**
+ *
+ * Implementation of the DayOfMonth() buildin. Input Date/Timestamp.
+ * An integer from 1 to 31 representing the day of the month in date
+ *
+ */
+@BuiltInFunction(name=DayOfMonthFunction.NAME,
+args={@Argument(allowedTypes={PTimestamp.class})})
+public class DayOfMonthFunction extends ScalarFunction {
+ public static final String NAME = "DAYOFMONTH";
+
+ public DayOfMonthFunction() {
+ }
+
+ public DayOfMonthFunction(List<Expression> children) throws SQLException {
+ super(children);
+ }
+
+ @Override
+ public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) {
+ Expression expression = getChildExpression();
+ if (!expression.evaluate(tuple, ptr)) {
+ return false;
+ }
+ if ( ptr.getLength() == 0) {
+ return true; //means null
+ }
+ long dateTime = expression.getDataType().getCodec().decodeLong(ptr, expression.getSortOrder());
+ DateTime dt = new DateTime(dateTime);
+ int day = dt.getDayOfMonth();
+ PDataType returnType = getDataType();
+ byte[] byteValue = new byte[returnType.getByteSize()];
+ returnType.getCodec().encodeInt(day, byteValue, 0);
+ ptr.set(byteValue);
+ return true;
+ }
+
+ @Override
+ public PDataType getDataType() {
+ return PInteger.INSTANCE;
+ }
+
+ @Override
+ public String getName() {
+ return NAME;
+ }
+
+ private Expression getChildExpression() {
+ return children.get(0);
+ }
+}
[4/5] phoenix git commit: PHOENIX-1846 Add MINUTE built-in function
(Alicia Ying Shu)
Posted by ja...@apache.org.
PHOENIX-1846 Add MINUTE built-in function (Alicia Ying Shu)
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/8975fc1a
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/8975fc1a
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/8975fc1a
Branch: refs/heads/master
Commit: 8975fc1a427700fc3f13d34ddd610404781683ae
Parents: 36a7f24
Author: James Taylor <jt...@salesforce.com>
Authored: Mon Apr 13 16:32:31 2015 -0700
Committer: James Taylor <jt...@salesforce.com>
Committed: Mon Apr 13 16:32:31 2015 -0700
----------------------------------------------------------------------
.../end2end/YearMonthSecondFunctionIT.java | 26 +++++++
.../phoenix/expression/ExpressionType.java | 4 +-
.../expression/function/MinuteFunction.java | 81 ++++++++++++++++++++
3 files changed, 110 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/phoenix/blob/8975fc1a/phoenix-core/src/it/java/org/apache/phoenix/end2end/YearMonthSecondFunctionIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/YearMonthSecondFunctionIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/YearMonthSecondFunctionIT.java
index cc51bdd..1206ee4 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/YearMonthSecondFunctionIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/YearMonthSecondFunctionIT.java
@@ -258,4 +258,30 @@ public class YearMonthSecondFunctionIT extends BaseHBaseManagedTimeIT {
assertEquals(new Date(date.getTime()-500), rs.getDate(2));
assertFalse(rs.next());
}
+
+ @Test
+ public void testMinuteFuncAgainstColumns() throws Exception {
+ String ddl =
+ "CREATE TABLE IF NOT EXISTS T1 (k1 INTEGER NOT NULL, dates DATE, timestamps TIMESTAMP, times TIME, " +
+ "unsignedDates UNSIGNED_DATE, unsignedTimestamps UNSIGNED_TIMESTAMP, unsignedTimes UNSIGNED_TIME CONSTRAINT pk PRIMARY KEY (k1))";
+ conn.createStatement().execute(ddl);
+ String dml = "UPSERT INTO T1 VALUES (1, TO_DATE('2004-03-01 00:10:10'), TO_TIMESTAMP('2006-04-12 00:20:20'), TO_TIME('2008-05-16 10:30:30'), " +
+ "TO_DATE('2010-06-20 00:40:40:789', 'yyyy-MM-dd HH:mm:ss:SSS'), TO_TIMESTAMP('2012-07-28'), TO_TIME('2015-12-25 00:50:50'))";
+ conn.createStatement().execute(dml);
+ dml = "UPSERT INTO T1 VALUES (2, TO_DATE('2004-03-01 00:10:10'), TO_TIMESTAMP('2006-04-12 00:50:20'), TO_TIME('2008-05-16 10:30:30'), " +
+ "TO_DATE('2010-06-20 00:40:40:789', 'yyyy-MM-dd HH:mm:ss:SSS'), TO_TIMESTAMP('2012-07-28'), TO_TIME('2015-12-25 00:50:50'))";
+ conn.createStatement().execute(dml);
+ conn.commit();
+
+ ResultSet rs = conn.createStatement().executeQuery("SELECT k1, MINUTE(dates), MINUTE(times), MINUTE(unsignedDates), MINUTE(unsignedTimestamps), " +
+ "MINUTE(unsignedTimes) FROM T1 where MINUTE(timestamps)=20");
+ assertTrue(rs.next());
+ assertEquals(1, rs.getInt(1));
+ assertEquals(10, rs.getInt(2));
+ assertEquals(30, rs.getInt(3));
+ assertEquals(40, rs.getInt(4));
+ assertEquals(0, rs.getInt(5));
+ assertEquals(50, rs.getInt(6));
+ assertFalse(rs.next());
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/phoenix/blob/8975fc1a/phoenix-core/src/main/java/org/apache/phoenix/expression/ExpressionType.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/ExpressionType.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/ExpressionType.java
index c25b1cc..d42c5f2 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/ExpressionType.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/ExpressionType.java
@@ -52,6 +52,7 @@ import org.apache.phoenix.expression.function.LpadFunction;
import org.apache.phoenix.expression.function.MD5Function;
import org.apache.phoenix.expression.function.MaxAggregateFunction;
import org.apache.phoenix.expression.function.MinAggregateFunction;
+import org.apache.phoenix.expression.function.MinuteFunction;
import org.apache.phoenix.expression.function.MonthFunction;
import org.apache.phoenix.expression.function.NowFunction;
import org.apache.phoenix.expression.function.NthValueFunction;
@@ -207,7 +208,8 @@ public enum ExpressionType {
WeekFunction(WeekFunction.class),
HourFunction(HourFunction.class),
NowFunction(NowFunction.class),
- InstrFunction(InstrFunction.class)
+ InstrFunction(InstrFunction.class),
+ MinuteFunction(MinuteFunction.class)
;
ExpressionType(Class<? extends Expression> clazz) {
http://git-wip-us.apache.org/repos/asf/phoenix/blob/8975fc1a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/MinuteFunction.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/MinuteFunction.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/MinuteFunction.java
new file mode 100644
index 0000000..fc721fc
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/MinuteFunction.java
@@ -0,0 +1,81 @@
+/*
+ * 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.expression.function;
+
+import java.sql.SQLException;
+import java.util.List;
+
+import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
+import org.apache.phoenix.expression.Expression;
+import org.apache.phoenix.parse.FunctionParseNode.Argument;
+import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
+import org.apache.phoenix.schema.tuple.Tuple;
+import org.apache.phoenix.schema.types.PDataType;
+import org.apache.phoenix.schema.types.PInteger;
+import org.apache.phoenix.schema.types.PTimestamp;
+
+/**
+ *
+ * Implementation of the Minute() buildin. Input Date/Timestamp/Time.
+ * Returns an integer from 0 to 59 representing the minute component of time
+ *
+ */
+@BuiltInFunction(name=MinuteFunction.NAME,
+args={@Argument(allowedTypes={PTimestamp.class})})
+public class MinuteFunction extends ScalarFunction {
+ public static final String NAME = "MINUTE";
+
+ public MinuteFunction() {
+ }
+
+ public MinuteFunction(List<Expression> children) throws SQLException {
+ super(children);
+ }
+
+ @Override
+ public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) {
+ Expression expression = getChildExpression();
+ if (!expression.evaluate(tuple, ptr)) {
+ return false;
+ }
+ if ( ptr.getLength() == 0) {
+ return true; //means null
+ }
+ long dateTime = expression.getDataType().getCodec().decodeLong(ptr, expression.getSortOrder());
+ int minute = (int)(((dateTime/1000) % 3600)/60);
+ PDataType returnType = getDataType();
+ byte[] byteValue = new byte[returnType.getByteSize()];
+ returnType.getCodec().encodeInt(minute, byteValue, 0);
+ ptr.set(byteValue);
+ return true;
+ }
+
+ @Override
+ public PDataType getDataType() {
+ return PInteger.INSTANCE;
+ }
+
+ @Override
+ public String getName() {
+ return NAME;
+ }
+
+ private Expression getChildExpression() {
+ return children.get(0);
+ }
+}
[2/5] phoenix git commit: PHOENIX-1826 Implement
TrackOrderPreservingExpressionCompiler as Expression visitor instead of
ParseNode visitor
Posted by ja...@apache.org.
PHOENIX-1826 Implement TrackOrderPreservingExpressionCompiler as Expression visitor instead of ParseNode visitor
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/2f0b51cb
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/2f0b51cb
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/2f0b51cb
Branch: refs/heads/master
Commit: 2f0b51cbe8db817471d87d2521508ba6e42174e9
Parents: 795debf
Author: James Taylor <jt...@salesforce.com>
Authored: Mon Apr 13 16:27:20 2015 -0700
Committer: James Taylor <jt...@salesforce.com>
Committed: Mon Apr 13 16:27:20 2015 -0700
----------------------------------------------------------------------
.../apache/phoenix/end2end/DerivedTableIT.java | 4 +-
.../org/apache/phoenix/end2end/HashJoinIT.java | 7 -
.../org/apache/phoenix/end2end/OrderByIT.java | 13 +-
.../org/apache/phoenix/end2end/SubqueryIT.java | 8 +-
.../end2end/SubqueryUsingSortMergeJoinIT.java | 20 +-
.../phoenix/end2end/VariableLengthPKIT.java | 2 +-
.../index/GlobalIndexOptimizationIT.java | 11 +-
.../apache/phoenix/compile/GroupByCompiler.java | 56 ++--
.../apache/phoenix/compile/OrderByCompiler.java | 46 ++--
.../phoenix/compile/OrderPreservingTracker.java | 259 +++++++++++++++++++
.../TrackOrderPreservingExpressionCompiler.java | 249 ------------------
.../phoenix/compile/QueryCompilerTest.java | 108 +++++++-
.../phoenix/compile/QueryOptimizerTest.java | 7 +-
13 files changed, 441 insertions(+), 349 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/phoenix/blob/2f0b51cb/phoenix-core/src/it/java/org/apache/phoenix/end2end/DerivedTableIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/DerivedTableIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/DerivedTableIT.java
index 7443267..b7c4906 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/DerivedTableIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/DerivedTableIT.java
@@ -309,8 +309,8 @@ public class DerivedTableIT extends BaseClientManagedTimeIT {
rs = conn.createStatement().executeQuery("EXPLAIN " + query);
assertEquals(plans[0], QueryUtil.getExplainPlan(rs));
- // distinct b (groupby b, a) groupby a
- query = "SELECT DISTINCT COLLECTDISTINCT(t.b) FROM (SELECT b_string b, a_string a FROM aTable GROUP BY b_string, a_string) AS t GROUP BY t.a";
+ // distinct b (groupby a, b) groupby a
+ query = "SELECT DISTINCT COLLECTDISTINCT(t.b) FROM (SELECT b_string b, a_string a FROM aTable GROUP BY a_string, b_string) AS t GROUP BY t.a";
statement = conn.prepareStatement(query);
rs = statement.executeQuery();
assertTrue (rs.next());
http://git-wip-us.apache.org/repos/asf/phoenix/blob/2f0b51cb/phoenix-core/src/it/java/org/apache/phoenix/end2end/HashJoinIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/HashJoinIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/HashJoinIT.java
index 1a2a1d0..a03204a 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/HashJoinIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/HashJoinIT.java
@@ -118,7 +118,6 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
"CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY [I.NAME]\n" +
"CLIENT MERGE SORT\n" +
- "CLIENT SORTED BY [I.NAME]\n" +
" PARALLEL LEFT-JOIN TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ITEM_TABLE_DISPLAY_NAME,
/*
@@ -156,7 +155,6 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
"CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ITEM_TABLE_DISPLAY_NAME + "\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY [I.NAME]\n" +
"CLIENT MERGE SORT\n" +
- "CLIENT SORTED BY [I.NAME]\n" +
" PARALLEL LEFT-JOIN TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME,
/*
@@ -307,7 +305,6 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
"CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY [I.NAME]\n" +
"CLIENT MERGE SORT\n" +
- "CLIENT SORTED BY [I.NAME]\n" +
" PARALLEL LEFT-JOIN TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ITEM_TABLE_DISPLAY_NAME,
/*
@@ -495,7 +492,6 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
"CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY [\"I.0:NAME\"]\n" +
"CLIENT MERGE SORT\n" +
- "CLIENT SORTED BY [\"I.0:NAME\"]\n" +
" PARALLEL LEFT-JOIN TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_SCHEMA + ".idx_item\n" +
" SERVER FILTER BY FIRST KEY ONLY",
@@ -687,7 +683,6 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
"CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY [I.NAME]\n" +
"CLIENT MERGE SORT\n" +
- "CLIENT SORTED BY [I.NAME]\n" +
" PARALLEL LEFT-JOIN TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_SCHEMA + ".idx_item\n" +
" SERVER FILTER BY FIRST KEY ONLY",
@@ -876,7 +871,6 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
"CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY [\"I.0:NAME\"]\n" +
"CLIENT MERGE SORT\n" +
- "CLIENT SORTED BY [\"I.0:NAME\"]\n" +
" PARALLEL LEFT-JOIN TABLE 0\n" +
" CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX + "" + JOIN_ITEM_TABLE_DISPLAY_NAME +" [-32768]\n" +
" SERVER FILTER BY FIRST KEY ONLY\n" +
@@ -1085,7 +1079,6 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
"CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY [I.NAME]\n" +
"CLIENT MERGE SORT\n" +
- "CLIENT SORTED BY [I.NAME]\n" +
" PARALLEL LEFT-JOIN TABLE 0\n" +
" CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX +""+JOIN_ITEM_TABLE_DISPLAY_NAME+" [-32768]\n"+
" SERVER FILTER BY FIRST KEY ONLY\n" +
http://git-wip-us.apache.org/repos/asf/phoenix/blob/2f0b51cb/phoenix-core/src/it/java/org/apache/phoenix/end2end/OrderByIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/OrderByIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/OrderByIT.java
index 74eb7fe..9fc3003 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/OrderByIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/OrderByIT.java
@@ -30,7 +30,6 @@ 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.sql.Connection;
import java.sql.Date;
@@ -499,9 +498,15 @@ public class OrderByIT extends BaseClientManagedTimeIT {
stmt.execute();
conn.commit();
- String query = "SELECT col1+col2, col4, TRUNC(col3, 'HOUR') FROM e_table ORDER BY 1, 2";
- conn.createStatement().executeQuery(query);
- fail();
+ String query = "SELECT col1+col2, col4, a_string FROM e_table ORDER BY 1, 2";
+ ResultSet rs = conn.createStatement().executeQuery(query);
+ assertTrue(rs.next());
+ assertEquals("a", rs.getString(3));
+ assertTrue(rs.next());
+ assertEquals("c", rs.getString(3));
+ assertTrue(rs.next());
+ assertEquals("b", rs.getString(3));
+ assertFalse(rs.next());
} catch (SQLException e) {
} finally {
conn.close();
http://git-wip-us.apache.org/repos/asf/phoenix/blob/2f0b51cb/phoenix-core/src/it/java/org/apache/phoenix/end2end/SubqueryIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SubqueryIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SubqueryIT.java
index f655e0a..13354da 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SubqueryIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SubqueryIT.java
@@ -200,7 +200,7 @@ public class SubqueryIT extends BaseHBaseManagedTimeIT {
" PARALLEL LEFT-JOIN TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_SCHEMA + ".idx_item\n" +
" SERVER FILTER BY FIRST KEY ONLY\n" +
- " SERVER AGGREGATE INTO ORDERED DISTINCT ROWS BY \\[\".+.0:NAME\", \".+.:item_id\"\\]\n" +
+ " SERVER AGGREGATE INTO ORDERED DISTINCT ROWS BY \\[\".+.:item_id\", \".+.0:NAME\"\\]\n" +
" CLIENT MERGE SORT\n" +
" PARALLEL ANTI-JOIN TABLE 0 \\(SKIP MERGE\\)\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
@@ -209,7 +209,7 @@ public class SubqueryIT extends BaseHBaseManagedTimeIT {
" PARALLEL LEFT-JOIN TABLE 1\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_SCHEMA + ".idx_item\n" +
" SERVER FILTER BY FIRST KEY ONLY\n" +
- " SERVER AGGREGATE INTO ORDERED DISTINCT ROWS BY \\[\".+.0:NAME\", \".+.:item_id\"\\]\n" +
+ " SERVER AGGREGATE INTO ORDERED DISTINCT ROWS BY \\[\".+.:item_id\", \".+.0:NAME\"\\]\n" +
" CLIENT MERGE SORT\n" +
" PARALLEL SEMI-JOIN TABLE 0 \\(SKIP MERGE\\)\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
@@ -274,7 +274,7 @@ public class SubqueryIT extends BaseHBaseManagedTimeIT {
" PARALLEL LEFT-JOIN TABLE 0\n" +
" CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX + JOIN_ITEM_TABLE_DISPLAY_NAME + " \\[-32768\\]\n" +
" SERVER FILTER BY FIRST KEY ONLY\n" +
- " SERVER AGGREGATE INTO ORDERED DISTINCT ROWS BY \\[\".+.0:NAME\", \".+.:item_id\"\\]\n" +
+ " SERVER AGGREGATE INTO ORDERED DISTINCT ROWS BY \\[\".+.:item_id\", \".+.0:NAME\"\\]\n" +
" CLIENT MERGE SORT\n" +
" PARALLEL ANTI-JOIN TABLE 0 \\(SKIP MERGE\\)\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
@@ -283,7 +283,7 @@ public class SubqueryIT extends BaseHBaseManagedTimeIT {
" PARALLEL LEFT-JOIN TABLE 1\n" +
" CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX + JOIN_ITEM_TABLE_DISPLAY_NAME + " \\[-32768\\]\n" +
" SERVER FILTER BY FIRST KEY ONLY\n" +
- " SERVER AGGREGATE INTO ORDERED DISTINCT ROWS BY \\[\".+.0:NAME\", \".+.:item_id\"\\]\n" +
+ " SERVER AGGREGATE INTO ORDERED DISTINCT ROWS BY \\[\".+.:item_id\", \".+.0:NAME\"\\]\n" +
" CLIENT MERGE SORT\n" +
" PARALLEL SEMI-JOIN TABLE 0 \\(SKIP MERGE\\)\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
http://git-wip-us.apache.org/repos/asf/phoenix/blob/2f0b51cb/phoenix-core/src/it/java/org/apache/phoenix/end2end/SubqueryUsingSortMergeJoinIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SubqueryUsingSortMergeJoinIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SubqueryUsingSortMergeJoinIT.java
index 59f75e5..cb9f4b1 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SubqueryUsingSortMergeJoinIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SubqueryUsingSortMergeJoinIT.java
@@ -121,7 +121,6 @@ public class SubqueryUsingSortMergeJoinIT extends BaseHBaseManagedTimeIT {
" CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + " ['000000000000001'] - [*]\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY [\"item_id\"]\n" +
" CLIENT MERGE SORT\n" +
- " CLIENT SORTED BY [\"item_id\"]\n" +
"CLIENT SORTED BY [I.NAME]",
"SORT-MERGE-JOIN \\(LEFT\\) TABLES\n" +
@@ -132,7 +131,6 @@ public class SubqueryUsingSortMergeJoinIT extends BaseHBaseManagedTimeIT {
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ITEM_TABLE_DISPLAY_NAME + "\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY \\[\".+.item_id\", .+.NAME\\]\n" +
" CLIENT MERGE SORT\n" +
- " CLIENT SORTED BY \\[\".+.item_id\", .+.NAME\\]\n" +
" PARALLEL ANTI-JOIN TABLE 0 \\(SKIP MERGE\\)\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY \\[\"item_id\"]\\\n" +
@@ -142,7 +140,6 @@ public class SubqueryUsingSortMergeJoinIT extends BaseHBaseManagedTimeIT {
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ITEM_TABLE_DISPLAY_NAME + "\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY \\[\".+.item_id\", .+.NAME\\]\n" +
" CLIENT MERGE SORT\n" +
- " CLIENT SORTED BY \\[\".+.item_id\", .+.NAME\\]\n" +
" SKIP-SCAN-JOIN TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY \\[\"item_id\"\\]\n" +
@@ -156,7 +153,6 @@ public class SubqueryUsingSortMergeJoinIT extends BaseHBaseManagedTimeIT {
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ITEM_TABLE_DISPLAY_NAME + "\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY \\[\"O.customer_id\"\\]\n" +
" CLIENT MERGE SORT\n" +
- " CLIENT SORTED BY \\[\"O.customer_id\"\\]\n" +
" PARALLEL INNER-JOIN TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" PARALLEL LEFT-JOIN TABLE 1\\(DELAYED EVALUATION\\)\n" +
@@ -187,7 +183,6 @@ public class SubqueryUsingSortMergeJoinIT extends BaseHBaseManagedTimeIT {
" CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + " ['000000000000001'] - [*]\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY [\"item_id\"]\n" +
" CLIENT MERGE SORT\n" +
- " CLIENT SORTED BY [\"item_id\"]\n" +
"CLIENT SORTED BY [\"I.0:NAME\"]",
"SORT-MERGE-JOIN \\(LEFT\\) TABLES\n" +
@@ -197,9 +192,8 @@ public class SubqueryUsingSortMergeJoinIT extends BaseHBaseManagedTimeIT {
" AND\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_SCHEMA + ".idx_item\n" +
" SERVER FILTER BY FIRST KEY ONLY\n" +
- " SERVER AGGREGATE INTO ORDERED DISTINCT ROWS BY \\[\".+.0:NAME\", \".+.:item_id\"\\]\n" +
+ " SERVER AGGREGATE INTO ORDERED DISTINCT ROWS BY \\[\".+.:item_id\", \".+.0:NAME\"\\]\n" +
" CLIENT MERGE SORT\n" +
- " CLIENT SORTED BY \\[\".+.:item_id\", \".+.0:NAME\"\\]\n" +
" PARALLEL ANTI-JOIN TABLE 0 \\(SKIP MERGE\\)\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY \\[\"item_id\"\\]\n" +
@@ -208,9 +202,8 @@ public class SubqueryUsingSortMergeJoinIT extends BaseHBaseManagedTimeIT {
"AND\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_SCHEMA + ".idx_item\n" +
" SERVER FILTER BY FIRST KEY ONLY\n" +
- " SERVER AGGREGATE INTO ORDERED DISTINCT ROWS BY \\[\".+.0:NAME\", \".+.:item_id\"\\]\n" +
+ " SERVER AGGREGATE INTO ORDERED DISTINCT ROWS BY \\[\".+.:item_id\", \".+.0:NAME\"\\]\n" +
" CLIENT MERGE SORT\n" +
- " CLIENT SORTED BY \\[\".+.:item_id\", \".+.0:NAME\"\\]\n" +
" PARALLEL SEMI-JOIN TABLE 0 \\(SKIP MERGE\\)\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY \\[\"item_id\"\\]\n" +
@@ -227,7 +220,6 @@ public class SubqueryUsingSortMergeJoinIT extends BaseHBaseManagedTimeIT {
" SERVER FILTER BY FIRST KEY ONLY\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY \\[\"O.customer_id\"\\]\n" +
" CLIENT MERGE SORT\n" +
- " CLIENT SORTED BY \\[\"O.customer_id\"\\]\n" +
" PARALLEL INNER-JOIN TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" PARALLEL LEFT-JOIN TABLE 1\\(DELAYED EVALUATION\\)\n" +
@@ -257,7 +249,6 @@ public class SubqueryUsingSortMergeJoinIT extends BaseHBaseManagedTimeIT {
" CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + " ['000000000000001'] - [*]\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY [\"item_id\"]\n" +
" CLIENT MERGE SORT\n" +
- " CLIENT SORTED BY [\"item_id\"]\n" +
"CLIENT SORTED BY [\"I.0:NAME\"]",
"SORT-MERGE-JOIN \\(LEFT\\) TABLES\n" +
@@ -267,9 +258,8 @@ public class SubqueryUsingSortMergeJoinIT extends BaseHBaseManagedTimeIT {
" AND\n" +
" CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX + JOIN_ITEM_TABLE_DISPLAY_NAME + " \\[-32768\\]\n" +
" SERVER FILTER BY FIRST KEY ONLY\n" +
- " SERVER AGGREGATE INTO ORDERED DISTINCT ROWS BY \\[\".+.0:NAME\", \".+.:item_id\"\\]\n" +
+ " SERVER AGGREGATE INTO ORDERED DISTINCT ROWS BY \\[\".+.:item_id\", \".+.0:NAME\"\\]\n" +
" CLIENT MERGE SORT\n" +
- " CLIENT SORTED BY \\[\".+.:item_id\", \".+.0:NAME\"\\]\n" +
" PARALLEL ANTI-JOIN TABLE 0 \\(SKIP MERGE\\)\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY \\[\"item_id\"\\]\n" +
@@ -278,9 +268,8 @@ public class SubqueryUsingSortMergeJoinIT extends BaseHBaseManagedTimeIT {
"AND\n" +
" CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX + JOIN_ITEM_TABLE_DISPLAY_NAME + " \\[-32768\\]\n" +
" SERVER FILTER BY FIRST KEY ONLY\n" +
- " SERVER AGGREGATE INTO ORDERED DISTINCT ROWS BY \\[\".+.0:NAME\", \".+.:item_id\"\\]\n" +
+ " SERVER AGGREGATE INTO ORDERED DISTINCT ROWS BY \\[\".+.:item_id\", \".+.0:NAME\"\\]\n" +
" CLIENT MERGE SORT\n" +
- " CLIENT SORTED BY \\[\".+.:item_id\", \".+.0:NAME\"\\]\n" +
" PARALLEL SEMI-JOIN TABLE 0 \\(SKIP MERGE\\)\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY \\[\"item_id\"\\]\n" +
@@ -298,7 +287,6 @@ public class SubqueryUsingSortMergeJoinIT extends BaseHBaseManagedTimeIT {
" SERVER FILTER BY FIRST KEY ONLY\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY \\[\"O.customer_id\"\\]\n" +
" CLIENT MERGE SORT\n" +
- " CLIENT SORTED BY \\[\"O.customer_id\"\\]\n" +
" PARALLEL INNER-JOIN TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" PARALLEL LEFT-JOIN TABLE 1\\(DELAYED EVALUATION\\)\n" +
http://git-wip-us.apache.org/repos/asf/phoenix/blob/2f0b51cb/phoenix-core/src/it/java/org/apache/phoenix/end2end/VariableLengthPKIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/VariableLengthPKIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/VariableLengthPKIT.java
index b7bc7cc..1e48f8c 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/VariableLengthPKIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/VariableLengthPKIT.java
@@ -1090,7 +1090,7 @@ public class VariableLengthPKIT extends BaseClientManagedTimeIT {
@Test
public void testMultiFixedLengthNull() throws Exception {
long ts = nextTimestamp();
- String query = "SELECT B_INTEGER,C_INTEGER,COUNT(1) FROM BTABLE GROUP BY C_INTEGER,B_INTEGER";
+ String query = "SELECT B_INTEGER,C_INTEGER,COUNT(1) FROM BTABLE GROUP BY B_INTEGER,C_INTEGER";
String url = getUrl() + ";" + PhoenixRuntime.CURRENT_SCN_ATTRIB + "=" + (ts + 5); // Run query at timestamp 5
Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
Connection conn = DriverManager.getConnection(url, props);
http://git-wip-us.apache.org/repos/asf/phoenix/blob/2f0b51cb/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/GlobalIndexOptimizationIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/GlobalIndexOptimizationIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/GlobalIndexOptimizationIT.java
index 07d87b7..b97176f 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/GlobalIndexOptimizationIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/GlobalIndexOptimizationIT.java
@@ -198,7 +198,7 @@ public class GlobalIndexOptimizationIT extends BaseHBaseManagedTimeIT {
expected =
"CLIENT PARALLEL \\d-WAY FULL SCAN OVER " + TestUtil.DEFAULT_DATA_TABLE_NAME + "\n" +
- " SERVER AGGREGATE INTO DISTINCT ROWS BY \\[T.T_ID, T.V1, T.K3\\]\n" +
+ " SERVER AGGREGATE INTO DISTINCT ROWS BY \\[T.V1, T.T_ID, T.K3\\]\n" +
"CLIENT MERGE SORT\n" +
" SKIP-SCAN-JOIN TABLE 0\n" +
" CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + TestUtil.DEFAULT_INDEX_TABLE_NAME + " \\[\\*\\] - \\['z'\\]\n" +
@@ -209,10 +209,6 @@ public class GlobalIndexOptimizationIT extends BaseHBaseManagedTimeIT {
rs = conn1.createStatement().executeQuery(query);
assertTrue(rs.next());
- assertEquals("b", rs.getString("t_id"));;
- assertEquals(4, rs.getInt("k3"));
- assertEquals("z", rs.getString("V1"));
- assertTrue(rs.next());
assertEquals("f", rs.getString("t_id"));
assertEquals(3, rs.getInt("k3"));
assertEquals("a", rs.getString("V1"));
@@ -224,6 +220,10 @@ public class GlobalIndexOptimizationIT extends BaseHBaseManagedTimeIT {
assertEquals("q", rs.getString("t_id"));
assertEquals(1, rs.getInt("k3"));
assertEquals("c", rs.getString("V1"));
+ assertTrue(rs.next());
+ assertEquals("b", rs.getString("t_id"));;
+ assertEquals(4, rs.getInt("k3"));
+ assertEquals("z", rs.getString("V1"));
assertFalse(rs.next());
query = "SELECT /*+ INDEX(" + TestUtil.DEFAULT_DATA_TABLE_NAME + " " + TestUtil.DEFAULT_INDEX_TABLE_NAME + ")*/ v1,sum(k3) from " + TestUtil.DEFAULT_DATA_TABLE_FULL_NAME + " where v1 <='z' group by v1 order by v1";
@@ -233,7 +233,6 @@ public class GlobalIndexOptimizationIT extends BaseHBaseManagedTimeIT {
"CLIENT PARALLEL \\d-WAY FULL SCAN OVER T\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY \\[T.V1\\]\n" +
"CLIENT MERGE SORT\n" +
- "CLIENT SORTED BY \\[T.V1\\]\n" +
" SKIP-SCAN-JOIN TABLE 0\n" +
" CLIENT PARALLEL 1-WAY RANGE SCAN OVER I \\[\\*\\] - \\['z'\\]\n" +
" SERVER FILTER BY FIRST KEY ONLY\n" +
http://git-wip-us.apache.org/repos/asf/phoenix/blob/2f0b51cb/phoenix-core/src/main/java/org/apache/phoenix/compile/GroupByCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/GroupByCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/GroupByCompiler.java
index 4f1ba5b..7d9df02 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/GroupByCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/GroupByCompiler.java
@@ -23,9 +23,9 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.List;
+import org.apache.hadoop.hbase.util.Pair;
import org.apache.http.annotation.Immutable;
-import org.apache.phoenix.compile.TrackOrderPreservingExpressionCompiler.Entry;
-import org.apache.phoenix.compile.TrackOrderPreservingExpressionCompiler.Ordering;
+import org.apache.phoenix.compile.OrderPreservingTracker.Ordering;
import org.apache.phoenix.coprocessor.BaseScannerRegionObserver;
import org.apache.phoenix.exception.SQLExceptionCode;
import org.apache.phoenix.exception.SQLExceptionInfo;
@@ -158,29 +158,30 @@ public class GroupByCompiler {
}
// Accumulate expressions in GROUP BY
- TrackOrderPreservingExpressionCompiler groupByVisitor =
- new TrackOrderPreservingExpressionCompiler(context,
- GroupBy.EMPTY_GROUP_BY, groupByNodes.size(),
- Ordering.UNORDERED, tupleProjector);
- for (ParseNode node : groupByNodes) {
- Expression expression = node.accept(groupByVisitor);
- if (groupByVisitor.isAggregate()) {
- throw new SQLExceptionInfo.Builder(SQLExceptionCode.AGGREGATE_IN_GROUP_BY)
- .setMessage(expression.toString()).build().buildException();
- }
+ ExpressionCompiler compiler =
+ new ExpressionCompiler(context, GroupBy.EMPTY_GROUP_BY);
+ List<Pair<Integer,Expression>> groupBys = Lists.newArrayListWithExpectedSize(groupByNodes.size());
+ OrderPreservingTracker tracker = new OrderPreservingTracker(context, GroupBy.EMPTY_GROUP_BY, Ordering.UNORDERED, groupByNodes.size(), tupleProjector);
+ for (int i = 0; i < groupByNodes.size(); i++) {
+ ParseNode node = groupByNodes.get(i);
+ Expression expression = node.accept(compiler);
if (!expression.isStateless()) {
- groupByVisitor.addEntry(expression);
+ if (compiler.isAggregate()) {
+ throw new SQLExceptionInfo.Builder(SQLExceptionCode.AGGREGATE_IN_GROUP_BY)
+ .setMessage(expression.toString()).build().buildException();
+ }
+ tracker.track(expression);
+ groupBys.add(new Pair<Integer,Expression>(i,expression));
}
- groupByVisitor.reset();
+ compiler.reset();
}
- List<Entry> groupByEntries = groupByVisitor.getEntries();
- if (groupByEntries.isEmpty()) {
+ if (groupBys.isEmpty()) {
return GroupBy.EMPTY_GROUP_BY;
}
- boolean isRowKeyOrderedGrouping = isInRowKeyOrder && groupByVisitor.isOrderPreserving();
- List<Expression> expressions = Lists.newArrayListWithCapacity(groupByEntries.size());
+ boolean isRowKeyOrderedGrouping = isInRowKeyOrder && tracker.isOrderPreserving();
+ List<Expression> expressions = Lists.newArrayListWithExpectedSize(groupBys.size());
List<Expression> keyExpressions = expressions;
String groupExprAttribName;
// This is true if the GROUP BY is composed of only PK columns. We further check here that
@@ -188,8 +189,8 @@ public class GroupByCompiler {
// column and use each subsequent one in PK order).
if (isRowKeyOrderedGrouping) {
groupExprAttribName = BaseScannerRegionObserver.KEY_ORDERED_GROUP_BY_EXPRESSIONS;
- for (Entry groupByEntry : groupByEntries) {
- expressions.add(groupByEntry.getExpression());
+ for (Pair<Integer,Expression> groupBy : groupBys) {
+ expressions.add(groupBy.getSecond());
}
} else {
/*
@@ -211,11 +212,11 @@ public class GroupByCompiler {
* Within each bucket, order based on the column position in the schema. Putting the fixed width values
* in the beginning optimizes access to subsequent values.
*/
- Collections.sort(groupByEntries, new Comparator<Entry>() {
+ Collections.sort(groupBys, new Comparator<Pair<Integer,Expression>>() {
@Override
- public int compare(Entry o1, Entry o2) {
- Expression e1 = o1.getExpression();
- Expression e2 = o2.getExpression();
+ public int compare(Pair<Integer,Expression> gb1, Pair<Integer,Expression> gb2) {
+ Expression e1 = gb1.getSecond();
+ Expression e2 = gb2.getSecond();
boolean isFixed1 = e1.getDataType().isFixedWidth();
boolean isFixed2 = e2.getDataType().isFixedWidth();
boolean isFixedNullable1 = e1.isNullable() &&isFixed1;
@@ -224,7 +225,8 @@ public class GroupByCompiler {
if (isFixed1 == isFixed2) {
// Not strictly necessary, but forces the order to match the schema
// column order (with PK columns before value columns).
- return o1.getColumnPosition() - o2.getColumnPosition();
+ //return o1.getColumnPosition() - o2.getColumnPosition();
+ return gb1.getFirst() - gb2.getFirst();
} else if (isFixed1) {
return -1;
} else {
@@ -237,8 +239,8 @@ public class GroupByCompiler {
}
}
});
- for (Entry groupByEntry : groupByEntries) {
- expressions.add(groupByEntry.getExpression());
+ for (Pair<Integer,Expression> groupBy : groupBys) {
+ expressions.add(groupBy.getSecond());
}
for (int i = expressions.size()-2; i >= 0; i--) {
Expression expression = expressions.get(i);
http://git-wip-us.apache.org/repos/asf/phoenix/blob/2f0b51cb/phoenix-core/src/main/java/org/apache/phoenix/compile/OrderByCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/OrderByCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/OrderByCompiler.java
index d8e86ad..f0406d4 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/OrderByCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/OrderByCompiler.java
@@ -24,17 +24,15 @@ import java.util.LinkedHashSet;
import java.util.List;
import org.apache.phoenix.compile.GroupByCompiler.GroupBy;
-import org.apache.phoenix.compile.TrackOrderPreservingExpressionCompiler.Ordering;
+import org.apache.phoenix.compile.OrderPreservingTracker.Ordering;
import org.apache.phoenix.exception.SQLExceptionCode;
import org.apache.phoenix.exception.SQLExceptionInfo;
import org.apache.phoenix.expression.Expression;
import org.apache.phoenix.expression.OrderByExpression;
-import org.apache.phoenix.parse.ColumnParseNode;
import org.apache.phoenix.parse.LiteralParseNode;
import org.apache.phoenix.parse.OrderByNode;
import org.apache.phoenix.parse.ParseNode;
import org.apache.phoenix.parse.SelectStatement;
-import org.apache.phoenix.parse.TableName;
import org.apache.phoenix.query.QueryServices;
import org.apache.phoenix.query.QueryServicesOptions;
import org.apache.phoenix.schema.PTableType;
@@ -90,13 +88,12 @@ public class OrderByCompiler {
if (orderByNodes.isEmpty()) {
return OrderBy.EMPTY_ORDER_BY;
}
+ ExpressionCompiler compiler = new ExpressionCompiler(context, groupBy);
// accumulate columns in ORDER BY
- TrackOrderPreservingExpressionCompiler visitor =
- new TrackOrderPreservingExpressionCompiler(context, groupBy,
- orderByNodes.size(), Ordering.ORDERED, null);
+ OrderPreservingTracker tracker =
+ new OrderPreservingTracker(context, groupBy, Ordering.ORDERED, orderByNodes.size());
LinkedHashSet<OrderByExpression> orderByExpressions = Sets.newLinkedHashSetWithExpectedSize(orderByNodes.size());
for (OrderByNode node : orderByNodes) {
- boolean isAscending = node.isAscending();
ParseNode parseNode = node.getNode();
Expression expression = null;
if (parseNode instanceof LiteralParseNode && ((LiteralParseNode)parseNode).getType() == PInteger.INSTANCE){
@@ -104,24 +101,13 @@ public class OrderByCompiler {
int size = projector.getColumnProjectors().size();
if (index > size || index <= 0 ) {
throw new SQLExceptionInfo.Builder(SQLExceptionCode.PARAM_INDEX_OUT_OF_BOUND)
- .setMessage("").build().buildException();
+ .build().buildException();
}
- ColumnProjector colProj = projector.getColumnProjector(index-1);
- TableName tableName = null;
- if (statement.getSelects().size() > 0 )
- tableName = TableName.create(context.getCurrentTable().getTable().getName().toString(), null);
- else {
- tableName = TableName.create(context.getResolver().getTables().get(0).getTable().getSchemaName().toString(),
- context.getResolver().getTables().get(0).getTable().getTableName().toString());
- }
- ColumnParseNode colParseNode = new ColumnParseNode(tableName, colProj.getName(), null);
- expression = colParseNode.accept(visitor);
+ expression = projector.getColumnProjector(index-1).getExpression();
} else {
- expression = node.getNode().accept(visitor);
- }
- if (!expression.isStateless() && visitor.addEntry(expression, isAscending ? SortOrder.ASC : SortOrder.DESC)) {
+ expression = node.getNode().accept(compiler);
// Detect mix of aggregate and non aggregates (i.e. ORDER BY txns, SUM(txns)
- if (!visitor.isAggregate()) {
+ if (!expression.isStateless() && !compiler.isAggregate()) {
if (statement.isAggregate() || statement.isDistinct()) {
// Detect ORDER BY not in SELECT DISTINCT: SELECT DISTINCT count(*) FROM t ORDER BY x
if (statement.isDistinct()) {
@@ -131,21 +117,29 @@ public class OrderByCompiler {
ExpressionCompiler.throwNonAggExpressionInAggException(expression.toString());
}
}
+ }
+ if (!expression.isStateless()) {
+ boolean isAscending = node.isAscending();
+ boolean isNullsLast = node.isNullsLast();
+ tracker.track(expression, isAscending ? SortOrder.ASC : SortOrder.DESC, isNullsLast);
+ // FIXME: this isn't correct. If we have a schema where column A is DESC,
+ // An ORDER BY A should still be ASC.
if (expression.getSortOrder() == SortOrder.DESC) {
isAscending = !isAscending;
+ isNullsLast = !isNullsLast;
}
- OrderByExpression orderByExpression = new OrderByExpression(expression, node.isNullsLast(), isAscending);
+ OrderByExpression orderByExpression = new OrderByExpression(expression, isNullsLast, isAscending);
orderByExpressions.add(orderByExpression);
}
- visitor.reset();
+ compiler.reset();
}
if (orderByExpressions.isEmpty()) {
return OrderBy.EMPTY_ORDER_BY;
}
// If we're ordering by the order returned by the scan, we don't need an order by
- if (isInRowKeyOrder && visitor.isOrderPreserving()) {
- if (visitor.isReverse()) {
+ if (isInRowKeyOrder && tracker.isOrderPreserving()) {
+ if (tracker.isReverse()) {
// Don't use reverse scan if we're using a skip scan, as our skip scan doesn't support this yet.
// REV_ROW_KEY_ORDER_BY scan would not take effect for a projected table, so don't return it for such table types.
if (context.getConnection().getQueryServices().getProps().getBoolean(QueryServices.USE_REVERSE_SCAN_ATTRIB, QueryServicesOptions.DEFAULT_USE_REVERSE_SCAN)
http://git-wip-us.apache.org/repos/asf/phoenix/blob/2f0b51cb/phoenix-core/src/main/java/org/apache/phoenix/compile/OrderPreservingTracker.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/OrderPreservingTracker.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/OrderPreservingTracker.java
new file mode 100644
index 0000000..1c31606
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/OrderPreservingTracker.java
@@ -0,0 +1,259 @@
+/*
+ * 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.compile;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.phoenix.compile.GroupByCompiler.GroupBy;
+import org.apache.phoenix.execute.TupleProjector;
+import org.apache.phoenix.expression.CoerceExpression;
+import org.apache.phoenix.expression.Expression;
+import org.apache.phoenix.expression.ProjectedColumnExpression;
+import org.apache.phoenix.expression.RowKeyColumnExpression;
+import org.apache.phoenix.expression.RowValueConstructorExpression;
+import org.apache.phoenix.expression.function.FunctionExpression.OrderPreserving;
+import org.apache.phoenix.expression.function.ScalarFunction;
+import org.apache.phoenix.expression.visitor.StatelessTraverseNoExpressionVisitor;
+import org.apache.phoenix.schema.PTable;
+import org.apache.phoenix.schema.SortOrder;
+
+import com.google.common.collect.Iterators;
+import com.google.common.collect.Lists;
+
+/**
+ * Determines if the natural key order of the rows returned by the scan
+ * will match the order of the expressions. For GROUP BY, if order is preserved we can use
+ * an optimization during server-side aggregation to do the aggregation on-the-fly versus
+ * keeping track of each distinct group. We can only do this optimization if all the rows
+ * for each group will be contiguous. For ORDER BY, we can drop the ORDER BY statement if
+ * the order is preserved.
+ *
+ */
+public class OrderPreservingTracker {
+ public enum Ordering {ORDERED, UNORDERED};
+
+ public static class Info {
+ public final OrderPreserving orderPreserving;
+ public final int pkPosition;
+ public final int slotSpan;
+
+ public Info(int pkPosition) {
+ this.pkPosition = pkPosition;
+ this.orderPreserving = OrderPreserving.YES;
+ this.slotSpan = 1;
+ }
+
+ public Info(Info info, OrderPreserving orderPreserving) {
+ this.pkPosition = info.pkPosition;
+ this.slotSpan = info.slotSpan;
+ this.orderPreserving = orderPreserving;
+ }
+
+ public Info(Info info, int slotSpan, OrderPreserving orderPreserving) {
+ this.pkPosition = info.pkPosition;
+ this.slotSpan = slotSpan;
+ this.orderPreserving = orderPreserving;
+ }
+ }
+ private final TrackOrderPreservingExpressionVisitor visitor;
+ private final GroupBy groupBy;
+ private final Ordering ordering;
+ private final int pkPositionOffset;
+ private final List<Info> orderPreservingInfos;
+ private boolean isOrderPreserving = true;
+ private Boolean isReverse = null;
+
+ public OrderPreservingTracker(StatementContext context, GroupBy groupBy, Ordering ordering, int nNodes) {
+ this(context, groupBy, ordering, nNodes, null);
+ }
+
+ public OrderPreservingTracker(StatementContext context, GroupBy groupBy, Ordering ordering, int nNodes, TupleProjector projector) {
+ int pkPositionOffset = 0;
+ if (groupBy.isEmpty()) { // FIXME: would the below table have any of these set in the case of a GROUP BY?
+ PTable table = context.getResolver().getTables().get(0).getTable();
+ boolean isSalted = table.getBucketNum() != null;
+ boolean isMultiTenant = context.getConnection().getTenantId() != null && table.isMultiTenant();
+ boolean isSharedViewIndex = table.getViewIndexId() != null;
+ // TODO: util for this offset, as it's computed in numerous places
+ pkPositionOffset = (isSalted ? 1 : 0) + (isMultiTenant ? 1 : 0) + (isSharedViewIndex ? 1 : 0);
+ }
+ this.pkPositionOffset = pkPositionOffset;
+ this.groupBy = groupBy;
+ this.visitor = new TrackOrderPreservingExpressionVisitor(projector);
+ this.orderPreservingInfos = Lists.newArrayListWithExpectedSize(nNodes);
+ this.ordering = ordering;
+ }
+
+ public void track(Expression node) {
+ SortOrder sortOrder = node.getSortOrder();
+ track(node, sortOrder, sortOrder != SortOrder.getDefault());
+ }
+
+ public void track(Expression node, SortOrder sortOrder, boolean isNullsLast) {
+ if (isOrderPreserving) {
+ Info info = node.accept(visitor);
+ if (info == null) {
+ isOrderPreserving = false;
+ } else {
+ // If the expression is sorted in a different order than the specified sort order
+ // then the expressions are not order preserving.
+ if (node.getSortOrder() != sortOrder) {
+ if (isReverse == null) {
+ isReverse = true;
+ /*
+ * When a GROUP BY is not order preserving, we cannot do a reverse
+ * scan to eliminate the ORDER BY since our server-side scan is not
+ * ordered in that case.
+ */
+ if (!groupBy.isEmpty() && !groupBy.isOrderPreserving()) {
+ isOrderPreserving = false;
+ return;
+ }
+ } else if (!isReverse){
+ isOrderPreserving = false;
+ return;
+ }
+ } else {
+ if (isReverse == null) {
+ isReverse = false;
+ } else if (isReverse){
+ isOrderPreserving = false;
+ return;
+ }
+ }
+ if (node.isNullable()) {
+ if (!Boolean.valueOf(isNullsLast).equals(isReverse)) {
+ isOrderPreserving = false;
+ return;
+ }
+ }
+ orderPreservingInfos.add(info);
+ }
+ }
+ }
+
+ public boolean isOrderPreserving() {
+ if (!isOrderPreserving) {
+ return false;
+ }
+ if (ordering == Ordering.UNORDERED) {
+ // Sort by position
+ Collections.sort(orderPreservingInfos, new Comparator<Info>() {
+ @Override
+ public int compare(Info o1, Info o2) {
+ return o1.pkPosition-o2.pkPosition;
+ }
+ });
+ }
+ // Determine if there are any gaps in the PK columns (in which case we don't need
+ // to sort in the coprocessor because the keys will already naturally be in sorted
+ // order.
+ int prevSlotSpan = 1;
+ int prevPos = pkPositionOffset - 1;
+ OrderPreserving prevOrderPreserving = OrderPreserving.YES;
+ for (int i = 0; i < orderPreservingInfos.size() && isOrderPreserving; i++) {
+ Info entry = orderPreservingInfos.get(i);
+ int pos = entry.pkPosition;
+ isOrderPreserving &= (entry.orderPreserving != OrderPreserving.NO) && (pos == prevPos || ((pos - prevSlotSpan == prevPos) && (prevOrderPreserving == OrderPreserving.YES)));
+ prevPos = pos;
+ prevSlotSpan = entry.slotSpan;
+ prevOrderPreserving = entry.orderPreserving;
+ }
+ return isOrderPreserving;
+ }
+
+ public boolean isReverse() {
+ return Boolean.TRUE.equals(isReverse);
+ }
+
+ private static class TrackOrderPreservingExpressionVisitor extends StatelessTraverseNoExpressionVisitor<Info> {
+ private final TupleProjector projector;
+
+ public TrackOrderPreservingExpressionVisitor(TupleProjector projector) {
+ this.projector = projector;
+ }
+
+ @Override
+ public Info visit(RowKeyColumnExpression node) {
+ return new Info(node.getPosition());
+ }
+
+ @Override
+ public Info visit(ProjectedColumnExpression node) {
+ if (projector == null) {
+ return super.visit(node);
+ }
+ Expression expression = projector.getExpressions()[node.getPosition()];
+ // FIXME: prevents infinite recursion for union all in subquery, but
+ // should a ProjectedColumnExpression be used in this case? Wouldn't
+ // it make more sense to not create this wrapper in this case?
+ if (expression == node) {
+ return super.visit(node);
+ }
+ return expression.accept(this);
+ }
+
+ @Override
+ public Iterator<Expression> visitEnter(ScalarFunction node) {
+ return node.preservesOrder() == OrderPreserving.NO ? Iterators.<Expression> emptyIterator() : Iterators
+ .singletonIterator(node.getChildren().get(node.getKeyFormationTraversalIndex()));
+ }
+
+ @Override
+ public Info visitLeave(ScalarFunction node, List<Info> l) {
+ if (l.isEmpty()) { return null; }
+ Info info = l.get(0);
+ // Keep the minimum value between this function and the current value,
+ // so that we never increase OrderPreserving from NO or YES_IF_LAST.
+ OrderPreserving orderPreserving = OrderPreserving.values()[Math.min(node.preservesOrder().ordinal(), info.orderPreserving.ordinal())];
+ if (orderPreserving == info.orderPreserving) {
+ return info;
+ }
+ return new Info(info, orderPreserving);
+ }
+
+ @Override
+ public Iterator<Expression> visitEnter(CoerceExpression node) {
+ return node.getChildren().iterator();
+ }
+
+ @Override
+ public Info visitLeave(CoerceExpression node, List<Info> l) {
+ if (l.isEmpty()) { return null; }
+ return l.get(0);
+ }
+
+ @Override
+ public Iterator<Expression> visitEnter(RowValueConstructorExpression node) {
+ return node.getChildren().iterator();
+ }
+
+ @Override
+ public Info visitLeave(RowValueConstructorExpression node, List<Info> l) {
+ // Child expression returned null and was filtered, so not order preserving
+ if (l.size() != node.getChildren().size()) { return null; }
+ Info firstInfo = l.get(0);
+ Info lastInfo = firstInfo;
+ // Check that pkPos are consecutive which is the only way a RVC can be order preserving
+ for (int i = 1; i < l.size(); i++) {
+ // not order preserving since it's not last
+ if (lastInfo.orderPreserving == OrderPreserving.YES_IF_LAST) { return null; }
+ Info info = l.get(i);
+ // not order preserving since there's a gap in the pk
+ if (info.pkPosition != lastInfo.pkPosition + 1) { return null; }
+ lastInfo = info;
+ }
+ return new Info(firstInfo, l.size(), lastInfo.orderPreserving);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/2f0b51cb/phoenix-core/src/main/java/org/apache/phoenix/compile/TrackOrderPreservingExpressionCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/TrackOrderPreservingExpressionCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/TrackOrderPreservingExpressionCompiler.java
deleted file mode 100644
index 9fd6837..0000000
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/TrackOrderPreservingExpressionCompiler.java
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * 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.compile;
-
-import java.sql.SQLException;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-import org.apache.phoenix.compile.GroupByCompiler.GroupBy;
-import org.apache.phoenix.execute.TupleProjector;
-import org.apache.phoenix.expression.Expression;
-import org.apache.phoenix.expression.LiteralExpression;
-import org.apache.phoenix.expression.RowKeyColumnExpression;
-import org.apache.phoenix.expression.function.FunctionExpression;
-import org.apache.phoenix.expression.function.FunctionExpression.OrderPreserving;
-import org.apache.phoenix.parse.CaseParseNode;
-import org.apache.phoenix.parse.ColumnParseNode;
-import org.apache.phoenix.parse.DivideParseNode;
-import org.apache.phoenix.parse.MultiplyParseNode;
-import org.apache.phoenix.parse.SubtractParseNode;
-import org.apache.phoenix.schema.ColumnRef;
-import org.apache.phoenix.schema.PTable;
-import org.apache.phoenix.schema.PTableType;
-import org.apache.phoenix.schema.SortOrder;
-import com.google.common.collect.Lists;
-
-/**
- * Visitor that builds the expressions of a GROUP BY and ORDER BY clause. While traversing
- * the parse node tree, the visitor also determines if the natural key order of the scan
- * will match the order of the expressions. For GROUP BY, if order is preserved we can use
- * an optimization during server-side aggregation to do the aggregation on-the-fly versus
- * keeping track of each distinct group. We can only do this optimization if all the rows
- * for each group will be contiguous. For ORDER BY, we can drop the ORDER BY statement if
- * the order is preserved.
- *
- */
-public class TrackOrderPreservingExpressionCompiler extends ExpressionCompiler {
- public enum Ordering {ORDERED, UNORDERED};
-
- private final List<Entry> entries;
- private final Ordering ordering;
- private final int positionOffset;
- private final TupleProjector tupleProjector; // for derived-table query compilation
- private OrderPreserving orderPreserving = OrderPreserving.YES;
- private ColumnRef columnRef;
- private boolean isOrderPreserving = true;
- private Boolean isReverse;
-
- TrackOrderPreservingExpressionCompiler(StatementContext context, GroupBy groupBy, int expectedEntrySize, Ordering ordering, TupleProjector tupleProjector) {
- super(context, groupBy);
- PTable table = context.getResolver().getTables().get(0).getTable();
- boolean isSalted = table.getBucketNum() != null;
- boolean isMultiTenant = context.getConnection().getTenantId() != null && table.isMultiTenant();
- boolean isSharedViewIndex = table.getViewIndexId() != null;
- // TODO: util for this offset, as it's computed in numerous places
- positionOffset = (isSalted ? 1 : 0) + (isMultiTenant ? 1 : 0) + (isSharedViewIndex ? 1 : 0);
- entries = Lists.newArrayListWithExpectedSize(expectedEntrySize);
- this.ordering = ordering;
- this.tupleProjector = tupleProjector;
- }
-
- public Boolean isReverse() {
- return isReverse;
- }
-
- public boolean isOrderPreserving() {
- if (!isOrderPreserving) {
- return false;
- }
- if (ordering == Ordering.UNORDERED) {
- // Sort by position
- Collections.sort(entries, new Comparator<Entry>() {
- @Override
- public int compare(Entry o1, Entry o2) {
- return o1.getPkPosition()-o2.getPkPosition();
- }
- });
- }
- // Determine if there are any gaps in the PK columns (in which case we don't need
- // to sort in the coprocessor because the keys will already naturally be in sorted
- // order.
- int prevPos = positionOffset - 1;
- OrderPreserving prevOrderPreserving = OrderPreserving.YES;
- for (int i = 0; i < entries.size() && isOrderPreserving; i++) {
- Entry entry = entries.get(i);
- int pos = entry.getPkPosition();
- isOrderPreserving &= (entry.getOrderPreserving() != OrderPreserving.NO) && (pos == prevPos || ((pos - 1 == prevPos) && (prevOrderPreserving == OrderPreserving.YES)));
- prevPos = pos;
- prevOrderPreserving = entries.get(i).getOrderPreserving();
- }
- return isOrderPreserving;
- }
-
- @Override
- protected Expression addExpression(Expression expression) {
- // TODO: have FunctionExpression visitor instead and remove this cast
- if (expression instanceof FunctionExpression) {
- // Keep the minimum value between this function and the current value,
- // so that we never increase OrderPreserving from NO or YES_IF_LAST.
- orderPreserving = OrderPreserving.values()[Math.min(orderPreserving.ordinal(), ((FunctionExpression)expression).preservesOrder().ordinal())];
- }
- return super.addExpression(expression);
- }
-
- @Override
- public boolean visitEnter(CaseParseNode node) throws SQLException {
- orderPreserving = OrderPreserving.NO;
- return super.visitEnter(node);
- }
-
- @Override
- public boolean visitEnter(DivideParseNode node) throws SQLException {
- // A divide expression may not preserve row order.
- // For example: GROUP BY 1/x
- orderPreserving = OrderPreserving.NO;
- return super.visitEnter(node);
- }
-
- @Override
- public boolean visitEnter(SubtractParseNode node) throws SQLException {
- // A subtract expression may not preserve row order.
- // For example: GROUP BY 10 - x
- orderPreserving = OrderPreserving.NO;
- return super.visitEnter(node);
- }
-
- @Override
- public boolean visitEnter(MultiplyParseNode node) throws SQLException {
- // A multiply expression may not preserve row order.
- // For example: GROUP BY -1 * x
- orderPreserving = OrderPreserving.NO;
- return super.visitEnter(node);
- }
-
- @Override
- public void reset() {
- super.reset();
- columnRef = null;
- orderPreserving = OrderPreserving.YES;
- }
-
- @Override
- protected ColumnRef resolveColumn(ColumnParseNode node) throws SQLException {
- ColumnRef ref = super.resolveColumn(node);
- // If we encounter any non PK column, then we can't aggregate on-the-fly
- // because the distinct groups have no correlation to the KV column value
- if (getColumnPKPosition(ref) < 0) {
- orderPreserving = OrderPreserving.NO;
- }
-
- if (columnRef == null) {
- columnRef = ref;
- } else if (!columnRef.equals(ref)) {
- // If we encounter more than one column reference in an expression,
- // we can't assume the result of the expression will be key ordered.
- // For example GROUP BY a * b
- orderPreserving = OrderPreserving.NO;
- }
- return ref;
- }
-
- private int getColumnPKPosition(ColumnRef ref) {
- if (tupleProjector != null && ref.getTable().getType() == PTableType.SUBQUERY) {
- Expression expression = tupleProjector.getExpressions()[ref.getColumnPosition()];
- if (expression instanceof RowKeyColumnExpression) {
- return ((RowKeyColumnExpression) expression).getPosition();
- }
- }
-
- return ref.getPKSlotPosition();
- }
-
- public boolean addEntry(Expression expression) {
- if (expression instanceof LiteralExpression) {
- return false;
- }
- isOrderPreserving &= (orderPreserving != OrderPreserving.NO);
- entries.add(new Entry(expression, columnRef, orderPreserving));
- return true;
- }
-
- public boolean addEntry(Expression expression, SortOrder sortOrder) {
- // If the expression is sorted in a different order than the specified sort order
- // then the expressions are not order preserving.
- if (expression.getSortOrder() != sortOrder) {
- if (isReverse == null) {
- isReverse = true;
- } else if (!isReverse){
- orderPreserving = OrderPreserving.NO;
- }
- } else {
- if (isReverse == null) {
- isReverse = false;
- } else if (isReverse){
- orderPreserving = OrderPreserving.NO;
- }
- }
- return addEntry(expression);
- }
-
- public List<Entry> getEntries() {
- return entries;
- }
-
- public class Entry {
- private final Expression expression;
- private final ColumnRef columnRef;
- private final OrderPreserving orderPreserving;
-
- private Entry(Expression expression, ColumnRef columnRef, OrderPreserving orderPreserving) {
- this.expression = expression;
- this.columnRef = columnRef;
- this.orderPreserving = orderPreserving;
- }
-
- public Expression getExpression() {
- return expression;
- }
-
- public int getPkPosition() {
- return getColumnPKPosition(columnRef);
- }
-
- public int getColumnPosition() {
- return columnRef.getColumnPosition();
- }
-
- public OrderPreserving getOrderPreserving() {
- return orderPreserving;
- }
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/phoenix/blob/2f0b51cb/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java b/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java
index 77c1f9e..77eb237 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java
@@ -41,6 +41,7 @@ import java.util.Properties;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.filter.FirstKeyOnlyFilter;
import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.phoenix.compile.OrderByCompiler.OrderBy;
import org.apache.phoenix.coprocessor.BaseScannerRegionObserver;
import org.apache.phoenix.exception.SQLExceptionCode;
import org.apache.phoenix.expression.Expression;
@@ -52,6 +53,7 @@ import org.apache.phoenix.expression.function.TimeUnit;
import org.apache.phoenix.jdbc.PhoenixConnection;
import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
import org.apache.phoenix.jdbc.PhoenixPreparedStatement;
+import org.apache.phoenix.jdbc.PhoenixStatement;
import org.apache.phoenix.query.BaseConnectionlessQueryTest;
import org.apache.phoenix.query.QueryConstants;
import org.apache.phoenix.schema.AmbiguousColumnException;
@@ -1450,8 +1452,8 @@ public class QueryCompilerTest extends BaseConnectionlessQueryTest {
conn.createStatement().execute("CREATE TABLE t (k1 varchar, k2 varchar, v varchar, constraint pk primary key(k1,k2))");
ResultSet rs;
String[] queries = {
- "SELECT DISTINCT v FROM T ORDER BY v LIMIT 3",
- "SELECT v FROM T GROUP BY v,k1 ORDER BY v LIMIT 3",
+// "SELECT DISTINCT v FROM T ORDER BY v LIMIT 3",
+// "SELECT v FROM T GROUP BY v,k1 ORDER BY v LIMIT 3",
"SELECT DISTINCT count(*) FROM T GROUP BY k1 LIMIT 3",
"SELECT count(1) FROM T GROUP BY v,k1 LIMIT 3",
"SELECT max(v) FROM T GROUP BY k1,k2 HAVING count(k1) > 1 LIMIT 3",
@@ -1461,7 +1463,8 @@ public class QueryCompilerTest extends BaseConnectionlessQueryTest {
for (int i = 0; i < queries.length; i++) {
query = queries[i];
rs = conn.createStatement().executeQuery("EXPLAIN " + query);
- assertFalse("Did not expected to find GROUP BY limit optimization in: " + query, QueryUtil.getExplainPlan(rs).contains(" LIMIT 3 GROUPS"));
+ String explainPlan = QueryUtil.getExplainPlan(rs);
+ assertFalse("Did not expected to find GROUP BY limit optimization in: " + query, explainPlan.contains(" LIMIT 3 GROUPS"));
}
}
@@ -1631,4 +1634,103 @@ public class QueryCompilerTest extends BaseConnectionlessQueryTest {
}
+ @Test
+ public void testOrderByOrderPreservingFwd() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ conn.createStatement().execute("CREATE TABLE t (k1 date not null, k2 date not null, k3 date not null, v varchar, constraint pk primary key(k1,k2,k3))");
+ String[] queries = {
+ "SELECT * FROM T ORDER BY (k1,k2), k3",
+ "SELECT * FROM T ORDER BY k1,k2,k3",
+ "SELECT * FROM T ORDER BY k1,k2",
+ "SELECT * FROM T ORDER BY k1",
+ "SELECT * FROM T ORDER BY CAST(k1 AS TIMESTAMP)",
+ "SELECT * FROM T ORDER BY (k1,k2,k3)",
+ "SELECT * FROM T ORDER BY TRUNC(k1, 'DAY'), CEIL(k2, 'HOUR')",
+ "SELECT * FROM T ORDER BY INVERT(k1) DESC",
+ };
+ String query;
+ for (int i = 0; i < queries.length; i++) {
+ query = queries[i];
+ QueryPlan plan = conn.createStatement().unwrap(PhoenixStatement.class).compileQuery(query);
+ assertTrue("Expected order by to be compiled out: " + query, plan.getOrderBy() == OrderBy.FWD_ROW_KEY_ORDER_BY);
+ }
+ }
+
+ @Test
+ public void testOrderByOrderPreservingRev() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ conn.createStatement().execute("CREATE TABLE t (k1 date not null, k2 date not null, k3 date not null, v varchar, constraint pk primary key(k1,k2 DESC,k3))");
+ String[] queries = {
+ "SELECT * FROM T ORDER BY INVERT(k1),k2",
+ "SELECT * FROM T ORDER BY INVERT(k1)",
+ "SELECT * FROM T ORDER BY TRUNC(k1, 'DAY') DESC, CEIL(k2, 'HOUR') DESC",
+ "SELECT * FROM T ORDER BY k1 DESC",
+ };
+ String query;
+ for (int i = 0; i < queries.length; i++) {
+ query = queries[i];
+ QueryPlan plan = conn.createStatement().unwrap(PhoenixStatement.class).compileQuery(query);
+ assertTrue("Expected order by to be compiled out: " + query, plan.getOrderBy() == OrderBy.REV_ROW_KEY_ORDER_BY);
+ }
+ }
+
+ @Test
+ public void testNotOrderByOrderPreserving() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ conn.createStatement().execute("CREATE TABLE t (k1 date not null, k2 date not null, k3 date not null, v varchar, constraint pk primary key(k1,k2,k3))");
+ String[] queries = {
+ "SELECT * FROM T ORDER BY k1,k3",
+ "SELECT * FROM T ORDER BY SUBSTR(TO_CHAR(k1),1,4)",
+ "SELECT * FROM T ORDER BY k2",
+ "SELECT * FROM T ORDER BY INVERT(k1),k3",
+ "SELECT * FROM T ORDER BY CASE WHEN k1 = CURRENT_DATE() THEN 0 ELSE 1 END",
+ "SELECT * FROM T ORDER BY TO_CHAR(k1)",
+ };
+ String query;
+ for (int i = 0; i < queries.length; i++) {
+ query = queries[i];
+ QueryPlan plan = conn.createStatement().unwrap(PhoenixStatement.class).compileQuery(query);
+ assertFalse("Expected order by not to be compiled out: " + query, plan.getOrderBy().getOrderByExpressions().isEmpty());
+ }
+ }
+
+ @Test
+ public void testGroupByOrderPreserving() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ conn.createStatement().execute("CREATE TABLE t (k1 date not null, k2 date not null, k3 date not null, v varchar, constraint pk primary key(k1,k2,k3))");
+ String[] queries = {
+ "SELECT 1 FROM T GROUP BY k3, (k1,k2)",
+ "SELECT 1 FROM T GROUP BY k2,k1,k3",
+ "SELECT 1 FROM T GROUP BY k1,k2",
+ "SELECT 1 FROM T GROUP BY k1",
+ "SELECT 1 FROM T GROUP BY CAST(k1 AS TIMESTAMP)",
+ "SELECT 1 FROM T GROUP BY (k1,k2,k3)",
+ "SELECT 1 FROM T GROUP BY TRUNC(k2, 'DAY'), CEIL(k1, 'HOUR')",
+ };
+ String query;
+ for (int i = 0; i < queries.length; i++) {
+ query = queries[i];
+ QueryPlan plan = conn.createStatement().unwrap(PhoenixStatement.class).compileQuery(query);
+ assertTrue("Expected group by to be order preserving: " + query, plan.getGroupBy().isOrderPreserving());
+ }
+ }
+
+ @Test
+ public void testNotGroupByOrderPreserving() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ conn.createStatement().execute("CREATE TABLE t (k1 date not null, k2 date not null, k3 date not null, v varchar, constraint pk primary key(k1,k2,k3))");
+ String[] queries = {
+ "SELECT 1 FROM T GROUP BY k1,k3",
+ "SELECT 1 FROM T GROUP BY k2",
+ "SELECT 1 FROM T GROUP BY INVERT(k1),k3",
+ "SELECT 1 FROM T GROUP BY CASE WHEN k1 = CURRENT_DATE() THEN 0 ELSE 1 END",
+ "SELECT 1 FROM T GROUP BY TO_CHAR(k1)",
+ };
+ String query;
+ for (int i = 0; i < queries.length; i++) {
+ query = queries[i];
+ QueryPlan plan = conn.createStatement().unwrap(PhoenixStatement.class).compileQuery(query);
+ assertFalse("Expected group by not to be order preserving: " + query, plan.getGroupBy().isOrderPreserving());
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/2f0b51cb/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryOptimizerTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryOptimizerTest.java b/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryOptimizerTest.java
index 67c44bd..cd51683 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryOptimizerTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryOptimizerTest.java
@@ -19,6 +19,7 @@ package org.apache.phoenix.compile;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import java.sql.Array;
import java.sql.Connection;
@@ -33,7 +34,6 @@ import java.util.Properties;
import org.apache.hadoop.hbase.util.Pair;
import org.apache.phoenix.compile.OrderByCompiler.OrderBy;
-import org.apache.phoenix.exception.SQLExceptionCode;
import org.apache.phoenix.jdbc.PhoenixPreparedStatement;
import org.apache.phoenix.jdbc.PhoenixStatement;
import org.apache.phoenix.query.BaseConnectionlessQueryTest;
@@ -84,9 +84,8 @@ public class QueryOptimizerTest extends BaseConnectionlessQueryTest {
try{
conn.createStatement().execute("CREATE TABLE foo (k VARCHAR NOT NULL PRIMARY KEY, v VARCHAR) IMMUTABLE_ROWS=true");
PhoenixStatement stmt = conn.createStatement().unwrap(PhoenixStatement.class);
- QueryPlan plan = stmt.optimizeQuery("SELECT * FROM foo ORDER BY 1,2,3");
- } catch (SQLException e) {
- assertEquals(SQLExceptionCode.PARAM_INDEX_OUT_OF_BOUND.getErrorCode(), e.getErrorCode());
+ QueryPlan plan = stmt.optimizeQuery("SELECT * FROM foo ORDER BY 'a','b','c'");
+ assertTrue(plan.getOrderBy().getOrderByExpressions().isEmpty());
} finally {
conn.close();
}
[3/5] phoenix git commit: PHOENIX-1792 Add Week() and Hour()
built-ins (Alicia Ying Shu)
Posted by ja...@apache.org.
PHOENIX-1792 Add Week() and Hour() built-ins (Alicia Ying Shu)
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/36a7f248
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/36a7f248
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/36a7f248
Branch: refs/heads/master
Commit: 36a7f248bb7beb9234a17eb74f6dfe3edf6e3b64
Parents: 2f0b51c
Author: James Taylor <jt...@salesforce.com>
Authored: Mon Apr 13 16:30:06 2015 -0700
Committer: James Taylor <jt...@salesforce.com>
Committed: Mon Apr 13 16:30:06 2015 -0700
----------------------------------------------------------------------
.../end2end/YearMonthSecondFunctionIT.java | 42 +++++++++++++++++---
1 file changed, 36 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/phoenix/blob/36a7f248/phoenix-core/src/it/java/org/apache/phoenix/end2end/YearMonthSecondFunctionIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/YearMonthSecondFunctionIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/YearMonthSecondFunctionIT.java
index 20a88c0..cc51bdd 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/YearMonthSecondFunctionIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/YearMonthSecondFunctionIT.java
@@ -60,7 +60,7 @@ public class YearMonthSecondFunctionIT extends BaseHBaseManagedTimeIT {
public void testYearFunctionDate() throws SQLException {
assertEquals(2015, callYearFunction("YEAR(current_date())"));
-
+
assertEquals(2015, callYearFunction("YEAR(now())"));
assertEquals(2008, callYearFunction("YEAR(TO_DATE('2008-01-01', 'yyyy-MM-dd', 'local'))"));
@@ -113,6 +113,12 @@ public class YearMonthSecondFunctionIT extends BaseHBaseManagedTimeIT {
String dml = "UPSERT INTO T1 VALUES (1, TO_DATE('2004-03-01 00:00:00'), TO_TIMESTAMP('2006-02-01 00:00:00'), TO_TIME('2008-02-01 00:00:00'), " +
"TO_DATE('2010-03-01 00:00:00:896', 'yyyy-MM-dd HH:mm:ss:SSS'), TO_TIMESTAMP('2012-02-01'), TO_TIME('2015-02-01 00:00:00'))";
conn.createStatement().execute(dml);
+ dml = "UPSERT INTO T1 VALUES (2, TO_DATE('2005-03-01 00:00:00'), TO_TIMESTAMP('2006-02-01 00:00:00'), TO_TIME('2008-02-01 00:00:00'), " +
+ "TO_DATE('2010-03-01 00:00:00:896', 'yyyy-MM-dd HH:mm:ss:SSS'), TO_TIMESTAMP('2012-02-01'), TO_TIME('2015-02-01 00:00:00'))";
+ conn.createStatement().execute(dml);
+ dml = "UPSERT INTO T1 VALUES (3, TO_DATE('2006-03-01 00:00:00'), TO_TIMESTAMP('2006-02-01 00:00:00'), TO_TIME('2008-02-01 00:00:00'), " +
+ "TO_DATE('2010-03-01 00:00:00:896', 'yyyy-MM-dd HH:mm:ss:SSS'), TO_TIMESTAMP('2012-02-01'), TO_TIME('2015-02-01 00:00:00'))";
+ conn.createStatement().execute(dml);
conn.commit();
ResultSet rs = conn.createStatement().executeQuery("SELECT k1, YEAR(timestamps), YEAR(times), Year(unsignedDates), YEAR(unsignedTimestamps), " +
@@ -136,6 +142,12 @@ public class YearMonthSecondFunctionIT extends BaseHBaseManagedTimeIT {
String dml = "UPSERT INTO T1 VALUES (1, TO_DATE('2004-03-10 00:00:00'), TO_TIMESTAMP('2006-04-12 00:00:00'), TO_TIME('2008-05-16 00:00:00'), " +
"TO_DATE('2010-06-20 00:00:00:789', 'yyyy-MM-dd HH:mm:ss:SSS'), TO_TIMESTAMP('2012-07-28'), TO_TIME('2015-12-25 00:00:00'))";
conn.createStatement().execute(dml);
+ dml = "UPSERT INTO T1 VALUES (2, TO_DATE('2004-04-10 00:00:00'), TO_TIMESTAMP('2006-04-12 00:00:00'), TO_TIME('2008-05-16 00:00:00'), " +
+ "TO_DATE('2010-06-20 00:00:00:789', 'yyyy-MM-dd HH:mm:ss:SSS'), TO_TIMESTAMP('2012-07-28'), TO_TIME('2015-12-25 00:00:00'))";
+ conn.createStatement().execute(dml);
+ dml = "UPSERT INTO T1 VALUES (3, TO_DATE('2004-05-10 00:00:00'), TO_TIMESTAMP('2006-04-12 00:00:00'), TO_TIME('2008-05-16 00:00:00'), " +
+ "TO_DATE('2010-06-20 00:00:00:789', 'yyyy-MM-dd HH:mm:ss:SSS'), TO_TIMESTAMP('2012-07-28'), TO_TIME('2015-12-25 00:00:00'))";
+ conn.createStatement().execute(dml);
conn.commit();
ResultSet rs = conn.createStatement().executeQuery("SELECT k1, MONTH(timestamps), MONTH(times), MONTH(unsignedDates), MONTH(unsignedTimestamps), " +
@@ -159,6 +171,12 @@ public class YearMonthSecondFunctionIT extends BaseHBaseManagedTimeIT {
String dml = "UPSERT INTO T1 VALUES (1, TO_DATE('2004-03-01 00:00:10'), TO_TIMESTAMP('2006-04-12 00:00:20'), TO_TIME('2008-05-16 10:00:30'), " +
"TO_DATE('2010-06-20 00:00:40:789', 'yyyy-MM-dd HH:mm:ss:SSS'), TO_TIMESTAMP('2012-07-28'), TO_TIME('2015-12-25 00:00:50'))";
conn.createStatement().execute(dml);
+ dml = "UPSERT INTO T1 VALUES (2, TO_DATE('2004-03-01 00:00:10'), TO_TIMESTAMP('2006-04-12 00:20:30'), TO_TIME('2008-05-16 10:00:30'), " +
+ "TO_DATE('2010-06-20 00:00:40:789', 'yyyy-MM-dd HH:mm:ss:SSS'), TO_TIMESTAMP('2012-07-28'), TO_TIME('2015-12-25 00:00:50'))";
+ conn.createStatement().execute(dml);
+ dml = "UPSERT INTO T1 VALUES (3, TO_DATE('2004-03-01 00:00:10'), TO_TIMESTAMP('2006-04-12 00:50:30'), TO_TIME('2008-05-16 10:00:30'), " +
+ "TO_DATE('2010-06-20 00:00:40:789', 'yyyy-MM-dd HH:mm:ss:SSS'), TO_TIMESTAMP('2012-07-28'), TO_TIME('2015-12-25 00:00:50'))";
+ conn.createStatement().execute(dml);
conn.commit();
ResultSet rs = conn.createStatement().executeQuery("SELECT k1, SECOND(dates), SECOND(times), SECOND(unsignedDates), SECOND(unsignedTimestamps), " +
@@ -178,14 +196,18 @@ public class YearMonthSecondFunctionIT extends BaseHBaseManagedTimeIT {
String ddl =
"CREATE TABLE IF NOT EXISTS T1 (k1 INTEGER NOT NULL, dates DATE, timestamps TIMESTAMP, times TIME CONSTRAINT pk PRIMARY KEY (k1))";
conn.createStatement().execute(ddl);
- String dml = "UPSERT INTO T1 VALUES (1, TO_DATE('2004-02-01 00:00:10'), TO_TIMESTAMP('2006-04-12 00:00:20'), TO_TIME('2008-05-16 10:00:30'))";
+ String dml = "UPSERT INTO T1 VALUES (1, TO_DATE('2004-01-10 10:00:10'), TO_TIMESTAMP('2006-04-12 08:00:20'), TO_TIME('2008-05-16 10:00:30'))";
+ conn.createStatement().execute(dml);
+ dml = "UPSERT INTO T1 VALUES (2, TO_DATE('2004-01-10 10:00:10'), TO_TIMESTAMP('2006-05-18 08:00:20'), TO_TIME('2008-05-16 10:00:30'))";
+ conn.createStatement().execute(dml);
+ dml = "UPSERT INTO T1 VALUES (3, TO_DATE('2004-01-10 10:00:10'), TO_TIMESTAMP('2006-05-18 08:00:20'), TO_TIME('2008-05-16 10:00:30'))";
conn.createStatement().execute(dml);
conn.commit();
ResultSet rs = conn.createStatement().executeQuery("SELECT k1, WEEK(dates), WEEK(times) FROM T1 where WEEK(timestamps)=15");
assertTrue(rs.next());
assertEquals(1, rs.getInt(1));
- assertEquals(5, rs.getInt(2));
+ assertEquals(2, rs.getInt(2));
assertEquals(20, rs.getInt(3));
assertFalse(rs.next());
}
@@ -198,14 +220,19 @@ public class YearMonthSecondFunctionIT extends BaseHBaseManagedTimeIT {
String dml = "UPSERT INTO T1 VALUES (1, TO_DATE('Sat, 3 Feb 2008 03:05:06 GMT', 'EEE, d MMM yyyy HH:mm:ss z', 'UTC'), TO_TIMESTAMP('2006-04-12 15:10:20'), " +
"TO_TIME('2008-05-16 20:40:30'))";
conn.createStatement().execute(dml);
+ dml = "UPSERT INTO T1 VALUES (2, TO_DATE('Sat, 3 Feb 2008 03:05:06 GMT', 'EEE, d MMM yyyy HH:mm:ss z', 'UTC'), TO_TIMESTAMP('2006-04-12 10:10:20'), " +
+ "TO_TIME('2008-05-16 20:40:30'))";
+ conn.createStatement().execute(dml);
+ dml = "UPSERT INTO T1 VALUES (3, TO_DATE('Sat, 3 Feb 2008 03:05:06 GMT', 'EEE, d MMM yyyy HH:mm:ss z', 'UTC'), TO_TIMESTAMP('2006-04-12 08:10:20'), " +
+ "TO_TIME('2008-05-16 20:40:30'))";
+ conn.createStatement().execute(dml);
conn.commit();
- ResultSet rs = conn.createStatement().executeQuery("SELECT k1, HOUR(dates), HOUR(timestamps), HOUR(times) FROM T1");
+ ResultSet rs = conn.createStatement().executeQuery("SELECT k1, HOUR(dates), HOUR(times) FROM T1 where HOUR(timestamps)=15");
assertTrue(rs.next());
assertEquals(1, rs.getInt(1));
assertEquals(3, rs.getInt(2));
- assertEquals(15, rs.getInt(3));
- assertEquals(20, rs.getInt(4));
+ assertEquals(20, rs.getInt(3));
assertFalse(rs.next());
}
@@ -220,6 +247,9 @@ public class YearMonthSecondFunctionIT extends BaseHBaseManagedTimeIT {
stmt.setInt(1, 1);
stmt.setDate(2, new Date(date.getTime()-500));
stmt.execute();
+ stmt.setInt(1, 2);
+ stmt.setDate(2, new Date(date.getTime()+600000));
+ stmt.execute();
conn.commit();
ResultSet rs = conn.createStatement().executeQuery("SELECT * from T1 where now() > timestamps");