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 | |
8 | namespace duckdb { |
9 | |
10 | IndexBinder::IndexBinder(Binder &binder, ClientContext &context, optional_ptr<TableCatalogEntry> table, |
11 | optional_ptr<CreateIndexInfo> info) |
12 | : ExpressionBinder(binder, context), table(table), info(info) { |
13 | } |
14 | |
15 | BindResult 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 | |
52 | string IndexBinder::UnsupportedAggregateMessage() { |
53 | return "aggregate functions are not allowed in index expressions" ; |
54 | } |
55 | |
56 | } // namespace duckdb |
57 | |