class CreateTableAsAnalyzer {

    private final CreateTableStatementAnalyzer createTableStatementAnalyzer;
    private final InsertAnalyzer insertAnalyzer;
    private final RelationAnalyzer relationAnalyzer;

    public CreateTableAsAnalyzer(CreateTableStatementAnalyzer createTableStatementAnalyzer,
                                 InsertAnalyzer insertAnalyzer,
                                 RelationAnalyzer relationAnalyzer) {

        this.createTableStatementAnalyzer = createTableStatementAnalyzer;
        this.insertAnalyzer = insertAnalyzer;
        this.relationAnalyzer = relationAnalyzer;
    }

    public AnalyzedCreateTableAs analyze(CreateTableAs<Expression> createTableAs,
                                         ParamTypeHints paramTypeHints,
                                         CoordinatorTxnCtx txnCtx) {<FILL_FUNCTION_BODY>}
}


        RelationName relationName = RelationName.of(
            createTableAs.name().getName(),
            txnCtx.sessionSettings().searchPath().currentSchema());

        relationName.ensureValidForRelationCreation();

        AnalyzedRelation analyzedSourceQuery = relationAnalyzer.analyze(
            createTableAs.query(),
            new StatementAnalysisContext(paramTypeHints, Operation.READ, txnCtx));

        List<TableElement<Expression>> tableElements =
            Lists.map(analyzedSourceQuery.outputs(), Symbols::toColumnDefinition);

        CreateTable<Expression> createTable = new CreateTable<Expression>(
            createTableAs.name(),
            tableElements,
            Optional.empty(),
            Optional.empty(),
            GenericProperties.empty(),
            false);

        // This is only a preliminary analysis to to have the source available for privilege checks.
        // It will be analyzed again with the target columns from the target table once
        // the table has been created.
        AnalyzedRelation sourceRelation = relationAnalyzer.analyze(
            createTableAs.query(),
            new StatementAnalysisContext(paramTypeHints, Operation.READ, txnCtx)
        );

        //postponing the analysis of the insert statement, since the table has not been created yet.
        Supplier<AnalyzedInsertStatement> postponedInsertAnalysis = () -> {
            Insert<Expression> insert = new Insert<Expression>(
                createTableAs.name(),
                createTableAs.query(),
                Collections.emptyList(),
                Collections.emptyList(),
                Insert.DuplicateKeyContext.none());

            return insertAnalyzer.analyze(insert, paramTypeHints, txnCtx);
        };

        return new AnalyzedCreateTableAs(
            createTableStatementAnalyzer.analyze(createTable, paramTypeHints, txnCtx),
            sourceRelation,
            postponedInsertAnalysis
        );
    
<no_super_class>