Repository: phoenix
Updated Branches:
  refs/heads/calcite 50e4406db -> 413247da5


PHOENIX-2416 Implement multi-tenant tables in Phoenix/Calcite integration


Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/413247da
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/413247da
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/413247da

Branch: refs/heads/calcite
Commit: 413247da5618803e0f61bd9a6661bcc4bb5e4d34
Parents: 50e4406
Author: maryannxue <[email protected]>
Authored: Tue Nov 17 00:15:40 2015 -0500
Committer: maryannxue <[email protected]>
Committed: Tue Nov 17 00:15:40 2015 -0500

----------------------------------------------------------------------
 .../org/apache/phoenix/calcite/CalciteIT.java   | 45 ++++++++++++++++++++
 .../apache/phoenix/calcite/PhoenixSchema.java   |  5 ++-
 .../apache/phoenix/calcite/PhoenixTable.java    |  5 ++-
 .../phoenix/calcite/rel/PhoenixTableScan.java   | 21 ++++-----
 4 files changed, 62 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/413247da/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteIT.java 
b/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteIT.java
index 2d904ef..8daf255 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteIT.java
@@ -268,6 +268,7 @@ public class CalciteIT extends BaseClientManagedTimeIT {
         initJoinTableValues(url, null, null);
         initArrayTable();
         initSaltedTables();
+        initMultiTenantTables();
         createIndices(
                 "CREATE INDEX IDX1 ON aTable (a_string) INCLUDE (b_string, 
x_integer)",
                 "CREATE INDEX IDX2 ON aTable (b_string) INCLUDE (a_string, 
y_integer)",
@@ -395,6 +396,39 @@ public class CalciteIT extends BaseClientManagedTimeIT {
         conn.close();        
     }
     
+    protected static final String MULTI_TENANT_TABLE = 
"multitenant_test_table";
+    
+    protected void initMultiTenantTables() throws SQLException {
+        Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+        Connection conn = DriverManager.getConnection(getUrl(), props);
+        try {
+            conn.createStatement().execute(
+                    "CREATE TABLE " + MULTI_TENANT_TABLE + " (tenant_id 
VARCHAR NOT NULL, id VARCHAR NOT NULL, col0 INTEGER, col1 INTEGER CONSTRAINT pk 
PRIMARY KEY (tenant_id, id)) MULTI_TENANT=true");
+            PreparedStatement stmt = conn.prepareStatement(
+                    "UPSERT INTO " + MULTI_TENANT_TABLE
+                    + " VALUES(?, ?, ?, ?)");
+            stmt.setString(1, "10");
+            stmt.setString(2, "2");
+            stmt.setInt(3, 3);
+            stmt.setInt(4, 4);
+            stmt.execute();
+            stmt.setString(1, "15");
+            stmt.setString(2, "3");
+            stmt.setInt(3, 4);
+            stmt.setInt(4, 5);
+            stmt.execute();
+            stmt.setString(1, "20");
+            stmt.setString(2, "4");
+            stmt.setInt(3, 5);
+            stmt.setInt(4, 6);
+            stmt.execute();
+            conn.commit();
+        } catch (TableAlreadyExistsException e) {
+        } finally {
+            conn.close();
+        }
+    }
+    
     @Test public void testTableScan() throws Exception {
         start(false).sql("select * from aTable where a_string = 'a'")
                 .explainIs("PhoenixToEnumerableConverter\n" +
@@ -1522,6 +1556,17 @@ public class CalciteIT extends BaseClientManagedTimeIT {
                         {2, 3, 4, 5, 2, 3, 4, 5}})
                 .close();
     }
+    
+    @Test public void testMultiTenant() {
+        Properties props = getConnectionProps(false);
+        props.setProperty("TenantId", "15");
+        start(props).sql("select * from " + MULTI_TENANT_TABLE)
+                .explainIs("PhoenixToEnumerableConverter\n" +
+                           "  PhoenixTableScan(table=[[phoenix, 
MULTITENANT_TEST_TABLE]])\n")
+                .resultIs(new Object[][] {
+                        {"3", 4, 5}})
+                .close();
+    }
 
     /** Tests a simple command that is defined in Phoenix's extended SQL 
parser. */
     @Ignore

