surrealdb_core/sql/statements/
analyze.rs1use crate::ctx::Context;
2use crate::dbs::Options;
3use crate::doc::CursorDoc;
4use crate::err::Error;
5use crate::iam::{Action, ResourceKind};
6use crate::idx::ft::FtIndex;
7use crate::idx::trees::mtree::MTreeIndex;
8use crate::idx::IndexKeyBase;
9use crate::kvs::TransactionType;
10use crate::sql::ident::Ident;
11use crate::sql::index::Index;
12use crate::sql::value::Value;
13use crate::sql::Base;
14
15use revision::revisioned;
16use serde::{Deserialize, Serialize};
17use std::fmt;
18use std::fmt::{Display, Formatter};
19
20#[revisioned(revision = 1)]
21#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
22#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
23#[non_exhaustive]
24pub enum AnalyzeStatement {
25 Idx(Ident, Ident),
26}
27
28impl AnalyzeStatement {
29 pub(crate) async fn compute(
31 &self,
32 ctx: &Context,
33 opt: &Options,
34 _doc: Option<&CursorDoc>,
35 ) -> Result<Value, Error> {
36 match self {
37 AnalyzeStatement::Idx(tb, idx) => {
38 opt.is_allowed(Action::View, ResourceKind::Index, &Base::Db)?;
40 let (ns, db) = opt.ns_db()?;
42 let ix = ctx.tx().get_tb_index(ns, db, tb, idx).await?;
43 let ikb = IndexKeyBase::new(ns, db, &ix)?;
44 let value: Value = match &ix.index {
46 Index::Search(p) => {
47 let ft =
48 FtIndex::new(ctx, opt, p.az.as_str(), ikb, p, TransactionType::Read)
49 .await?;
50 ft.statistics(ctx).await?.into()
51 }
52 Index::MTree(p) => {
53 let tx = ctx.tx();
54 let mt = MTreeIndex::new(&tx, ikb, p, TransactionType::Read).await?;
55 mt.statistics(&tx).await?.into()
56 }
57 _ => {
58 return Err(Error::FeatureNotYetImplemented {
59 feature: "Statistics on unique and non-unique indexes.".to_string(),
60 })
61 }
62 };
63 Ok(value)
65 }
66 }
67 }
68}
69
70impl Display for AnalyzeStatement {
71 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
72 match self {
73 Self::Idx(tb, idx) => write!(f, "ANALYZE INDEX {idx} ON {tb}"),
74 }
75 }
76}