Skip to content

Commit

Permalink
Merge pull request gluesql#1026 from gluesql/put-columns-into-row-struct
Browse files Browse the repository at this point in the history
Prior steps - Make data::Row struct only work in execution layer, don't expose to user via neither Payload or Store traits.
- Change Payload::Select rows to use Vec<Value>
- Replace data::Row to Vec<Value> in Store traits

Main
- Put columns into Row struct
- Remove columns from FilterContext, BlendContext
- Remove redandunt columns field uses
  • Loading branch information
panarch committed Dec 1, 2022
2 parents 075a3c4 + 5c37b7b commit b58ced5
Show file tree
Hide file tree
Showing 35 changed files with 410 additions and 480 deletions.
3 changes: 1 addition & 2 deletions cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ use {
futures::executor::block_on,
gluesql_core::{
ast::{Expr, SetExpr, Statement, ToSql, Values},
prelude::Row,
store::{GStore, GStoreMut, Store, Transaction},
},
gluesql_memory_storage::MemoryStorage,
Expand Down Expand Up @@ -96,7 +95,7 @@ pub fn dump_database(storage: SledStorage, dump_path: PathBuf) -> Result<SledSto
for rows in &rows_list {
let exprs_list = rows
.map(|result| {
result.map(|Row(values)| {
result.map(|values| {
values
.into_iter()
.map(|value| Ok(Expr::try_from(value)?))
Expand Down
45 changes: 16 additions & 29 deletions cli/src/print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ mod tests {
fn print_payload() {
use gluesql_core::{
ast::DataType,
prelude::{Payload, PayloadVariable, Row, Value},
prelude::{Payload, PayloadVariable, Value},
};

let mut print = Print::new(Vec::new(), None, Default::default());
Expand Down Expand Up @@ -361,8 +361,8 @@ mod tests {
rows: [101, 202, 301, 505, 1001]
.into_iter()
.map(Value::I64)
.map(|v| vec![v].into())
.collect::<Vec<Row>>(),
.map(|v| vec![v])
.collect::<Vec<Vec<Value>>>(),
},
"
| id |
Expand All @@ -384,32 +384,27 @@ mod tests {
Value::I64(1),
Value::Str("foo".to_owned()),
Value::Bool(true)
]
.into(),
],
vec![
Value::I64(2),
Value::Str("bar".to_owned()),
Value::Bool(false)
]
.into(),
],
vec![
Value::I64(3),
Value::Str("bas".to_owned()),
Value::Bool(false)
]
.into(),
],
vec![
Value::I64(4),
Value::Str("lim".to_owned()),
Value::Bool(true)
]
.into(),
],
vec![
Value::I64(5),
Value::Str("kim".to_owned()),
Value::Bool(true)
]
.into(),
],
],
},
"
Expand Down Expand Up @@ -477,14 +472,12 @@ mod tests {
Value::I64(1),
Value::Str("foo".to_owned()),
Value::Bool(true)
]
.into(),
],
vec![
Value::I64(2),
Value::Str("bar".to_owned()),
Value::Bool(false)
]
.into(),
],
]
},
"
Expand All @@ -508,14 +501,12 @@ id|title|valid
Value::I64(1),
Value::Str("foo".to_owned()),
Value::Bool(true)
]
.into(),
],
vec![
Value::I64(2),
Value::Str("bar".to_owned()),
Value::Bool(false)
]
.into(),
],
],
},
"
Expand All @@ -538,14 +529,12 @@ id,title,valid
Value::I64(1),
Value::Str("foo".to_owned()),
Value::Bool(true)
]
.into(),
],
vec![
Value::I64(2),
Value::Str("bar".to_owned()),
Value::Bool(false)
]
.into(),
],
],
},
"
Expand All @@ -567,14 +556,12 @@ id,title,valid
Value::I64(1),
Value::Str("foo".to_owned()),
Value::Bool(true)
]
.into(),
],
vec![
Value::I64(2),
Value::Str("bar".to_owned()),
Value::Bool(false)
]
.into(),
],
],
},
"
Expand Down
70 changes: 33 additions & 37 deletions core/src/data/row.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use {
executor::evaluate_stateless,
result::Result,
},
serde::{Deserialize, Serialize},
std::{fmt::Debug, slice::Iter, vec::IntoIter},
serde::Serialize,
std::{fmt::Debug, rc::Rc},
thiserror::Error,
};

