QuotaForIntervalsPtr Quota::get(const String & quota_key, const String & user_name, const Poco::Net::IPAddress & ip) { if (!quota_key.empty() && !ignore_key_if_not_keyed && (!is_keyed || keyed_by_ip)) throw Exception("Quota " + name + " (for user " + user_name + ") doesn't allow client supplied keys.", ErrorCodes::QUOTA_DOESNT_ALLOW_KEYS); /** Quota is calculated separately: * - for each IP-address, if 'keyed_by_ip'; * - otherwise for each 'quota_key', if present; * - otherwise for each 'user_name'. */ UInt64 quota_key_hashed = sipHash64( keyed_by_ip ? ip.toString() : (!quota_key.empty() ? quota_key : user_name)); std::lock_guard<std::mutex> lock(mutex); Container::iterator it = quota_for_keys.find(quota_key_hashed); if (quota_for_keys.end() == it) it = quota_for_keys.emplace(quota_key_hashed, std::make_shared<QuotaForIntervals>(max, user_name)).first; return it->second; }
StoragePtr TableFunctionShardByHash::execute(ASTPtr ast_function, Context & context) const { ASTs & args_func = typeid_cast<ASTFunction &>(*ast_function).children; const char * err = "Table function 'shardByHash' requires 4 parameters: " "cluster name, key string to hash, name of remote database, name of remote table."; if (args_func.size() != 1) throw Exception(err, ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); ASTs & args = typeid_cast<ASTExpressionList &>(*args_func.at(0)).children; if (args.size() != 4) throw Exception(err, ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); String cluster_name; String key; String remote_database; String remote_table; auto getStringLiteral = [](const IAST & node, const char * description) { const ASTLiteral * lit = typeid_cast<const ASTLiteral *>(&node); if (!lit) throw Exception(description + String(" must be string literal (in single quotes)."), ErrorCodes::BAD_ARGUMENTS); if (lit->value.getType() != Field::Types::String) throw Exception(description + String(" must be string literal (in single quotes)."), ErrorCodes::BAD_ARGUMENTS); return safeGet<const String &>(lit->value); }; cluster_name = getClusterName(*args[0]); key = getStringLiteral(*args[1], "Key to hash"); args[2] = evaluateConstantExpressionOrIdentidierAsLiteral(args[2], context); args[3] = evaluateConstantExpressionOrIdentidierAsLiteral(args[3], context); remote_database = static_cast<const ASTLiteral &>(*args[2]).value.safeGet<String>(); remote_table = static_cast<const ASTLiteral &>(*args[3]).value.safeGet<String>(); /// Аналогично другим TableFunctions. for (auto & arg : args) if (ASTIdentifier * id = typeid_cast<ASTIdentifier *>(arg.get())) id->kind = ASTIdentifier::Table; const Cluster & cluster = context.getCluster(cluster_name); size_t shard_index = sipHash64(key) % cluster.getShardCount(); std::shared_ptr<Cluster> shard(cluster.getClusterWithSingleShard(shard_index).release()); return StorageDistributed::create( getName(), std::make_shared<NamesAndTypesList>(getStructureOfRemoteTable(*shard, remote_database, remote_table, context)), remote_database, remote_table, shard, context); }