class DropTableAnalyzer {

    private static final Logger LOGGER = LogManager.getLogger(DropTableAnalyzer.class);

    private final Schemas schemas;
    private final ClusterService clusterService;

    DropTableAnalyzer(ClusterService clusterService, Schemas schemas) {
        this.clusterService = clusterService;
        this.schemas = schemas;
    }

    public AnalyzedDropTable<DocTableInfo> analyze(DropTable<?> node, CoordinatorSessionSettings sessionSettings) {
        return analyze(node.table().getName(), node.dropIfExists(), sessionSettings);
    }

    public AnalyzedDropTable<BlobTableInfo> analyze(DropBlobTable<?> node, CoordinatorSessionSettings sessionSettings) {
        List<String> parts = node.table().getName().getParts();
        if (parts.size() != 1 && !parts.get(0).equals(BlobSchemaInfo.NAME)) {
            throw new IllegalArgumentException("No blob tables in schema `" + parts.get(0) + "`");
        } else {
            QualifiedName name = new QualifiedName(
                List.of(BlobSchemaInfo.NAME, node.table().getName().getSuffix()));
            return analyze(name, node.ignoreNonExistentTable(), sessionSettings);
        }
    }

    private <T extends TableInfo> AnalyzedDropTable<T> analyze(QualifiedName name,
                                                               boolean dropIfExists,
                                                               CoordinatorSessionSettings sessionSettings) {<FILL_FUNCTION_BODY>}
}

        T tableInfo;
        RelationName tableName;
        boolean maybeCorrupt = false;
        try {
            tableInfo = schemas.findRelation(
                name,
                Operation.DROP,
                sessionSettings.sessionUser(),
                sessionSettings.searchPath()
            );
            tableName = tableInfo.ident();
        } catch (SchemaUnknownException | RelationUnknown e) {
            tableName = RelationName.of(name, sessionSettings.searchPath().currentSchema());
            var metadata = clusterService.state().metadata();
            var indexNameOrAlias = tableName.indexNameOrAlias();

            if (metadata.hasIndex(indexNameOrAlias) || metadata.templates().containsKey(indexNameOrAlias)) {
                tableInfo = null;
                maybeCorrupt = true;
            } else if (dropIfExists) {
                tableInfo = null;
            } else {
                throw e;
            }
        } catch (OperationOnInaccessibleRelationException e) {
            throw e;
        } catch (Throwable t) {
            if (!sessionSettings.sessionUser().isSuperUser()) {
                throw t;
            }
            tableInfo = null;
            maybeCorrupt = true;
            tableName = RelationName.of(name, sessionSettings.searchPath().currentSchema());
            LOGGER.info(
                "Unexpected error resolving table during DROP TABLE operation on {}. " +
                "Proceeding with operation as table schema may be corrupt (error={})",
                tableName,
                t
            );
        }
        return new AnalyzedDropTable<>(tableInfo, dropIfExists, tableName, maybeCorrupt);
    
<no_super_class>