Repository: tajo Updated Branches: refs/heads/master 2056aaa81 -> f868c0e23
TAJO-1735: Implement MetadataProvider and LinkedMetadataManager. Closes #673 Project: http://git-wip-us.apache.org/repos/asf/tajo/repo Commit: http://git-wip-us.apache.org/repos/asf/tajo/commit/f868c0e2 Tree: http://git-wip-us.apache.org/repos/asf/tajo/tree/f868c0e2 Diff: http://git-wip-us.apache.org/repos/asf/tajo/diff/f868c0e2 Branch: refs/heads/master Commit: f868c0e237f7523f429d0196e67652e980ca5907 Parents: 2056aaa Author: Hyunsik Choi <[email protected]> Authored: Thu Aug 6 16:10:20 2015 +0900 Committer: Hyunsik Choi <[email protected]> Committed: Thu Aug 6 16:10:20 2015 +0900 ---------------------------------------------------------------------- CHANGES | 2 + .../tajo/catalog/AbstractCatalogClient.java | 18 +- .../apache/tajo/catalog/MetadataProvider.java | 39 ++ .../InsufficientPrivilegeException.java | 29 ++ .../org/apache/tajo/catalog/CatalogServer.java | 379 ++++++++++++++----- .../tajo/catalog/LinkedMetadataManager.java | 241 ++++++++++++ .../InfoSchemaMetadataDictionary.java | 8 +- .../org/apache/tajo/catalog/TestCatalog.java | 12 +- .../tajo/catalog/TestLinkedMetadataManager.java | 271 +++++++++++++ .../java/org/apache/tajo/master/TajoMaster.java | 3 +- 10 files changed, 890 insertions(+), 112 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tajo/blob/f868c0e2/CHANGES ---------------------------------------------------------------------- diff --git a/CHANGES b/CHANGES index 3757f7f..b478ffb 100644 --- a/CHANGES +++ b/CHANGES @@ -459,6 +459,8 @@ Release 0.11.0 - unreleased SUB TASKS + TAJO-1735: Implement MetadataProvider and LinkedMetadataManager. (hyunsik) + TAJO-1723: INSERT INTO statement should allow nested fields as target columns. (hyunsik) http://git-wip-us.apache.org/repos/asf/tajo/blob/f868c0e2/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 e239b78..3dca859 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 @@ -95,8 +95,15 @@ public abstract class AbstractCatalogClient implements CatalogService, Closeable try { final BlockingInterface stub = getStub(); - return isSuccess(stub.existTablespace(null, ProtoUtil.convertString(tablespaceName))); + ReturnState state = stub.existTablespace(null, ProtoUtil.convertString(tablespaceName)); + + if (isThisError(state, ResultCode.UNDEFINED_TABLESPACE)) { + return false; + } + + ensureOk(state); + return true; } catch (ServiceException e) { throw new RuntimeException(e); } @@ -196,8 +203,15 @@ public abstract class AbstractCatalogClient implements CatalogService, Closeable try { final BlockingInterface stub = getStub(); - return isSuccess(stub.existDatabase(null, ProtoUtil.convertString(databaseName))); + ReturnState state = stub.existDatabase(null, ProtoUtil.convertString(databaseName)); + + if (isThisError(state, ResultCode.UNDEFINED_DATABASE)) { + return false; + } + + ensureOk(state); + return true; } catch (ServiceException e) { throw new RuntimeException(e); } http://git-wip-us.apache.org/repos/asf/tajo/blob/f868c0e2/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/MetadataProvider.java ---------------------------------------------------------------------- diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/MetadataProvider.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/MetadataProvider.java new file mode 100644 index 0000000..216d33c --- /dev/null +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/MetadataProvider.java @@ -0,0 +1,39 @@ +/* + * 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 org.apache.tajo.catalog.exception.UndefinedTablespaceException; + +import javax.annotation.Nullable; +import java.net.URI; +import java.util.Collection; + +public interface MetadataProvider { + String getTablespaceName(); + + URI getTablespaceUri(); + + String getDatabaseName(); + + Collection<String> getCatalogs(); + + Collection<String> getTables(@Nullable String catalog); + + TableDesc getTableDescriptor(String catalogName, String tableName) throws UndefinedTablespaceException; +} http://git-wip-us.apache.org/repos/asf/tajo/blob/f868c0e2/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/InsufficientPrivilegeException.java ---------------------------------------------------------------------- diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/InsufficientPrivilegeException.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/InsufficientPrivilegeException.java new file mode 100644 index 0000000..9bcc866 --- /dev/null +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/exception/InsufficientPrivilegeException.java @@ -0,0 +1,29 @@ +/* + * 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.exception; + +import org.apache.tajo.error.Errors.ResultCode; +import org.apache.tajo.exception.TajoException; + +public class InsufficientPrivilegeException extends TajoException { + + public InsufficientPrivilegeException(String towhat) { + super(ResultCode.INSUFFICIENT_PRIVILEGE, towhat); + } +} http://git-wip-us.apache.org/repos/asf/tajo/blob/f868c0e2/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 e2dcfcd..a7e8348 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 @@ -18,8 +18,11 @@ package org.apache.tajo.catalog; +import com.google.common.base.Function; import com.google.common.base.Objects; +import com.google.common.base.Optional; import com.google.common.base.Preconditions; +import com.google.common.collect.Collections2; import com.google.common.collect.Lists; import com.google.protobuf.RpcController; import com.google.protobuf.ServiceException; @@ -33,6 +36,7 @@ import org.apache.tajo.catalog.CatalogProtocol.*; import org.apache.tajo.catalog.dictionary.InfoSchemaMetadataDictionary; import org.apache.tajo.catalog.exception.CatalogException; import org.apache.tajo.catalog.exception.DuplicateDatabaseException; +import org.apache.tajo.catalog.exception.UndefinedTableException; import org.apache.tajo.catalog.exception.UndefinedTablespaceException; import org.apache.tajo.catalog.proto.CatalogProtos.*; import org.apache.tajo.catalog.store.CatalogStore; @@ -50,6 +54,7 @@ import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.ReturnState; import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.StringListResponse; import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.StringProto; import org.apache.tajo.util.NetUtils; +import org.apache.tajo.util.Pair; import org.apache.tajo.util.TUtil; import java.io.IOException; @@ -84,6 +89,8 @@ public class CatalogServer extends AbstractService { private CatalogStore store; private Map<String, List<FunctionDescProto>> functions = new ConcurrentHashMap<String, List<FunctionDescProto>>(); + + private final LinkedMetadataManager linkedMetadataManager; private final InfoSchemaMetadataDictionary metaDictionary = new InfoSchemaMetadataDictionary(); // RPC variables @@ -97,19 +104,17 @@ public class CatalogServer extends AbstractService { public CatalogServer() throws IOException { super(CatalogServer.class.getName()); this.handler = new CatalogProtocolHandler(); + this.linkedMetadataManager = new LinkedMetadataManager(Collections.EMPTY_LIST); this.builtingFuncs = new ArrayList<FunctionDesc>(); } - public CatalogServer(Collection<FunctionDesc> sqlFuncs) throws IOException { - this(); + public CatalogServer(Set<MetadataProvider> metadataProviders, Collection<FunctionDesc> sqlFuncs) throws IOException { + super(CatalogServer.class.getName()); + this.handler = new CatalogProtocolHandler(); + this.linkedMetadataManager = new LinkedMetadataManager(metadataProviders); this.builtingFuncs = sqlFuncs; } - public void reloadBuiltinFunctions(List<FunctionDesc> builtingFuncs) throws ServiceException { - this.builtingFuncs = builtingFuncs; - initBuiltinFunctions(builtingFuncs); - } - @Override public void serviceInit(Configuration conf) throws Exception { @@ -146,20 +151,6 @@ public class CatalogServer extends AbstractService { return store.getClass().getCanonicalName(); } - public String getCatalogServerName() { - String catalogUri = null; - if(conf.get(CatalogConstants.DEPRECATED_CATALOG_URI) != null) { - LOG.warn("Configuration parameter " + CatalogConstants.DEPRECATED_CATALOG_URI + " " + - "is deprecated. Use " + CatalogConstants.CATALOG_URI + " instead."); - catalogUri = conf.get(CatalogConstants.DEPRECATED_CATALOG_URI); - } else { - catalogUri = conf.get(CatalogConstants.CATALOG_URI); - } - - return bindAddressStr + ", store=" + this.store.getClass().getSimpleName() + ", catalogUri=" - + catalogUri; - } - private void initBuiltinFunctions(Collection<FunctionDesc> functions) throws ServiceException { for (FunctionDesc desc : functions) { @@ -288,6 +279,7 @@ public class CatalogServer extends AbstractService { try { return StringListResponse.newBuilder() .setState(OK) + .addAllValues(linkedMetadataManager.getTablespaceNames()) .addAllValues(store.getAllDatabaseNames()) .build(); @@ -304,9 +296,25 @@ public class CatalogServer extends AbstractService { throws ServiceException { rlock.lock(); try { + + // retrieves tablespaces from catalog store + final List<TablespaceProto> tableSpaces = Lists.newArrayList(store.getTablespaces()); + + // retrieves tablespaces from linked meta data + tableSpaces.addAll(Collections2.transform(linkedMetadataManager.getTablespaces(), + new Function<Pair<String, URI>, TablespaceProto>() { + @Override + public TablespaceProto apply(Pair<String, URI> input) { + return TablespaceProto.newBuilder() + .setSpaceName(input.getFirst()) + .setUri(input.getSecond().toString()) + .build(); + } + })); + return GetTablespaceListResponse.newBuilder() .setState(OK) - .addAllTablespace(store.getTablespaces()) + .addAllTablespace(tableSpaces) .build(); } catch (Throwable t) { @@ -323,6 +331,19 @@ public class CatalogServer extends AbstractService { try { + // if there exists the tablespace in linked meta data + Optional<Pair<String, URI>> optional = linkedMetadataManager.getTablespace(request.getValue()); + + if (optional.isPresent()) { + Pair<String, URI> spaceInfo = optional.get(); + return GetTablespaceResponse.newBuilder() + .setState(OK) + .setTablespace(TablespaceProto.newBuilder() + .setSpaceName(spaceInfo.getFirst()) + .setUri(spaceInfo.getSecond().toString()) + ).build(); + } + return GetTablespaceResponse.newBuilder() .setState(OK) .setTablespace(store.getTablespace(request.getValue())) @@ -344,8 +365,13 @@ public class CatalogServer extends AbstractService { public ReturnState alterTablespace(RpcController controller, AlterTablespaceProto request) { wlock.lock(); try { + + if (linkedMetadataManager.getTablespace(request.getSpaceName()).isPresent()) { + return errInsufficientPrivilege("alter tablespace '"+request.getSpaceName()+"'"); + } + if (!store.existTablespace(request.getSpaceName())) { - throw new UndefinedTablespaceException(request.getSpaceName()); + return errUndefinedTablespace(request.getSpaceName()); } if (request.getCommandList().size() > 0) { @@ -380,6 +406,10 @@ public class CatalogServer extends AbstractService { String databaseName = request.getDatabaseName(); String tablespaceName = request.getTablespaceName(); + if (linkedMetadataManager.existsDatabase(request.getDatabaseName())) { + return errDuplicateDatabase(request.getDatabaseName()); + } + // check virtual database manually because catalog actually does not contain them. if (metaDictionary.isSystemDatabase(databaseName)) { return errDuplicateDatabase(databaseName); @@ -431,7 +461,11 @@ public class CatalogServer extends AbstractService { @Override public ReturnState alterTable(RpcController controller, AlterTableDescProto proto) { String [] split = CatalogUtil.splitTableName(proto.getTableName()); - + + if (linkedMetadataManager.existsDatabase(split[0])) { + return errInsufficientPrivilege("alter a table in database '" + split[0] + "'"); + } + if (metaDictionary.isSystemDatabase(split[0])) { return errInsufficientPrivilege("alter a table in database '" + split[0] + "'"); } @@ -458,7 +492,11 @@ public class CatalogServer extends AbstractService { @Override public ReturnState dropDatabase(RpcController controller, StringProto request) { String databaseName = request.getValue(); - + + if (linkedMetadataManager.existsDatabase(databaseName)) { + return errInsufficientPrivilege("alter a table in database '" + databaseName + "'"); + } + if (metaDictionary.isSystemDatabase(databaseName)) { return errInsufficientPrivilege("drop a table in database '" + databaseName + "'"); } @@ -485,6 +523,10 @@ public class CatalogServer extends AbstractService { public ReturnState existDatabase(RpcController controller, StringProto request) { String dbName = request.getValue(); + if (linkedMetadataManager.existsDatabase(dbName)) { + return OK; + } + if (metaDictionary.isSystemDatabase(dbName)) { return OK; } @@ -511,8 +553,9 @@ public class CatalogServer extends AbstractService { try { return StringListResponse.newBuilder() .setState(OK) - .addAllValues(store.getAllDatabaseNames()) + .addAllValues(linkedMetadataManager.getDatabases()) .addValues(metaDictionary.getSystemDatabaseName()) + .addAllValues(store.getAllDatabaseNames()) .build(); } catch (Throwable t) { @@ -547,41 +590,57 @@ public class CatalogServer extends AbstractService { @Override public TableResponse getTableDesc(RpcController controller, - TableIdentifierProto request) { + TableIdentifierProto request) throws ServiceException { String dbName = request.getDatabaseName(); String tbName = request.getTableName(); - rlock.lock(); try { + if (linkedMetadataManager.existsDatabase(dbName)) { + return TableResponse.newBuilder() + .setState(OK) + .setTable(linkedMetadataManager.getTable(dbName, "", tbName).getProto()) + .build(); + } + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return TableResponse.newBuilder().setState(returnError(t)).build(); + } - if (metaDictionary.isSystemDatabase(dbName)) { - + if (metaDictionary.isSystemDatabase(dbName)) { + try { return TableResponse.newBuilder() .setState(OK) .setTable(metaDictionary.getTableDesc(tbName)) .build(); + } catch (UndefinedTableException e) { + return TableResponse.newBuilder() + .setState(errUndefinedTable(tbName)) + .build(); + } + } - } else { - boolean contain; - contain = store.existDatabase(dbName); + rlock.lock(); + try { + boolean contain; + contain = store.existDatabase(dbName); + + if (contain) { + contain = store.existTable(dbName, tbName); if (contain) { - contain = store.existTable(dbName, tbName); - if (contain) { - return TableResponse.newBuilder() - .setState(OK) - .setTable(store.getTable(dbName, tbName)) - .build(); - } else { - return TableResponse.newBuilder() - .setState(errUndefinedTable(tbName)) - .build(); - } + return TableResponse.newBuilder() + .setState(OK) + .setTable(store.getTable(dbName, tbName)) + .build(); } else { return TableResponse.newBuilder() - .setState(errUndefinedDatabase(dbName)) + .setState(errUndefinedTable(tbName)) .build(); } + } else { + return TableResponse.newBuilder() + .setState(errUndefinedDatabase(dbName)) + .build(); } } catch (Throwable t) { @@ -601,28 +660,35 @@ public class CatalogServer extends AbstractService { String dbName = request.getValue(); - if (metaDictionary.isSystemDatabase(dbName)) { + try { + if (linkedMetadataManager.existsDatabase(dbName)) { + return returnStringList(linkedMetadataManager.getTableNames(dbName, null, null)); + } + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return returnFailedStringList(t); + } + if (metaDictionary.isSystemDatabase(dbName)) { return returnStringList(metaDictionary.getAllSystemTables()); + } - } else { - rlock.lock(); - try { - if (store.existDatabase(dbName)) { - return returnStringList(store.getAllTableNames(dbName)); - } else { - return StringListResponse.newBuilder() - .setState(errUndefinedDatabase(dbName)) - .build(); - } + rlock.lock(); + try { + if (store.existDatabase(dbName)) { + return returnStringList(store.getAllTableNames(dbName)); + } else { + return StringListResponse.newBuilder() + .setState(errUndefinedDatabase(dbName)) + .build(); + } - } catch (Throwable t) { - printStackTraceIfError(LOG, t); - return returnFailedStringList(t); + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return returnFailedStringList(t); - } finally { - rlock.unlock(); - } + } finally { + rlock.unlock(); } } @@ -646,6 +712,10 @@ public class CatalogServer extends AbstractService { String dbName = splitted[0]; String tbName = splitted[1]; + if (linkedMetadataManager.existsDatabase(dbName)) { + return errInsufficientPrivilege("drop a table in database '" + dbName + "'"); + } + if (metaDictionary.isSystemDatabase(dbName)) { return errInsufficientPrivilege("create a table in database '" + dbName + "'"); } @@ -683,7 +753,11 @@ public class CatalogServer extends AbstractService { String dbName = request.getDatabaseName(); String tbName = request.getTableName(); - + + if (linkedMetadataManager.existsDatabase(dbName)) { + return errInsufficientPrivilege("drop a table in database '" + dbName + "'"); + } + if (metaDictionary.isSystemDatabase(dbName)) { return errInsufficientPrivilege("drop a table in database '" + dbName + "'"); } @@ -720,15 +794,19 @@ public class CatalogServer extends AbstractService { String dbName = request.getDatabaseName(); String tbName = request.getTableName(); - rlock.lock(); - try { + if (linkedMetadataManager.existsDatabase(dbName)) { + return linkedMetadataManager.existsTable(dbName, "", tbName) ? OK : errUndefinedTable(tbName); + } - if (metaDictionary.isSystemDatabase(dbName)) { - return metaDictionary.existTable(tbName) ? OK : errUndefinedTable(tbName); + if (metaDictionary.isSystemDatabase(dbName)) { + return metaDictionary.existTable(tbName) ? OK : errUndefinedTable(tbName); - } else { + } else { + rlock.lock(); + try { boolean contain = store.existDatabase(dbName); + if (contain) { if (store.existTable(dbName, tbName)) { return OK; @@ -738,14 +816,14 @@ public class CatalogServer extends AbstractService { } else { return errUndefinedDatabase(dbName); } - } - } catch (Throwable t) { - printStackTraceIfError(LOG, t); - return returnError(t); + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return returnError(t); - } finally { - rlock.unlock(); + } finally { + rlock.unlock(); + } } } @@ -836,43 +914,55 @@ public class CatalogServer extends AbstractService { public GetPartitionMethodResponse getPartitionMethodByTableName(RpcController controller, TableIdentifierProto request) throws ServiceException { - String databaseName = request.getDatabaseName(); - String tableName = request.getTableName(); + String dbName = request.getDatabaseName(); + String tbName = request.getTableName(); - if (metaDictionary.isSystemDatabase(databaseName)) { - throw new ServiceException(databaseName + " is a system databsae. It does not contain any partitioned tables."); + try { + // linked meta data do not support partition. + // So, the request that wants to get partitions in this db will be failed. + if (linkedMetadataManager.existsDatabase(dbName)) { + return GetPartitionMethodResponse.newBuilder().setState(errUndefinedPartitionMethod(tbName)) + .build(); + } + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return GetPartitionMethodResponse.newBuilder().setState(returnError(t)).build(); + } + + if (metaDictionary.isSystemDatabase(dbName)) { + throw new ServiceException(dbName + " is a system databsae. It does not contain any partitioned tables."); } rlock.lock(); try { boolean contain; - contain = store.existDatabase(databaseName); + contain = store.existDatabase(dbName); if (contain) { - contain = store.existTable(databaseName, tableName); + contain = store.existTable(dbName, tbName); if (contain) { - if (store.existPartitionMethod(databaseName, tableName)) { + if (store.existPartitionMethod(dbName, tbName)) { return GetPartitionMethodResponse.newBuilder() .setState(OK) - .setPartition(store.getPartitionMethod(databaseName, tableName)) + .setPartition(store.getPartitionMethod(dbName, tbName)) .build(); } else { return GetPartitionMethodResponse.newBuilder() - .setState(errUndefinedPartitionMethod(tableName)) + .setState(errUndefinedPartitionMethod(tbName)) .build(); } } else { return GetPartitionMethodResponse.newBuilder() - .setState(errUndefinedTable(tableName)) + .setState(errUndefinedTable(tbName)) .build(); } } else { return GetPartitionMethodResponse.newBuilder() - .setState(errUndefinedDatabase(tableName)) + .setState(errUndefinedDatabase(tbName)) .build(); } @@ -889,10 +979,21 @@ public class CatalogServer extends AbstractService { @Override public ReturnState existPartitionMethod(RpcController controller, TableIdentifierProto request) { - String databaseName = request.getDatabaseName(); + String dbName = request.getDatabaseName(); String tableName = request.getTableName(); - - if (metaDictionary.isSystemDatabase(databaseName)) { + + try { + // linked meta data do not support partition. + // So, the request that wants to get partitions in this db will be failed. + if (linkedMetadataManager.existsDatabase(dbName)) { + return errUndefinedPartitionMethod(tableName); + } + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return returnError(t); + } + + if (metaDictionary.isSystemDatabase(dbName)) { ReturnStateUtil.errFeatureNotSupported("partition feature in virtual tables"); } @@ -900,12 +1001,12 @@ public class CatalogServer extends AbstractService { try { boolean contain; - contain = store.existDatabase(databaseName); + contain = store.existDatabase(dbName); if (contain) { - contain = store.existTable(databaseName, tableName); + contain = store.existTable(dbName, tableName); if (contain) { - if (store.existPartitionMethod(databaseName, tableName)) { + if (store.existPartitionMethod(dbName, tableName)) { return OK; } else { return errUndefinedPartitionMethod(tableName); @@ -914,7 +1015,7 @@ public class CatalogServer extends AbstractService { return errUndefinedTable(tableName); } } else { - return errUndefinedDatabase(databaseName); + return errUndefinedDatabase(dbName); } } catch (Throwable t) { printStackTraceIfError(LOG, t); @@ -937,8 +1038,19 @@ public class CatalogServer extends AbstractService { String tbName = request.getTableName(); String partitionName = request.getPartitionName(); + try { + // linked meta data do not support partition. + // So, the request that wants to get partitions in this db will be failed. + if (linkedMetadataManager.existsDatabase(dbName)) { + return GetPartitionDescResponse.newBuilder().setState(errUndefinedPartitionMethod(tbName)).build(); + } + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return GetPartitionDescResponse.newBuilder().setState(returnError(t)).build(); + } + if (metaDictionary.isSystemDatabase(dbName)) { - throw new ServiceException(dbName + " is a system databsae. It does not contain any partitioned tables."); + return GetPartitionDescResponse.newBuilder().setState(errUndefinedPartitionMethod(tbName)).build(); } rlock.lock(); @@ -995,8 +1107,21 @@ public class CatalogServer extends AbstractService { String dbName = request.getDatabaseName(); String tbName = request.getTableName(); + try { + // linked meta data do not support partition. + // So, the request that wants to get partitions in this db will be failed. + if (linkedMetadataManager.existsDatabase(dbName)) { + return GetPartitionsResponse.newBuilder().setState(errUndefinedPartitionMethod(tbName)).build(); + } + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return GetPartitionsResponse.newBuilder() + .setState(returnError(t)) + .build(); + } + if (metaDictionary.isSystemDatabase(dbName)) { - throw new ServiceException(dbName + " is a system databsae. It does not contain any partitioned tables."); + return GetPartitionsResponse.newBuilder().setState(errUndefinedPartitionMethod(tbName)).build(); } rlock.lock(); @@ -1107,7 +1232,17 @@ public class CatalogServer extends AbstractService { @Override public ReturnState createIndex(RpcController controller, IndexDescProto indexDesc) { String dbName = indexDesc.getTableIdentifier().getDatabaseName(); - + + try { + // linked meta data do not support index. The request will be failed. + if (linkedMetadataManager.existsDatabase(dbName)) { + return errInsufficientPrivilege("to create index in database '" + dbName + "'"); + } + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return returnError(t); + } + rlock.lock(); try { if (store.existIndexByName( @@ -1134,6 +1269,16 @@ public class CatalogServer extends AbstractService { String dbName = request.getDatabaseName(); String indexName = request.getIndexName(); + try { + // linked meta data do not support index. The request will be failed. + if (linkedMetadataManager.existsDatabase(dbName)) { + return errUndefinedIndexName(indexName); + } + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return returnError(t); + } + rlock.lock(); try { @@ -1161,6 +1306,16 @@ public class CatalogServer extends AbstractService { String tableName = identifier.getTableName(); List<String> columnNames = request.getColumnNamesList(); + try { + // linked meta data do not support index. The request will be failed. + if (linkedMetadataManager.existsDatabase(databaseName)) { + return errUndefinedIndex(tableName); + } + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return returnError(t); + } + rlock.lock(); try { @@ -1189,6 +1344,16 @@ public class CatalogServer extends AbstractService { String databaseName = request.getDatabaseName(); String tableName = request.getTableName(); + try { + // linked meta data do not support index. The request will be failed. + if (linkedMetadataManager.existsDatabase(databaseName)) { + return errUndefinedIndex(tableName); + } + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return returnError(t); + } + rlock.lock(); try { @@ -1255,6 +1420,7 @@ public class CatalogServer extends AbstractService { rlock.lock(); try { + if (!store.existIndexByColumns(databaseName, tableName, columnNames)) { return IndexResponse.newBuilder() .setState(errUndefinedIndex(tableName, columnNamesList)) @@ -1278,11 +1444,23 @@ public class CatalogServer extends AbstractService { @Override public IndexListResponse getAllIndexesByTable(RpcController controller, TableIdentifierProto request) throws ServiceException { - String databaseName = request.getDatabaseName(); - String tableName = request.getTableName(); + final String databaseName = request.getDatabaseName(); + final String tableName = request.getTableName(); + + try { + // linked meta data do not support index. + // So, the request that wants to check the index in this db will get empty list. + if (linkedMetadataManager.existsDatabase(databaseName)) { + return IndexListResponse.newBuilder().setState(OK).build(); + } + } catch (Throwable t) { + printStackTraceIfError(LOG, t); + return IndexListResponse.newBuilder().setState(returnError(t)).build(); + } rlock.lock(); try { + if (!store.existIndexesByTable(databaseName, tableName)) { return IndexListResponse.newBuilder() .setState(errUndefinedIndex(tableName)) @@ -1631,11 +1809,4 @@ public class CatalogServer extends AbstractService { } } - - public static void main(String[] args) throws Exception { - TajoConf conf = new TajoConf(); - CatalogServer catalog = new CatalogServer(new ArrayList<FunctionDesc>()); - catalog.init(conf); - catalog.start(); - } } http://git-wip-us.apache.org/repos/asf/tajo/blob/f868c0e2/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/LinkedMetadataManager.java ---------------------------------------------------------------------- diff --git a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/LinkedMetadataManager.java b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/LinkedMetadataManager.java new file mode 100644 index 0000000..080c984 --- /dev/null +++ b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/LinkedMetadataManager.java @@ -0,0 +1,241 @@ +/* + * 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.Optional; +import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; +import org.apache.tajo.catalog.exception.InsufficientPrivilegeException; +import org.apache.tajo.catalog.exception.UndefinedDatabaseException; +import org.apache.tajo.catalog.exception.UndefinedTablespaceException; +import org.apache.tajo.util.Pair; + +import javax.annotation.Nullable; +import java.net.URI; +import java.util.Collection; +import java.util.Map; +import java.util.regex.Pattern; + +import static com.google.common.collect.Collections2.filter; + +/** + * Linked Meta Data Manager which manages all meta data providers and access methods for them. + */ +public class LinkedMetadataManager { + private ImmutableMap<String, MetadataProvider> providerMap; + + /** + * Initialize Linked Metadata + * + * @param providers A collection of Metadata providers. + */ + public LinkedMetadataManager(Collection<MetadataProvider> providers) { + Map<String, MetadataProvider> builder = Maps.newHashMap(); + + for (MetadataProvider p : providers) { + builder.put(p.getDatabaseName(), p); + } + + this.providerMap = ImmutableMap.copyOf(builder); + } + + /** + * Get all tablespace names + * + * @return A collection of tablespace names + */ + public Collection<String> getTablespaceNames() { + ImmutableList.Builder<String> builder = ImmutableList.builder(); + for (MetadataProvider p : providerMap.values()) { + builder.add(p.getTablespaceName()); + } + return builder.build(); + } + + /** + * Get a tablespace by name. + * + * @param spaceName Tablespace name + * @return A pair where the first value is tablespace name and the second value is an URI. + */ + public Optional<Pair<String, URI>> getTablespace(final String spaceName) { + Collection<MetadataProvider> filtered = filter(providerMap.values(), + new Predicate<MetadataProvider>() { + @Override + public boolean apply(@Nullable MetadataProvider input) { + return input.getTablespaceName().equals(spaceName); + } + }); + + if (filtered.isEmpty()) { + return Optional.absent(); + } else { + MetadataProvider found = filtered.iterator().next(); + return Optional.of(new Pair<String, URI>(found.getTablespaceName(), found.getTablespaceUri())); + } + } + + /** + * Return all tablespaces. + * + * @return A list of pairs, each pair represents a tablespace, where the first value is tablespace name. + * the second value is an URI. + */ + public Collection<Pair<String, URI>> getTablespaces() { + ImmutableList.Builder<Pair<String, URI>> builder = ImmutableList.builder(); + for (MetadataProvider p : providerMap.values()) { + builder.add(new Pair<String, URI>(p.getDatabaseName(), p.getTablespaceUri())); + } + return builder.build(); + } + + /** + * Return all database names + * + * @return A collection of database names + */ + public Collection<String> getDatabases() { + return providerMap.keySet(); + } + + /** + * check if the database exists. + * + * @param dbName Database name + * @return True if the database exists. Otherwise, False. + */ + public boolean existsDatabase(String dbName) { + return providerMap.containsKey(dbName); + } + + /** + * check if the database exists. Otherwise, it throws an exception + * + * @param dbName Database name + * @throws UndefinedDatabaseException + */ + private void ensureIfDBExists(String dbName) throws UndefinedDatabaseException { + if (!providerMap.containsKey(dbName)) { + throw new UndefinedDatabaseException(dbName); + } + } + + /** + * Get schema names + * + * @param dbName Database name + * @return A list of schema names + * @throws UndefinedDatabaseException + */ + public Collection<String> getSchemas(@Nullable String dbName) throws UndefinedDatabaseException { + ensureIfDBExists(dbName); + + return providerMap.get(dbName).getCatalogs(); + } + + /** + * Get all table names matched to a given pattern + * + * @param dbName Database name + * @param schemaPattern a schema name pattern; must match the schema name + * as it is stored in the database; "" retrieves tables without a schema; + * <code>null</code> means that the schema name should not be used to narrow the search + * @param tablePattern a table name pattern: must match the table name as it is stored in the meta data provider; + * "" retrieves tables without a schema; <code>null</code> allows all schema names. + * + * @return + */ + public Collection<String> getTableNames(String dbName, + @Nullable final String schemaPattern, + final String tablePattern) throws UndefinedDatabaseException { + ensureIfDBExists(dbName); + + if (tablePattern == null) { // all tables in this database + return providerMap.get(dbName).getTables("null"); + + } else { + final Pattern pattern = Pattern.compile(tablePattern); + return filter(providerMap.get(dbName).getTables(schemaPattern), new Predicate<String>() { + @Override + public boolean apply(@Nullable String input) { + return pattern.matcher(tablePattern).matches(); + } + }); + } + } + + /** + * Create a table + * + * @param desc table description + * @throws InsufficientPrivilegeException + */ + public void createTable(TableDesc desc) throws InsufficientPrivilegeException { + // TODO - currently, meta data provider is read only. + throw new InsufficientPrivilegeException("create a table in external metadata store"); + } + + /** + * Drop table + * + * @param databaseName Database name + * @param schemaName a schema name; "" drops the table without a schema. + * @param tableName Table name + * @throws InsufficientPrivilegeException + */ + public void dropTable(String databaseName, String schemaName, String tableName) + throws InsufficientPrivilegeException { + // TODO - currently, meta data provider is read only. + throw new InsufficientPrivilegeException("drop any table in external metadata store"); + } + + /** + * Check if the table exists + * + * @param dbName Database name + * @param schemaName a schema name; "" checks the table without a schema. + * @param tableName a table name + * @return True if the table exists. Otherwise, False + */ + public boolean existsTable(String dbName, String schemaName, String tableName) { + if (providerMap.containsKey(dbName)) { + return providerMap.get(dbName).getTables(schemaName).contains(tableName); + } + + return false; + } + + /** + * Get Table description + * + * @param dbName Database name + * @param schemaName a schema name; "" checks the table without a schema. + * @param tbName Table name + * @return Table description + */ + public TableDesc getTable(String dbName, String schemaName, String tbName) + throws UndefinedDatabaseException, UndefinedTablespaceException { + + ensureIfDBExists(dbName); + + return providerMap.get(dbName).getTableDescriptor(schemaName, tbName); + } +} http://git-wip-us.apache.org/repos/asf/tajo/blob/f868c0e2/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/dictionary/InfoSchemaMetadataDictionary.java ---------------------------------------------------------------------- diff --git a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/dictionary/InfoSchemaMetadataDictionary.java b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/dictionary/InfoSchemaMetadataDictionary.java index b59d61c..2fde0e2 100644 --- a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/dictionary/InfoSchemaMetadataDictionary.java +++ b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/dictionary/InfoSchemaMetadataDictionary.java @@ -125,8 +125,12 @@ public class InfoSchemaMetadataDictionary { return tableDescriptor.getTableDescription(); } - public boolean existTable(String tableName) throws UndefinedTableException { - return getTableDescriptor(tableName) != null; + public boolean existTable(String tableName) { + try { + return getTableDescriptor(tableName) != null; + } catch (UndefinedTableException e) { + return false; + } } protected String getTablePath() { http://git-wip-us.apache.org/repos/asf/tajo/blob/f868c0e2/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/TestCatalog.java ---------------------------------------------------------------------- diff --git a/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/TestCatalog.java b/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/TestCatalog.java index caa85e8..e2a096a 100644 --- a/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/TestCatalog.java +++ b/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/TestCatalog.java @@ -64,8 +64,7 @@ public class TestCatalog { static CatalogServer server; static CatalogService catalog; - @BeforeClass - public static void setUp() throws Exception { + public static TajoConf newTajoConfForCatalogTest() throws IOException { final String HIVE_CATALOG_CLASS_NAME = "org.apache.tajo.catalog.store.HiveCatalogStore"; String driverClass = System.getProperty(CatalogConstants.STORE_CLASS); @@ -98,10 +97,17 @@ public class TestCatalog { } } + return conf; + } + + @BeforeClass + public static void setUp() throws Exception { + + Path defaultTableSpace = CommonTestingUtil.getTestDir(); server = new CatalogServer(); - server.init(conf); + server.init(newTajoConfForCatalogTest()); server.start(); catalog = new LocalCatalogWrapper(server); if (!catalog.existTablespace(TajoConstants.DEFAULT_TABLESPACE_NAME)) { http://git-wip-us.apache.org/repos/asf/tajo/blob/f868c0e2/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/TestLinkedMetadataManager.java ---------------------------------------------------------------------- diff --git a/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/TestLinkedMetadataManager.java b/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/TestLinkedMetadataManager.java new file mode 100644 index 0000000..4ddf7ab --- /dev/null +++ b/tajo-catalog/tajo-catalog-server/src/test/java/org/apache/tajo/catalog/TestLinkedMetadataManager.java @@ -0,0 +1,271 @@ +/* + * 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.Function; +import com.google.common.collect.Collections2; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import org.apache.hadoop.fs.Path; +import org.apache.tajo.TajoConstants; +import org.apache.tajo.catalog.exception.UndefinedTablespaceException; +import org.apache.tajo.catalog.proto.CatalogProtos; +import org.apache.tajo.common.TajoDataTypes.Type; +import org.apache.tajo.conf.TajoConf; +import org.apache.tajo.error.Errors; +import org.apache.tajo.exception.TajoInternalError; +import org.apache.tajo.util.CommonTestingUtil; +import org.apache.tajo.util.KeyValueSet; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import javax.annotation.Nullable; +import java.io.IOException; +import java.net.URI; +import java.util.Collection; +import java.util.Collections; + +import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME; +import static org.junit.Assert.*; + +public class TestLinkedMetadataManager { + + static TableDesc TABLE1 = new TableDesc( + "table1", + new Schema(new Column[]{new Column("c1", Type.INT8)}), + "TEXT", new KeyValueSet(), URI.create("http://space1/x/table1") + ); + + static TableDesc TABLE2 = new TableDesc( + "table2", + new Schema(new Column[]{new Column("c1", Type.INT8)}), + "TEXT", new KeyValueSet(), URI.create("http://space1/x/table2") + ); + + static TableDesc TABLE3 = new TableDesc( + "table3", + new Schema(new Column[]{new Column("c1", Type.INT8)}), + "TEXT", new KeyValueSet(), URI.create("http://space1/x/table3") + ); + + static TableDesc TABLE4 = new TableDesc( + "table4", + new Schema(new Column[]{new Column("c1", Type.INT8)}), + "TEXT", new KeyValueSet(), URI.create("http://space1/x/table4") + ); + + static class MockupMetadataProvider1 implements MetadataProvider { + + @Override + public String getTablespaceName() { + return "space1"; + } + + @Override + public URI getTablespaceUri() { + return URI.create("http://space1/x"); + } + + @Override + public String getDatabaseName() { + return "space1"; + } + + @Override + public Collection<String> getCatalogs() { + return Lists.newArrayList("cat1", "cat2"); + } + + @Override + public Collection<String> getTables(@Nullable String catalog) { + return Lists.newArrayList("table1", "table2"); + } + + @Override + public TableDesc getTableDescriptor(String catalogName, String tableName) throws UndefinedTablespaceException { + if (tableName.equals("table1")) { + return TABLE1; + } else if (tableName.equals("table2")) { + return TABLE2; + } + + throw new UndefinedTablespaceException(tableName); + } + } + + static class MockupMetadataProvider2 implements MetadataProvider { + + @Override + public String getTablespaceName() { + return "space2"; + } + + @Override + public URI getTablespaceUri() { + return URI.create("http://space2/y"); + } + + @Override + public String getDatabaseName() { + return "space2"; + } + + @Override + public Collection<String> getCatalogs() { + return Lists.newArrayList("cat3", "cat4"); + } + + @Override + public Collection<String> getTables(@Nullable String catalog) { + return Lists.newArrayList("table3", "table4"); + } + + @Override + public TableDesc getTableDescriptor(String catalogName, String tableName) throws UndefinedTablespaceException { + if (tableName.equals("table3")) { + return TABLE3; + } else if (tableName.equals("table4")) { + return TABLE4; + } + + throw new UndefinedTablespaceException(tableName); + } + } + + static CatalogServer server; + static CatalogService catalog; + + @BeforeClass + public static void setUp() throws IOException { + TajoConf conf = new TajoConf(); + conf.setVar(TajoConf.ConfVars.CATALOG_ADDRESS, "127.0.0.1:0"); + + server = new CatalogServer( + Sets.newHashSet(new MockupMetadataProvider1(), new MockupMetadataProvider2()), Collections.EMPTY_LIST); + server.init(TestCatalog.newTajoConfForCatalogTest()); + server.start(); + catalog = new LocalCatalogWrapper(server); + + Path defaultTableSpace = CommonTestingUtil.getTestDir(); + + if (!catalog.existTablespace(TajoConstants.DEFAULT_TABLESPACE_NAME)) { + catalog.createTablespace(TajoConstants.DEFAULT_TABLESPACE_NAME, defaultTableSpace.toUri().toString()); + } + if (!catalog.existDatabase(DEFAULT_DATABASE_NAME)) { + catalog.createDatabase(DEFAULT_DATABASE_NAME, TajoConstants.DEFAULT_TABLESPACE_NAME); + } + } + + @AfterClass + public static void tearDown() throws IOException { + server.stop(); + } + + @Test + public void testGetTablespaceNames() throws Exception { + assertEquals(Sets.newHashSet("space1", "space2", "default"), Sets.newHashSet(catalog.getAllTablespaceNames())); + } + + @Test + public void testGetTablespace() throws Exception { + CatalogProtos.TablespaceProto space1 = catalog.getTablespace("space1"); + assertEquals("space1", space1.getSpaceName()); + assertEquals("http://space1/x", space1.getUri()); + + CatalogProtos.TablespaceProto space2 = catalog.getTablespace("space2"); + assertEquals("space2", space2.getSpaceName()); + assertEquals("http://space2/y", space2.getUri()); + } + + @Test + public void testGetTablespaces() throws Exception { + Collection<String> names = Collections2.transform(catalog.getAllTablespaces(), + new Function<CatalogProtos.TablespaceProto, String>() { + @Override + public String apply(@Nullable CatalogProtos.TablespaceProto input) { + return input.getSpaceName(); + } + }); + + assertEquals(Sets.newHashSet("space1", "space2", "default"), Sets.newHashSet(names)); + } + + @Test + public void testGetDatabases() throws Exception { + assertEquals(Sets.newHashSet("space1", "space2", "default", "information_schema"), + Sets.newHashSet(catalog.getAllDatabaseNames())); + } + + @Test + public void testExistsDatabase() throws Exception { + assertTrue(catalog.existDatabase("space1")); + assertTrue(catalog.existDatabase("space2")); + assertTrue(catalog.existDatabase("default")); + + assertFalse(catalog.existDatabase("unknown")); + } + + @Test + public void testGetTableNames() throws Exception { + assertEquals(Sets.newHashSet("table1", "table2"), Sets.newHashSet(catalog.getAllTableNames("space1"))); + } + + @Test + public void testCreateTable() throws Exception { + TableDesc tb = new TableDesc( + "space1.errortable", + new Schema(), + new TableMeta("x", new KeyValueSet()), + URI.create("file:///")); + + try { + catalog.createTable(tb); + fail(); + } catch (TajoInternalError e) { + assertEquals(Errors.ResultCode.INTERNAL_ERROR, e.getErrorCode()); + } + } + + @Test + public void testDropTable() throws Exception { + try { + catalog.dropTable("space1.table1"); + fail(); + } catch (TajoInternalError e) { + assertEquals(Errors.ResultCode.INTERNAL_ERROR, e.getErrorCode()); + } + } + + @Test + public void testExistsTable() throws Exception { + assertTrue(catalog.existsTable("space1", "table1")); + assertTrue(catalog.existsTable("space1", "table2")); + assertTrue(catalog.existsTable("space2", "table3")); + assertTrue(catalog.existsTable("space2", "table4")); + } + + @Test + public void testGetTable() throws Exception { + assertEquals(TABLE1, catalog.getTableDesc("space1", "table1")); + assertEquals(TABLE2, catalog.getTableDesc("space1", "table2")); + assertEquals(TABLE3, catalog.getTableDesc("space2", "table3")); + assertEquals(TABLE4, catalog.getTableDesc("space2", "table4")); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tajo/blob/f868c0e2/tajo-core/src/main/java/org/apache/tajo/master/TajoMaster.java ---------------------------------------------------------------------- diff --git a/tajo-core/src/main/java/org/apache/tajo/master/TajoMaster.java b/tajo-core/src/main/java/org/apache/tajo/master/TajoMaster.java index d16f7d1..27aabfc 100644 --- a/tajo-core/src/main/java/org/apache/tajo/master/TajoMaster.java +++ b/tajo-core/src/main/java/org/apache/tajo/master/TajoMaster.java @@ -72,6 +72,7 @@ import java.lang.management.ThreadInfo; import java.lang.management.ThreadMXBean; import java.net.InetSocketAddress; import java.util.Collection; +import java.util.Collections; import java.util.Map; import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME; @@ -179,7 +180,7 @@ public class TajoMaster extends CompositeService { checkAndInitializeSystemDirectories(); diagnoseTajoMaster(); - catalogServer = new CatalogServer(loadFunctions()); + catalogServer = new CatalogServer(Collections.EMPTY_SET, loadFunctions()); addIfService(catalogServer); catalog = new LocalCatalogWrapper(catalogServer, systemConf);
