surrealdb_sql/statements/
analyze.rs

1use crate::ctx::Context;
2use crate::dbs::Options;
3use crate::dbs::Transaction;
4use crate::doc::CursorDoc;
5use crate::err::Error;
6use crate::iam::{Action, ResourceKind};
7use crate::ident::Ident;
8use crate::idx::ft::FtIndex;
9use crate::idx::trees::mtree::MTreeIndex;
10use crate::idx::trees::store::TreeStoreType;
11use crate::idx::IndexKeyBase;
12use crate::index::Index;
13use crate::value::Value;
14use crate::Base;
15use derive::Store;
16use revision::revisioned;
17use serde::{Deserialize, Serialize};
18use std::fmt;
19use std::fmt::{Display, Formatter};
20
21#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Store, Hash)]
22#[revisioned(revision = 1)]
23pub enum AnalyzeStatement {
24	Idx(Ident, Ident),
25}
26
27impl AnalyzeStatement {
28	/// Process this type returning a computed simple Value
29	pub(crate) async fn compute(
30		&self,
31		_ctx: &Context<'_>,
32		opt: &Options,
33		txn: &Transaction,
34		_doc: Option<&CursorDoc<'_>>,
35	) -> Result<Value, Error> {
36		match self {
37			AnalyzeStatement::Idx(tb, idx) => {
38				// Allowed to run?
39				opt.is_allowed(Action::View, ResourceKind::Index, &Base::Db)?;
40				// Read the index
41				let ix = txn
42					.lock()
43					.await
44					.get_and_cache_tb_index(opt.ns(), opt.db(), tb.as_str(), idx.as_str())
45					.await?;
46				let ikb = IndexKeyBase::new(opt, &ix);
47
48				// Index operation dispatching
49				let value: Value = match &ix.index {
50					Index::Search(p) => {
51						let ft =
52							FtIndex::new(opt, txn, p.az.as_str(), ikb, p, TreeStoreType::Traversal)
53								.await?;
54						ft.statistics(txn).await?.into()
55					}
56					Index::MTree(p) => {
57						let mut tx = txn.lock().await;
58						let mt = MTreeIndex::new(&mut tx, ikb, p, TreeStoreType::Traversal).await?;
59						mt.statistics(&mut tx).await?.into()
60					}
61					_ => {
62						return Err(Error::FeatureNotYetImplemented {
63							feature: "Statistics on unique and non-unique indexes.".to_string(),
64						})
65					}
66				};
67				// Return the result object
68				Ok(value)
69			}
70		}
71	}
72}
73
74impl Display for AnalyzeStatement {
75	fn fmt(&self, f: &mut Formatter) -> fmt::Result {
76		match self {
77			Self::Idx(tb, idx) => write!(f, "ANALYZE INDEX {idx} ON {tb}"),
78		}
79	}
80}