1#include "duckdb/planner/expression_binder/index_binder.hpp"
2
3#include "duckdb/parser/parsed_data/create_index_info.hpp"
4#include "duckdb/parser/expression/columnref_expression.hpp"
5#include "duckdb/planner/expression/bound_columnref_expression.hpp"
6#include "duckdb/planner/column_binding.hpp"
7
8namespace duckdb {
9
10IndexBinder::IndexBinder(Binder &binder, ClientContext &context, optional_ptr<TableCatalogEntry> table,
11 optional_ptr<CreateIndexInfo> info)
12 : ExpressionBinder(binder, context), table(table), info(info) {
13}
14
15BindResult IndexBinder::BindExpression(unique_ptr<ParsedExpression> &expr_ptr, idx_t depth, bool root_expression) {
16 auto &expr = *expr_ptr;
17 switch (expr.expression_class) {
18 case ExpressionClass::WINDOW:
19 return BindResult("window functions are not allowed in index expressions");
20 case ExpressionClass::SUBQUERY:
21 return BindResult("cannot use subquery in index expressions");
22 case ExpressionClass::COLUMN_REF: {
23 if (table) {
24 // WAL replay
25 // we assume that the parsed expressions have qualified column names
26 // and that the columns exist in the table
27 auto &col_ref = expr.Cast<ColumnRefExpression>();
28 auto col_idx = table->GetColumnIndex(name&: col_ref.column_names.back());
29 auto col_type = table->GetColumn(idx: col_idx).GetType();
30
31 // find the col_idx in the index.column_ids
32 auto col_id_idx = DConstants::INVALID_INDEX;
33 for (idx_t i = 0; i < info->column_ids.size(); i++) {
34 if (col_idx.index == info->column_ids[i]) {
35 col_id_idx = i;
36 }
37 }
38
39 if (col_id_idx == DConstants::INVALID_INDEX) {
40 throw InternalException("failed to replay CREATE INDEX statement - column id not found");
41 }
42 return BindResult(
43 make_uniq<BoundColumnRefExpression>(args: col_ref.GetColumnName(), args&: col_type, args: ColumnBinding(0, col_id_idx)));
44 }
45 return ExpressionBinder::BindExpression(expr_ptr, depth);
46 }
47 default:
48 return ExpressionBinder::BindExpression(expr_ptr, depth);
49 }
50}
51
52string IndexBinder::UnsupportedAggregateMessage() {
53 return "aggregate functions are not allowed in index expressions";
54}
55
56} // namespace duckdb
57