If they are defined, they can override table-level settings.
return false;
    }
    else
    {
        for (const auto & index : metadata_snapshot->getSecondaryIndices())
            if (index_wrapper_factory.get(index)->mayBenefitFromIndexForIn(left_in_operand))
                return true;
        for (const auto & projection : metadata_snapshot->getProjections())
        {
            if (projection.isPrimaryKeyColumnPossiblyWrappedInFunctions(left_in_operand))
                return true;
        }
        return isPrimaryOrMinMaxKeyColumnPossiblyWrappedInFunctions(left_in_operand, metadata_snapshot);
    }
}
using PartitionIdToMaxBlock = std::unordered_map<String, Int64>;
static void selectBestProjection(
    const MergeTreeDataSelectExecutor & reader,
    const StorageSnapshotPtr & storage_snapshot,
    const SelectQueryInfo & query_info,
    const Names & required_columns,
    ProjectionCandidate & candidate,
    ContextPtr query_context,
    std::shared_ptr<PartitionIdToMaxBlock> max_added_blocks,
    const Settings & settings,
    const MergeTreeData::DataPartsVector & parts,
    ProjectionCandidate *& selected_candidate,
    size_t & min_sum_marks)
{
    MergeTreeData::DataPartsVector projection_parts;