glaredb_core/engine/
mod.rs1pub mod query_result;
2pub mod session;
3pub mod single_user;
4
5use std::sync::Arc;
6
7use glaredb_error::Result;
8use session::Session;
9
10use crate::catalog::context::{DatabaseContext, SYSTEM_CATALOG};
11use crate::catalog::create::{
12 CreateAggregateFunctionInfo,
13 CreateScalarFunctionInfo,
14 CreateSchemaInfo,
15 CreateTableFunctionInfo,
16 OnConflict,
17};
18use crate::catalog::database::{AccessMode, Database};
19use crate::catalog::system::{DEFAULT_SCHEMA, new_system_catalog};
20use crate::catalog::{Catalog, Schema};
21use crate::extension::Extension;
22use crate::runtime::pipeline::PipelineRuntime;
23use crate::runtime::system::SystemRuntime;
24use crate::storage::storage_manager::StorageManager;
25
26#[derive(Debug)]
27pub struct Engine<P: PipelineRuntime, R: SystemRuntime> {
28 system_catalog: Arc<Database>,
29 executor: P,
30 runtime: R,
31}
32
33impl<P, R> Engine<P, R>
34where
35 P: PipelineRuntime,
36 R: SystemRuntime,
37{
38 pub fn new(executor: P, runtime: R) -> Result<Self> {
39 let system_catalog = Arc::new(Database {
40 name: SYSTEM_CATALOG.to_string(),
41 mode: AccessMode::ReadOnly,
42 catalog: Arc::new(new_system_catalog()?),
43 storage: Arc::new(StorageManager::empty()),
44 attach_info: None,
45 });
46
47 Ok(Engine {
48 system_catalog,
49 executor,
50 runtime,
51 })
52 }
53
54 pub fn new_base_database_context(&self) -> Result<DatabaseContext> {
59 DatabaseContext::new(self.system_catalog.clone())
60 }
61
62 pub fn new_session(&self) -> Result<Session<P, R>> {
64 let context = self.new_base_database_context()?;
65 Ok(Session::new(
66 context,
67 self.executor.clone(),
68 self.runtime.clone(),
69 ))
70 }
71
72 pub fn register_extension<E>(&self, _ext: E) -> Result<()>
74 where
75 E: Extension + 'static,
76 {
77 if let Some(functions) = E::FUNCTIONS {
78 let schema = self
80 .system_catalog
81 .catalog
82 .create_schema(&CreateSchemaInfo {
83 name: functions.namespace.to_string(),
84 on_conflict: OnConflict::Error,
85 })?;
86
87 for scalar in functions.scalar {
89 schema.create_scalar_function(&CreateScalarFunctionInfo {
90 name: scalar.name.to_string(),
91 implementation: scalar,
92 on_conflict: OnConflict::Error,
93 })?;
94
95 for alias in scalar.aliases {
96 schema.create_scalar_function(&CreateScalarFunctionInfo {
97 name: alias.to_string(),
98 implementation: scalar,
99 on_conflict: OnConflict::Error,
100 })?;
101 }
102 }
103
104 for agg in functions.aggregate {
106 schema.create_aggregate_function(&CreateAggregateFunctionInfo {
107 name: agg.name.to_string(),
108 implementation: agg,
109 on_conflict: OnConflict::Error,
110 })?;
111
112 for alias in agg.aliases {
113 schema.create_aggregate_function(&CreateAggregateFunctionInfo {
114 name: alias.to_string(),
115 implementation: agg,
116 on_conflict: OnConflict::Error,
117 })?;
118 }
119 }
120
121 let default_schema = self
122 .system_catalog
123 .catalog
124 .get_schema(DEFAULT_SCHEMA)?
125 .expect("default schema to exist");
126
127 for table_func in functions.table {
129 schema.create_table_function(&CreateTableFunctionInfo {
130 name: table_func.function.name.to_string(),
131 implementation: table_func.function,
132 infer_scan: None,
133 on_conflict: OnConflict::Error,
134 })?;
135
136 for alias in table_func.function.aliases {
137 schema.create_table_function(&CreateTableFunctionInfo {
138 name: alias.to_string(),
139 implementation: table_func.function,
140 infer_scan: None,
141 on_conflict: OnConflict::Error,
142 })?;
143 }
144
145 if let Some(alias_in_default) = table_func.aliases_in_default {
147 for alias in alias_in_default.aliases {
148 default_schema.create_table_function(&CreateTableFunctionInfo {
149 name: alias.to_string(),
150 implementation: table_func.function,
151 infer_scan: alias_in_default.infer_scan,
152 on_conflict: OnConflict::Error,
153 })?;
154 }
155 }
156 }
157 }
158
159 Ok(())
160 }
161}