use crate::base::{
database::{Column, TableOperationError, TableOperationResult},
scalar::{Scalar, ScalarExt},
};
use core::cmp::Ordering;
pub(crate) fn compare_indexes_by_columns<S: Scalar>(
order_by: &[Column<S>],
i: usize,
j: usize,
) -> Ordering {
order_by
.iter()
.map(|col| match col {
Column::Boolean(col) => col[i].cmp(&col[j]),
Column::Uint8(col) => col[i].cmp(&col[j]),
Column::TinyInt(col) => col[i].cmp(&col[j]),
Column::SmallInt(col) => col[i].cmp(&col[j]),
Column::Int(col) => col[i].cmp(&col[j]),
Column::BigInt(col) | Column::TimestampTZ(_, _, col) => col[i].cmp(&col[j]),
Column::Int128(col) => col[i].cmp(&col[j]),
Column::Decimal75(_, _, col) => col[i].signed_cmp(&col[j]),
Column::Scalar(col) => col[i].cmp(&col[j]),
Column::VarChar((col, _)) => col[i].cmp(col[j]),
Column::VarBinary((col, _)) => col[i].cmp(col[j]),
})
.find(|&ord| ord != Ordering::Equal)
.unwrap_or(Ordering::Equal)
}
pub(crate) fn compare_single_row_of_tables<S: Scalar>(
left: &[Column<S>],
right: &[Column<S>],
left_row_index: usize,
right_row_index: usize,
) -> TableOperationResult<Ordering> {
assert_eq!(left.len(), right.len());
for (left_col, right_col) in left.iter().zip(right.iter()) {
if left_col.column_type() != right_col.column_type() {
return Err(TableOperationError::JoinIncompatibleTypes {
left_type: left_col.column_type(),
right_type: right_col.column_type(),
});
}
let ordering = match (left_col, right_col) {
(Column::Boolean(left_col), Column::Boolean(right_col)) => {
left_col[left_row_index].cmp(&right_col[right_row_index])
}
(Column::Uint8(left_col), Column::Uint8(right_col)) => {
left_col[left_row_index].cmp(&right_col[right_row_index])
}
(Column::TinyInt(left_col), Column::TinyInt(right_col)) => {
left_col[left_row_index].cmp(&right_col[right_row_index])
}
(Column::SmallInt(left_col), Column::SmallInt(right_col)) => {
left_col[left_row_index].cmp(&right_col[right_row_index])
}
(Column::Int(left_col), Column::Int(right_col)) => {
left_col[left_row_index].cmp(&right_col[right_row_index])
}
(Column::BigInt(left_col), Column::BigInt(right_col))
| (Column::TimestampTZ(_, _, left_col), Column::TimestampTZ(_, _, right_col)) => {
left_col[left_row_index].cmp(&right_col[right_row_index])
}
(Column::Int128(left_col), Column::Int128(right_col)) => {
left_col[left_row_index].cmp(&right_col[right_row_index])
}
(Column::Decimal75(_, _, left_col), Column::Decimal75(_, _, right_col)) => {
left_col[left_row_index].signed_cmp(&right_col[right_row_index])
}
(Column::Scalar(left_col), Column::Scalar(right_col)) => {
left_col[left_row_index].cmp(&right_col[right_row_index])
}
(Column::VarChar((left_col, _)), Column::VarChar((right_col, _))) => {
left_col[left_row_index].cmp(right_col[right_row_index])
}
_ => unreachable!(),
};
if ordering != Ordering::Equal {
return Ok(ordering);
}
}
Ok(Ordering::Equal)
}