spacetimedb/sql/
parser.rs

1use crate::db::datastore::locking_tx_datastore::state_view::StateView;
2use crate::db::datastore::locking_tx_datastore::MutTxId;
3use crate::sql::ast::SchemaViewer;
4use spacetimedb_expr::check::parse_and_type_sub;
5use spacetimedb_expr::expr::ProjectName;
6use spacetimedb_lib::db::auth::StAccess;
7use spacetimedb_lib::db::raw_def::v9::RawRowLevelSecurityDefV9;
8use spacetimedb_lib::identity::AuthCtx;
9use spacetimedb_schema::schema::RowLevelSecuritySchema;
10
11pub struct RowLevelExpr {
12    pub sql: ProjectName,
13    pub def: RowLevelSecuritySchema,
14}
15
16impl RowLevelExpr {
17    pub fn build_row_level_expr(
18        tx: &mut MutTxId,
19        auth_ctx: &AuthCtx,
20        rls: &RawRowLevelSecurityDefV9,
21    ) -> anyhow::Result<Self> {
22        let (sql, _) = parse_and_type_sub(&rls.sql, &SchemaViewer::new(tx, auth_ctx), auth_ctx)?;
23        let table_id = sql.return_table_id().unwrap();
24        let schema = tx.schema_for_table(table_id)?;
25
26        match schema.table_access {
27            StAccess::Private => {
28                anyhow::bail!(
29                    "Cannot define RLS rule on private table: {}. \
30                        Please make table public if you wish to restrict access using RLS.",
31                    schema.table_name
32                )
33            }
34            StAccess::Public => Ok(Self {
35                def: RowLevelSecuritySchema {
36                    table_id,
37                    sql: rls.sql.clone(),
38                },
39                sql,
40            }),
41        }
42    }
43}