1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
use reblessive::tree::Stk;
use super::IgnoreError;
use crate::ctx::FrozenContext;
use crate::dbs::{Options, Statement};
use crate::doc::Document;
use crate::val::Value;
impl Document {
pub(crate) async fn create(
&mut self,
stk: &mut Stk,
ctx: &FrozenContext,
opt: &Options,
stm: &Statement<'_>,
) -> Result<Value, IgnoreError> {
// SECURITY (GHSA-2v9j): confine record users to their own tenant. The
// read path enforces this at the scan operators, but writes perform no
// scan, so the gate must be applied explicitly here.
self.check_record_user_access(opt)?;
// Ensure we can write to the table at all
self.check_permissions_quick_create(ctx, opt)?;
// Reject writes to read-only view tables (after the permission gate)
self.check_table_not_view(opt)?;
// Ensure any input data is computed
self.compute_input_data(stk, ctx, opt, stm).await?;
// Set the specified record content
self.process_record_data(stk, ctx, opt).await?;
// Generate a new record id if necessary
self.generate_record_id(stk, ctx, opt).await?;
// Ensure we can store this type of record
self.check_table_type_create()?;
// Ensure all special fields are valid
self.check_data_fields()?;
// Set the default record field values
self.default_record_data()?;
// Process the field schema for the table
self.process_table_fields(stk, ctx, opt, stm).await?;
// Clean up table fields and NONE values
self.cleanup_table_fields()?;
// Check table permissions after create. A predicate naming a COMPUTED
// field is evaluated against that field's value, materialised on a scratch
// copy so the derived value never reaches storage.
self.check_create_permissions(stk, ctx, opt, &self.current).await?;
// Store the document and index data
self.store_record_data(ctx, stm).await?;
self.store_index_data(stk, ctx, opt).await?;
// Materialise the computed fields the record's observers read: they are
// stripped before storage, so events, live queries, changefeeds and the
// output projection would otherwise see the record without them.
self.materialise_observed_fields(stk, ctx, opt).await?;
// Process additional table operations
self.process_table_references(stk, ctx, opt).await?;
self.process_table_views(stk, ctx, opt, super::Action::Create).await?;
self.process_table_events(stk, ctx, opt, super::Action::Create).await?;
self.process_table_lives(stk, ctx, opt, super::Action::Create).await?;
self.process_changefeeds(ctx, opt).await?;
// Check table permissions for output
self.check_select_permissions(stk, ctx, opt, &self.current).await?;
// Process the projected output document
self.output_write(stk, ctx, opt, stm.output(), stm).await
}
}