proof_of_sql/base/database/table_utility.rs
1//! Utility functions for creating [`Table`]s and [`Column`]s.
2//! These functions are primarily intended for use in tests.
3//!
4//! # Example
5//! ```
6//! use bumpalo::Bump;
7//! use proof_of_sql::base::{database::table_utility::*};
8//! # use proof_of_sql::base::scalar::MontScalar;
9//! # pub type MyScalar = MontScalar<ark_curve25519::FrConfig>;
10//! let alloc = Bump::new();
11//! let result = table::<MyScalar>([
12//! borrowed_bigint("a", [1, 2, 3], &alloc),
13//! borrowed_boolean("b", [true, false, true], &alloc),
14//! borrowed_int128("c", [1, 2, 3], &alloc),
15//! borrowed_scalar("d", [1, 2, 3], &alloc),
16//! borrowed_varchar("e", ["a", "b", "c"], &alloc),
17//! borrowed_decimal75("f", 12, 1, [1, 2, 3], &alloc),
18//! ]);
19//! ```
20use super::{Column, Table, TableOptions};
21use crate::base::{
22 posql_time::{PoSQLTimeUnit, PoSQLTimeZone},
23 scalar::Scalar,
24};
25use alloc::{string::String, vec::Vec};
26use bumpalo::Bump;
27use sqlparser::ast::Ident;
28
29/// Creates an [`Table`] from a list of `(Ident, Column)` pairs.
30/// This is a convenience wrapper around [`Table::try_from_iter`] primarily for use in tests and
31/// intended to be used along with the other methods in this module (e.g. [`borrowed_bigint`],
32/// [`borrowed_boolean`], etc).
33/// The function will panic under a variety of conditions. See [`Table::try_from_iter`] for more details.
34///
35/// # Example
36/// ```
37/// use bumpalo::Bump;
38/// use proof_of_sql::base::{database::table_utility::*};
39/// # use proof_of_sql::base::scalar::MontScalar;
40/// # pub type MyScalar = MontScalar<ark_curve25519::FrConfig>;
41/// let alloc = Bump::new();
42/// let result = table::<MyScalar>([
43/// borrowed_bigint("a", [1, 2, 3], &alloc),
44/// borrowed_boolean("b", [true, false, true], &alloc),
45/// borrowed_int128("c", [1, 2, 3], &alloc),
46/// borrowed_scalar("d", [1, 2, 3], &alloc),
47/// borrowed_varchar("e", ["a", "b", "c"], &alloc),
48/// borrowed_decimal75("f", 12, 1, [1, 2, 3], &alloc),
49/// ]);
50/// ```
51///
52/// # Panics
53/// - Panics if converting the iterator into an `Table<'a, S>` fails.
54pub fn table<'a, S: Scalar>(
55 iter: impl IntoIterator<Item = (Ident, Column<'a, S>)>,
56) -> Table<'a, S> {
57 Table::try_from_iter(iter).unwrap()
58}
59
60/// Creates an [`Table`] from a list of `(Ident, Column)` pairs with a specified row count.
61/// The main reason for this function is to allow for creating tables that may potentially have
62/// no columns, but still have a specified row count.
63///
64/// # Panics
65/// - Panics if the given row count doesn't match the number of rows in any of the columns.
66pub fn table_with_row_count<'a, S: Scalar>(
67 iter: impl IntoIterator<Item = (Ident, Column<'a, S>)>,
68 row_count: usize,
69) -> Table<'a, S> {
70 Table::try_from_iter_with_options(iter, TableOptions::new(Some(row_count))).unwrap()
71}
72
73/// Creates a (Ident, `Column`) pair for a uint8 column.
74/// This is primarily intended for use in conjunction with [`table`].
75/// # Example
76/// ```
77/// use bumpalo::Bump;
78/// use proof_of_sql::base::{database::table_utility::*};
79/// # use proof_of_sql::base::scalar::MontScalar;
80/// # pub type MyScalar = MontScalar<ark_curve25519::FrConfig>;
81/// let alloc = Bump::new();
82/// let result = table::<MyScalar>([
83/// borrowed_uint8("a", [1_u8, 2, 3], &alloc),
84/// ]);
85///```
86pub fn borrowed_uint8<S: Scalar>(
87 name: impl Into<Ident>,
88 data: impl IntoIterator<Item = impl Into<u8>>,
89 alloc: &Bump,
90) -> (Ident, Column<'_, S>) {
91 let transformed_data: Vec<u8> = data.into_iter().map(Into::into).collect();
92 let alloc_data = alloc.alloc_slice_copy(&transformed_data);
93 (name.into(), Column::Uint8(alloc_data))
94}
95
96/// Creates a (Ident, `Column`) pair for a tinyint column.
97/// This is primarily intended for use in conjunction with [`table`].
98/// # Example
99/// ```
100/// use bumpalo::Bump;
101/// use proof_of_sql::base::{database::table_utility::*};
102/// # use proof_of_sql::base::scalar::MontScalar;
103/// # pub type MyScalar = MontScalar<ark_curve25519::FrConfig>;
104/// let alloc = Bump::new();
105/// let result = table::<MyScalar>([
106/// borrowed_tinyint("a", [1_i8, 2, 3], &alloc),
107/// ]);
108///```
109pub fn borrowed_tinyint<S: Scalar>(
110 name: impl Into<Ident>,
111 data: impl IntoIterator<Item = impl Into<i8>>,
112 alloc: &Bump,
113) -> (Ident, Column<'_, S>) {
114 let transformed_data: Vec<i8> = data.into_iter().map(Into::into).collect();
115 let alloc_data = alloc.alloc_slice_copy(&transformed_data);
116 (name.into(), Column::TinyInt(alloc_data))
117}
118
119/// Creates a `(Ident, Column)` pair for a smallint column.
120/// This is primarily intended for use in conjunction with [`table`].
121///
122/// # Example
123/// ```rust
124/// use bumpalo::Bump;
125/// use proof_of_sql::base::{database::table_utility::*};
126/// # use proof_of_sql::base::scalar::MontScalar;
127/// # pub type MyScalar = MontScalar<ark_curve25519::FrConfig>;
128/// let alloc = Bump::new();
129/// let result = table::<MyScalar>([
130/// borrowed_smallint("a", [1_i16, 2, 3], &alloc),
131/// ]);
132/// ```
133///
134pub fn borrowed_smallint<S: Scalar>(
135 name: impl Into<Ident>,
136 data: impl IntoIterator<Item = impl Into<i16>>,
137 alloc: &Bump,
138) -> (Ident, Column<'_, S>) {
139 let transformed_data: Vec<i16> = data.into_iter().map(Into::into).collect();
140 let alloc_data = alloc.alloc_slice_copy(&transformed_data);
141 (name.into(), Column::SmallInt(alloc_data))
142}
143
144/// Creates a `(Ident, Column)` pair for an int column.
145/// This is primarily intended for use in conjunction with [`table`].
146///
147/// # Example
148/// ```rust
149/// use bumpalo::Bump;
150/// use proof_of_sql::base::{database::table_utility::*};
151/// # use proof_of_sql::base::scalar::MontScalar;
152/// # pub type MyScalar = MontScalar<ark_curve25519::FrConfig>;
153/// let alloc = Bump::new();
154/// let result = table::<MyScalar>([
155/// borrowed_int("a", [1, 2, 3], &alloc),
156/// ]);
157/// ```
158///
159pub fn borrowed_int<S: Scalar>(
160 name: impl Into<Ident>,
161 data: impl IntoIterator<Item = impl Into<i32>>,
162 alloc: &Bump,
163) -> (Ident, Column<'_, S>) {
164 let transformed_data: Vec<i32> = data.into_iter().map(Into::into).collect();
165 let alloc_data = alloc.alloc_slice_copy(&transformed_data);
166 (name.into(), Column::Int(alloc_data))
167}
168
169/// Creates a `(Ident, Column)` pair for a bigint column.
170/// This is primarily intended for use in conjunction with [`table`].
171///
172/// # Example
173/// ```rust
174/// use bumpalo::Bump;
175/// use proof_of_sql::base::{database::table_utility::*};
176/// # use proof_of_sql::base::scalar::MontScalar;
177/// # pub type MyScalar = MontScalar<ark_curve25519::FrConfig>;
178/// let alloc = Bump::new();
179/// let result = table::<MyScalar>([
180/// borrowed_bigint("a", [1, 2, 3], &alloc),
181/// ]);
182/// ```
183pub fn borrowed_bigint<S: Scalar>(
184 name: impl Into<Ident>,
185 data: impl IntoIterator<Item = impl Into<i64>>,
186 alloc: &Bump,
187) -> (Ident, Column<'_, S>) {
188 let transformed_data: Vec<i64> = data.into_iter().map(Into::into).collect();
189 let alloc_data = alloc.alloc_slice_copy(&transformed_data);
190 (name.into(), Column::BigInt(alloc_data))
191}
192
193/// Creates a `(Ident, Column)` pair for a boolean column.
194/// This is primarily intended for use in conjunction with [`table`].
195///
196/// # Example
197/// ```
198/// use bumpalo::Bump;
199/// use proof_of_sql::base::{database::table_utility::*};
200/// # use proof_of_sql::base::scalar::MontScalar;
201/// # pub type MyScalar = MontScalar<ark_curve25519::FrConfig>;
202/// let alloc = Bump::new();
203/// let result = table::<MyScalar>([
204/// borrowed_boolean("a", [true, false, true], &alloc),
205/// ]);
206/// ```
207pub fn borrowed_boolean<S: Scalar>(
208 name: impl Into<Ident>,
209 data: impl IntoIterator<Item = impl Into<bool>>,
210 alloc: &Bump,
211) -> (Ident, Column<'_, S>) {
212 let transformed_data: Vec<bool> = data.into_iter().map(Into::into).collect();
213 let alloc_data = alloc.alloc_slice_copy(&transformed_data);
214 (name.into(), Column::Boolean(alloc_data))
215}
216
217/// Creates a `(Ident, Column)` pair for an int128 column.
218/// This is primarily intended for use in conjunction with [`table`].
219///
220/// # Example
221/// ```
222/// use bumpalo::Bump;
223/// use proof_of_sql::base::{database::table_utility::*};
224/// # use proof_of_sql::base::scalar::MontScalar;
225/// # pub type MyScalar = MontScalar<ark_curve25519::FrConfig>;
226/// let alloc = Bump::new();
227/// let result = table::<MyScalar>([
228/// borrowed_int128("a", [1, 2, 3], &alloc),
229/// ]);
230/// ```
231pub fn borrowed_int128<S: Scalar>(
232 name: impl Into<Ident>,
233 data: impl IntoIterator<Item = impl Into<i128>>,
234 alloc: &Bump,
235) -> (Ident, Column<'_, S>) {
236 let transformed_data: Vec<i128> = data.into_iter().map(Into::into).collect();
237 let alloc_data = alloc.alloc_slice_copy(&transformed_data);
238 (name.into(), Column::Int128(alloc_data))
239}
240
241/// Creates a `(Ident, Column)` pair for a scalar column.
242/// This is primarily intended for use in conjunction with [`table`].
243///
244/// # Example
245/// ```
246/// use bumpalo::Bump;
247/// use proof_of_sql::base::{database::table_utility::*};
248/// # use proof_of_sql::base::scalar::MontScalar;
249/// # pub type MyScalar = MontScalar<ark_curve25519::FrConfig>;
250/// let alloc = Bump::new();
251/// let result = table::<MyScalar>([
252/// borrowed_scalar("a", [1, 2, 3], &alloc),
253/// ]);
254/// ```
255pub fn borrowed_scalar<S: Scalar>(
256 name: impl Into<Ident>,
257 data: impl IntoIterator<Item = impl Into<S>>,
258 alloc: &Bump,
259) -> (Ident, Column<'_, S>) {
260 let transformed_data: Vec<S> = data.into_iter().map(Into::into).collect();
261 let alloc_data = alloc.alloc_slice_copy(&transformed_data);
262 (name.into(), Column::Scalar(alloc_data))
263}
264
265/// Creates a `(Ident, Column)` pair for a varchar column.
266/// This is primarily intended for use in conjunction with [`table`].
267/// # Example
268/// ```
269/// use bumpalo::Bump;
270/// use proof_of_sql::base::{database::table_utility::*};
271/// # use proof_of_sql::base::scalar::MontScalar;
272/// # pub type MyScalar = MontScalar<ark_curve25519::FrConfig>;
273/// let alloc = Bump::new();
274/// let result = table::<MyScalar>([
275/// borrowed_varchar("a", ["a", "b", "c"], &alloc),
276/// ]);
277/// ```
278pub fn borrowed_varchar<'a, S: Scalar>(
279 name: impl Into<Ident>,
280 data: impl IntoIterator<Item = impl Into<String>>,
281 alloc: &'a Bump,
282) -> (Ident, Column<'a, S>) {
283 let strings: Vec<&'a str> = data
284 .into_iter()
285 .map(|item| {
286 let string = item.into();
287 alloc.alloc_str(&string) as &'a str
288 })
289 .collect();
290 let alloc_strings = alloc.alloc_slice_clone(&strings);
291 let scalars: Vec<S> = strings.iter().map(|s| (*s).into()).collect();
292 let alloc_scalars = alloc.alloc_slice_copy(&scalars);
293 (name.into(), Column::VarChar((alloc_strings, alloc_scalars)))
294}
295
296/// Creates a `(Ident, Column)` pair for a decimal75 column.
297/// This is primarily intended for use in conjunction with [`table`].
298/// # Example
299/// ```
300/// use bumpalo::Bump;
301/// use proof_of_sql::base::{database::table_utility::*};
302/// # use proof_of_sql::base::scalar::MontScalar;
303/// # pub type MyScalar = MontScalar<ark_curve25519::FrConfig>;
304/// let alloc = Bump::new();
305/// let result = table::<MyScalar>([
306/// borrowed_decimal75("a", 12, 1, [1, 2, 3], &alloc),
307/// ]);
308/// ```
309/// # Panics
310/// - Panics if creating the `Precision` from the specified precision value fails.
311pub fn borrowed_decimal75<S: Scalar>(
312 name: impl Into<Ident>,
313 precision: u8,
314 scale: i8,
315 data: impl IntoIterator<Item = impl Into<S>>,
316 alloc: &Bump,
317) -> (Ident, Column<'_, S>) {
318 let transformed_data: Vec<S> = data.into_iter().map(Into::into).collect();
319 let alloc_data = alloc.alloc_slice_copy(&transformed_data);
320 (
321 name.into(),
322 Column::Decimal75(
323 crate::base::math::decimal::Precision::new(precision).unwrap(),
324 scale,
325 alloc_data,
326 ),
327 )
328}
329
330/// Creates a `(Ident, Column)` pair for a timestamp column.
331/// This is primarily intended for use in conjunction with [`table`].
332///
333/// # Parameters
334/// - `name`: The name of the column.
335/// - `time_unit`: The time unit of the timestamps.
336/// - `timezone`: The timezone for the timestamps.
337/// - `data`: The data for the column, provided as an iterator over `i64` values representing time since the unix epoch.
338/// - `alloc`: The bump allocator to use for allocating the column data.
339///
340/// # Example
341/// ```
342/// use bumpalo::Bump;
343/// use proof_of_sql::base::{database::table_utility::*, posql_time::{PoSQLTimeZone, PoSQLTimeUnit}};
344/// # use proof_of_sql::base::scalar::MontScalar;
345/// # pub type MyScalar = MontScalar<ark_curve25519::FrConfig>;
346///
347/// let alloc = Bump::new();
348/// let result = table::<MyScalar>([
349/// borrowed_timestamptz("event_time", PoSQLTimeUnit::Second, PoSQLTimeZone::utc(), vec![1625072400, 1625076000, 1625079600], &alloc),
350/// ]);
351/// ```
352pub fn borrowed_timestamptz<S: Scalar>(
353 name: impl Into<Ident>,
354 time_unit: PoSQLTimeUnit,
355 timezone: PoSQLTimeZone,
356 data: impl IntoIterator<Item = i64>,
357 alloc: &Bump,
358) -> (Ident, Column<'_, S>) {
359 let vec_data: Vec<i64> = data.into_iter().collect();
360 let alloc_data = alloc.alloc_slice_copy(&vec_data);
361 (
362 name.into(),
363 Column::TimestampTZ(time_unit, timezone, alloc_data),
364 )
365}