TAJO-1300: Merge the index branch into the master branch. Closes #651
Project: http://git-wip-us.apache.org/repos/asf/tajo/repo Commit: http://git-wip-us.apache.org/repos/asf/tajo/commit/9840d378 Tree: http://git-wip-us.apache.org/repos/asf/tajo/tree/9840d378 Diff: http://git-wip-us.apache.org/repos/asf/tajo/diff/9840d378 Branch: refs/heads/master Commit: 9840d378522ae921d32c04f21b3e0673fc9dd90c Parents: 97e61e6 Author: Jihoon Son <[email protected]> Authored: Thu Jul 30 13:37:40 2015 +0900 Committer: Jihoon Son <[email protected]> Committed: Thu Jul 30 13:37:40 2015 +0900 ---------------------------------------------------------------------- CHANGES | 13 ++ .../org/apache/tajo/algebra/CreateDatabase.java | 2 +- .../org/apache/tajo/algebra/CreateIndex.java | 146 +++++++++++++ .../org/apache/tajo/algebra/CreateTable.java | 2 +- .../java/org/apache/tajo/algebra/DropIndex.java | 54 +++++ .../java/org/apache/tajo/algebra/Insert.java | 2 +- .../java/org/apache/tajo/algebra/OpType.java | 2 + .../tajo/catalog/AbstractCatalogClient.java | 122 ++++++++--- .../src/main/proto/CatalogProtocol.proto | 18 +- .../apache/tajo/catalog/CatalogConstants.java | 1 + .../org/apache/tajo/catalog/CatalogService.java | 24 ++- .../org/apache/tajo/catalog/CatalogUtil.java | 46 ++++- .../org/apache/tajo/catalog/DDLBuilder.java | 22 ++ .../java/org/apache/tajo/catalog/IndexDesc.java | 126 +++++++----- .../java/org/apache/tajo/catalog/IndexMeta.java | 180 ++++++++++++++++ .../java/org/apache/tajo/catalog/TableDesc.java | 5 - .../exception/UndefinedIndexException.java | 2 +- .../src/main/proto/CatalogProtos.proto | 48 ++--- .../org/apache/tajo/catalog/TestIndexDesc.java | 59 ++++-- .../tajo/catalog/store/HiveCatalogStore.java | 50 +++-- .../org/apache/tajo/catalog/CatalogServer.java | 148 +++++++++---- .../dictionary/IndexesTableDescriptor.java | 8 +- .../tajo/catalog/store/AbstractDBStore.java | 184 ++++++++++------- .../apache/tajo/catalog/store/CatalogStore.java | 29 +-- .../org/apache/tajo/catalog/store/MemStore.java | 113 ++++++---- .../src/main/resources/schemas/derby/derby.xml | 32 +-- .../main/resources/schemas/mariadb/mariadb.xml | 20 +- .../src/main/resources/schemas/mysql/mysql.xml | 20 +- .../main/resources/schemas/oracle/oracle.xml | 30 +-- .../resources/schemas/postgresql/postgresql.xml | 32 +-- .../org/apache/tajo/catalog/TestCatalog.java | 89 ++++---- .../org/apache/tajo/cli/tools/TajoDump.java | 14 +- .../cli/tsql/commands/DescTableCommand.java | 19 ++ .../apache/tajo/client/CatalogAdminClient.java | 15 ++ .../tajo/client/CatalogAdminClientImpl.java | 110 +++++++++- .../org/apache/tajo/client/QueryClientImpl.java | 4 +- .../apache/tajo/client/SessionConnection.java | 1 - .../org/apache/tajo/client/TajoClientImpl.java | 36 ++++ tajo-client/src/main/proto/ClientProtos.proto | 10 + .../main/proto/TajoMasterClientProtocol.proto | 9 + .../java/org/apache/tajo/OverridableConf.java | 2 +- .../main/java/org/apache/tajo/SessionVars.java | 5 + .../java/org/apache/tajo/conf/TajoConf.java | 6 +- .../apache/tajo/exception/ErrorMessages.java | 3 + .../apache/tajo/exception/ReturnStateUtil.java | 11 +- .../main/java/org/apache/tajo/util/TUtil.java | 10 + tajo-common/src/main/proto/errors.proto | 11 +- .../org/apache/tajo/engine/parser/SQLParser.g4 | 13 +- .../engine/codegen/ExecutorPreCompiler.java | 7 + .../apache/tajo/engine/parser/SQLAnalyzer.java | 47 +++++ .../engine/planner/PhysicalPlannerImpl.java | 34 ++- .../engine/planner/global/GlobalPlanner.java | 23 +++ .../planner/physical/BSTIndexScanExec.java | 173 +++++++++++++--- .../engine/planner/physical/ProjectionExec.java | 4 +- .../engine/planner/physical/StoreIndexExec.java | 102 +++++++++ .../utils/test/ErrorInjectionRewriter.java | 7 +- .../org/apache/tajo/master/GlobalEngine.java | 3 +- .../tajo/master/TajoMasterClientService.java | 204 +++++++++++++++++- .../apache/tajo/master/exec/DDLExecutor.java | 134 +++++++++--- .../NonForwardQueryResultSystemScanner.java | 40 ++-- .../apache/tajo/master/exec/QueryExecutor.java | 42 +++- .../java/org/apache/tajo/querymaster/Query.java | 46 +++++ .../tajo/querymaster/QueryMasterTask.java | 13 +- .../java/org/apache/tajo/util/IndexUtil.java | 152 -------------- .../tajo/worker/TajoWorkerClientService.java | 2 +- .../apache/tajo/worker/TaskAttemptContext.java | 13 +- .../java/org/apache/tajo/worker/TaskImpl.java | 29 ++- .../tajo/ws/rs/resources/QueryResource.java | 4 +- .../java/org/apache/tajo/QueryTestCaseBase.java | 3 + .../org/apache/tajo/cli/tools/TestTajoDump.java | 95 +++++++-- .../apache/tajo/engine/eval/ExprTestBase.java | 12 +- .../engine/planner/TestJoinOrderAlgorithm.java | 2 +- .../engine/planner/TestLogicalOptimizer.java | 3 +- .../tajo/engine/planner/TestLogicalPlanner.java | 36 +++- .../planner/physical/TestBSTIndexExec.java | 206 ------------------- .../planner/physical/TestHashAntiJoinExec.java | 6 +- .../planner/physical/TestHashSemiJoinExec.java | 6 +- .../planner/physical/TestPhysicalPlanner.java | 18 +- .../engine/planner/physical/TestSortExec.java | 6 +- .../planner/physical/TestSortIntersectExec.java | 2 +- .../tajo/engine/query/TestCreateIndex.java | 113 ++++++++++ .../apache/tajo/engine/query/TestIndexScan.java | 144 +++++++++++++ .../tajo/engine/query/TestTablePartitions.java | 8 +- .../tajo/master/TestExecutionBlockCursor.java | 2 +- .../apache/tajo/querymaster/TestKillQuery.java | 4 +- .../queries/TestCreateIndex/testCreateIndex.sql | 1 + .../testCreateIndexOnExpression.sql | 1 + .../testCreateIndexOnLocation.sql | 1 + .../testCreateIndexOnMultiAttrs.sql | 1 + .../testCreateIndexOnMultiExprs.sql | 1 + .../testCreateIndexWithCondition.sql | 1 + .../TestIndexScan/testOnMultipleExprs.result | 3 + .../TestIndexScan/testOnMultipleKeys.result | 3 + .../TestIndexScan/testOnMultipleKeys2.result | 3 + .../testOnSortedNonUniqueKeys.result | 4 + .../TestIndexScan/testOnUnsortedTextKeys.result | 3 + .../TestIndexScan/testWithGroupBy.result | 3 + .../results/TestIndexScan/testWithJoin.result | 4 + .../results/TestIndexScan/testWithSort.result | 4 + .../TestTajoCli/testHelpSessionVars.result | 2 + .../results/TestTajoDump/testDump3.result | 20 ++ tajo-docs/src/main/sphinx/index/how_to_use.rst | 2 +- .../org/apache/tajo/jdbc/TajoStatement.java | 3 +- .../org/apache/tajo/plan/LogicalOptimizer.java | 12 +- .../java/org/apache/tajo/plan/LogicalPlan.java | 28 +++ .../tajo/plan/LogicalPlanPreprocessor.java | 17 ++ .../org/apache/tajo/plan/LogicalPlanner.java | 93 ++++++++- .../org/apache/tajo/plan/NamedExprsManager.java | 1 + .../tajo/plan/algebra/AlgebraVisitor.java | 2 + .../tajo/plan/algebra/BaseAlgebraVisitor.java | 17 ++ .../apache/tajo/plan/expr/AlgebraicUtil.java | 70 +++++++ .../org/apache/tajo/plan/expr/EvalTreeUtil.java | 6 +- .../tajo/plan/logical/CreateIndexNode.java | 161 +++++++++++++++ .../apache/tajo/plan/logical/DropIndexNode.java | 92 +++++++++ .../apache/tajo/plan/logical/IndexScanNode.java | 92 ++++----- .../org/apache/tajo/plan/logical/NodeType.java | 4 +- .../rewrite/BaseLogicalPlanRewriteEngine.java | 9 +- .../BaseLogicalPlanRewriteRuleProvider.java | 4 +- .../plan/rewrite/LogicalPlanRewriteEngine.java | 3 +- .../plan/rewrite/LogicalPlanRewriteRule.java | 6 +- .../rewrite/LogicalPlanRewriteRuleContext.java | 65 ++++++ .../tajo/plan/rewrite/rules/AccessPathInfo.java | 52 +++++ .../plan/rewrite/rules/AccessPathRewriter.java | 129 ++++++++++++ .../plan/rewrite/rules/FilterPushDownRule.java | 95 ++++++++- .../tajo/plan/rewrite/rules/IndexScanInfo.java | 113 ++++++++++ .../rules/LogicalPlanEqualityTester.java | 9 +- .../rewrite/rules/PartitionedTableRewriter.java | 10 +- .../rewrite/rules/ProjectionPushDownRule.java | 21 +- .../tajo/plan/rewrite/rules/SeqScanInfo.java | 43 ++++ .../plan/serder/LogicalNodeDeserializer.java | 69 +++++++ .../tajo/plan/serder/LogicalNodeSerializer.java | 75 +++++++ .../org/apache/tajo/plan/util/IndexUtil.java | 72 +++++++ .../org/apache/tajo/plan/util/PlannerUtil.java | 35 +++- .../plan/visitor/BasicLogicalPlanVisitor.java | 32 ++- .../plan/visitor/ExplainLogicalPlanVisitor.java | 14 +- .../tajo/plan/visitor/LogicalPlanVisitor.java | 10 +- .../tajo/plan/visitor/SimpleAlgebraVisitor.java | 1 - tajo-plan/src/main/proto/Plan.proto | 86 +++++--- .../apache/tajo/storage/OldStorageManager.java | 16 -- .../org/apache/tajo/storage/Tablespace.java | 15 ++ .../tajo/storage/hbase/HBaseTablespace.java | 5 +- .../storage/hbase/SortedInsertRewriter.java | 11 +- .../apache/tajo/storage/index/TestBSTIndex.java | 48 +++-- .../index/TestSingleCSVFileBSTIndex.java | 12 +- 144 files changed, 4163 insertions(+), 1205 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tajo/blob/9840d378/CHANGES ---------------------------------------------------------------------- diff --git a/CHANGES b/CHANGES index 2b9ea92..4c44aec 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,6 @@ Tajo Change Log + Release 0.11.0 - unreleased NEW FEATURES @@ -200,6 +201,14 @@ Release 0.11.0 - unreleased BUG FIXES + TAJO-1608: Fix test failure in index_support branch. (jihoon) + + TAJO-1594: Catalog schema is invalid for some databases. (jihoon) + + TAJO-1657: Tajo Rest API /database/{database-name]/tables should return table + names only without invalid external table info. + (Contributed by DaeMyung Kang, Committed by jihoon) + TAJO-1552: NPE occurs when GreedyHeuristicJoinOrderAlgorithm.getCost() returns infinity. (Contributed by Hyoungjun Kim, Committed by jihoon) @@ -373,6 +382,8 @@ Release 0.11.0 - unreleased TASKS + TAJO-1300: Merge the index branch into the master branch. (jihoon) + TAJO-1713: Change the type of edge cache in JoinGraphContext from HashMap to LRUMap. (jihoon) @@ -432,6 +443,8 @@ Release 0.11.0 - unreleased SUB TASKS + TAJO-1302: Support index metadata backup and restore. (jihoon) + TAJO-1484 Apply on ColPartitionStoreExec. (Contributed by Navis, committed by hyunsik) http://git-wip-us.apache.org/repos/asf/tajo/blob/9840d378/tajo-algebra/src/main/java/org/apache/tajo/algebra/CreateDatabase.java ---------------------------------------------------------------------- diff --git a/tajo-algebra/src/main/java/org/apache/tajo/algebra/CreateDatabase.java b/tajo-algebra/src/main/java/org/apache/tajo/algebra/CreateDatabase.java index 1144b6e..6e74d3d 100644 --- a/tajo-algebra/src/main/java/org/apache/tajo/algebra/CreateDatabase.java +++ b/tajo-algebra/src/main/java/org/apache/tajo/algebra/CreateDatabase.java @@ -32,7 +32,7 @@ public class CreateDatabase extends Expr { private String tablespaceName; @Expose @SerializedName("IfNotExists") private boolean ifNotExists; - @Expose @SerializedName("DatabaseProperties") + @Expose @SerializedName("Properties") private Map<String, String> params; public CreateDatabase(final String databaseName, final String tablespaceName, final boolean ifNotExists) { http://git-wip-us.apache.org/repos/asf/tajo/blob/9840d378/tajo-algebra/src/main/java/org/apache/tajo/algebra/CreateIndex.java ---------------------------------------------------------------------- diff --git a/tajo-algebra/src/main/java/org/apache/tajo/algebra/CreateIndex.java b/tajo-algebra/src/main/java/org/apache/tajo/algebra/CreateIndex.java new file mode 100644 index 0000000..a9f734d --- /dev/null +++ b/tajo-algebra/src/main/java/org/apache/tajo/algebra/CreateIndex.java @@ -0,0 +1,146 @@ +/* + * 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.tajo.algebra; + +import com.google.common.base.Objects; +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; +import org.apache.tajo.algebra.Sort.SortSpec; +import org.apache.tajo.util.TUtil; + +import java.util.Map; + +public class CreateIndex extends UnaryOperator { + @Expose @SerializedName("IsUnique") + private boolean unique = false; + @Expose @SerializedName("IndexName") + private String indexName; + @Expose @SerializedName("SortSpecs") + private SortSpec[] sortSpecs; + @Expose @SerializedName("Properties") + private Map<String, String> params; + @Expose @SerializedName("IndexMethodSpec") + private IndexMethodSpec methodSpec; + private boolean external = false; + @Expose @SerializedName("IndexPath") + private String indexPath; + + public CreateIndex(final String indexName, final SortSpec[] sortSpecs) { + super(OpType.CreateIndex); + this.indexName = indexName; + this.sortSpecs = sortSpecs; + this.methodSpec = new IndexMethodSpec("TWO_LEVEL_BIN_TREE"); + } + + public void setUnique(boolean unique) { + this.unique = unique; + } + + public boolean isUnique() { + return this.unique; + } + + public void setIndexName(String indexName) { + this.indexName = indexName; + } + + public String getIndexName() { + return indexName; + } + + public void setSortSpecs(SortSpec[] sortSpecs) { + this.sortSpecs = sortSpecs; + } + + public SortSpec[] getSortSpecs() { + return sortSpecs; + } + + public void setParams(Map<String, String> params) { + this.params = params; + } + + public Map<String, String> getParams() { + return this.params; + } + + public void setMethodSpec(IndexMethodSpec methodSpec) { + this.methodSpec = methodSpec; + } + + public IndexMethodSpec getMethodSpec() { + return this.methodSpec; + } + + public void setIndexPath(String indexPath) { + this.external = true; + this.indexPath = indexPath; + } + + public boolean isExternal() { + return this.external; + } + + public String getIndexPath() { + return this.indexPath; + } + + @Override + public int hashCode() { + return Objects.hashCode(unique, indexName, sortSpecs, params, methodSpec, external); + } + + @Override + boolean equalsTo(Expr expr) { + CreateIndex other = (CreateIndex) expr; + return this.unique == other.unique && + this.indexName.equals(other.indexName) && + TUtil.checkEquals(this.sortSpecs, other.sortSpecs) && + TUtil.checkEquals(this.params, other.params) && + this.methodSpec.equals(other.methodSpec) && + this.external == other.external; + } + + public static class IndexMethodSpec { + @Expose @SerializedName("IndexMethodName") + private String name; + + public IndexMethodSpec(final String name) { + this.name = name; + } + + public String getName() { + return this.name; + } + + @Override + public int hashCode() { + return name.hashCode(); + } + + @Override + public boolean equals(Object o) { + if (o instanceof IndexMethodSpec) { + IndexMethodSpec other = (IndexMethodSpec) o; + return this.name.equals(other.name); + } + return false; + } + } +} http://git-wip-us.apache.org/repos/asf/tajo/blob/9840d378/tajo-algebra/src/main/java/org/apache/tajo/algebra/CreateTable.java ---------------------------------------------------------------------- diff --git a/tajo-algebra/src/main/java/org/apache/tajo/algebra/CreateTable.java b/tajo-algebra/src/main/java/org/apache/tajo/algebra/CreateTable.java index 5d1599d..ef10c4c 100644 --- a/tajo-algebra/src/main/java/org/apache/tajo/algebra/CreateTable.java +++ b/tajo-algebra/src/main/java/org/apache/tajo/algebra/CreateTable.java @@ -46,7 +46,7 @@ public class CreateTable extends Expr { private String location; @Expose @SerializedName("SubPlan") private Expr subquery; - @Expose @SerializedName("TableProperties") + @Expose @SerializedName("Properties") private Map<String, String> params; @Expose @SerializedName("PartitionMethodDesc") private PartitionMethodDescExpr partition; http://git-wip-us.apache.org/repos/asf/tajo/blob/9840d378/tajo-algebra/src/main/java/org/apache/tajo/algebra/DropIndex.java ---------------------------------------------------------------------- diff --git a/tajo-algebra/src/main/java/org/apache/tajo/algebra/DropIndex.java b/tajo-algebra/src/main/java/org/apache/tajo/algebra/DropIndex.java new file mode 100644 index 0000000..5a75e78 --- /dev/null +++ b/tajo-algebra/src/main/java/org/apache/tajo/algebra/DropIndex.java @@ -0,0 +1,54 @@ +/* + * 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.tajo.algebra; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class DropIndex extends Expr { + @Expose @SerializedName("IndexName") + private String indexName; + + public DropIndex(final String indexName) { + super(OpType.DropIndex); + this.indexName = indexName; + } + + @Override + public int hashCode() { + return indexName.hashCode(); + } + + @Override + boolean equalsTo(Expr expr) { + DropIndex other = (DropIndex) expr; + return this.indexName.equals(other.indexName); + } + + @Override + public Object clone() throws CloneNotSupportedException { + DropIndex clone = (DropIndex) super.clone(); + clone.indexName = indexName; + return clone; + } + + public String getIndexName() { + return indexName; + } +} http://git-wip-us.apache.org/repos/asf/tajo/blob/9840d378/tajo-algebra/src/main/java/org/apache/tajo/algebra/Insert.java ---------------------------------------------------------------------- diff --git a/tajo-algebra/src/main/java/org/apache/tajo/algebra/Insert.java b/tajo-algebra/src/main/java/org/apache/tajo/algebra/Insert.java index 0826d90..f0cd5f9 100644 --- a/tajo-algebra/src/main/java/org/apache/tajo/algebra/Insert.java +++ b/tajo-algebra/src/main/java/org/apache/tajo/algebra/Insert.java @@ -39,7 +39,7 @@ public class Insert extends Expr { private String location; @Expose @SerializedName("SubPlan") private Expr subquery; - @Expose @SerializedName("InsertParams") + @Expose @SerializedName("Properties") private Map<String, String> params; public Insert() { http://git-wip-us.apache.org/repos/asf/tajo/blob/9840d378/tajo-algebra/src/main/java/org/apache/tajo/algebra/OpType.java ---------------------------------------------------------------------- diff --git a/tajo-algebra/src/main/java/org/apache/tajo/algebra/OpType.java b/tajo-algebra/src/main/java/org/apache/tajo/algebra/OpType.java index 3e7d277..47fea64 100644 --- a/tajo-algebra/src/main/java/org/apache/tajo/algebra/OpType.java +++ b/tajo-algebra/src/main/java/org/apache/tajo/algebra/OpType.java @@ -53,6 +53,8 @@ public enum OpType { DropTable(DropTable.class), AlterTablespace(AlterTablespace.class), AlterTable(AlterTable.class), + CreateIndex(CreateIndex.class), + DropIndex(DropIndex.class), TruncateTable(TruncateTable.class), // Insert or Update http://git-wip-us.apache.org/repos/asf/tajo/blob/9840d378/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java ---------------------------------------------------------------------- diff --git a/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java b/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java index f7f7785..402df0f 100644 --- a/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java +++ b/tajo-catalog/tajo-catalog-client/src/main/java/org/apache/tajo/catalog/AbstractCatalogClient.java @@ -34,8 +34,10 @@ import org.apache.tajo.conf.TajoConf; import org.apache.tajo.error.Errors.ResultCode; import org.apache.tajo.exception.ReturnStateUtil; import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.NullProto; +import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.ReturnState; import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.StringListResponse; import org.apache.tajo.util.ProtoUtil; +import org.apache.tajo.util.TUtil; import java.io.Closeable; import java.util.ArrayList; @@ -315,6 +317,18 @@ public abstract class AbstractCatalogClient implements CatalogService, Closeable } @Override + public List<IndexDescProto> getAllIndexes() { + try { + CatalogProtocolService.BlockingInterface stub = getStub(); + IndexListResponse response = stub.getAllIndexes(null, ProtoUtil.NULL_PROTO); + return response.getIndexDescList(); + } catch (ServiceException e) { + LOG.error(e.getMessage(), e); + return null; + } + } + + @Override public final PartitionMethodDesc getPartitionMethod(final String databaseName, final String tableName) { try { @@ -496,7 +510,13 @@ public abstract class AbstractCatalogClient implements CatalogService, Closeable try { final BlockingInterface stub = getStub(); - return isSuccess(stub.createIndex(null, index.getProto())); + final ReturnState state = stub.createIndex(null, index.getProto()); + if (isSuccess(state)) { + return true; + } else { + // TODO + return false; + } } catch (ServiceException e) { throw new RuntimeException(e); @@ -521,18 +541,35 @@ public abstract class AbstractCatalogClient implements CatalogService, Closeable } @Override - public boolean existIndexByColumn(final String databaseName, final String tableName, final String columnName) { + public boolean existIndexByColumns(final String databaseName, final String tableName, final Column [] columns) { + return existIndexByColumnNames(databaseName, tableName, extractColumnNames(columns)); + } + + @Override + public boolean existIndexByColumnNames(final String databaseName, final String tableName, final String [] columnNames) { try { - final GetIndexByColumnRequest request = GetIndexByColumnRequest.newBuilder() - .setTableIdentifier(buildTableIdentifier(databaseName, tableName)) - .setColumnName(columnName) - .build(); + GetIndexByColumnNamesRequest.Builder builder = GetIndexByColumnNamesRequest.newBuilder(); + builder.setTableIdentifier(CatalogUtil.buildTableIdentifier(databaseName, tableName)); + for (String colunName : columnNames) { + builder.addColumnNames(colunName); + } final BlockingInterface stub = getStub(); - return isSuccess(stub.existIndexByColumn(null, request)); + return isSuccess(stub.existIndexByColumnNames(null, builder.build())); + } catch (ServiceException e) { + throw new RuntimeException(e); + } + } + + @Override + public boolean existIndexesByTable(final String databaseName, final String tableName) { + try { + final BlockingInterface stub = getStub(); + return isSuccess( + stub.existIndexesByTable(null, CatalogUtil.buildTableIdentifier(databaseName, tableName))); } catch (ServiceException e) { throw new RuntimeException(e); } @@ -548,64 +585,83 @@ public abstract class AbstractCatalogClient implements CatalogService, Closeable .build(); final BlockingInterface stub = getStub(); - final GetIndexResponse response = stub.getIndexByName(null, request); + final IndexResponse response = stub.getIndexByName(null, request); ensureOk(response.getState()); - return new IndexDesc(response.getIndex()); + return new IndexDesc(response.getIndexDesc()); } catch (ServiceException e) { throw new RuntimeException(e); } } + private static String[] extractColumnNames(Column[] columns) { + String[] columnNames = new String [columns.length]; + for (int i = 0; i < columnNames.length; i++) { + columnNames[i] = columns[i].getSimpleName(); + } + return columnNames; + } + @Override - public final IndexDesc getIndexByColumn(final String databaseName, - final String tableName, - final String columnName) { - try { + public final IndexDesc getIndexByColumns(final String databaseName, + final String tableName, + final Column [] columns) { + return getIndexByColumnNames(databaseName, tableName, extractColumnNames(columns)); + } - final GetIndexByColumnRequest request = GetIndexByColumnRequest.newBuilder() - .setTableIdentifier(buildTableIdentifier(databaseName, tableName)) - .setColumnName(columnName) - .build(); + @Override + public final IndexDesc getIndexByColumnNames(final String databaseName, + final String tableName, + final String [] columnNames) { + try { + GetIndexByColumnNamesRequest.Builder builder = GetIndexByColumnNamesRequest.newBuilder(); + builder.setTableIdentifier(CatalogUtil.buildTableIdentifier(databaseName, tableName)); + for (String columnName : columnNames) { + builder.addColumnNames(columnName); + } final BlockingInterface stub = getStub(); - final GetIndexResponse response = stub.getIndexByColumn(null, request); - ensureOk(response.getState());; - - return new IndexDesc(response.getIndex()); + final IndexResponse response = stub.getIndexByColumnNames(null, builder.build()); + ensureOk(response.getState()); + return new IndexDesc(response.getIndexDesc()); } catch (ServiceException e) { throw new RuntimeException(e); } } @Override - public boolean dropIndex(final String dbName, final String indexName) { + public final Collection<IndexDesc> getAllIndexesByTable(final String databaseName, + final String tableName) { try { - final IndexNameProto request = IndexNameProto.newBuilder() - .setDatabaseName(dbName) - .setIndexName(indexName) - .build(); + TableIdentifierProto proto = CatalogUtil.buildTableIdentifier(databaseName, tableName); final BlockingInterface stub = getStub(); + final IndexListResponse response = stub.getAllIndexesByTable(null, proto); + ensureOk(response.getState()); - return isSuccess(stub.dropIndex(null, request)); - + List<IndexDesc> indexDescs = TUtil.newList(); + for (IndexDescProto descProto : response.getIndexDescList()) { + indexDescs.add(new IndexDesc(descProto)); + } + return indexDescs; } catch (ServiceException e) { throw new RuntimeException(e); } } @Override - public List<IndexProto> getAllIndexes() { - + public boolean dropIndex(final String dbName, final String indexName) { try { + final IndexNameProto request = IndexNameProto.newBuilder() + .setDatabaseName(dbName) + .setIndexName(indexName) + .build(); + final BlockingInterface stub = getStub(); - final GetIndexesResponse response = stub.getAllIndexes(null, ProtoUtil.NULL_PROTO); - ensureOk(response.getState()); - return response.getIndexList(); + return isSuccess(stub.dropIndex(null, request)); } catch (ServiceException e) { throw new RuntimeException(e); http://git-wip-us.apache.org/repos/asf/tajo/blob/9840d378/tajo-catalog/tajo-catalog-client/src/main/proto/CatalogProtocol.proto ---------------------------------------------------------------------- diff --git a/tajo-catalog/tajo-catalog-client/src/main/proto/CatalogProtocol.proto b/tajo-catalog/tajo-catalog-client/src/main/proto/CatalogProtocol.proto index 8d0eef6..ee74aa0 100644 --- a/tajo-catalog/tajo-catalog-client/src/main/proto/CatalogProtocol.proto +++ b/tajo-catalog/tajo-catalog-client/src/main/proto/CatalogProtocol.proto @@ -69,14 +69,14 @@ message GetPartitionDescResponse { optional PartitionDescProto partition = 2; } -message GetIndexResponse { +message GetIndexeDescResponse { required ReturnState state = 1; optional IndexDescProto index = 2; } -message GetIndexesResponse { - required ReturnState state = 1; - repeated IndexProto index = 2; +message GetIndexByColumnNamesRequest { + required TableIdentifierProto tableIdentifier = 1; + repeated string columnNames = 2; } message GetPartitionsResponse { @@ -128,10 +128,12 @@ service CatalogProtocolService { rpc createIndex(IndexDescProto) returns (ReturnState); rpc dropIndex(IndexNameProto) returns (ReturnState); rpc existIndexByName(IndexNameProto) returns (ReturnState); - rpc existIndexByColumn(GetIndexByColumnRequest) returns (ReturnState); - rpc getIndexByName(IndexNameProto) returns (GetIndexResponse); - rpc getIndexByColumn(GetIndexByColumnRequest) returns (GetIndexResponse); - rpc getAllIndexes(NullProto) returns (GetIndexesResponse); + rpc existIndexByColumnNames(GetIndexByColumnNamesRequest) returns (ReturnState); + rpc existIndexesByTable(TableIdentifierProto) returns (ReturnState); + rpc getIndexByName(IndexNameProto) returns (IndexResponse); + rpc getIndexByColumnNames(GetIndexByColumnNamesRequest) returns (IndexResponse); + rpc getAllIndexesByTable(TableIdentifierProto) returns (IndexListResponse); + rpc getAllIndexes(NullProto) returns (IndexListResponse); rpc createFunction(FunctionDescProto) returns (ReturnState); rpc dropFunction(UnregisterFunctionRequest) returns (ReturnState); http://git-wip-us.apache.org/repos/asf/tajo/blob/9840d378/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogConstants.java ---------------------------------------------------------------------- diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogConstants.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogConstants.java index 8265e38..721bcf1 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogConstants.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogConstants.java @@ -53,6 +53,7 @@ public class CatalogConstants { public static final String COL_TABLESPACE_PK = "SPACE_ID"; public static final String COL_DATABASES_PK = "DB_ID"; public static final String COL_TABLES_PK = "TID"; + public static final String COL_INDEXES_PK = "INDEX_ID"; public static final String COL_TABLES_NAME = "TABLE_NAME"; public static final String COL_PARTITIONS_PK = "PARTITION_ID"; http://git-wip-us.apache.org/repos/asf/tajo/blob/9840d378/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogService.java ---------------------------------------------------------------------- diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogService.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogService.java index f1bfe6a..7704191 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogService.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogService.java @@ -21,16 +21,12 @@ package org.apache.tajo.catalog; import org.apache.tajo.catalog.exception.UndefinedFunctionException; import org.apache.tajo.catalog.exception.UndefinedPartitionException; import org.apache.tajo.catalog.partition.PartitionMethodDesc; -import org.apache.tajo.catalog.proto.CatalogProtos; import org.apache.tajo.catalog.proto.CatalogProtos.*; import org.apache.tajo.common.TajoDataTypes.DataType; import java.util.Collection; import java.util.List; -import static org.apache.tajo.catalog.proto.CatalogProtos.*; - - public interface CatalogService { /** @@ -148,6 +144,8 @@ public interface CatalogService { */ List<ColumnProto> getAllColumns(); + List<IndexDescProto> getAllIndexes(); + /** * * @return All FunctionDescs @@ -178,10 +176,10 @@ public interface CatalogService { boolean existPartitionMethod(String databaseName, String tableName); - CatalogProtos.PartitionDescProto getPartition(String databaseName, String tableName, String partitionName) + PartitionDescProto getPartition(String databaseName, String tableName, String partitionName) throws UndefinedPartitionException; - List<CatalogProtos.PartitionDescProto> getPartitions(String databaseName, String tableName); + List<PartitionDescProto> getPartitions(String databaseName, String tableName); List<TablePartitionProto> getAllPartitions(); @@ -189,15 +187,21 @@ public interface CatalogService { boolean existIndexByName(String databaseName, String indexName); - boolean existIndexByColumn(String databaseName, String tableName, String columnName); + boolean existIndexByColumns(String databaseName, String tableName, Column[] columns); + + boolean existIndexByColumnNames(String databaseName, String tableName, String [] columnNames); + + boolean existIndexesByTable(String databaseName, String tableName); IndexDesc getIndexByName(String databaseName, String indexName); - IndexDesc getIndexByColumn(String databaseName, String tableName, String columnName); + IndexDesc getIndexByColumns(String databaseName, String tableName, Column [] columns); + + IndexDesc getIndexByColumnNames(String databaseName, String tableName, String [] columnNames); + + Collection<IndexDesc> getAllIndexesByTable(String databaseName, String tableName); boolean dropIndex(String databaseName, String indexName); - - List<IndexProto> getAllIndexes(); boolean createFunction(FunctionDesc funcDesc); http://git-wip-us.apache.org/repos/asf/tajo/blob/9840d378/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogUtil.java ---------------------------------------------------------------------- diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogUtil.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogUtil.java index 8205e9b..378bbcb 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogUtil.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogUtil.java @@ -29,6 +29,7 @@ import org.apache.tajo.catalog.partition.PartitionMethodDesc; import org.apache.tajo.catalog.proto.CatalogProtos; import org.apache.tajo.catalog.proto.CatalogProtos.PartitionKeyProto; import org.apache.tajo.catalog.proto.CatalogProtos.SchemaProto; +import org.apache.tajo.catalog.proto.CatalogProtos.StoreType; import org.apache.tajo.catalog.proto.CatalogProtos.TableDescProto; import org.apache.tajo.catalog.proto.CatalogProtos.TableIdentifierProto; import org.apache.tajo.common.TajoDataTypes; @@ -46,12 +47,8 @@ import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; -import static org.apache.tajo.catalog.proto.CatalogProtos.StoreType; import static org.apache.tajo.common.TajoDataTypes.Type; public class CatalogUtil { @@ -967,4 +964,43 @@ public class CatalogUtil { return options; } + + /** + * Make a unique name by concatenating column names. + * The concatenation is performed in sequence of columns' occurrence in the relation schema. + * + * @param originalSchema original relation schema + * @param columnNames column names which will be unified + * @return unified name + */ + public static String getUnifiedSimpleColumnName(Schema originalSchema, String[] columnNames) { + String[] simpleNames = new String[columnNames.length]; + for (int i = 0; i < simpleNames.length; i++) { + String[] identifiers = columnNames[i].split(CatalogConstants.IDENTIFIER_DELIMITER_REGEXP); + simpleNames[i] = identifiers[identifiers.length-1]; + } + Arrays.sort(simpleNames, new ColumnPosComparator(originalSchema)); + StringBuilder sb = new StringBuilder(); + for (String colName : simpleNames) { + sb.append(colName).append("_"); + } + sb.deleteCharAt(sb.length()-1); + return sb.toString(); + } + + /** + * Given column names, compare the position of columns in the relation schema. + */ + public static class ColumnPosComparator implements Comparator<String> { + + private Schema originlSchema; + public ColumnPosComparator(Schema originalSchema) { + this.originlSchema = originalSchema; + } + + @Override + public int compare(String o1, String o2) { + return originlSchema.getColumnId(o1) - originlSchema.getColumnId(o2); + } + } } http://git-wip-us.apache.org/repos/asf/tajo/blob/9840d378/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/DDLBuilder.java ---------------------------------------------------------------------- diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/DDLBuilder.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/DDLBuilder.java index f313aa5..2923654 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/DDLBuilder.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/DDLBuilder.java @@ -68,6 +68,28 @@ public class DDLBuilder { return sb.toString(); } + public static String buildDDLForIndex(IndexDesc desc) { + StringBuilder sb = new StringBuilder(); + + sb.append("--\n") + .append("-- Name: ").append(CatalogUtil.denormalizeIdentifier(desc.getName())).append("; Type: INDEX;") + .append(" Index Method: ").append(desc.getIndexMethod()); + sb.append("\n--\n"); + sb.append("CREATE INDEX ").append(CatalogUtil.denormalizeIdentifier(desc.getName())); + sb.append(" on ").append(CatalogUtil.denormalizeIdentifier(desc.getTableName())).append(" ( "); + + for (SortSpec sortSpec : desc.getKeySortSpecs()) { + sb.append(sortSpec.getSortKey().getQualifiedName()).append(" "); + sb.append(sortSpec.isAscending() ? "asc" : "desc").append(" "); + sb.append(sortSpec.isNullFirst() ? "null first" : "null last").append(", "); + } + sb.replace(sb.length()-2, sb.length()-1, " )"); + + sb.append(" location '").append(desc.getIndexPath()).append("';"); + + return sb.toString(); + } + public static void buildSchema(StringBuilder sb, Schema schema) { boolean first = true; http://git-wip-us.apache.org/repos/asf/tajo/blob/9840d378/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/IndexDesc.java ---------------------------------------------------------------------- diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/IndexDesc.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/IndexDesc.java index 151b919..9f64913 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/IndexDesc.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/IndexDesc.java @@ -26,66 +26,86 @@ import org.apache.tajo.catalog.proto.CatalogProtos.IndexDescProto; import org.apache.tajo.catalog.proto.CatalogProtos.IndexMethod; import org.apache.tajo.common.ProtoObject; +import java.net.URI; +import java.net.URISyntaxException; + public class IndexDesc implements ProtoObject<IndexDescProto>, Cloneable { - private String indexName; // required private String databaseName; // required private String tableName; // required - private Column column; // required - private IndexMethod indexMethod; // required - private boolean isUnique = false; // optional [default = false] - private boolean isClustered = false; // optional [default = false] - private boolean isAscending = false; // optional [default = false] - + private IndexMeta indexMeta; // required + public IndexDesc() { } - public IndexDesc(String idxName, String databaseName, String tableName, Column column, - IndexMethod type, boolean isUnique, boolean isClustered, boolean isAscending) { + public IndexDesc(String databaseName, String tableName, String indexName, URI indexPath, SortSpec[] keySortSpecs, + IndexMethod type, boolean isUnique, boolean isClustered, Schema targetRelationSchema) { this(); - this.indexName = idxName; - this.databaseName = databaseName; - this.tableName = tableName; - this.column = column; - this.indexMethod = type; - this.isUnique = isUnique; - this.isClustered = isClustered; - this.isAscending = isAscending; + this.set(databaseName, tableName, indexName, indexPath, keySortSpecs, type, isUnique, isClustered, + targetRelationSchema); } public IndexDesc(IndexDescProto proto) { - this(proto.getIndexName(), - proto.getTableIdentifier().getDatabaseName(), - proto.getTableIdentifier().getTableName(), - new Column(proto.getColumn()), - proto.getIndexMethod(), proto.getIsUnique(), proto.getIsClustered(), proto.getIsAscending()); + this(); + + SortSpec[] keySortSpecs = new SortSpec[proto.getKeySortSpecsCount()]; + for (int i = 0; i < keySortSpecs.length; i++) { + keySortSpecs[i] = new SortSpec(proto.getKeySortSpecs(i)); + } + + try { + this.set(proto.getTableIdentifier().getDatabaseName(), + proto.getTableIdentifier().getTableName(), + proto.getIndexName(), new URI(proto.getIndexPath()), + keySortSpecs, + proto.getIndexMethod(), proto.getIsUnique(), proto.getIsClustered(), + new Schema(proto.getTargetRelationSchema())); + } catch (URISyntaxException e) { + e.printStackTrace(); + } } - - public String getIndexName() { - return indexName; + + public void set(String databaseName, String tableName, String indexName, URI indexPath, SortSpec[] keySortSpecs, + IndexMethod type, boolean isUnique, boolean isClustered, Schema targetRelationSchema) { + this.databaseName = databaseName; + this.tableName = tableName; + this.indexMeta = new IndexMeta(indexName, indexPath, keySortSpecs, type, isUnique, isClustered, + targetRelationSchema); } - + + public String getDatabaseName() { + return databaseName; + } + public String getTableName() { return tableName; } + + public String getName() { + return indexMeta.getIndexName(); + } - public Column getColumn() { - return column; + public URI getIndexPath() { + return indexMeta.getIndexPath(); + } + + public SortSpec[] getKeySortSpecs() { + return indexMeta.getKeySortSpecs(); } public IndexMethod getIndexMethod() { - return this.indexMethod; + return indexMeta.getIndexMethod(); } public boolean isClustered() { - return this.isClustered; + return indexMeta.isClustered(); } public boolean isUnique() { - return this.isUnique; + return indexMeta.isUnique(); } - - public boolean isAscending() { - return this.isAscending; + + public Schema getTargetRelationSchema() { + return indexMeta.getTargetRelationSchema(); } @Override @@ -101,12 +121,15 @@ public class IndexDesc implements ProtoObject<IndexDescProto>, Cloneable { } builder.setTableIdentifier(tableIdentifierBuilder.build()); - builder.setIndexName(this.indexName); - builder.setColumn(this.column.getProto()); - builder.setIndexMethod(indexMethod); - builder.setIsUnique(this.isUnique); - builder.setIsClustered(this.isClustered); - builder.setIsAscending(this.isAscending); + builder.setIndexName(indexMeta.getIndexName()); + builder.setIndexPath(indexMeta.getIndexPath().toString()); + for (SortSpec colSpec : indexMeta.getKeySortSpecs()) { + builder.addKeySortSpecs(colSpec.getProto()); + } + builder.setIndexMethod(indexMeta.getIndexMethod()); + builder.setIsUnique(indexMeta.isUnique()); + builder.setIsClustered(indexMeta.isClustered()); + builder.setTargetRelationSchema(indexMeta.getTargetRelationSchema().getProto()); return builder.build(); } @@ -114,32 +137,23 @@ public class IndexDesc implements ProtoObject<IndexDescProto>, Cloneable { public boolean equals(Object obj) { if (obj instanceof IndexDesc) { IndexDesc other = (IndexDesc) obj; - return getIndexName().equals(other.getIndexName()) + return getDatabaseName().equals(other.getDatabaseName()) && getTableName().equals(other.getTableName()) - && getColumn().equals(other.getColumn()) - && getIndexMethod().equals(other.getIndexMethod()) - && isUnique() == other.isUnique() - && isClustered() == other.isClustered() - && isAscending() == other.isAscending(); + && this.indexMeta.equals(other.indexMeta); } else { return false; } } public int hashCode() { - return Objects.hashCode(getIndexName(), getTableName(), getColumn(), - getIndexMethod(), isUnique(), isClustered(), isAscending()); + return Objects.hashCode(databaseName, tableName, indexMeta); } public Object clone() throws CloneNotSupportedException { IndexDesc desc = (IndexDesc) super.clone(); - desc.indexName = indexName; - desc.tableName = tableName; - desc.column = column; - desc.indexMethod = indexMethod; - desc.isUnique = isUnique; - desc.isClustered = isClustered; - desc.isAscending = isAscending; + desc.databaseName = this.databaseName; + desc.tableName = this.tableName; + desc.indexMeta = (IndexMeta) this.indexMeta.clone(); return desc; } @@ -147,4 +161,4 @@ public class IndexDesc implements ProtoObject<IndexDescProto>, Cloneable { Gson gson = new GsonBuilder().setPrettyPrinting().create(); return gson.toJson(this); } -} \ No newline at end of file +} http://git-wip-us.apache.org/repos/asf/tajo/blob/9840d378/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/IndexMeta.java ---------------------------------------------------------------------- diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/IndexMeta.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/IndexMeta.java new file mode 100644 index 0000000..a911055 --- /dev/null +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/IndexMeta.java @@ -0,0 +1,180 @@ +/** + * 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.tajo.catalog; + +import com.google.common.base.Objects; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.annotations.Expose; +import org.apache.tajo.catalog.proto.CatalogProtos.IndexMethod; +import org.apache.tajo.util.KeyValueSet; +import org.apache.tajo.util.TUtil; + +import java.net.URI; +import java.util.Arrays; +import java.util.Comparator; + +/** + * IndexMeta contains meta information of an index. + * Meta information is the name, an index method, a path to the stored location, index keys, and so on. + */ +public class IndexMeta implements Cloneable { + @Expose private String indexName; // index name + @Expose private IndexMethod indexMethod; // index method + @Expose private URI indexPath; // path to the location + @Expose private SortSpec[] keySortSpecs; // index keys. This array should always be sorted + // according to the position in the targetRelationSchema + @Expose private boolean isUnique = false; // unique key or not + @Expose private boolean isClustered = false; // clustered index or not + @Expose private Schema targetRelationSchema; // schema of the indexed relation + @Expose private KeyValueSet options; // index options. TODO: will be added + + public IndexMeta() {} + + public IndexMeta(String indexName, URI indexPath, SortSpec[] keySortSpecs, + IndexMethod type, boolean isUnique, boolean isClustered, + Schema targetRelationSchema) { + this.indexName = indexName; + this.indexPath = indexPath; + this.indexMethod = type; + this.isUnique = isUnique; + this.isClustered = isClustered; + this.targetRelationSchema = targetRelationSchema; + initKeySortSpecs(targetRelationSchema, keySortSpecs); + } + + private void initKeySortSpecs(final Schema targetRelationSchema, final SortSpec[] keySortSpecs) { + this.targetRelationSchema = targetRelationSchema; + this.keySortSpecs = new SortSpec[keySortSpecs.length]; + for (int i = 0; i < keySortSpecs.length; i++) { + this.keySortSpecs[i] = new SortSpec(keySortSpecs[i].getSortKey(), keySortSpecs[i].isAscending(), + keySortSpecs[i].isNullFirst()); + } + Arrays.sort(this.keySortSpecs, new Comparator<SortSpec>() { + @Override + public int compare(SortSpec o1, SortSpec o2) { + return targetRelationSchema.getColumnId(o1.getSortKey().getSimpleName()) + - targetRelationSchema.getColumnId(o2.getSortKey().getSimpleName()); + } + }); + } + + public String getIndexName() { + return indexName; + } + + public void setIndexName(final String indexName) { + this.indexName = indexName; + } + + public IndexMethod getIndexMethod() { + return indexMethod; + } + + public void setIndexMethod(final IndexMethod type) { + this.indexMethod = type; + } + + public URI getIndexPath() { + return indexPath; + } + + public void setIndexPath(final URI indexPath) { + this.indexPath = indexPath; + } + + public SortSpec[] getKeySortSpecs() { + return keySortSpecs; + } + + public void setKeySortSpecs(final Schema targetRelationSchema, final SortSpec[] keySortSpecs) { + initKeySortSpecs(targetRelationSchema, keySortSpecs); + } + + public boolean isUnique() { + return isUnique; + } + + public void setUnique(boolean unique) { + this.isUnique = unique; + } + + public boolean isClustered() { + return isClustered; + } + + public void setClustered(boolean clustered) { + this.isClustered = clustered; + } + + public Schema getTargetRelationSchema() { + return targetRelationSchema; + } + + public KeyValueSet getOptions() { + return options; + } + + public void setOptions(KeyValueSet options) { + this.options = options; + } + + @Override + public boolean equals(Object o) { + if (o instanceof IndexMeta) { + IndexMeta other = (IndexMeta) o; + return this.indexName.equals(other.indexName) + && this.indexPath.equals(other.indexPath) + && this.indexMethod.equals(other.indexMethod) + && TUtil.checkEquals(this.keySortSpecs, other.keySortSpecs) + && this.isUnique == other.isUnique + && this.isClustered == other.isClustered + && this.targetRelationSchema.equals(other.targetRelationSchema); + } + return false; + } + + @Override + public int hashCode() { + return Objects.hashCode(indexName, indexPath, indexMethod, Objects.hashCode(keySortSpecs), + isUnique, isClustered, targetRelationSchema); + } + + @Override + public Object clone() throws CloneNotSupportedException { + IndexMeta clone = (IndexMeta) super.clone(); + clone.indexName = indexName; + clone.indexPath = indexPath; + clone.indexMethod = indexMethod; + clone.keySortSpecs = new SortSpec[keySortSpecs.length]; + for (int i = 0; i < keySortSpecs.length; i++) { + clone.keySortSpecs[i] = new SortSpec(this.keySortSpecs[i].getProto()); + } + clone.isUnique = this.isUnique; + clone.isClustered = this.isClustered; + clone.targetRelationSchema = this.targetRelationSchema; + return clone; + } + + @Override + public String toString() { + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + return gson.toJson(this); + } +} http://git-wip-us.apache.org/repos/asf/tajo/blob/9840d378/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/TableDesc.java ---------------------------------------------------------------------- diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/TableDesc.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/TableDesc.java index 4700322..add77f2 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/TableDesc.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/TableDesc.java @@ -22,9 +22,6 @@ import com.google.common.base.Objects; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.annotations.Expose; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.apache.tajo.catalog.json.CatalogGsonHelper; import org.apache.tajo.catalog.partition.PartitionMethodDesc; import org.apache.tajo.catalog.proto.CatalogProtos.TableDescProto; @@ -37,8 +34,6 @@ import org.apache.tajo.util.TUtil; import java.net.URI; public class TableDesc implements ProtoObject<TableDescProto>, GsonObject, Cloneable { - private final Log LOG = LogFactory.getLog(TableDesc.class); - @Expose protected String tableName; // required @Expose protected Schema schema; @Expose protected TableMeta meta; // required http://git-wip-us.apache.org/repos/asf/tajo/blob/9840d378/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedIndexException.java ---------------------------------------------------------------------- diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedIndexException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedIndexException.java index d228a40..036a5cc 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedIndexException.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/UndefinedIndexException.java @@ -24,7 +24,7 @@ public class UndefinedIndexException extends CatalogException { private static final long serialVersionUID = 3705839985189534673L; public UndefinedIndexException(String tableName, String columnName) { - super(ResultCode.UNDEFINED_INDEX, tableName, columnName); + super(ResultCode.UNDEFINED_INDEX_FOR_COLUMNS, tableName, columnName); } public UndefinedIndexException(String indexName) { http://git-wip-us.apache.org/repos/asf/tajo/blob/9840d378/tajo-catalog/tajo-catalog-common/src/main/proto/CatalogProtos.proto ---------------------------------------------------------------------- diff --git a/tajo-catalog/tajo-catalog-common/src/main/proto/CatalogProtos.proto b/tajo-catalog/tajo-catalog-common/src/main/proto/CatalogProtos.proto index f95df0a..86fee86 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/proto/CatalogProtos.proto +++ b/tajo-catalog/tajo-catalog-common/src/main/proto/CatalogProtos.proto @@ -119,11 +119,12 @@ message NamespaceProto { message IndexDescProto { required TableIdentifierProto tableIdentifier = 1; required string indexName = 2; - required ColumnProto column = 3; - required IndexMethod indexMethod = 4; - optional bool isUnique = 5 [default = false]; - optional bool isClustered = 6 [default = false]; - optional bool isAscending = 7 [default = false]; + required IndexMethod indexMethod = 3; + required string indexPath = 4; + repeated SortSpecProto key_sort_specs = 5; + required SchemaProto targetRelationSchema = 6; + optional bool isUnique = 7 [default = false]; + optional bool isClustered = 8 [default = false]; } enum IndexMethod { @@ -133,20 +134,10 @@ enum IndexMethod { BITMAP_IDX = 3; } -message GetIndexesProto { - repeated IndexProto index = 1; -} - -message IndexProto { - required int32 dbId = 1; - required int32 tId = 2; +message IndexNameProto { + required string databaseName = 1; + optional string namespace = 2; required string indexName = 3; - required string columnName = 4; - required string dataType = 5; - required string indexType = 6; - optional bool isUnique = 7 [default = false]; - optional bool isClustered = 8 [default = false]; - optional bool isAscending = 9 [default = false]; } message TableOptionProto { @@ -161,17 +152,6 @@ message TablePartitionProto { optional string path = 4; } -message GetIndexByColumnRequest { - required TableIdentifierProto tableIdentifier = 1; - required string columnName = 2; -} - -message IndexNameProto { - required string databaseName = 1; - optional string namespace = 2; - required string indexName = 3; -} - message GetFunctionsResponse { repeated FunctionDescProto functionDesc = 1; } @@ -407,3 +387,13 @@ message FunctionListResponse { required ReturnState state = 1; repeated FunctionDescProto function = 2; } + +message IndexListResponse { + required ReturnState state = 1; + repeated IndexDescProto indexDesc = 2; +} + +message IndexResponse { + required ReturnState state = 1; + optional IndexDescProto indexDesc = 2; +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tajo/blob/9840d378/tajo-catalog/tajo-catalog-common/src/test/java/org/apache/tajo/catalog/TestIndexDesc.java ---------------------------------------------------------------------- diff --git a/tajo-catalog/tajo-catalog-common/src/test/java/org/apache/tajo/catalog/TestIndexDesc.java b/tajo-catalog/tajo-catalog-common/src/test/java/org/apache/tajo/catalog/TestIndexDesc.java index 3fa8f53..247cd41 100644 --- a/tajo-catalog/tajo-catalog-common/src/test/java/org/apache/tajo/catalog/TestIndexDesc.java +++ b/tajo-catalog/tajo-catalog-common/src/test/java/org/apache/tajo/catalog/TestIndexDesc.java @@ -25,6 +25,9 @@ import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; +import java.net.URI; +import java.net.URISyntaxException; + import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotSame; @@ -33,23 +36,29 @@ public class TestIndexDesc { static IndexDesc desc1; static IndexDesc desc2; static IndexDesc desc3; - - static { - desc1 = new IndexDesc( - "idx_test", DEFAULT_DATABASE_NAME, "indexed", new Column("id", Type.INT4), - IndexMethod.TWO_LEVEL_BIN_TREE, true, true, true); - - desc2 = new IndexDesc( - "idx_test2", DEFAULT_DATABASE_NAME, "indexed", new Column("score", Type.FLOAT8), - IndexMethod.TWO_LEVEL_BIN_TREE, false, false, false); - - desc3 = new IndexDesc( - "idx_test", DEFAULT_DATABASE_NAME, "indexed", new Column("id", Type.INT4), - IndexMethod.TWO_LEVEL_BIN_TREE, true, true, true); - } + static Schema relationSchema; @BeforeClass public static void setUp() throws Exception { + relationSchema = new Schema(new Column[]{new Column("id", Type.INT4), + new Column("score", Type.FLOAT8), new Column("name", Type.TEXT)}); + SortSpec[] colSpecs1 = new SortSpec[1]; + colSpecs1[0] = new SortSpec(new Column("id", Type.INT4), true, true); + desc1 = new IndexDesc(DEFAULT_DATABASE_NAME, "indexed", + "idx_test", new URI("idx_test"), colSpecs1, + IndexMethod.TWO_LEVEL_BIN_TREE, true, true, relationSchema); + + SortSpec[] colSpecs2 = new SortSpec[1]; + colSpecs2[0] = new SortSpec(new Column("score", Type.FLOAT8), false, false); + desc2 = new IndexDesc(DEFAULT_DATABASE_NAME, "indexed", + "idx_test2", new URI("idx_test2"), colSpecs2, + IndexMethod.TWO_LEVEL_BIN_TREE, false, false, relationSchema); + + SortSpec[] colSpecs3 = new SortSpec[1]; + colSpecs3[0] = new SortSpec(new Column("id", Type.INT4), true, true); + desc3 = new IndexDesc(DEFAULT_DATABASE_NAME, "indexed", + "idx_test", new URI("idx_test"), colSpecs3, + IndexMethod.TWO_LEVEL_BIN_TREE, true, true, relationSchema); } @AfterClass @@ -64,22 +73,28 @@ public class TestIndexDesc { } @Test - public void testGetFields() { - assertEquals("idx_test", desc1.getIndexName()); + public void testGetFields() throws URISyntaxException { + assertEquals("idx_test", desc1.getName()); assertEquals("indexed", desc1.getTableName()); - assertEquals(new Column("id", Type.INT4), desc1.getColumn()); + assertEquals(1, desc1.getKeySortSpecs().length); + assertEquals(new Column("id", Type.INT4), desc1.getKeySortSpecs()[0].getSortKey()); + assertEquals(true, desc1.getKeySortSpecs()[0].isAscending()); + assertEquals(true, desc1.getKeySortSpecs()[0].isNullFirst()); assertEquals(IndexMethod.TWO_LEVEL_BIN_TREE, desc1.getIndexMethod()); + assertEquals(new URI("idx_test"), desc1.getIndexPath()); assertEquals(true, desc1.isUnique()); assertEquals(true, desc1.isClustered()); - assertEquals(true, desc1.isAscending()); - - assertEquals("idx_test2", desc2.getIndexName()); + + assertEquals("idx_test2", desc2.getName()); assertEquals("indexed", desc2.getTableName()); - assertEquals(new Column("score", Type.FLOAT8), desc2.getColumn()); + assertEquals(1, desc2.getKeySortSpecs().length); + assertEquals(new Column("score", Type.FLOAT8), desc2.getKeySortSpecs()[0].getSortKey()); + assertEquals(false, desc2.getKeySortSpecs()[0].isAscending()); + assertEquals(false, desc2.getKeySortSpecs()[0].isNullFirst()); assertEquals(IndexMethod.TWO_LEVEL_BIN_TREE, desc2.getIndexMethod()); + assertEquals(new URI("idx_test2"), desc2.getIndexPath()); assertEquals(false, desc2.isUnique()); assertEquals(false, desc2.isClustered()); - assertEquals(false, desc2.isAscending()); } @Test http://git-wip-us.apache.org/repos/asf/tajo/blob/9840d378/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogStore.java ---------------------------------------------------------------------- diff --git a/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogStore.java b/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogStore.java index 8a08b77..b49499f 100644 --- a/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogStore.java +++ b/tajo-catalog/tajo-catalog-drivers/tajo-hive/src/main/java/org/apache/tajo/catalog/store/HiveCatalogStore.java @@ -41,7 +41,7 @@ import org.apache.tajo.catalog.partition.PartitionMethodDesc; import org.apache.tajo.catalog.proto.CatalogProtos; import org.apache.tajo.catalog.proto.CatalogProtos.ColumnProto; import org.apache.tajo.catalog.proto.CatalogProtos.DatabaseProto; -import org.apache.tajo.catalog.proto.CatalogProtos.IndexProto; +import org.apache.tajo.catalog.proto.CatalogProtos.IndexDescProto; import org.apache.tajo.catalog.proto.CatalogProtos.TableDescriptorProto; import org.apache.tajo.catalog.proto.CatalogProtos.TableOptionProto; import org.apache.tajo.catalog.proto.CatalogProtos.TablePartitionProto; @@ -762,22 +762,26 @@ public class HiveCatalogStore extends CatalogConstants implements CatalogStore { @Override public void addPartitionMethod(CatalogProtos.PartitionMethodProto partitionMethodProto) throws CatalogException { // TODO - not implemented yet + throw new UnsupportedOperationException(); } @Override public CatalogProtos.PartitionMethodProto getPartitionMethod(String databaseName, String tableName) throws CatalogException { - return null; // TODO - not implemented yet + // TODO - not implemented yet + throw new UnsupportedOperationException(); } @Override public boolean existPartitionMethod(String databaseName, String tableName) throws CatalogException { - return false; // TODO - not implemented yet + // TODO - not implemented yet + throw new UnsupportedOperationException(); } @Override public void dropPartitionMethod(String databaseName, String tableName) throws CatalogException { // TODO - not implemented yet + throw new UnsupportedOperationException(); } @Override @@ -827,63 +831,75 @@ public class HiveCatalogStore extends CatalogConstants implements CatalogStore { @Override public final void addFunction(final FunctionDesc func) throws CatalogException { // TODO - not implemented yet + throw new UnsupportedOperationException(); } @Override public final void deleteFunction(final FunctionDesc func) throws CatalogException { // TODO - not implemented yet + throw new UnsupportedOperationException(); } @Override public final void existFunction(final FunctionDesc func) throws CatalogException { // TODO - not implemented yet + throw new UnsupportedOperationException(); } @Override public final List<String> getAllFunctionNames() throws CatalogException { // TODO - not implemented yet - return null; + throw new UnsupportedOperationException(); } @Override - public void dropIndex(String databaseName, String indexName) throws CatalogException { + public void createIndex(CatalogProtos.IndexDescProto proto) throws CatalogException { // TODO - not implemented yet + throw new UnsupportedOperationException(); } @Override - public boolean existIndexByName(String databaseName, String indexName) throws CatalogException { + public void dropIndex(String databaseName, String indexName) throws CatalogException { // TODO - not implemented yet - return false; + throw new UnsupportedOperationException(); } @Override - public CatalogProtos.IndexDescProto[] getIndexes(String databaseName, String tableName) throws CatalogException { + public CatalogProtos.IndexDescProto getIndexByName(String databaseName, String indexName) throws CatalogException { // TODO - not implemented yet - return null; + throw new UnsupportedOperationException(); } @Override - public void createIndex(CatalogProtos.IndexDescProto proto) throws CatalogException { + public CatalogProtos.IndexDescProto getIndexByColumns(String databaseName, String tableName, String[] columnNames) + throws CatalogException { // TODO - not implemented yet + throw new UnsupportedOperationException(); } @Override - public CatalogProtos.IndexDescProto getIndexByName(String databaseName, String indexName) throws CatalogException { + public boolean existIndexByName(String databaseName, String indexName) throws CatalogException { // TODO - not implemented yet - return null; + throw new UnsupportedOperationException(); } @Override - public CatalogProtos.IndexDescProto getIndexByColumn(String databaseName, String tableName, String columnName) + public boolean existIndexByColumns(String databaseName, String tableName, String[] columnNames) throws CatalogException { // TODO - not implemented yet - return null; + throw new UnsupportedOperationException(); } @Override - public boolean existIndexByColumn(String databaseName, String tableName, String columnName) throws CatalogException { + public List<String> getAllIndexNamesByTable(String databaseName, String tableName) throws CatalogException { // TODO - not implemented yet - return false; + throw new UnsupportedOperationException(); + } + + @Override + public boolean existIndexesByTable(String databaseName, String tableName) throws CatalogException { + // TODO - not implemented yet + throw new UnsupportedOperationException(); } @Override @@ -931,7 +947,7 @@ public class HiveCatalogStore extends CatalogConstants implements CatalogStore { } @Override - public List<IndexProto> getAllIndexes() throws CatalogException { + public List<IndexDescProto> getAllIndexes() throws CatalogException { throw new UnsupportedOperationException(); } http://git-wip-us.apache.org/repos/asf/tajo/blob/9840d378/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java ---------------------------------------------------------------------- diff --git a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java index 6a3fc16..0327367 100644 --- a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java +++ b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java @@ -31,7 +31,9 @@ import org.apache.tajo.TajoConstants; import org.apache.tajo.annotation.ThreadSafe; import org.apache.tajo.catalog.CatalogProtocol.*; import org.apache.tajo.catalog.dictionary.InfoSchemaMetadataDictionary; -import org.apache.tajo.catalog.exception.*; +import org.apache.tajo.catalog.exception.CatalogException; +import org.apache.tajo.catalog.exception.DuplicateDatabaseException; +import org.apache.tajo.catalog.exception.UndefinedTablespaceException; import org.apache.tajo.catalog.proto.CatalogProtos.*; import org.apache.tajo.catalog.store.CatalogStore; import org.apache.tajo.catalog.store.DerbyStore; @@ -1094,7 +1096,12 @@ public class CatalogServer extends AbstractService { rlock.lock(); try { - return store.existIndexByName(dbName, indexName) ? OK : errUndefinedIndexName(indexName); + + if (store.existDatabase(dbName)) { + return store.existIndexByName(dbName, indexName) ? OK : errUndefinedIndexName(indexName); + } else { + return errUndefinedDatabase(dbName); + } } catch (Throwable t) { printStackTraceIfError(LOG, t); @@ -1106,30 +1113,65 @@ public class CatalogServer extends AbstractService { } @Override - public ReturnState existIndexByColumn(RpcController controller, GetIndexByColumnRequest request) { + public ReturnState existIndexByColumnNames(RpcController controller, GetIndexByColumnNamesRequest request) + throws ServiceException { TableIdentifierProto identifier = request.getTableIdentifier(); String databaseName = identifier.getDatabaseName(); String tableName = identifier.getTableName(); - String columnName = request.getColumnName(); + List<String> columnNames = request.getColumnNamesList(); rlock.lock(); try { - return store.existIndexByColumn(databaseName, tableName, columnName) ? - OK : errUndefinedIndex(tableName, columnName); + + if (store.existDatabase(databaseName)) { + if (store.existTable(databaseName, tableName)) { + return store.existIndexByColumns(databaseName, tableName, + columnNames.toArray(new String[columnNames.size()])) ? OK : errUndefinedIndex(tableName, columnNames); + } else { + return errUndefinedTable(tableName); + } + } else { + return errUndefinedDatabase(databaseName); + } } catch (Throwable t) { printStackTraceIfError(LOG, t); return returnError(t); - } finally { rlock.unlock(); } } @Override - public GetIndexResponse getIndexByName(RpcController controller, IndexNameProto request) + public ReturnState existIndexesByTable(RpcController controller, TableIdentifierProto request) throws ServiceException { + String databaseName = request.getDatabaseName(); + String tableName = request.getTableName(); + + rlock.lock(); + try { + + if (store.existDatabase(databaseName)) { + if (store.existTable(databaseName, tableName)) { + return store.existIndexesByTable(databaseName, tableName) ? OK : errUndefinedIndex(tableName); + } else { + return errUndefinedTable(tableName); + } + } else { + return errUndefinedDatabase(databaseName); + } + + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return returnError(t); + } finally { + rlock.unlock(); + } + } + + @Override + public IndexResponse getIndexByName(RpcController controller, IndexNameProto request) throws ServiceException { String databaseName = request.getDatabaseName(); String indexName = request.getIndexName(); @@ -1138,20 +1180,20 @@ public class CatalogServer extends AbstractService { try { if (!store.existIndexByName(databaseName, indexName)) { - return GetIndexResponse.newBuilder() + return IndexResponse.newBuilder() .setState(errUndefinedIndexName(indexName)) .build(); } - return GetIndexResponse.newBuilder() + return IndexResponse.newBuilder() .setState(OK) - .setIndex(store.getIndexByName(databaseName, indexName)) + .setIndexDesc(store.getIndexByName(databaseName, indexName)) .build(); } catch (Throwable t) { printStackTraceIfError(LOG, t); - return GetIndexResponse.newBuilder() + return IndexResponse.newBuilder() .setState(returnError(t)) .build(); @@ -1161,31 +1203,77 @@ public class CatalogServer extends AbstractService { } @Override - public GetIndexResponse getIndexByColumn(RpcController controller, GetIndexByColumnRequest request) + public IndexResponse getIndexByColumnNames(RpcController controller, GetIndexByColumnNamesRequest request) throws ServiceException { TableIdentifierProto identifier = request.getTableIdentifier(); String databaseName = identifier.getDatabaseName(); String tableName = identifier.getTableName(); - String columnName = request.getColumnName(); + List<String> columnNamesList = request.getColumnNamesList(); + String[] columnNames = new String[columnNamesList.size()]; + columnNames = columnNamesList.toArray(columnNames); rlock.lock(); try { - if (!store.existIndexByColumn(databaseName, tableName, columnName)) { - return GetIndexResponse.newBuilder() - .setState(errUndefinedIndex(tableName, columnName)) + if (!store.existIndexByColumns(databaseName, tableName, columnNames)) { + return IndexResponse.newBuilder() + .setState(errUndefinedIndex(tableName, columnNamesList)) .build(); } - - return GetIndexResponse.newBuilder() + return IndexResponse.newBuilder() .setState(OK) - .setIndex(store.getIndexByColumn(databaseName, tableName, columnName)) + .setIndexDesc(store.getIndexByColumns(databaseName, tableName, columnNames)) .build(); + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return IndexResponse.newBuilder() + .setState(returnError(t)) + .build(); + } finally { + rlock.unlock(); + } + } + + @Override + public IndexListResponse getAllIndexesByTable(RpcController controller, TableIdentifierProto request) + throws ServiceException { + String databaseName = request.getDatabaseName(); + String tableName = request.getTableName(); + + rlock.lock(); + try { + if (!store.existIndexesByTable(databaseName, tableName)) { + return IndexListResponse.newBuilder() + .setState(errUndefinedIndex(tableName)) + .build(); + } + IndexListResponse.Builder builder = IndexListResponse.newBuilder().setState(OK); + for (String eachIndexName : store.getAllIndexNamesByTable(databaseName, tableName)) { + builder.addIndexDesc(store.getIndexByName(databaseName, eachIndexName)); + } + return builder.build(); } catch (Throwable t) { printStackTraceIfError(LOG, t); - return GetIndexResponse.newBuilder() + return IndexListResponse.newBuilder() + .setState(returnError(t)) + .build(); + } finally { + rlock.unlock(); + } + } + + @Override + public IndexListResponse getAllIndexes(RpcController controller, NullProto request) throws ServiceException { + rlock.lock(); + try { + return IndexListResponse.newBuilder().addAllIndexDesc(store.getAllIndexes()).build(); + + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + + return IndexListResponse.newBuilder() .setState(returnError(t)) .build(); @@ -1217,24 +1305,6 @@ public class CatalogServer extends AbstractService { wlock.unlock(); } } - - @Override - public GetIndexesResponse getAllIndexes(RpcController controller, NullProto request) throws ServiceException { - rlock.lock(); - try { - return GetIndexesResponse.newBuilder().addAllIndex(store.getAllIndexes()).build(); - - } catch (Throwable t) { - printStackTraceIfError(LOG, t); - - return GetIndexesResponse.newBuilder() - .setState(returnError(t)) - .build(); - - } finally { - rlock.unlock(); - } - } private boolean containFunction(String signature) { List<FunctionDescProto> found = findFunction(signature); http://git-wip-us.apache.org/repos/asf/tajo/blob/9840d378/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/dictionary/IndexesTableDescriptor.java ---------------------------------------------------------------------- diff --git a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/dictionary/IndexesTableDescriptor.java b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/dictionary/IndexesTableDescriptor.java index a079a93..d527b19 100644 --- a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/dictionary/IndexesTableDescriptor.java +++ b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/dictionary/IndexesTableDescriptor.java @@ -27,12 +27,8 @@ class IndexesTableDescriptor extends AbstractTableDescriptor { new ColumnDescriptor("db_id", Type.INT4, 0), new ColumnDescriptor("tid", Type.INT4, 0), new ColumnDescriptor("index_name", Type.TEXT, 0), - new ColumnDescriptor("column_name", Type.TEXT, 0), - new ColumnDescriptor("data_type", Type.TEXT, 0), - new ColumnDescriptor("index_type", Type.TEXT, 0), - new ColumnDescriptor("is_unique", Type.BOOLEAN, 0), - new ColumnDescriptor("is_clustered", Type.BOOLEAN, 0), - new ColumnDescriptor("is_ascending", Type.BOOLEAN, 0) + new ColumnDescriptor("index_method", Type.TEXT, 0), + new ColumnDescriptor("index_path", Type.TEXT, 0), }; public IndexesTableDescriptor(InfoSchemaMetadataDictionary metadataDictionary) {
