use crate::types::{FieldId, RowId, TableId};
pub const CATALOG_TABLE_ID: TableId = 0;
pub const TEMPORARY_TABLE_ID_START: TableId = 0x8000;
pub const INFORMATION_SCHEMA_TABLE_ID_START: TableId = 0xC000;
#[inline]
pub fn is_information_schema_table(id: TableId) -> bool {
id >= INFORMATION_SCHEMA_TABLE_ID_START
}
#[inline]
pub fn is_reserved_table_id(id: TableId) -> bool {
id == CATALOG_TABLE_ID
}
#[inline]
pub fn reserved_table_id_message(id: TableId) -> String {
format!("Table ID {} is reserved for system use", id)
}
pub const ROW_ID_FIELD_ID: FieldId = 0;
pub const MVCC_CREATED_BY_FIELD_ID: FieldId = u32::MAX;
pub const MVCC_DELETED_BY_FIELD_ID: FieldId = u32::MAX - 1;
pub const FIRST_USER_FIELD_ID: FieldId = 1;
#[inline]
pub fn is_reserved_field_id(id: FieldId) -> bool {
id == ROW_ID_FIELD_ID || id == MVCC_CREATED_BY_FIELD_ID || id == MVCC_DELETED_BY_FIELD_ID
}
#[inline]
pub fn is_system_field(id: FieldId) -> bool {
id == ROW_ID_FIELD_ID || id == MVCC_CREATED_BY_FIELD_ID || id == MVCC_DELETED_BY_FIELD_ID
}
#[inline]
pub fn is_mvcc_field(id: FieldId) -> bool {
id == MVCC_CREATED_BY_FIELD_ID || id == MVCC_DELETED_BY_FIELD_ID
}
#[inline]
pub fn reserved_field_id_message(id: FieldId) -> String {
match id {
ROW_ID_FIELD_ID => "Field ID 0 is reserved for row_id".to_string(),
MVCC_CREATED_BY_FIELD_ID => {
format!("Field ID {} (u32::MAX) is reserved for MVCC created_by", id)
}
MVCC_DELETED_BY_FIELD_ID => format!(
"Field ID {} (u32::MAX - 1) is reserved for MVCC deleted_by",
id
),
_ => format!("Field ID {} is reserved for system use", id),
}
}
pub const CATALOG_NEXT_TABLE_ROW_ID: RowId = 0;
pub const CATALOG_NEXT_TXN_ROW_ID: RowId = 1;
pub const CATALOG_LAST_COMMITTED_TXN_ROW_ID: RowId = 2;
pub const CATALOG_STATE_ROW_ID: RowId = 3;
#[inline]
pub fn is_reserved_catalog_row_id(id: RowId) -> bool {
id == CATALOG_NEXT_TABLE_ROW_ID
|| id == CATALOG_NEXT_TXN_ROW_ID
|| id == CATALOG_LAST_COMMITTED_TXN_ROW_ID
|| id == CATALOG_STATE_ROW_ID
}
#[inline]
pub fn reserved_catalog_row_id_message(id: RowId) -> String {
match id {
CATALOG_NEXT_TABLE_ROW_ID => "Row ID 0 is reserved for catalog's next_table_id".to_string(),
CATALOG_NEXT_TXN_ROW_ID => "Row ID 1 is reserved for catalog's next_txn_id".to_string(),
CATALOG_LAST_COMMITTED_TXN_ROW_ID => {
"Row ID 2 is reserved for catalog's last_committed_txn_id".to_string()
}
CATALOG_STATE_ROW_ID => "Row ID 3 is reserved for catalog's catalog_state".to_string(),
_ => format!("Row ID {} is reserved in catalog table", id),
}
}
pub const CATALOG_FIELD_TABLE_META_ID: u32 = 1;
pub const CATALOG_FIELD_COL_META_ID: u32 = 10;
pub const CATALOG_FIELD_NEXT_TABLE_ID: u32 = 100;
pub const CATALOG_FIELD_NEXT_TXN_ID: u32 = 101;
pub const CATALOG_FIELD_LAST_COMMITTED_TXN_ID: u32 = 102;
pub const CATALOG_FIELD_CATALOG_STATE: u32 = 103;
pub const CATALOG_FIELD_SCHEMA_META_ID: u32 = 104;
pub const CATALOG_FIELD_MULTI_COLUMN_UNIQUE_META_ID: u32 = 105;
pub const CATALOG_FIELD_SINGLE_COLUMN_INDEX_META_ID: u32 = 109;
pub const CATALOG_FIELD_MULTI_COLUMN_INDEX_META_ID: u32 = 110;
pub const CATALOG_FIELD_TRIGGER_META_ID: u32 = 111;
pub const CATALOG_FIELD_CONSTRAINT_META_ID: u32 = 106;
pub const CATALOG_FIELD_CONSTRAINT_NAME_ID: u32 = 107;
pub const CATALOG_FIELD_CUSTOM_TYPE_META_ID: u32 = 108;
#[inline]
pub fn is_catalog_internal_field(id: u32) -> bool {
matches!(
id,
CATALOG_FIELD_TABLE_META_ID
| CATALOG_FIELD_COL_META_ID
| CATALOG_FIELD_NEXT_TABLE_ID
| CATALOG_FIELD_NEXT_TXN_ID
| CATALOG_FIELD_LAST_COMMITTED_TXN_ID
| CATALOG_FIELD_CATALOG_STATE
| CATALOG_FIELD_SCHEMA_META_ID
| CATALOG_FIELD_MULTI_COLUMN_UNIQUE_META_ID
| CATALOG_FIELD_CONSTRAINT_META_ID
| CATALOG_FIELD_CONSTRAINT_NAME_ID
| CATALOG_FIELD_CUSTOM_TYPE_META_ID
| CATALOG_FIELD_SINGLE_COLUMN_INDEX_META_ID
| CATALOG_FIELD_MULTI_COLUMN_INDEX_META_ID
| CATALOG_FIELD_TRIGGER_META_ID
)
}
pub const TXN_ID_NONE: u64 = u64::MAX;
pub const TXN_ID_AUTO_COMMIT: u64 = 1;
pub const TXN_ID_MIN_MULTI_STATEMENT: u64 = TXN_ID_AUTO_COMMIT + 1;
#[inline]
pub fn is_reserved_txn_id(id: u64) -> bool {
id == TXN_ID_NONE || id <= TXN_ID_AUTO_COMMIT
}
#[inline]
pub fn reserved_txn_id_message(id: u64) -> String {
match id {
TXN_ID_NONE => format!(
"Transaction ID {} (u64::MAX) is reserved for TXN_ID_NONE",
id
),
0 => "Transaction ID 0 is invalid".to_string(),
TXN_ID_AUTO_COMMIT => "Transaction ID 1 is reserved for TXN_ID_AUTO_COMMIT".to_string(),
_ => format!("Transaction ID {} is reserved", id),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_table_id_reservations() {
assert!(is_reserved_table_id(CATALOG_TABLE_ID));
assert!(!is_reserved_table_id(1));
assert!(!is_reserved_table_id(100));
}
#[test]
fn test_field_id_reservations() {
assert!(is_reserved_field_id(ROW_ID_FIELD_ID));
assert!(is_reserved_field_id(MVCC_CREATED_BY_FIELD_ID));
assert!(is_reserved_field_id(MVCC_DELETED_BY_FIELD_ID));
assert!(!is_reserved_field_id(FIRST_USER_FIELD_ID));
assert!(!is_reserved_field_id(100));
}
#[test]
fn test_system_field_helpers() {
assert!(is_system_field(ROW_ID_FIELD_ID));
assert!(is_system_field(MVCC_CREATED_BY_FIELD_ID));
assert!(is_system_field(MVCC_DELETED_BY_FIELD_ID));
assert!(!is_system_field(FIRST_USER_FIELD_ID));
assert!(!is_system_field(100));
assert!(!is_mvcc_field(ROW_ID_FIELD_ID));
assert!(is_mvcc_field(MVCC_CREATED_BY_FIELD_ID));
assert!(is_mvcc_field(MVCC_DELETED_BY_FIELD_ID));
assert!(!is_mvcc_field(FIRST_USER_FIELD_ID));
}
#[test]
fn test_first_user_field_id() {
assert_eq!(FIRST_USER_FIELD_ID, 1);
assert!(!is_system_field(FIRST_USER_FIELD_ID));
assert!(!is_reserved_field_id(FIRST_USER_FIELD_ID));
}
#[test]
fn test_catalog_row_id_reservations() {
assert!(is_reserved_catalog_row_id(CATALOG_NEXT_TABLE_ROW_ID));
assert!(is_reserved_catalog_row_id(CATALOG_NEXT_TXN_ROW_ID));
assert!(is_reserved_catalog_row_id(
CATALOG_LAST_COMMITTED_TXN_ROW_ID
));
assert!(is_reserved_catalog_row_id(CATALOG_STATE_ROW_ID));
assert!(!is_reserved_catalog_row_id(4));
assert!(!is_reserved_catalog_row_id(100));
}
#[test]
fn test_txn_id_reservations() {
assert!(is_reserved_txn_id(TXN_ID_NONE));
assert!(is_reserved_txn_id(0));
assert!(is_reserved_txn_id(TXN_ID_AUTO_COMMIT));
assert!(!is_reserved_txn_id(TXN_ID_MIN_MULTI_STATEMENT));
assert!(!is_reserved_txn_id(100));
}
#[test]
fn test_catalog_internal_fields() {
assert!(is_catalog_internal_field(CATALOG_FIELD_TABLE_META_ID));
assert!(is_catalog_internal_field(CATALOG_FIELD_COL_META_ID));
assert!(is_catalog_internal_field(CATALOG_FIELD_NEXT_TABLE_ID));
assert!(is_catalog_internal_field(CATALOG_FIELD_NEXT_TXN_ID));
assert!(is_catalog_internal_field(
CATALOG_FIELD_LAST_COMMITTED_TXN_ID
));
assert!(is_catalog_internal_field(CATALOG_FIELD_CATALOG_STATE));
assert!(is_catalog_internal_field(CATALOG_FIELD_SCHEMA_META_ID));
assert!(is_catalog_internal_field(
CATALOG_FIELD_MULTI_COLUMN_UNIQUE_META_ID
));
assert!(is_catalog_internal_field(CATALOG_FIELD_CONSTRAINT_META_ID));
assert!(is_catalog_internal_field(CATALOG_FIELD_CONSTRAINT_NAME_ID));
assert!(is_catalog_internal_field(CATALOG_FIELD_CUSTOM_TYPE_META_ID));
assert!(is_catalog_internal_field(CATALOG_FIELD_TRIGGER_META_ID));
assert!(!is_catalog_internal_field(2));
assert!(!is_catalog_internal_field(200));
}
}