surrealdb_core/sql/statements/
analyze.rs

1use 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	/// Process this type returning a computed simple Value
30	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				// Allowed to run?
39				opt.is_allowed(Action::View, ResourceKind::Index, &Base::Db)?;
40				// Read the index
41				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				// Index operation dispatching
45				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				// Return the result object
64				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}