2011-08-15 01:12:57 +00:00
|
|
|
#pragma once
|
2010-03-04 19:20:28 +00:00
|
|
|
|
2017-04-01 09:19:00 +00:00
|
|
|
#include <Common/Exception.h>
|
2018-11-27 16:45:45 +00:00
|
|
|
#include <Common/RWLock.h>
|
2018-11-19 14:31:16 +00:00
|
|
|
#include <Core/Names.h>
|
2017-04-01 09:19:00 +00:00
|
|
|
#include <Core/QueryProcessingStage.h>
|
2018-10-14 15:30:06 +00:00
|
|
|
#include <Databases/IDatabase.h>
|
2017-04-01 09:19:00 +00:00
|
|
|
#include <Storages/ITableDeclaration.h>
|
2019-03-05 10:12:20 +00:00
|
|
|
#include <Storages/TableStructureLockHolder.h>
|
2017-07-15 03:48:36 +00:00
|
|
|
#include <Storages/SelectQueryInfo.h>
|
2019-02-04 13:04:02 +00:00
|
|
|
#include <Interpreters/CancellationCode.h>
|
2017-07-28 17:34:02 +00:00
|
|
|
#include <shared_mutex>
|
2015-02-10 21:10:58 +00:00
|
|
|
#include <memory>
|
2017-11-20 04:15:43 +00:00
|
|
|
#include <optional>
|
2018-05-21 13:49:54 +00:00
|
|
|
#include <Common/ActionLock.h>
|
2013-01-23 17:38:03 +00:00
|
|
|
|
2010-03-01 16:59:51 +00:00
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
2016-01-11 21:46:36 +00:00
|
|
|
namespace ErrorCodes
|
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
extern const int TABLE_IS_DROPPED;
|
2018-11-22 21:19:58 +00:00
|
|
|
extern const int NOT_IMPLEMENTED;
|
2016-01-11 21:46:36 +00:00
|
|
|
}
|
|
|
|
|
2013-06-17 07:01:31 +00:00
|
|
|
class Context;
|
2014-03-19 10:45:13 +00:00
|
|
|
class IBlockInputStream;
|
|
|
|
class IBlockOutputStream;
|
|
|
|
|
2018-05-21 13:49:54 +00:00
|
|
|
using StorageActionBlockType = size_t;
|
|
|
|
|
2016-05-28 12:22:22 +00:00
|
|
|
using BlockOutputStreamPtr = std::shared_ptr<IBlockOutputStream>;
|
|
|
|
using BlockInputStreamPtr = std::shared_ptr<IBlockInputStream>;
|
2016-05-28 10:15:36 +00:00
|
|
|
using BlockInputStreams = std::vector<BlockInputStreamPtr>;
|
2013-06-17 07:01:31 +00:00
|
|
|
|
2017-09-17 18:49:43 +00:00
|
|
|
class ASTCreateQuery;
|
2010-03-01 16:59:51 +00:00
|
|
|
|
2014-03-24 13:24:47 +00:00
|
|
|
class IStorage;
|
|
|
|
|
2016-05-28 10:15:36 +00:00
|
|
|
using StoragePtr = std::shared_ptr<IStorage>;
|
2018-03-23 16:33:51 +00:00
|
|
|
using StorageWeakPtr = std::weak_ptr<IStorage>;
|
2014-03-24 13:24:47 +00:00
|
|
|
|
2017-01-21 04:24:28 +00:00
|
|
|
struct Settings;
|
|
|
|
|
|
|
|
class AlterCommands;
|
2018-06-13 20:02:27 +00:00
|
|
|
class MutationCommands;
|
2018-11-13 13:48:53 +00:00
|
|
|
class PartitionCommands;
|
2017-01-21 04:24:28 +00:00
|
|
|
|
|
|
|
|
2017-04-16 15:00:33 +00:00
|
|
|
/** Storage. Responsible for
|
|
|
|
* - storage of the table data;
|
2017-06-06 17:06:14 +00:00
|
|
|
* - the definition in which files (or not in files) the data is stored;
|
|
|
|
* - data lookups and appends;
|
2017-04-16 15:00:33 +00:00
|
|
|
* - data storage structure (compression, etc.)
|
|
|
|
* - concurrent access to data (locks, etc.)
|
2010-03-01 16:59:51 +00:00
|
|
|
*/
|
2016-08-26 21:25:05 +00:00
|
|
|
class IStorage : public std::enable_shared_from_this<IStorage>, private boost::noncopyable, public ITableDeclaration
|
2010-03-01 16:59:51 +00:00
|
|
|
{
|
|
|
|
public:
|
2017-04-16 15:00:33 +00:00
|
|
|
/// The main name of the table type (for example, StorageMergeTree).
|
2017-04-01 07:20:54 +00:00
|
|
|
virtual std::string getName() const = 0;
|
|
|
|
|
2019-03-29 20:31:06 +00:00
|
|
|
/// The name of the table.
|
2018-03-06 20:18:34 +00:00
|
|
|
virtual std::string getTableName() const = 0;
|
2019-03-29 20:31:06 +00:00
|
|
|
virtual std::string getDatabaseName() const { return {}; } // FIXME: should be abstract method.
|
2018-03-06 20:18:34 +00:00
|
|
|
|
2017-06-06 17:06:14 +00:00
|
|
|
/** Returns true if the storage receives data from a remote server or servers. */
|
2017-04-01 07:20:54 +00:00
|
|
|
virtual bool isRemote() const { return false; }
|
|
|
|
|
2017-04-16 15:00:33 +00:00
|
|
|
/** Returns true if the storage supports queries with the SAMPLE section. */
|
2017-04-01 07:20:54 +00:00
|
|
|
virtual bool supportsSampling() const { return false; }
|
|
|
|
|
2017-04-16 15:00:33 +00:00
|
|
|
/** Returns true if the storage supports queries with the FINAL section. */
|
2017-04-01 07:20:54 +00:00
|
|
|
virtual bool supportsFinal() const { return false; }
|
|
|
|
|
2017-04-16 15:00:33 +00:00
|
|
|
/** Returns true if the storage supports queries with the PREWHERE section. */
|
2017-04-01 07:20:54 +00:00
|
|
|
virtual bool supportsPrewhere() const { return false; }
|
|
|
|
|
2017-04-25 15:21:03 +00:00
|
|
|
/** Returns true if the storage replicates SELECT, INSERT and ALTER commands among replicas. */
|
|
|
|
virtual bool supportsReplication() const { return false; }
|
|
|
|
|
2018-05-21 23:17:57 +00:00
|
|
|
/** Returns true if the storage supports deduplication of inserted data blocks . */
|
|
|
|
virtual bool supportsDeduplication() const { return false; }
|
2017-04-25 15:21:03 +00:00
|
|
|
|
2019-03-05 10:12:20 +00:00
|
|
|
|
2019-03-07 18:34:46 +00:00
|
|
|
/// Acquire this lock if you need the table structure to remain constant during the execution of
|
|
|
|
/// the query. If will_add_new_data is true, this means that the query will add new data to the table
|
|
|
|
/// (INSERT or a parts merge).
|
2019-03-07 18:04:47 +00:00
|
|
|
TableStructureReadLockHolder lockStructureForShare(bool will_add_new_data, const String & query_id)
|
2017-04-01 07:20:54 +00:00
|
|
|
{
|
2019-03-07 18:04:47 +00:00
|
|
|
TableStructureReadLockHolder result;
|
2019-03-05 10:12:20 +00:00
|
|
|
if (will_add_new_data)
|
|
|
|
result.new_data_structure_lock = new_data_structure_lock->getLock(RWLockImpl::Read, query_id);
|
|
|
|
result.structure_lock = structure_lock->getLock(RWLockImpl::Read, query_id);
|
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
if (is_dropped)
|
|
|
|
throw Exception("Table is dropped", ErrorCodes::TABLE_IS_DROPPED);
|
2019-03-05 10:12:20 +00:00
|
|
|
return result;
|
2017-04-01 07:20:54 +00:00
|
|
|
}
|
|
|
|
|
2019-03-07 18:34:46 +00:00
|
|
|
/// Acquire this lock at the start of ALTER to lock out other ALTERs and make sure that only you
|
|
|
|
/// can modify the table structure. It can later be upgraded to the exclusive lock.
|
2019-03-07 18:04:47 +00:00
|
|
|
TableStructureWriteLockHolder lockAlterIntention(const String & query_id)
|
2017-04-01 07:20:54 +00:00
|
|
|
{
|
2019-03-07 18:04:47 +00:00
|
|
|
TableStructureWriteLockHolder result;
|
2019-03-05 10:12:20 +00:00
|
|
|
result.alter_intention_lock = alter_intention_lock->getLock(RWLockImpl::Write, query_id);
|
2017-04-01 07:20:54 +00:00
|
|
|
|
2019-03-05 10:12:20 +00:00
|
|
|
if (is_dropped)
|
|
|
|
throw Exception("Table is dropped", ErrorCodes::TABLE_IS_DROPPED);
|
|
|
|
return result;
|
2017-04-01 07:20:54 +00:00
|
|
|
}
|
|
|
|
|
2019-03-07 18:34:46 +00:00
|
|
|
/// Upgrade alter intention lock and make sure that no new data is inserted into the table.
|
|
|
|
/// This is used by the ALTER MODIFY of the MergeTree storage to consistently determine
|
|
|
|
/// the set of parts that needs to be altered.
|
2019-03-07 18:04:47 +00:00
|
|
|
void lockNewDataStructureExclusively(TableStructureWriteLockHolder & lock_holder, const String & query_id)
|
2017-04-01 07:20:54 +00:00
|
|
|
{
|
2019-03-05 10:12:20 +00:00
|
|
|
if (!lock_holder.alter_intention_lock)
|
|
|
|
throw Exception("Alter intention lock for table " + getTableName() + " was not taken. This is a bug.",
|
|
|
|
ErrorCodes::LOGICAL_ERROR);
|
|
|
|
|
|
|
|
lock_holder.new_data_structure_lock = new_data_structure_lock->getLock(RWLockImpl::Write, query_id);
|
2017-04-01 07:20:54 +00:00
|
|
|
}
|
|
|
|
|
2019-03-07 18:34:46 +00:00
|
|
|
/// Upgrade alter intention lock to the full exclusive structure lock. This is done by ALTER queries
|
|
|
|
/// to ensure that no other query uses the table structure and it can be safely changed.
|
2019-03-07 18:04:47 +00:00
|
|
|
void lockStructureExclusively(TableStructureWriteLockHolder & lock_holder, const String & query_id)
|
2017-04-01 07:20:54 +00:00
|
|
|
{
|
2019-03-05 10:12:20 +00:00
|
|
|
if (!lock_holder.alter_intention_lock)
|
|
|
|
throw Exception("Alter intention lock for table " + getTableName() + " was not taken. This is a bug.",
|
|
|
|
ErrorCodes::LOGICAL_ERROR);
|
|
|
|
|
|
|
|
if (!lock_holder.new_data_structure_lock)
|
|
|
|
lock_holder.new_data_structure_lock = new_data_structure_lock->getLock(RWLockImpl::Write, query_id);
|
|
|
|
lock_holder.structure_lock = structure_lock->getLock(RWLockImpl::Write, query_id);
|
|
|
|
}
|
|
|
|
|
2019-03-07 18:34:46 +00:00
|
|
|
/// Acquire the full exclusive lock immediately. No other queries can run concurrently.
|
2019-03-07 18:04:47 +00:00
|
|
|
TableStructureWriteLockHolder lockExclusively(const String & query_id)
|
2019-03-05 10:12:20 +00:00
|
|
|
{
|
2019-03-07 18:04:47 +00:00
|
|
|
TableStructureWriteLockHolder result;
|
2019-03-05 10:12:20 +00:00
|
|
|
result.alter_intention_lock = alter_intention_lock->getLock(RWLockImpl::Write, query_id);
|
|
|
|
|
|
|
|
if (is_dropped)
|
|
|
|
throw Exception("Table is dropped", ErrorCodes::TABLE_IS_DROPPED);
|
|
|
|
|
2019-03-07 18:04:47 +00:00
|
|
|
result.new_data_structure_lock = new_data_structure_lock->getLock(RWLockImpl::Write, query_id);
|
|
|
|
result.structure_lock = structure_lock->getLock(RWLockImpl::Write, query_id);
|
|
|
|
|
2019-03-05 10:12:20 +00:00
|
|
|
return result;
|
2017-04-01 07:20:54 +00:00
|
|
|
}
|
|
|
|
|
2018-04-19 14:47:09 +00:00
|
|
|
/** Returns stage to which query is going to be processed in read() function.
|
|
|
|
* (Normally, the function only reads the columns from the list, but in other cases,
|
|
|
|
* for example, the request can be partially processed on a remote server.)
|
|
|
|
*/
|
|
|
|
virtual QueryProcessingStage::Enum getQueryProcessingStage(const Context &) const { return QueryProcessingStage::FetchColumns; }
|
2017-04-01 07:20:54 +00:00
|
|
|
|
2017-04-16 15:00:33 +00:00
|
|
|
/** Read a set of columns from the table.
|
|
|
|
* Accepts a list of columns to read, as well as a description of the query,
|
|
|
|
* from which information can be extracted about how to retrieve data
|
|
|
|
* (indexes, locks, etc.)
|
|
|
|
* Returns a stream with which you can read data sequentially
|
|
|
|
* or multiple streams for parallel data reading.
|
2018-04-19 14:47:09 +00:00
|
|
|
* The `processed_stage` must be the result of getQueryProcessingStage() function.
|
2017-04-01 07:20:54 +00:00
|
|
|
*
|
2017-05-24 21:06:29 +00:00
|
|
|
* context contains settings for one query.
|
2017-04-16 15:00:33 +00:00
|
|
|
* Usually Storage does not care about these settings, since they are used in the interpreter.
|
|
|
|
* But, for example, for distributed query processing, the settings are passed to the remote server.
|
2017-04-01 07:20:54 +00:00
|
|
|
*
|
2017-06-02 15:54:39 +00:00
|
|
|
* num_streams - a recommendation, how many streams to return,
|
|
|
|
* if the storage can return a different number of streams.
|
2017-04-01 07:20:54 +00:00
|
|
|
*
|
2017-04-16 15:00:33 +00:00
|
|
|
* It is guaranteed that the structure of the table will not change over the lifetime of the returned streams (that is, there will not be ALTER, RENAME and DROP).
|
2017-04-01 07:20:54 +00:00
|
|
|
*/
|
|
|
|
virtual BlockInputStreams read(
|
2017-12-01 19:34:51 +00:00
|
|
|
const Names & /*column_names*/,
|
|
|
|
const SelectQueryInfo & /*query_info*/,
|
|
|
|
const Context & /*context*/,
|
2018-04-19 14:47:09 +00:00
|
|
|
QueryProcessingStage::Enum /*processed_stage*/,
|
2019-02-18 17:31:18 +00:00
|
|
|
size_t /*max_block_size*/,
|
2017-12-01 19:34:51 +00:00
|
|
|
unsigned /*num_streams*/)
|
2017-04-01 07:20:54 +00:00
|
|
|
{
|
|
|
|
throw Exception("Method read is not supported by storage " + getName(), ErrorCodes::NOT_IMPLEMENTED);
|
|
|
|
}
|
|
|
|
|
2017-04-16 15:00:33 +00:00
|
|
|
/** Writes the data to a table.
|
|
|
|
* Receives a description of the query, which can contain information about the data write method.
|
|
|
|
* Returns an object by which you can write data sequentially.
|
2017-04-01 07:20:54 +00:00
|
|
|
*
|
2017-04-16 15:00:33 +00:00
|
|
|
* It is guaranteed that the table structure will not change over the lifetime of the returned streams (that is, there will not be ALTER, RENAME and DROP).
|
2017-04-01 07:20:54 +00:00
|
|
|
*/
|
|
|
|
virtual BlockOutputStreamPtr write(
|
2017-12-01 19:34:51 +00:00
|
|
|
const ASTPtr & /*query*/,
|
2019-02-27 18:26:24 +00:00
|
|
|
const Context & /*context*/)
|
2017-04-01 07:20:54 +00:00
|
|
|
{
|
|
|
|
throw Exception("Method write is not supported by storage " + getName(), ErrorCodes::NOT_IMPLEMENTED);
|
|
|
|
}
|
|
|
|
|
2017-04-16 15:00:33 +00:00
|
|
|
/** Delete the table data. Called before deleting the directory with the data.
|
2018-06-09 15:48:22 +00:00
|
|
|
* The method can be called only after detaching table from Context (when no queries are performed with table).
|
|
|
|
* The table is not usable during and after call to this method.
|
2017-04-16 15:00:33 +00:00
|
|
|
* If you do not need any action other than deleting the directory with data, you can leave this method blank.
|
2017-04-01 07:20:54 +00:00
|
|
|
*/
|
|
|
|
virtual void drop() {}
|
|
|
|
|
2018-06-09 15:48:22 +00:00
|
|
|
/** Clear the table data and leave it empty.
|
2018-06-09 18:17:27 +00:00
|
|
|
* Must be called under lockForAlter.
|
2018-04-21 00:35:20 +00:00
|
|
|
*/
|
2018-12-28 13:39:44 +00:00
|
|
|
virtual void truncate(const ASTPtr & /*query*/, const Context & /* context */)
|
2018-04-21 00:35:20 +00:00
|
|
|
{
|
|
|
|
throw Exception("Truncate is not supported by storage " + getName(), ErrorCodes::NOT_IMPLEMENTED);
|
|
|
|
}
|
|
|
|
|
2017-04-16 15:00:33 +00:00
|
|
|
/** Rename the table.
|
|
|
|
* Renaming a name in a file with metadata, the name in the list of tables in the RAM, is done separately.
|
|
|
|
* In this function, you need to rename the directory with the data, if any.
|
|
|
|
* Called when the table structure is locked for write.
|
2017-04-01 07:20:54 +00:00
|
|
|
*/
|
2017-12-01 19:34:51 +00:00
|
|
|
virtual void rename(const String & /*new_path_to_db*/, const String & /*new_database_name*/, const String & /*new_table_name*/)
|
2017-04-01 07:20:54 +00:00
|
|
|
{
|
|
|
|
throw Exception("Method rename is not supported by storage " + getName(), ErrorCodes::NOT_IMPLEMENTED);
|
|
|
|
}
|
|
|
|
|
2017-04-16 15:00:33 +00:00
|
|
|
/** ALTER tables in the form of column changes that do not affect the change to Storage or its parameters.
|
|
|
|
* This method must fully execute the ALTER query, taking care of the locks itself.
|
|
|
|
* To update the table metadata on disk, this method should call InterpreterAlterQuery::updateMetadata.
|
2017-04-01 07:20:54 +00:00
|
|
|
*/
|
2019-03-07 20:52:25 +00:00
|
|
|
virtual void alter(const AlterCommands & params, const String & database_name, const String & table_name, const Context & context, TableStructureWriteLockHolder & table_lock_holder);
|
2018-05-21 13:49:54 +00:00
|
|
|
|
2018-11-13 13:48:53 +00:00
|
|
|
/** ALTER tables with regard to its partitions.
|
|
|
|
* Should handle locks for each command on its own.
|
2017-04-01 07:20:54 +00:00
|
|
|
*/
|
2018-11-26 14:43:40 +00:00
|
|
|
virtual void alterPartition(const ASTPtr & /* query */, const PartitionCommands & /* commands */, const Context & /* context */)
|
2017-04-01 07:20:54 +00:00
|
|
|
{
|
2018-11-13 13:48:53 +00:00
|
|
|
throw Exception("Partition operations are not supported by storage " + getName(), ErrorCodes::NOT_IMPLEMENTED);
|
2017-04-01 07:20:54 +00:00
|
|
|
}
|
|
|
|
|
2017-04-16 15:00:33 +00:00
|
|
|
/** Perform any background work. For example, combining parts in a MergeTree type table.
|
|
|
|
* Returns whether any work has been done.
|
2017-04-01 07:20:54 +00:00
|
|
|
*/
|
2017-12-01 19:34:51 +00:00
|
|
|
virtual bool optimize(const ASTPtr & /*query*/, const ASTPtr & /*partition*/, bool /*final*/, bool /*deduplicate*/, const Context & /*context*/)
|
2017-04-01 07:20:54 +00:00
|
|
|
{
|
|
|
|
throw Exception("Method optimize is not supported by storage " + getName(), ErrorCodes::NOT_IMPLEMENTED);
|
|
|
|
}
|
|
|
|
|
2018-02-02 16:02:43 +00:00
|
|
|
/// Mutate the table contents
|
|
|
|
virtual void mutate(const MutationCommands &, const Context &)
|
|
|
|
{
|
|
|
|
throw Exception("Mutations are not supported by storage " + getName(), ErrorCodes::NOT_IMPLEMENTED);
|
|
|
|
}
|
|
|
|
|
2019-01-10 18:19:29 +00:00
|
|
|
/// Cancel a mutation.
|
2019-02-04 13:04:02 +00:00
|
|
|
virtual CancellationCode killMutation(const String & /*mutation_id*/)
|
2019-01-10 18:19:29 +00:00
|
|
|
{
|
|
|
|
throw Exception("Mutations are not supported by storage " + getName(), ErrorCodes::NOT_IMPLEMENTED);
|
|
|
|
}
|
|
|
|
|
2017-06-06 17:06:14 +00:00
|
|
|
/** If the table have to do some complicated work on startup,
|
|
|
|
* that must be postponed after creation of table object
|
|
|
|
* (like launching some background threads),
|
|
|
|
* do it in this method.
|
|
|
|
* You should call this method after creation of object.
|
|
|
|
* By default, does nothing.
|
|
|
|
* Cannot be called simultaneously by multiple threads.
|
|
|
|
*/
|
|
|
|
virtual void startup() {}
|
|
|
|
|
|
|
|
/** If the table have to do some complicated work when destroying an object - do it in advance.
|
2017-04-16 15:00:33 +00:00
|
|
|
* For example, if the table contains any threads for background work - ask them to complete and wait for completion.
|
2017-06-06 17:06:14 +00:00
|
|
|
* By default, does nothing.
|
2017-04-16 15:00:33 +00:00
|
|
|
* Can be called simultaneously from different threads, even after a call to drop().
|
2017-04-01 07:20:54 +00:00
|
|
|
*/
|
|
|
|
virtual void shutdown() {}
|
|
|
|
|
2018-05-21 13:49:54 +00:00
|
|
|
/// Asks table to stop executing some action identified by action_type
|
|
|
|
/// If table does not support such type of lock, and empty lock is returned
|
2018-05-28 15:37:30 +00:00
|
|
|
virtual ActionLock getActionLock(StorageActionBlockType /* action_type */)
|
2018-05-21 13:49:54 +00:00
|
|
|
{
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
bool is_dropped{false};
|
|
|
|
|
|
|
|
/// Does table support index for IN sections
|
|
|
|
virtual bool supportsIndexForIn() const { return false; }
|
|
|
|
|
2018-01-23 08:18:12 +00:00
|
|
|
/// Provides a hint that the storage engine may evaluate the IN-condition by using an index.
|
2019-02-27 18:26:24 +00:00
|
|
|
virtual bool mayBenefitFromIndexForIn(const ASTPtr & /* left_in_operand */, const Context & /* query_context */) const { return false; }
|
2018-01-21 07:30:07 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
/// Checks validity of the data
|
2018-11-22 21:19:58 +00:00
|
|
|
virtual bool checkData() const { throw Exception("Check query is not supported for " + getName() + " storage", ErrorCodes::NOT_IMPLEMENTED); }
|
2017-04-01 07:20:54 +00:00
|
|
|
|
|
|
|
/// Checks that table could be dropped right now
|
2018-08-03 09:54:46 +00:00
|
|
|
/// Otherwise - throws an exception with detailed information.
|
2018-08-03 13:19:53 +00:00
|
|
|
/// We do not use mutex because it is not very important that the size could change during the operation.
|
2018-08-03 09:39:01 +00:00
|
|
|
virtual void checkTableCanBeDropped() const {}
|
2017-01-23 19:18:25 +00:00
|
|
|
|
2018-08-01 17:41:18 +00:00
|
|
|
/// Checks that Partition could be dropped right now
|
2018-08-03 09:54:46 +00:00
|
|
|
/// Otherwise - throws an exception with detailed information.
|
2018-08-03 13:19:53 +00:00
|
|
|
/// We do not use mutex because it is not very important that the size could change during the operation.
|
2018-08-03 09:39:01 +00:00
|
|
|
virtual void checkPartitionCanBeDropped(const ASTPtr & /*partition*/) {}
|
2017-01-23 19:18:25 +00:00
|
|
|
|
2017-10-03 23:43:55 +00:00
|
|
|
/** Notify engine about updated dependencies for this storage. */
|
|
|
|
virtual void updateDependencies() {}
|
|
|
|
|
2018-02-21 19:26:59 +00:00
|
|
|
/// Returns data path if storage supports it, empty string otherwise.
|
|
|
|
virtual String getDataPath() const { return {}; }
|
|
|
|
|
2018-11-27 17:07:10 +00:00
|
|
|
/// Returns ASTExpressionList of partition key expression for storage or nullptr if there is none.
|
|
|
|
virtual ASTPtr getPartitionKeyAST() const { return nullptr; }
|
2018-09-07 15:13:08 +00:00
|
|
|
|
2018-11-27 17:07:10 +00:00
|
|
|
/// Returns ASTExpressionList of sorting key expression for storage or nullptr if there is none.
|
|
|
|
virtual ASTPtr getSortingKeyAST() const { return nullptr; }
|
2018-10-04 08:58:19 +00:00
|
|
|
|
2018-11-27 17:07:10 +00:00
|
|
|
/// Returns ASTExpressionList of primary key expression for storage or nullptr if there is none.
|
|
|
|
virtual ASTPtr getPrimaryKeyAST() const { return nullptr; }
|
2018-11-09 09:39:07 +00:00
|
|
|
|
2018-11-27 17:07:10 +00:00
|
|
|
/// Returns sampling expression AST for storage or nullptr if there is none.
|
|
|
|
virtual ASTPtr getSamplingKeyAST() const { return nullptr; }
|
2018-11-08 17:45:41 +00:00
|
|
|
|
2018-11-27 17:07:10 +00:00
|
|
|
/// Returns additional columns that need to be read to calculate partition key.
|
|
|
|
virtual Names getColumnsRequiredForPartitionKey() const { return {}; }
|
2018-11-19 14:31:16 +00:00
|
|
|
|
2018-11-27 17:07:10 +00:00
|
|
|
/// Returns additional columns that need to be read to calculate sorting key.
|
|
|
|
virtual Names getColumnsRequiredForSortingKey() const { return {}; }
|
2018-11-19 14:31:16 +00:00
|
|
|
|
2018-11-27 17:07:10 +00:00
|
|
|
/// Returns additional columns that need to be read to calculate primary key.
|
|
|
|
virtual Names getColumnsRequiredForPrimaryKey() const { return {}; }
|
2018-11-19 14:31:16 +00:00
|
|
|
|
2018-11-27 17:07:10 +00:00
|
|
|
/// Returns additional columns that need to be read to calculate sampling key.
|
|
|
|
virtual Names getColumnsRequiredForSampling() const { return {}; }
|
|
|
|
|
|
|
|
/// Returns additional columns that need to be read for FINAL to work.
|
|
|
|
virtual Names getColumnsRequiredForFinal() const { return {}; }
|
2018-11-19 14:31:16 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
using ITableDeclaration::ITableDeclaration;
|
|
|
|
using std::enable_shared_from_this<IStorage>::shared_from_this;
|
2014-03-09 17:36:01 +00:00
|
|
|
|
2013-01-23 17:38:03 +00:00
|
|
|
private:
|
2019-03-05 10:12:20 +00:00
|
|
|
/// You always need to take the next three locks in this order.
|
2017-04-01 07:20:54 +00:00
|
|
|
|
2019-03-07 18:34:46 +00:00
|
|
|
/// If you hold this lock exclusively, you can be sure that no other structure modifying queries
|
|
|
|
/// (e.g. ALTER, DROP) are concurrently executing. But queries that only read table structure
|
|
|
|
/// (e.g. SELECT, INSERT) can continue to execute.
|
2019-03-05 10:12:20 +00:00
|
|
|
mutable RWLock alter_intention_lock = RWLockImpl::create();
|
2017-04-01 07:20:54 +00:00
|
|
|
|
2019-03-07 18:34:46 +00:00
|
|
|
/// It is taken for share for the entire INSERT query and the entire merge of the parts (for MergeTree).
|
2019-03-11 19:05:59 +00:00
|
|
|
/// ALTER COLUMN queries acquire an exclusive lock to ensure that no new parts with the old structure
|
|
|
|
/// are added to the table and thus the set of parts to modify doesn't change.
|
2019-03-05 10:12:20 +00:00
|
|
|
mutable RWLock new_data_structure_lock = RWLockImpl::create();
|
2017-04-01 07:20:54 +00:00
|
|
|
|
2019-03-07 18:34:46 +00:00
|
|
|
/// Lock for the table column structure (names, types, etc.) and data path.
|
|
|
|
/// It is taken in exclusive mode by queries that modify them (e.g. RENAME, ALTER and DROP)
|
|
|
|
/// and in share mode by other queries.
|
2018-11-27 16:45:45 +00:00
|
|
|
mutable RWLock structure_lock = RWLockImpl::create();
|
2013-01-23 17:38:03 +00:00
|
|
|
};
|
2010-03-01 16:59:51 +00:00
|
|
|
|
2017-04-16 15:00:33 +00:00
|
|
|
/// table name -> table
|
2015-09-04 20:52:00 +00:00
|
|
|
using Tables = std::map<String, StoragePtr>;
|
|
|
|
|
2011-08-15 01:12:57 +00:00
|
|
|
}
|