http://git-wip-us.apache.org/repos/asf/phoenix/blob/413247da/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixSchema.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixSchema.java 
b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixSchema.java
index 01913b9..40afe5f 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixSchema.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixSchema.java
@@ -96,7 +96,9 @@ public class PhoenixSchema implements Schema {
             while (rs.next()) {
                 String tableName = 
rs.getString(PhoenixDatabaseMetaData.TABLE_NAME);
                 String tableType = 
rs.getString(PhoenixDatabaseMetaData.TABLE_TYPE);
-                if (!tableType.equals(PTableType.VIEW.getValue().getString())) 
{
+                String viewType = 
rs.getString(PhoenixDatabaseMetaData.VIEW_TYPE);
+                if (!tableType.equals(PTableType.VIEW.getValue().getString())
+                        || ViewType.MAPPED.name().equals(viewType)) {
                     ColumnResolver x = FromCompiler.getResolver(
                             NamedTableNode.create(
                                     null,
@@ -107,7 +109,6 @@ public class PhoenixSchema implements Schema {
                     tableMap.put(tableName, tables.get(0).getTable());
                 } else {
                     String viewSql = 
rs.getString(PhoenixDatabaseMetaData.VIEW_STATEMENT);
-                    String viewType = 
rs.getString(PhoenixDatabaseMetaData.VIEW_TYPE);
                     viewDefMap.put(tableName, new ViewDef(viewSql, 
viewType.equals(ViewType.UPDATABLE.name())));
                 }
             }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/413247da/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixTable.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixTable.java 
b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixTable.java
index cb07a7c..df6e338 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixTable.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixTable.java
@@ -50,8 +50,9 @@ public class PhoenixTable extends AbstractTable implements 
TranslatableTable {
       this.pTable = Preconditions.checkNotNull(pTable);
       List<Integer> pkPositions = Lists.<Integer> newArrayList();
       List<RelFieldCollation> fieldCollations = Lists.<RelFieldCollation> 
newArrayList();
-      for (PColumn column : pTable.getPKColumns()) {
-          int position = column.getPosition();
+      int start = getStartingColumnPosition(pTable);
+      for (PColumn column : pTable.getPKColumns().subList(start, 
pTable.getPKColumns().size())) {
+          int position = column.getPosition() - start;
           SortOrder sortOrder = column.getSortOrder();
           pkPositions.add(position);
           fieldCollations.add(new RelFieldCollation(position, sortOrder == 
SortOrder.ASC ? Direction.ASCENDING : Direction.DESCENDING));

http://git-wip-us.apache.org/repos/asf/phoenix/blob/413247da/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixTableScan.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixTableScan.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixTableScan.java
index 1933ccb..864b4ca 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixTableScan.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixTableScan.java
@@ -239,20 +239,21 @@ public class PhoenixTableScan extends TableScan 
implements PhoenixRel {
             StatementContext context = new StatementContext(stmt, resolver, 
new Scan(), new SequenceManager(stmt));
             SelectStatement select = SelectStatement.SELECT_ONE;
             ImmutableIntList columnRefList = 
implementor.getCurrentContext().columnRefList;
+            Expression filterExpr = 
LiteralExpression.newConstant(Boolean.TRUE);
             Expression dynamicFilter = null;
             if (filter != null) {
                 ImmutableBitSet bitSet = 
InputFinder.analyze(filter).inputBitSet.addAll(columnRefList).build();
                 columnRefList = ImmutableIntList.copyOf(bitSet.asList());
-                Expression filterExpr = CalciteUtils.toExpression(filter, 
implementor);
-                filterExpr = WhereOptimizer.pushKeyExpressionsToScan(context, 
select, filterExpr);
-                WhereCompiler.setScanFilter(context, select, filterExpr, true, 
false);
-                // TODO This is not absolutely strict. We may have a filter 
like:
-                // pk = '0' and pk = $cor0 where $cor0 happens to get a sample 
value
-                // as '0', thus making the below test return false and adding 
an
-                // unnecessary dynamic filter. This would only be a 
performance bug though.
-                if (!context.getScanRanges().equals(this.scanRanges)) {
-                    dynamicFilter = filterExpr;
-                }
+                filterExpr = CalciteUtils.toExpression(filter, implementor);
+            }
+            filterExpr = WhereOptimizer.pushKeyExpressionsToScan(context, 
select, filterExpr);
+            WhereCompiler.setScanFilter(context, select, filterExpr, true, 
false);
+            // TODO This is not absolutely strict. We may have a filter like:
+            // pk = '0' and pk = $cor0 where $cor0 happens to get a sample 
value
+            // as '0', thus making the below test return false and adding an
+            // unnecessary dynamic filter. This would only be a performance 
bug though.
+            if (filter != null && 
!context.getScanRanges().equals(this.scanRanges)) {
+                dynamicFilter = filterExpr;
             }
             projectColumnFamilies(context.getScan(), phoenixTable.getTable(), 
columnRefList);
             if (implementor.getCurrentContext().forceProject) {

Reply via email to