Index: standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/cache/CachedStore.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/cache/CachedStore.java (revision c1e5fa3d80511ac625476b0a9c454783bd6c4ad1) +++ standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/cache/CachedStore.java (revision 9981ddd55e10ab4b60b867822d3c827abf5a6851) @@ -35,6 +35,8 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import com.google.common.collect.Lists; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.hadoop.conf.Configurable; import org.apache.hadoop.conf.Configuration; @@ -71,8 +73,10 @@ import org.apache.hadoop.hive.metastore.messaging.DeletePartitionColumnStatMessage; import org.apache.hadoop.hive.metastore.messaging.MessageBuilder; import org.apache.hadoop.hive.metastore.messaging.MessageDeserializer; -import org.apache.hadoop.hive.metastore.partition.spec.PartitionSpecProxy; +import org.apache.hadoop.hive.metastore.messaging.CreateFunctionMessage; +import org.apache.hadoop.hive.metastore.messaging.DropFunctionMessage; import org.apache.hadoop.hive.metastore.messaging.MessageFactory; +import org.apache.hadoop.hive.metastore.partition.spec.PartitionSpecProxy; import org.apache.hadoop.hive.metastore.txn.TxnUtils; import org.apache.hadoop.hive.metastore.utils.FileUtils; import org.apache.hadoop.hive.metastore.utils.JavaUtils; @@ -402,6 +406,14 @@ sharedCache.removePartitionColStatsFromCache(catalogName, dbName, tableName, msgPart.getPartValues(), msgPart.getColName()); break; + case MessageBuilder.CREATE_FUNCTION_EVENT: + CreateFunctionMessage msgCreateFunc = deserializer.getCreateFunctionMessage(message); + sharedCache.addFunctionToCache(catalogName, dbName, msgCreateFunc.getFunctionObj().getFunctionName(), + msgCreateFunc.getFunctionObj()); + break; + case MessageBuilder.DROP_FUNCTION_EVENT: + DropFunctionMessage msgDropFunc = deserializer.getDropFunctionMessage(message); + sharedCache.removeFunctionFromCache(catalogName, dbName, msgDropFunc.getFunctionName()); default: LOG.error("Event is not supported for cache invalidation : " + event.getEventType()); } @@ -567,6 +579,23 @@ continue; } } + // add function in Cache + try { + List functions = rawStore.getFunctions(db.getCatalogName(), db.getName(), "*"); + List funcList = new ArrayList<>(); + if (functions != null && functions.size() > 0) { + for (String function : functions) { + Function funNew = rawStore.getFunction(db.getCatalogName(), db.getName(), function); + funcList.add(funNew); + } + } + sharedCache.populateFunctionsInCache(funcList); + } catch (MetaException e) { + LOG.warn("Failed to cache functions for database " + + DatabaseName.getQualified(catName, dbName) + ", moving on"); + } + + LOG.debug("Processed database: {}. Cached {} / {} databases so far.", dbName, ++numberOfDatabasesCachedSoFar, databases.size()); } @@ -778,6 +807,7 @@ // Update aggregate partition column stats for a table in cache updateTableAggregatePartitionColStats(rawStore, catName, dbName, tblName); } + updateFunctions(rawStore, catName); } } sharedCache.incrementUpdateCount(); @@ -964,7 +994,32 @@ LOG.info("Updating CachedStore: unable to read aggregate column stats of table: " + tblName, e); } } + + // update all functions for catName + private void updateFunctions(RawStore rawStore, String catName) { + LOG.debug("CachedStore: updating cached function for catalog: {}", catName); + boolean committed = false; + rawStore.openTransaction(); + try { + List funcs = rawStore.getAllFunctions(catName); + if (funcs != null && funcs.size() > 0) { + for (Function func : funcs) { + // Update Function Infomation. + sharedCache.alterFunctionInCache(catName, func.getDbName(), func.getFunctionName(), func); - } + } + } + committed = rawStore.commitTransaction(); + LOG.debug("CachedStore: updated cached function for catalog: {}", catName); + } catch (MetaException e) { + LOG.info("Unable to refresh functions for catalog: " + catName, e); + } finally { + if (!committed) { + sharedCache.removeAllFunctionsFromCache(); + rawStore.rollbackTransaction(); + } + } + } + } @Override public Configuration getConf() { return rawStore.getConf(); @@ -2400,37 +2455,106 @@ } @Override public void createFunction(Function func) throws InvalidObjectException, MetaException { - // TODO fucntionCache rawStore.createFunction(func); + // in case of event based cache update, cache will be updated during commit. + if (canUseEvents) { + return; - } + } + String catName = normalizeIdentifier(func.getCatName()); + String dbName = normalizeIdentifier(func.getDbName()); + String funcName = normalizeIdentifier(func.getFunctionName()); + sharedCache.addFunctionToCache(catName, dbName, funcName, func); + } @Override public void alterFunction(String catName, String dbName, String funcName, Function newFunction) - throws InvalidObjectException, MetaException { + throws InvalidObjectException, MetaException { - // TODO fucntionCache rawStore.alterFunction(catName, dbName, funcName, newFunction); + // in case of event based cache update, cache will be updated during commit. + if (canUseEvents) { + return; - } + } + catName = normalizeIdentifier(catName); + dbName = normalizeIdentifier(dbName); + funcName = normalizeIdentifier(funcName); + String newFuncName = normalizeIdentifier(newFunction.getFunctionName()); + + Function oldFunction = sharedCache.getFunctionFromCache(catName, dbName, funcName); + if (oldFunction == null) { + return; + } + sharedCache.removeFunctionFromCache(catName, dbName, funcName); + sharedCache.alterFunctionInCache(catName, dbName, newFuncName, newFunction); + } + @Override public void dropFunction(String catName, String dbName, String funcName) - throws MetaException, NoSuchObjectException, InvalidObjectException, InvalidInputException { + throws MetaException, NoSuchObjectException, InvalidObjectException, InvalidInputException { - // TODO fucntionCache rawStore.dropFunction(catName, dbName, funcName); + // in case of event based cache update, cache will be updated during commit. + if (!canUseEvents) { + catName = normalizeIdentifier(catName); + dbName = normalizeIdentifier(dbName); + funcName = normalizeIdentifier(funcName); + sharedCache.removeFunctionFromCache(catName, dbName, funcName); - } + } + } @Override public Function getFunction(String catName, String dbName, String funcName) throws MetaException { - // TODO fucntionCache - return rawStore.getFunction(catName, dbName, funcName); + + catName = normalizeIdentifier(catName); + dbName = StringUtils.normalizeIdentifier(dbName); + funcName = StringUtils.normalizeIdentifier(funcName); + Function func = sharedCache.getFunctionFromCache(catName, dbName, funcName); + + if (func == null) { + Function funcRawStore = rawStore.getFunction(catName, dbName, funcName); + if (funcRawStore != null) { + sharedCache.addFunctionToCache(catName, dbName, funcName, funcRawStore); + func = funcRawStore; - } + } + } - @Override public List getAllFunctions(String catName) throws MetaException { - // TODO fucntionCache - return rawStore.getAllFunctions(catName); + return func; } - @Override public List getFunctions(String catName, String dbName, String pattern) throws MetaException { - // TODO fucntionCache - return rawStore.getFunctions(catName, dbName, pattern); + @Override + public List getAllFunctions(String catName) throws MetaException { + List funcList = null; + if (!isCachePrewarmed.get()) { + funcList = rawStore.getAllFunctions(catName); + } else { + List tmpFunctionList = sharedCache.getAllFunctionsFromCache(catName); + if (tmpFunctionList != null && tmpFunctionList.size() > 0) { + funcList = tmpFunctionList; + } else { + funcList = rawStore.getAllFunctions(catName); - } + } + } + if (CollectionUtils.isEmpty(funcList)) { + funcList = Lists.newArrayList(); + } + return funcList; + } + @Override + public List getFunctions(String catName, String dbName, String pattern) throws MetaException { + List funcs = null; + if (!isCachePrewarmed.get()) { + funcs = rawStore.getFunctions(catName, dbName, pattern); + } else { + List tmpFuncs = sharedCache.getFunctionsFromCacheByPattern(catName, dbName, pattern); + if (tmpFuncs != null && tmpFuncs.size() > 0) { + funcs = tmpFuncs; + } else { + funcs = rawStore.getFunctions(catName, dbName, pattern); + } + } + if (CollectionUtils.isEmpty(funcs)) { + funcs = Lists.newArrayList(); + } + return funcs; + } + @Override public NotificationEventResponse getNextNotification(NotificationEventRequest rqst) { return rawStore.getNextNotification(rqst); } @@ -2861,4 +2985,5 @@ throws MetaException, NoSuchObjectException { return rawStore.getPartitionColsWithStats(catName, dbName, tableName); } + } Index: standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/cache/CacheUtils.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/cache/CacheUtils.java (revision c1e5fa3d80511ac625476b0a9c454783bd6c4ad1) +++ standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/cache/CacheUtils.java (revision 48017a6db4a489afb5a9e4598ac5008acd601383) @@ -145,4 +145,9 @@ } return false; } + + public static String buildFunctionKey(String catName, String dbName, String functionName) { + return buildKey(catName.toLowerCase(), + dbName.toLowerCase(), functionName.toLowerCase()); + } } Index: standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/cache/SharedCache.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/cache/SharedCache.java (revision c1e5fa3d80511ac625476b0a9c454783bd6c4ad1) +++ standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/cache/SharedCache.java (revision 9981ddd55e10ab4b60b867822d3c827abf5a6851) @@ -38,6 +38,8 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; @@ -46,6 +48,8 @@ import com.google.common.cache.RemovalListener; import com.google.common.cache.RemovalNotification; import com.google.common.cache.Weigher; +import com.google.common.collect.Lists; +import org.apache.commons.collections.CollectionUtils; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hive.common.ValidReaderWriteIdList; import org.apache.hadoop.hive.common.ValidWriteIdList; @@ -65,6 +69,7 @@ import org.apache.hadoop.hive.metastore.api.StorageDescriptor; import org.apache.hadoop.hive.metastore.api.Table; import org.apache.hadoop.hive.metastore.api.TableMeta; +import org.apache.hadoop.hive.metastore.api.Function; import org.apache.hadoop.hive.metastore.conf.MetastoreConf; import org.apache.hadoop.hive.metastore.txn.TxnUtils; import org.apache.hadoop.hive.metastore.utils.MetaStoreServerUtils; @@ -75,6 +80,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; + import com.google.common.annotations.VisibleForTesting; import static org.apache.hadoop.hive.metastore.utils.StringUtils.normalizeIdentifier; @@ -111,6 +117,9 @@ private ScheduledExecutorService executor = null; private Map tableSizeMap = null; + private Map functionCache = new TreeMap<>(); + private boolean isFunctionCachePrewarmed = false; + enum StatsType { ALL(0), ALLBUTDEFAULT(1), PARTIAL(2); @@ -2114,5 +2123,153 @@ public void incrementUpdateCount() { cacheUpdateCount.incrementAndGet(); + } + + public void populateFunctionsInCache(Collection functions) { + for (Function func : functions) { + Function funcCopy = func.deepCopy(); + funcCopy.setFunctionName(funcCopy.getFunctionName().toLowerCase()); + try { + cacheLock.writeLock().lock(); + String key = CacheUtils.buildFunctionKey(funcCopy.getCatName().toLowerCase(), + funcCopy.getDbName().toLowerCase(), funcCopy.getFunctionName().toLowerCase()); + functionCache.putIfAbsent(key, funcCopy); + isFunctionCachePrewarmed = true; + } finally { + cacheLock.writeLock().unlock(); + } + } + } + + public Function getFunctionFromCache(String catName, String dbName, String funcName) { + Function func = null; + try { + cacheLock.readLock().lock(); + Function funcQuery = functionCache.get(CacheUtils.buildTableKey(catName, dbName, funcName)); + if (funcQuery != null) { + func = funcQuery; + } + } finally { + cacheLock.readLock().unlock(); + } + return func; + } + + public void addFunctionToCache(String catName, String dbName, String funcName, Function func) { + Function funcCopy = func.deepCopy(); + try { + cacheLock.writeLock().lock(); + String key = CacheUtils.buildFunctionKey(catName.toLowerCase(), dbName.toLowerCase(), funcName.toLowerCase()); + functionCache.putIfAbsent(key, funcCopy); + } finally { + cacheLock.writeLock().unlock(); + } + } + + public void alterFunctionInCache(String catName, String dbName, String funcName, Function func) { + try { + cacheLock.writeLock().lock(); + removeFunctionFromCache(catName, dbName, funcName); + addFunctionToCache(catName, dbName, funcName, func); + } finally { + cacheLock.writeLock().unlock(); + } + } + + public void removeFunctionFromCache(String catName, String dbName, String funcName) { + try { + cacheLock.writeLock().lock(); + String key = CacheUtils.buildFunctionKey(catName, dbName, funcName); + Function func = functionCache.get(key); + if (func == null) { + return; + } + functionCache.remove(key); + } finally { + cacheLock.writeLock().unlock(); + } + } + + public List getAllFunctionsFromCache(String catName) { + catName = catName.toLowerCase(); + List funcs = new ArrayList(); + try { + cacheLock.readLock().lock(); + if (functionCache != null && functionCache.size() > 0) { + for (Function func : functionCache.values()) { + if (org.apache.commons.lang.StringUtils.isNotBlank(func.getCatName()) && + org.apache.commons.lang.StringUtils.equals(func.getCatName(), catName)) { + funcs.add(func); + } + } + } + } finally { + cacheLock.readLock().unlock(); + } + return funcs; + } + + public List getFunctionsFromCacheByPattern(String catName, String dbName, String pattern) { + List funcs = Lists.newArrayList(); + try { + cacheLock.readLock().lock(); + if (functionCache != null && functionCache.size() > 0) { + for (Function func : functionCache.values()) { + if (org.apache.commons.lang.StringUtils.isNotBlank(func.getCatName()) + && org.apache.commons.lang.StringUtils.equals(func.getCatName(), catName) + && org.apache.commons.lang.StringUtils.equals(func.getDbName(), dbName)) { + funcs.add(func.getFunctionName()); + } + } + if (CollectionUtils.isNotEmpty(funcs)) { + funcs = filterByPattern(pattern, funcs); + } + } + } finally { + cacheLock.readLock().unlock(); + } + return funcs; + } + + private List filterByPattern(String pattern, List names) { + if (pattern != null && !isStarPattern(pattern)) { + // There may be multiple patterns separated by |. + String[] parts = pattern.trim().split("\\|"); + Pattern[] regexes = new Pattern[parts.length]; + int i = 0; + for (String part : parts) { + part = "(?i)" + part.replaceAll("\\*", ".*"); + regexes[i++] = Pattern.compile(part); + } + LOG.info("Patterns: " + regexes); + Iterator iter = names.iterator(); + while (iter.hasNext()) { + boolean remove = true; + for (Pattern regex : regexes) { + Matcher m = regex.matcher(iter.next()); + if (m.matches()) { + remove = false; + break; + } + } + if (remove) { + iter.remove(); + } + } + } + return names; + } + + private boolean isStarPattern(String pattern) { + return "*".equals(pattern); + } + + public void removeAllFunctionsFromCache() { + try { + cacheLock.writeLock().lock(); + functionCache.clear(); + } finally { + cacheLock.writeLock().unlock(); + } } } Index: standalone-metastore/metastore-server/src/test/java/org/apache/hadoop/hive/metastore/cache/TestCachedStore.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- standalone-metastore/metastore-server/src/test/java/org/apache/hadoop/hive/metastore/cache/TestCachedStore.java (revision c1e5fa3d80511ac625476b0a9c454783bd6c4ad1) +++ standalone-metastore/metastore-server/src/test/java/org/apache/hadoop/hive/metastore/cache/TestCachedStore.java (revision 9981ddd55e10ab4b60b867822d3c827abf5a6851) @@ -54,6 +54,10 @@ import org.apache.hadoop.hive.metastore.api.SerDeInfo; import org.apache.hadoop.hive.metastore.api.StorageDescriptor; import org.apache.hadoop.hive.metastore.api.Table; +import org.apache.hadoop.hive.metastore.api.Function; +import org.apache.hadoop.hive.metastore.api.ResourceUri; +import org.apache.hadoop.hive.metastore.api.FunctionType; +import org.apache.hadoop.hive.metastore.api.ResourceType; import org.apache.hadoop.hive.metastore.api.utils.DecimalUtils; import org.apache.hadoop.hive.metastore.client.builder.DatabaseBuilder; import org.apache.hadoop.hive.metastore.columnstats.cache.DateColumnStatsDataInspector; @@ -70,6 +74,7 @@ import org.junit.experimental.categories.Category; import static org.apache.hadoop.hive.metastore.Warehouse.DEFAULT_CATALOG_NAME; +import static org.apache.hadoop.hive.metastore.Warehouse.LOG; /** * Unit tests for CachedStore @@ -193,6 +198,7 @@ List db2Ptbl1PartitionsOS = objectStore.getPartitions(DEFAULT_CATALOG_NAME, db2.getName(), db2Ptbl1.getTableName(), -1); Assert.assertTrue(db2Ptbl1Partitions.containsAll(db2Ptbl1PartitionsOS)); + System.out.print("xxxxxx"); cachedStore.shutdown(); } @@ -1798,5 +1804,176 @@ throw new Exception("Unable to update SharedCache in 100 attempts; possibly some bug"); } CachedStore.stopCacheUpdateService(100); + } + + @Test + public void testGetFunction() throws Exception { + Configuration conf = MetastoreConf.newMetastoreConf(); + MetastoreConf.setBoolVar(conf, MetastoreConf.ConfVars.HIVE_IN_TEST, true); + MetastoreConf.setVar(conf, MetastoreConf.ConfVars.CACHED_RAW_STORE_MAX_CACHE_MEMORY, "5kb"); + MetaStoreTestUtils.setConfForStandloneMode(conf); + CachedStore cachedStore = new CachedStore(); + CachedStore.clearSharedCache(); + cachedStore.setConfForTestExceptSharedCache(conf); + ObjectStore objectStore = (ObjectStore) cachedStore.getRawStore(); + Function func1 = new Function(); + func1.setCatName(DEFAULT_CATALOG_NAME); + func1.setDbName(db1.getName()); + func1.setFunctionName("test1"); + func1.setClassName("com.test.test1"); + func1.setOwnerType(PrincipalType.USER); + func1.setFunctionType(FunctionType.JAVA); + Date createDate = new Date(); + func1.setCreateTime((int) createDate.getDaysSinceEpoch()); + List lists = new ArrayList(); + ResourceUri url = new ResourceUri(); + url.setResourceType(ResourceType.ARCHIVE); + url.setUri("test_url"); + lists.add(url); + func1.setResourceUris(lists); + cachedStore.setRawStore(objectStore); + objectStore.createFunction(func1); + Function funcs = cachedStore.getFunction(DEFAULT_CATALOG_NAME, db1.getName(), func1.getFunctionName()); + LOG.info("funcs.size={}", funcs); + Assert.assertEquals(funcs.getFunctionName(), "test1"); + objectStore.dropFunction(DEFAULT_CATALOG_NAME, db1.getName(), func1.getFunctionName()); + cachedStore.shutdown(); + } + + @Test + public void testGetAllFunctions() throws Exception { + Configuration conf = MetastoreConf.newMetastoreConf(); + MetastoreConf.setBoolVar(conf, MetastoreConf.ConfVars.HIVE_IN_TEST, true); + MetastoreConf.setVar(conf, MetastoreConf.ConfVars.CACHED_RAW_STORE_MAX_CACHE_MEMORY, "5kb"); + MetaStoreTestUtils.setConfForStandloneMode(conf); + CachedStore cachedStore = new CachedStore(); + CachedStore.clearSharedCache(); + cachedStore.setConfForTestExceptSharedCache(conf); + ObjectStore objectStore = (ObjectStore) cachedStore.getRawStore(); + + // func1 + Function func1 = new Function(); + func1.setCatName(DEFAULT_CATALOG_NAME); + func1.setDbName(db1.getName()); + func1.setFunctionName("test1"); + func1.setClassName("com.test.test1"); + func1.setOwnerType(PrincipalType.USER); + func1.setFunctionType(FunctionType.JAVA); + Date createDate = new Date(); + func1.setCreateTime((int) createDate.getDaysSinceEpoch()); + List lists = new ArrayList(); + ResourceUri url = new ResourceUri(); + url.setResourceType(ResourceType.ARCHIVE); + url.setUri("test_url"); + func1.setResourceUris(lists); + lists.add(url); + objectStore.createFunction(func1); + + // func2 + Function func2 = new Function(); + func2.setCatName(DEFAULT_CATALOG_NAME); + func2.setDbName(db1.getName()); + func2.setFunctionName("test2"); + func2.setClassName("com.test.test1"); + func2.setOwnerType(PrincipalType.USER); + func2.setFunctionType(FunctionType.JAVA); + Date createDate1 = new Date(); + func2.setCreateTime((int) createDate1.getDaysSinceEpoch()); + List lists1 = new ArrayList(); + ResourceUri url1 = new ResourceUri(); + url1.setResourceType(ResourceType.ARCHIVE); + url1.setUri("test_url2"); + func2.setResourceUris(lists); + lists1.add(url); + objectStore.createFunction(func2); + + // cached store + cachedStore.setRawStore(objectStore); + List funcs = cachedStore.getAllFunctions(DEFAULT_CATALOG_NAME); + Assert.assertEquals(funcs.size(), 2); + + // drop functions + objectStore.dropFunction(DEFAULT_CATALOG_NAME, db1.getName(), func1.getFunctionName()); + objectStore.dropFunction(DEFAULT_CATALOG_NAME, db1.getName(), func2.getFunctionName()); + cachedStore.shutdown(); + } + + @Test + public void testGreateFunction() throws Exception { + Configuration conf = MetastoreConf.newMetastoreConf(); + MetastoreConf.setBoolVar(conf, MetastoreConf.ConfVars.HIVE_IN_TEST, true); + MetastoreConf.setVar(conf, MetastoreConf.ConfVars.CACHED_RAW_STORE_MAX_CACHE_MEMORY, "5kb"); + MetaStoreTestUtils.setConfForStandloneMode(conf); + CachedStore cachedStore = new CachedStore(); + CachedStore.clearSharedCache(); + cachedStore.setConfForTestExceptSharedCache(conf); + ObjectStore objectStore = (ObjectStore) cachedStore.getRawStore(); + + // func1 + Function func1 = new Function(); + func1.setCatName(DEFAULT_CATALOG_NAME); + func1.setDbName(db1.getName()); + func1.setFunctionName("test1"); + func1.setClassName("com.test.test1"); + func1.setOwnerType(PrincipalType.USER); + func1.setFunctionType(FunctionType.JAVA); + Date createDate = new Date(); + func1.setCreateTime((int) createDate.getDaysSinceEpoch()); + List lists = new ArrayList(); + ResourceUri url = new ResourceUri(); + url.setResourceType(ResourceType.ARCHIVE); + url.setUri("test_url"); + func1.setResourceUris(lists); + lists.add(url); + + // cached store + cachedStore.setRawStore(objectStore); + cachedStore.createFunction(func1); + + // get function + Function funcCached = cachedStore.getFunction(DEFAULT_CATALOG_NAME,db1.getName(),func1.getFunctionName()); + Assert.assertEquals(funcCached.getFunctionName(), "test1"); + + // drop function + objectStore.dropFunction(DEFAULT_CATALOG_NAME, db1.getName(), func1.getFunctionName()); + cachedStore.shutdown(); + } + + @Test + public void testDropFunction() throws Exception { + Configuration conf = MetastoreConf.newMetastoreConf(); + MetastoreConf.setBoolVar(conf, MetastoreConf.ConfVars.HIVE_IN_TEST, true); + MetastoreConf.setVar(conf, MetastoreConf.ConfVars.CACHED_RAW_STORE_MAX_CACHE_MEMORY, "5kb"); + MetaStoreTestUtils.setConfForStandloneMode(conf); + CachedStore cachedStore = new CachedStore(); + CachedStore.clearSharedCache(); + cachedStore.setConfForTestExceptSharedCache(conf); + ObjectStore objectStore = (ObjectStore) cachedStore.getRawStore(); + + // func1 + Function func1 = new Function(); + func1.setCatName(DEFAULT_CATALOG_NAME); + func1.setDbName(db1.getName()); + func1.setFunctionName("test1"); + func1.setClassName("com.test.test1"); + func1.setOwnerType(PrincipalType.USER); + func1.setFunctionType(FunctionType.JAVA); + Date createDate = new Date(); + func1.setCreateTime((int) createDate.getDaysSinceEpoch()); + List lists = new ArrayList(); + ResourceUri url = new ResourceUri(); + url.setResourceType(ResourceType.ARCHIVE); + url.setUri("test_url"); + func1.setResourceUris(lists); + lists.add(url); + + // cached store + cachedStore.setRawStore(objectStore); + cachedStore.createFunction(func1); + cachedStore.dropFunction(DEFAULT_CATALOG_NAME, db1.getName(), func1.getFunctionName()); + List functions = cachedStore.getAllFunctions(DEFAULT_CATALOG_NAME); + Assert.assertEquals(functions.size(), 0); + + cachedStore.shutdown(); } }