#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace ProfileEvents { extern const Event Query; extern const Event SelectQuery; extern const Event InsertQuery; } namespace DB { namespace ErrorCodes { extern const int READONLY; extern const int UNKNOWN_TYPE_OF_QUERY; extern const int QUERY_IS_PROHIBITED; } static void throwIfNoAccess(Context & context) { if (context.getSettingsRef().readonly) { const auto & client_info = context.getClientInfo(); if (client_info.interface == ClientInfo::Interface::HTTP && client_info.http_method == ClientInfo::HTTPMethod::GET) throw Exception("Cannot execute query in readonly mode. " "For queries over HTTP, method GET implies readonly. You should use method POST for modifying queries.", ErrorCodes::READONLY); else throw Exception("Cannot execute query in readonly mode", ErrorCodes::READONLY); } else if (!context.getSettingsRef().allow_ddl) throw Exception("Cannot execute query. DDL queries are prohibited for the user", ErrorCodes::QUERY_IS_PROHIBITED); } std::unique_ptr InterpreterFactory::get(ASTPtr & query, Context & context, QueryProcessingStage::Enum stage) { ProfileEvents::increment(ProfileEvents::Query); if (typeid_cast(query.get())) { /// This is internal part of ASTSelectWithUnionQuery. /// Even if there is SELECT without union, it is represented by ASTSelectWithUnionQuery with single ASTSelectQuery as a child. return std::make_unique(query, context, SelectQueryOptions(stage)); } else if (typeid_cast(query.get())) { ProfileEvents::increment(ProfileEvents::SelectQuery); return std::make_unique(query, context, SelectQueryOptions(stage)); } else if (typeid_cast(query.get())) { ProfileEvents::increment(ProfileEvents::InsertQuery); /// readonly is checked inside InterpreterInsertQuery bool allow_materialized = static_cast(context.getSettingsRef().insert_allow_materialized_columns); return std::make_unique(query, context, allow_materialized); } else if (typeid_cast(query.get())) { /// readonly and allow_ddl are checked inside InterpreterCreateQuery return std::make_unique(query, context); } else if (typeid_cast(query.get())) { /// readonly and allow_ddl are checked inside InterpreterDropQuery return std::make_unique(query, context); } else if (typeid_cast(query.get())) { throwIfNoAccess(context); return std::make_unique(query, context); } else if (typeid_cast(query.get())) { return std::make_unique(query, context); } else if (typeid_cast(query.get())) { return std::make_unique(query, context); } else if (typeid_cast(query.get())) { /// readonly is checked inside InterpreterSetQuery return std::make_unique(query, context); } else if (typeid_cast(query.get())) { throwIfNoAccess(context); return std::make_unique(query, context); } else if (typeid_cast(query.get())) { return std::make_unique(query, context); } else if (typeid_cast(query.get())) { return std::make_unique(query, context); } else if (typeid_cast(query.get())) { return std::make_unique(query, context); } else if (typeid_cast(query.get())) { return std::make_unique(query, context); } else if (typeid_cast(query.get())) { return std::make_unique(query, context); } else if (typeid_cast(query.get())) { return std::make_unique(query, context); } else if (typeid_cast(query.get())) { throwIfNoAccess(context); return std::make_unique(query, context); } else if (typeid_cast(query.get())) { return std::make_unique(query, context); } else if (typeid_cast(query.get())) { return std::make_unique(query, context); } else if (typeid_cast(query.get())) { throwIfNoAccess(context); return std::make_unique(query, context); } else throw Exception("Unknown type of query: " + query->getID(), ErrorCodes::UNKNOWN_TYPE_OF_QUERY); } }