Expand Down Expand Up @@ -37,29 +37,37 @@ enum Columns<I1, I2> {
Specified(I2),
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Row(pub Vec<Value>);
#[derive(Clone, Debug, PartialEq)]
pub struct Row {
pub columns: Rc<[String]>,
pub values: Vec<Value>,
}

impl Row {
pub fn get_value_by_index(&self, index: usize) -> Option<&Value> {
self.0.get(index)
self.values.get(index)
}

pub fn get_value(&self, columns: &[String], ident: &str) -> Option<&Value> {
columns
pub fn get_value(&self, ident: &str) -> Option<&Value> {
self.columns
.iter()
.position(|column| column == ident)
.and_then(|index| self.0.get(index))
.and_then(|index| self.values.get(index))
}

pub fn take_first_value(self) -> Result<Value> {
self.0
self.values
.into_iter()
.next()
.ok_or_else(|| RowError::ConflictOnEmptyRow.into())
}

pub fn new(column_defs: &[ColumnDef], columns: &[String], values: &[Expr]) -> Result<Self> {
pub fn new(
column_defs: &[ColumnDef],
labels: Rc<[String]>,
columns: &[String],
values: &[Expr],
) -> Result<Self> {
if !columns.is_empty() && values.len() != columns.len() {
return Err(RowError::ColumnAndValuesNotMatched.into());
} else if values.len() > column_defs.len() {
Expand All @@ -82,7 +90,7 @@ impl Row {

let column_name_value_list = columns.zip(values.iter()).collect::<Vec<(_, _)>>();

column_defs
let values = column_defs
.iter()
.map(|column_def| {
let ColumnDef {
Expand All @@ -107,8 +115,12 @@ impl Row {
}
}
})
.collect::<Result<_>>()
.map(Self)
.collect::<Result<Vec<Value>>>()?;

Ok(Row {
columns: labels,
values,
})
}

pub fn validate(&self, column_defs: &[ColumnDef]) -> Result<()> {
Expand All @@ -135,47 +147,31 @@ impl Row {
Ok(())
}

pub fn iter(&self) -> Iter<'_, Value> {
self.0.iter()
}

pub fn len(&self) -> usize {
self.0.len()
self.values.len()
}

pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}

impl IntoIterator for Row {
type Item = Value;
type IntoIter = IntoIter<Self::Item>;

fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
self.values.is_empty()
}
}

impl From<Row> for Vec<Value> {
fn from(row: Row) -> Self {
row.0
}
}

impl From<Vec<Value>> for Row {
fn from(values: Vec<Value>) -> Self {
Row(values)
row.values
}
}

#[cfg(test)]
mod tests {
use {super::Row, crate::data::Value};
use {super::Row, crate::data::Value, std::rc::Rc};

#[test]
fn len() {
let row: Row = vec![Value::Bool(true), Value::I64(100)].into();
let row = Row {
columns: Rc::from(vec!["T".to_owned()]),
values: vec![Value::Bool(true), Value::I64(100)],
};

assert_eq!(row.len(), 2);
assert!(!row.is_empty());
Expand Down
12 changes: 9 additions & 3 deletions core/src/executor/alter/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,15 @@ pub async fn create_table<T: GStore + GStoreMut>(

match source {
Some(q) => {
let (storage, rows) = async { select(&storage, q, None).await?.try_collect().await }
.await
.try_self(storage)?;
let (storage, rows) = async {
select(&storage, q, None)
.await?
.map_ok(Into::into)
.try_collect()
.await
}
.await
.try_self(storage)?;

storage.append_data(target_table_name, rows).await
}
Expand Down
25 changes: 9 additions & 16 deletions core/src/executor/context/blend_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,34 @@ use {

#[derive(Debug)]
pub enum BlendContextRow {
Single(Option<Row>),
Single(Row),
Shared(Rc<Row>),
}

#[derive(Debug)]
pub struct BlendContext<'a> {
table_alias: &'a str,
columns: Rc<[String]>,
row: BlendContextRow,
next: Option<Rc<BlendContext<'a>>>,
}

impl<'a> BlendContext<'a> {
pub fn new(
table_alias: &'a str,
columns: Rc<[String]>,
row: BlendContextRow,
next: Option<Rc<BlendContext<'a>>>,
) -> Self {
Self {
table_alias,
columns,
row,
next,
}
}

pub fn get_value(&'a self, target: &str) -> Option<&'a Value> {
let value = match &self.row {
BlendContextRow::Shared(row) => row.get_value(&self.columns, target),
BlendContextRow::Single(Some(row)) => row.get_value(&self.columns, target),
BlendContextRow::Single(None) => Some(&Value::Null),
BlendContextRow::Shared(row) => row.get_value(target),
BlendContextRow::Single(row) => row.get_value(target),
};

if value.is_some() {
Expand All @@ -55,9 +51,8 @@ impl<'a> BlendContext<'a> {
}

match &self.row {
BlendContextRow::Shared(row) => row.get_value(&self.columns, target),
BlendContextRow::Single(Some(row)) => row.get_value(&self.columns, target),
BlendContextRow::Single(None) => Some(&Value::Null),
BlendContextRow::Shared(row) => row.get_value(target),
BlendContextRow::Single(row) => row.get_value(target),
}
})();

Expand All @@ -73,9 +68,8 @@ impl<'a> BlendContext<'a> {
pub fn get_alias_values(&self, alias: &str) -> Option<Vec<Value>> {
if self.table_alias == alias {
let values = match &self.row {
BlendContextRow::Shared(row) => row.0.clone(),
BlendContextRow::Single(Some(row)) => row.0.clone(),
BlendContextRow::Single(None) => self.columns.iter().map(|_| Value::Null).collect(),
BlendContextRow::Shared(row) => row.values.clone(),
BlendContextRow::Single(row) => row.values.clone(),
};

Some(values)
Expand All @@ -88,9 +82,8 @@ impl<'a> BlendContext<'a> {

pub fn get_all_values(&'a self) -> Vec<Value> {
let values: Vec<Value> = match &self.row {
BlendContextRow::Shared(row) => row.0.clone(),
BlendContextRow::Single(Some(row)) => row.0.clone(),
BlendContextRow::Single(None) => self.columns.iter().map(|_| Value::Null).collect(),
BlendContextRow::Shared(row) => row.values.clone(),
BlendContextRow::Single(row) => row.values.clone(),
};

match &self.next {
Expand Down

0 comments on commit b58ced5

Please sign in to comment.