| 113 | } |
| 114 | |
| 115 | StorageMaterializedView::StorageMaterializedView( |
| 116 | const StorageID & table_id_, |
| 117 | ContextPtr local_context, |
| 118 | const ASTCreateQuery & query, |
| 119 | const ColumnsDescription & columns_, |
| 120 | LoadingStrictnessLevel mode, |
| 121 | const String & comment, |
| 122 | bool is_restore_from_backup) |
| 123 | : StorageWithCommonVirtualColumns(table_id_), WithMutableContext(local_context->getGlobalContext()) |
| 124 | { |
| 125 | StorageInMemoryMetadata storage_metadata; |
| 126 | storage_metadata.setColumns(columns_); |
| 127 | |
| 128 | if (query.sql_security) |
| 129 | storage_metadata.setSQLSecurity(query.sql_security->as<ASTSQLSecurity &>()); |
| 130 | |
| 131 | /// Materialized view doesn't support SQL SECURITY INVOKER. |
| 132 | if (storage_metadata.sql_security_type == SQLSecurityType::INVOKER) |
| 133 | throw Exception(ErrorCodes::QUERY_IS_NOT_SUPPORTED_IN_MATERIALIZED_VIEW, "SQL SECURITY INVOKER can't be specified for MATERIALIZED VIEW"); |
| 134 | |
| 135 | if (storage_metadata.sql_security_type == SQLSecurityType::DEFINER) |
| 136 | ViewDefinerDependencies::instance().addViewDependency(*storage_metadata.definer, table_id_); |
| 137 | |
| 138 | if (!query.select) |
| 139 | throw Exception(ErrorCodes::INCORRECT_QUERY, "SELECT query is not specified for {}", getName()); |
| 140 | |
| 141 | /// If the destination table is not set, use inner table |
| 142 | auto to_table_id = query.getTargetTableID(ViewTarget::To); |
| 143 | has_inner_table = to_table_id.empty(); |
| 144 | auto to_inner_uuid = query.getTargetInnerUUID(ViewTarget::To); |
| 145 | auto * to_table_engine = query.getTargetInnerEngine(ViewTarget::To); |
| 146 | |
| 147 | if (has_inner_table && !to_table_engine) |
| 148 | throw Exception(ErrorCodes::INCORRECT_QUERY, |
| 149 | "You must specify where to save results of a MaterializedView query: " |
| 150 | "either ENGINE or an existing table in a TO clause"); |
| 151 | |
| 152 | if (to_table_engine && to_table_engine->primary_key) |
| 153 | storage_metadata.primary_key = KeyDescription::getKeyFromAST(to_table_engine->primary_key->ptr(), |
| 154 | storage_metadata.columns, |
| 155 | {}, |
| 156 | local_context->getGlobalContext()); |
| 157 | /// Use the database where the materialized view is created to resolve nested views |
| 158 | ContextMutablePtr mv_db_context = Context::createCopy(local_context); |
| 159 | mv_db_context->setCurrentDatabase(table_id_.database_name); |
| 160 | |
| 161 | auto select = SelectQueryDescription::getSelectQueryFromASTForMatView(query.select->clone(), query.refresh_strategy != nullptr, mv_db_context); |
| 162 | if (select.select_table_id) |
| 163 | { |
| 164 | auto select_table_dependent_views = DatabaseCatalog::instance().getDependentViews(select.select_table_id); |
| 165 | |
| 166 | auto max_materialized_views_count_for_table = getContext()->getServerSettings()[ServerSetting::max_materialized_views_count_for_table]; |
| 167 | if (max_materialized_views_count_for_table && select_table_dependent_views.size() >= max_materialized_views_count_for_table) |
| 168 | throw Exception(ErrorCodes::TOO_MANY_MATERIALIZED_VIEWS, |
| 169 | "Too many materialized views, maximum: {}", max_materialized_views_count_for_table.value); |
| 170 | } |
| 171 | |
| 172 | storage_metadata.setSelectQuery(select); |
nothing calls this directly
no test coverage detected