Repository: duckdb/duckdb
File: src/optimizer/filter_combiner.cpp (C++)

Code before:
	auto &func = expr.Cast<BoundFunctionExpression>();
	if (func.function.name != "prefix") {
		return FilterPushdownResult::NO_PUSHDOWN;
	}
	if (func.children[0]->GetExpressionClass() != ExpressionClass::BOUND_COLUMN_REF ||
	    func.children[1]->GetExpressionType() != ExpressionType::VALUE_CONSTANT) {
		// we need prefix(col, 'literal') in order to push this down
		return FilterPushdownResult::NO_PUSHDOWN;
	}
	auto &column_ref = func.children[0]->Cast<BoundColumnRefExpression>();
	auto &constant_value_expr = func.children[1]->Cast<BoundConstantExpression>();
	auto prefix_string = StringValue::Get(constant_value_expr.value);
	if (prefix_string.empty()) {
		// empty prefix - skip
		return FilterPushdownResult::NO_PUSHDOWN;
	}
	auto &column_index = column_ids[column_ref.binding.column_index];
	//! Replace prefix with a set of comparisons
	auto lower_bound = make_uniq<ConstantFilter>(ExpressionType::COMPARE_GREATERTHANOREQUALTO, Value(prefix_string));
	table_filters.PushFilter(column_index, std::move(lower_bound));
	prefix_string[prefix_string.size() - 1]++;
	if (Utf8Proc::Analyze(prefix_string.c_str(), prefix_string.size()) != UnicodeType::INVALID) {
		auto upper_bound = make_uniq<ConstantFilter>(ExpressionType::COMPARE_LESSTHAN, Value(prefix_string));
		table_filters.PushFilter(column_index, std::move(upper_bound));
	}
	return FilterPushdownResult::PUSHED_DOWN_FULLY;
}

FilterPushdownResult FilterCombiner::TryPushdownLikeFilter(TableFilterSet &table_filters,
                                                           const vector<ColumnIndex> &column_ids, Expression &expr) {
	if (expr.GetExpressionClass() != ExpressionClass::BOUND_FUNCTION) {
		return FilterPushdownResult::NO_PUSHDOWN;
	}
	auto &func = expr.Cast<BoundFunctionExpression>();
	if (func.function.name != "~~") {
		return FilterPushdownResult::NO_PUSHDOWN;
	}
	if (func.children[0]->GetExpressionClass() != ExpressionClass::BOUND_COLUMN_REF ||
	    func.children[1]->GetExpressionType() != ExpressionType::VALUE_CONSTANT) {
		// we need col LIKE 'literal' in order to generate extra filters
		return FilterPushdownResult::NO_PUSHDOWN;
	}

	//! This is a like function.
	auto &column_ref = func.children[0]->Cast<BoundColumnRefExpression>();
	auto &constant_value_expr = func.children[1]->Cast<BoundConstantExpression>();
	auto &column_index = column_ids[column_ref.binding.column_index];
	// constant value expr can sometimes be null. if so, push is not null filter, which will
	// make the filter unsatisfiable and return no results.
	if (constant_value_expr.value.IsNull()) {
		auto is_not_null = make_uniq<IsNotNullFilter>();

Review comment (suggestion):
this feels off, returning `FilterPushdownResult::PUSHED_DOWN_FULLY` when the table filter is not pushed

Code after:
	if (bindings.empty()) {
		return FilterPushdownResult::NO_PUSHDOWN;
	}
	// we can only pushdown expressions that refer to exactly one column
	for (idx_t i = 1; i < bindings.size(); i++) {
		if (bindings[i] != bindings[0]) {
			return FilterPushdownResult::NO_PUSHDOWN;
		}
	}
	if (!get.function.pushdown_expression(context, get, expr)) {
		// the scan does not support pushing down THIS expression
		return FilterPushdownResult::NO_PUSHDOWN;
	}
	// replace the BoundColumnRefExpression with a BoundReference
	auto filter_expr = expr.Copy();
	ReplaceWithBoundReference(filter_expr);

	// push the expression filter
	auto &column_ids = get.GetColumnIds();
	auto expr_filter = make_uniq<ExpressionFilter>(std::move(filter_expr));
	auto &column_index = column_ids[bindings[0].column_index];
	get.table_filters.PushFilter(column_index, std::move(expr_filter));
	return FilterPushdownResult::PUSHED_DOWN_FULLY;
}

FilterPushdownResult FilterCombiner::TryPushdownPrefixFilter(TableFilterSet &table_filters,
                                                             const vector<ColumnIndex> &column_ids, Expression &expr) {
	if (expr.GetExpressionClass() != ExpressionClass::BOUND_FUNCTION) {
		return FilterPushdownResult::NO_PUSHDOWN;
	}
	auto &func = expr.Cast<BoundFunctionExpression>();
	if (func.function.name != "prefix") {
		return FilterPushdownResult::NO_PUSHDOWN;
	}
	if (func.children[0]->GetExpressionClass() != ExpressionClass::BOUND_COLUMN_REF ||
	    func.children[1]->GetExpressionType() != ExpressionType::VALUE_CONSTANT) {
		// we need prefix(col, 'literal') in order to push this down
		return FilterPushdownResult::NO_PUSHDOWN;
	}
	auto &column_ref = func.children[0]->Cast<BoundColumnRefExpression>();
	auto &constant_value_expr = func.children[1]->Cast<BoundConstantExpression>();
	auto prefix_string = StringValue::Get(constant_value_expr.value);
	if (prefix_string.empty()) {
		// empty prefix - skip
		return FilterPushdownResult::NO_PUSHDOWN;
	}
	auto &column_index = column_ids[column_ref.binding.column_index];
	//! Replace prefix with a set of comparisons
	auto lower_bound = make_uniq<ConstantFilter>(ExpressionType::COMPARE_GREATERTHANOREQUALTO, Value(prefix_string));
	table_filters.PushFilter(column_index, std::move(lower_bound));
	if (FilterCombiner::FindNextLegalUTF8(prefix_string)) {