Skip to content

Commit 74cc11b

Browse files
committed
adds point scan ABIs to rust bindings, and uses more point scans internally
1 parent 907d67e commit 74cc11b

20 files changed

Lines changed: 971 additions & 342 deletions

File tree

crates/bindings-macro/src/table.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,11 +466,13 @@ impl ValidatedIndex<'_> {
466466
};
467467
let vis = superize_vis(vis);
468468

469+
let num_cols = cols.len();
469470
let mut decl = quote! {
470471
#typeck_direct_index
471472

472473
#vis struct #index_ident;
473474
impl spacetimedb::table::Index for #index_ident {
475+
const NUM_COLS_INDEXED: usize = #num_cols;
474476
fn index_id() -> spacetimedb::table::IndexId {
475477
static INDEX_ID: std::sync::OnceLock<spacetimedb::table::IndexId> = std::sync::OnceLock::new();
476478
*INDEX_ID.get_or_init(|| {

crates/bindings-sys/src/lib.rs

Lines changed: 140 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -588,7 +588,6 @@ pub mod raw {
588588
///
589589
/// - `out_ptr` is NULL or `out` is not in bounds of WASM memory.
590590
pub fn identity(out_ptr: *mut u8);
591-
592591
}
593592

594593
// See comment on previous `extern "C"` block re: ABI version.
@@ -775,6 +774,86 @@ pub mod raw {
775774
) -> u16;
776775
}
777776

777+
#[link(wasm_import_module = "spacetime_10.4")]
778+
extern "C" {
779+
/// Finds all rows in the index identified by `index_id`,
780+
/// according to `point = point_ptr[..point_len]` in WASM memory.
781+
///
782+
/// The index itself has a schema/type.
783+
/// Matching defined by first BSATN-decoding `point` to that `AlgebraicType`
784+
/// and then comparing the decoded `point` to the keys in the index
785+
/// using `Ord for AlgebraicValue`.
786+
/// to the keys in the index.
787+
/// The `point` is BSATN-decoded to that `AlgebraicType`.
788+
/// A match happens when `Ordering::Equal` is returned from `fn cmp`.
789+
/// This occurs exactly when the row's BSATN-encoding
790+
/// is equal to the encoding of the `AlgebraicValue`.
791+
///
792+
/// This ABI is not limited to single column indices.
793+
/// Multi-column indices can be queried by providing
794+
/// a BSATN-encoded `ProductValue`
795+
/// that is typed at the `ProductType` of the index.
796+
///
797+
/// The relevant table for the index is found implicitly via the `index_id`,
798+
/// which is unique for the module.
799+
///
800+
/// On success, the iterator handle is written to the `out` pointer.
801+
/// This handle can be advanced by [`row_iter_bsatn_advance`].
802+
///
803+
/// # Traps
804+
///
805+
/// Traps if:
806+
/// - `point_ptr` is NULL or `point` is not in bounds of WASM memory.
807+
/// - `out` is NULL or `out[..size_of::<RowIter>()]` is not in bounds of WASM memory.
808+
///
809+
/// # Errors
810+
///
811+
/// Returns an error:
812+
///
813+
/// - `NOT_IN_TRANSACTION`, when called outside of a transaction.
814+
/// - `NO_SUCH_INDEX`, when `index_id` is not a known ID of an index.
815+
/// - `WRONG_INDEX_ALGO` if the index is not a range-scan compatible index.
816+
/// - `BSATN_DECODE_ERROR`, when `point` cannot be decoded to an `AlgebraicValue`
817+
/// typed at the index's key type (`AlgebraicType`).
818+
pub fn datastore_index_scan_point_bsatn(
819+
index_id: IndexId,
820+
point_ptr: *const u8, // AlgebraicValue
821+
point_len: usize,
822+
out: *mut RowIter,
823+
) -> u16;
824+
825+
/// Deletes all rows found in the index identified by `index_id`,
826+
/// according to `point = point_ptr[..point_len]` in WASM memory.
827+
///
828+
/// This syscall will delete all the rows found by
829+
/// [`datastore_index_scan_point_bsatn`] with the same arguments passed.
830+
/// See `datastore_index_scan_point_bsatn` for details.
831+
///
832+
/// The number of rows deleted is written to the WASM pointer `out`.
833+
///
834+
/// # Traps
835+
///
836+
/// Traps if:
837+
/// - `point_ptr` is NULL or `point` is not in bounds of WASM memory.
838+
/// - `out` is NULL or `out[..size_of::<u32>()]` is not in bounds of WASM memory.
839+
///
840+
/// # Errors
841+
///
842+
/// Returns an error:
843+
///
844+
/// - `NOT_IN_TRANSACTION`, when called outside of a transaction.
845+
/// - `NO_SUCH_INDEX`, when `index_id` is not a known ID of an index.
846+
/// - `WRONG_INDEX_ALGO` if the index is not a range-compatible index.
847+
/// - `BSATN_DECODE_ERROR`, when `point` cannot be decoded to an `AlgebraicValue`
848+
/// typed at the index's key type (`AlgebraicType`).
849+
pub fn datastore_delete_by_index_scan_point_bsatn(
850+
index_id: IndexId,
851+
point_ptr: *const u8, // AlgebraicValue
852+
point_len: usize,
853+
out: *mut u32,
854+
) -> u16;
855+
}
856+
778857
/// What strategy does the database index use?
779858
///
780859
/// See also: <https://www.postgresql.org/docs/current/sql-createindex.html>
@@ -1095,6 +1174,44 @@ pub fn datastore_table_scan_bsatn(table_id: TableId) -> Result<RowIter> {
10951174
Ok(RowIter { raw })
10961175
}
10971176

1177+
/// Finds all rows in the index identified by `index_id`,
1178+
/// according to the `point.
1179+
///
1180+
/// The index itself has a schema/type.
1181+
/// Matching defined by first BSATN-decoding `point` to that `AlgebraicType`
1182+
/// and then comparing the decoded `point` to the keys in the index
1183+
/// using `Ord for AlgebraicValue`.
1184+
/// to the keys in the index.
1185+
/// The `point` is BSATN-decoded to that `AlgebraicType`.
1186+
/// A match happens when `Ordering::Equal` is returned from `fn cmp`.
1187+
/// This occurs exactly when the row's BSATN-encoding
1188+
/// is equal to the encoding of the `AlgebraicValue`.
1189+
///
1190+
/// This ABI is not limited to single column indices.
1191+
/// Multi-column indices can be queried by providing
1192+
/// a BSATN-encoded `ProductValue`
1193+
/// that is typed at the `ProductType` of the index.
1194+
///
1195+
/// The relevant table for the index is found implicitly via the `index_id`,
1196+
/// which is unique for the module.
1197+
///
1198+
/// On success, the iterator handle is written to the `out` pointer.
1199+
/// This handle can be advanced by [`RowIter::read`].
1200+
///
1201+
/// # Errors
1202+
///
1203+
/// Returns an error:
1204+
///
1205+
/// - `NOT_IN_TRANSACTION`, when called outside of a transaction.
1206+
/// - `NO_SUCH_INDEX`, when `index_id` is not a known ID of an index.
1207+
/// - `WRONG_INDEX_ALGO` if the index is not a range-compatible index.
1208+
/// - `BSATN_DECODE_ERROR`, when `point` cannot be decoded to an `AlgebraicValue`
1209+
/// typed at the index's key type (`AlgebraicType`).
1210+
pub fn datastore_index_scan_point_bsatn(index_id: IndexId, point: &[u8]) -> Result<RowIter> {
1211+
let raw = unsafe { call(|out| raw::datastore_index_scan_point_bsatn(index_id, point.as_ptr(), point.len(), out))? };
1212+
Ok(RowIter { raw })
1213+
}
1214+
10981215
/// Finds all rows in the index identified by `index_id`,
10991216
/// according to the `prefix`, `rstart`, and `rend`.
11001217
///
@@ -1169,6 +1286,28 @@ pub fn datastore_index_scan_range_bsatn(
11691286
Ok(RowIter { raw })
11701287
}
11711288

1289+
/// Deletes all rows found in the index identified by `index_id`,
1290+
/// according to the `point.
1291+
///
1292+
/// This syscall will delete all the rows found by
1293+
/// [`datastore_index_scan_point_bsatn`] with the same arguments passed.
1294+
/// See `datastore_index_scan_point_bsatn` for details.
1295+
///
1296+
/// The number of rows deleted is returned on success.
1297+
///
1298+
/// # Errors
1299+
///
1300+
/// Returns an error:
1301+
///
1302+
/// - `NOT_IN_TRANSACTION`, when called outside of a transaction.
1303+
/// - `NO_SUCH_INDEX`, when `index_id` is not a known ID of an index.
1304+
/// - `WRONG_INDEX_ALGO` if the index is not a range-compatible index.
1305+
/// - `BSATN_DECODE_ERROR`, when `point` cannot be decoded to an `AlgebraicValue`
1306+
/// typed at the index's key type (`AlgebraicType`).
1307+
pub fn datastore_delete_by_index_scan_point_bsatn(index_id: IndexId, point: &[u8]) -> Result<u32> {
1308+
unsafe { call(|out| raw::datastore_delete_by_index_scan_point_bsatn(index_id, point.as_ptr(), point.len(), out)) }
1309+
}
1310+
11721311
/// Deletes all rows found in the index identified by `index_id`,
11731312
/// according to the `prefix`, `rstart`, and `rend`.
11741313
///

0 commit comments

Comments
 (0)