MCPcopy Create free account
hub / github.com/NodeDB-Lab/nodedb / plan_create_index

Function plan_create_index

nodedb-sql/src/planner/index_ddl/create.rs:20–68  ·  view source on GitHub ↗

Plan a `CREATE INDEX` statement. Supports: - `CREATE [UNIQUE] INDEX [IF NOT EXISTS] [name] ON table (col [COLLATE coll])` - `COLLATE NOCASE` / `COLLATE CI` / `COLLATE CASE_INSENSITIVE` on the indexed column → `case_insensitive = true`. Multi-column indexes, expression indexes, and predicate (`WHERE`) indexes are rejected with a typed error rather than silently dropped.

(ci: &ast::CreateIndex)

Source from the content-addressed store, hash-verified

18/// Multi-column indexes, expression indexes, and predicate (`WHERE`) indexes
19/// are rejected with a typed error rather than silently dropped.
20pub fn plan_create_index(ci: &ast::CreateIndex) -> Result<SqlPlan> {
21 let collection =
22 normalize_object_name_checked(&ci.table_name).map_err(|_| SqlError::Parse {
23 detail: "CREATE INDEX: missing or schema-qualified table name".into(),
24 })?;
25
26 let index_name = match ci.name.as_ref() {
27 Some(n) => Some(normalize_object_name_checked(n)?),
28 None => None,
29 };
30
31 if ci.columns.is_empty() {
32 return Err(SqlError::Parse {
33 detail: "CREATE INDEX: at least one column is required".into(),
34 });
35 }
36 if ci.columns.len() > 1 {
37 return Err(SqlError::Unsupported {
38 detail: "CREATE INDEX: multi-column indexes are not supported".into(),
39 });
40 }
41
42 let col = &ci.columns[0];
43 let (field_expr, case_insensitive) = strip_collate(&col.column.expr);
44 let field = match field_expr {
45 ast::Expr::Identifier(ident) => normalize_ident(ident),
46 ast::Expr::CompoundIdentifier(parts) if parts.len() == 1 => normalize_ident(&parts[0]),
47 other => {
48 return Err(SqlError::Unsupported {
49 detail: format!("CREATE INDEX: expression indexes are not supported: {other}"),
50 });
51 }
52 };
53
54 if ci.predicate.is_some() {
55 return Err(SqlError::Unsupported {
56 detail: "CREATE INDEX: partial (WHERE) indexes are not supported".into(),
57 });
58 }
59
60 Ok(SqlPlan::CreateIndex {
61 index_name,
62 collection,
63 field,
64 unique: ci.unique,
65 if_not_exists: ci.if_not_exists,
66 case_insensitive,
67 })
68}
69
70/// Strip a `COLLATE <name>` wrapper from `expr` and return the inner
71/// expression together with whether the collation is a recognised

Callers 2

plan_statementsFunction · 0.85
planFunction · 0.85

Calls 6

strip_collateFunction · 0.85
normalize_identFunction · 0.85
as_refMethod · 0.45
is_emptyMethod · 0.45
lenMethod · 0.45

Tested by

no test coverage detected