Skip to content

Commit a08398e

Browse files
committed
Values are now supported by creating separate plans and changing aliases
1 parent 13dc38b commit a08398e

5 files changed

Lines changed: 93 additions & 33 deletions

File tree

src/binder/delete.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,12 @@ impl<T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'_, '_, T, A>
4040
let mut plan = TableScanOperator::build(table_name.clone(), table, true);
4141

4242
if let Some(alias_idents) = alias_idents {
43-
plan =
44-
self.bind_alias(plan, alias_idents, table_alias.unwrap(), table_name.clone())?;
43+
plan = self.bind_alias(
44+
plan,
45+
alias_idents,
46+
table_alias.unwrap(),
47+
Some(table_name.clone()),
48+
)?;
4549
}
4650

4751
if let Some(predicate) = selection {

src/binder/insert.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,7 @@ impl<T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'_, '_, T, A>
109109
))
110110
}
111111

112-
pub(crate) fn bind_values(
113-
&mut self,
114-
rows: Vec<Vec<DataValue>>,
115-
schema_ref: SchemaRef,
116-
) -> LogicalPlan {
112+
fn bind_values(&mut self, rows: Vec<Vec<DataValue>>, schema_ref: SchemaRef) -> LogicalPlan {
117113
LogicalPlan::new(
118114
Operator::Values(ValuesOperator { rows, schema_ref }),
119115
Childrens::None,

src/binder/select.rs

Lines changed: 69 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
use std::borrow::Borrow;
2-
use std::collections::HashSet;
3-
use std::sync::Arc;
4-
51
use crate::{
62
expression::ScalarExpression,
73
planner::{
@@ -13,15 +9,21 @@ use crate::{
139
},
1410
types::value::DataValue,
1511
};
12+
use std::borrow::Borrow;
13+
use std::collections::HashSet;
14+
use std::sync::Arc;
1615

1716
use super::{
1817
lower_case_name, lower_ident, Binder, BinderContext, QueryBindStep, Source, SubQueryType,
1918
};
2019

21-
use crate::catalog::{ColumnCatalog, ColumnRef, ColumnSummary, TableName};
20+
use crate::catalog::{ColumnCatalog, ColumnDesc, ColumnRef, ColumnSummary, TableName};
2221
use crate::errors::DatabaseError;
2322
use crate::execution::dql::join::joins_nullable;
2423
use crate::expression::agg::AggKind;
24+
use crate::expression::simplify::ConstantCalculator;
25+
use crate::expression::visitor_mut::VisitorMut;
26+
use crate::expression::ScalarExpression::Constant;
2527
use crate::expression::{AliasType, BinaryOperator};
2628
use crate::planner::operator::aggregate::AggregateOperator;
2729
use crate::planner::operator::except::ExceptOperator;
@@ -30,6 +32,8 @@ use crate::planner::operator::insert::InsertOperator;
3032
use crate::planner::operator::join::JoinCondition;
3133
use crate::planner::operator::sort::{SortField, SortOperator};
3234
use crate::planner::operator::union::UnionOperator;
35+
use crate::planner::operator::values::ValuesOperator;
36+
use crate::planner::operator::Operator::Values;
3337
use crate::planner::{Childrens, LogicalPlan, SchemaOutput};
3438
use crate::storage::Transaction;
3539
use crate::types::tuple::{Schema, SchemaRef};
@@ -59,6 +63,7 @@ impl<'a: 'b, 'b, T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'
5963
left,
6064
right,
6165
} => self.bind_set_operation(op, set_quantifier, left, right),
66+
SetExpr::Values(values) => self.bind_temp_values(&values.rows),
6267
expr => {
6368
return Err(DatabaseError::UnsupportedStmt(format!(
6469
"query body: {:?}",
@@ -156,6 +161,58 @@ impl<'a: 'b, 'b, T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'
156161
Ok(plan)
157162
}
158163

164+
fn bind_temp_values(
165+
&mut self,
166+
expr_rows: &Vec<Vec<Expr>>,
167+
) -> Result<LogicalPlan, DatabaseError> {
168+
if expr_rows.is_empty() {
169+
return Err(DatabaseError::ColumnsEmpty);
170+
}
171+
172+
let values_len = expr_rows[0].len();
173+
let mut column_ref = Vec::with_capacity(values_len);
174+
175+
let rows: Result<Vec<_>, _> = expr_rows
176+
.iter()
177+
.enumerate()
178+
.map(|(row_index, expr_row)| {
179+
if expr_row.len() != values_len {
180+
return Err(DatabaseError::ValuesLenMismatch(expr_row.len(), values_len));
181+
}
182+
183+
let mut row = Vec::with_capacity(values_len);
184+
for (col_index, expr) in expr_row.iter().enumerate() {
185+
let mut expression = self.bind_expr(expr)?;
186+
ConstantCalculator.visit(&mut expression)?;
187+
188+
if row_index == 0 {
189+
column_ref.push(ColumnRef(Arc::new(ColumnCatalog::new(
190+
col_index.to_string(),
191+
false,
192+
ColumnDesc::new(expression.return_type().clone(), None, false, None)?,
193+
))));
194+
}
195+
196+
if let Constant(value) = expression {
197+
row.push(value);
198+
} else {
199+
return Err(DatabaseError::InvalidType);
200+
}
201+
}
202+
Ok(row)
203+
})
204+
.collect();
205+
let rows = rows?;
206+
207+
Ok(LogicalPlan::new(
208+
Values(ValuesOperator {
209+
rows,
210+
schema_ref: Arc::new(column_ref),
211+
}),
212+
Childrens::None,
213+
))
214+
}
215+
159216
fn bind_set_cast(
160217
&self,
161218
mut left_plan: LogicalPlan,
@@ -357,8 +414,7 @@ impl<'a: 'b, 'b, T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'
357414
}
358415
let table_alias = Arc::new(name.value.to_lowercase());
359416

360-
plan =
361-
self.bind_alias(plan, alias_column, table_alias, tables.pop().unwrap())?;
417+
plan = self.bind_alias(plan, alias_column, table_alias, tables.pop())?;
362418
}
363419
plan
364420
}
@@ -380,7 +436,7 @@ impl<'a: 'b, 'b, T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'
380436
plan,
381437
alias_column,
382438
table_alias.clone().unwrap(),
383-
table_name.clone(),
439+
Some(table_name.clone()),
384440
)?;
385441
}
386442

@@ -403,7 +459,7 @@ impl<'a: 'b, 'b, T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'
403459
mut plan: LogicalPlan,
404460
alias_column: &[Ident],
405461
table_alias: TableName,
406-
table_name: TableName,
462+
table_name: Option<TableName>,
407463
) -> Result<LogicalPlan, DatabaseError> {
408464
let input_schema = plan.output_schema();
409465
if !alias_column.is_empty() && alias_column.len() != input_schema.len() {
@@ -446,7 +502,9 @@ impl<'a: 'b, 'b, T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'
446502
);
447503
alias_exprs.push(alias_column_expr);
448504
}
449-
self.context.add_table_alias(table_alias, table_name);
505+
if let Some(table_name) = table_name {
506+
self.context.add_table_alias(table_alias, table_name);
507+
}
450508
self.bind_project(plan, alias_exprs)
451509
}
452510

@@ -476,7 +534,7 @@ impl<'a: 'b, 'b, T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'
476534
};
477535

478536
if let Some(idents) = alias_idents {
479-
plan = self.bind_alias(plan, idents, table_alias.unwrap(), table_name.clone())?;
537+
plan = self.bind_alias(plan, idents, table_alias.unwrap(), Some(table_name.clone()))?;
480538
}
481539
Ok(plan)
482540
}

src/types/mod.rs

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -407,8 +407,9 @@ impl TryFrom<sqlparser::ast::DataType> for LogicalType {
407407
sqlparser::ast::DataType::String | sqlparser::ast::DataType::Text => {
408408
Ok(LogicalType::Varchar(None, CharLengthUnits::Characters))
409409
}
410-
sqlparser::ast::DataType::Float(_) => Ok(LogicalType::Float),
411-
sqlparser::ast::DataType::Real => Ok(LogicalType::Float),
410+
sqlparser::ast::DataType::Float(_) | sqlparser::ast::DataType::Real => {
411+
Ok(LogicalType::Float)
412+
}
412413
sqlparser::ast::DataType::Double | sqlparser::ast::DataType::DoublePrecision => {
413414
Ok(LogicalType::Double)
414415
}
@@ -438,7 +439,7 @@ impl TryFrom<sqlparser::ast::DataType> for LogicalType {
438439
Some(0..5) | None => (),
439440
_ => {
440441
return Err(DatabaseError::UnsupportedStmt(
441-
"time's precision must less than 5".to_string(),
442+
"time's precision must be less than 5".to_string(),
442443
))
443444
}
444445
}
@@ -455,7 +456,7 @@ impl TryFrom<sqlparser::ast::DataType> for LogicalType {
455456
Some(3 | 6 | 9) | None => (),
456457
_ => {
457458
return Err(DatabaseError::UnsupportedStmt(
458-
"timestamp's precision must 3,6,9".to_string(),
459+
"timestamp's precision must be 3,6,9".to_string(),
459460
))
460461
}
461462
}
@@ -464,15 +465,15 @@ impl TryFrom<sqlparser::ast::DataType> for LogicalType {
464465
}
465466
Ok(LogicalType::TimeStamp(precision, zone))
466467
}
467-
sqlparser::ast::DataType::Decimal(info) | sqlparser::ast::DataType::Dec(info) => {
468-
match info {
469-
ExactNumberInfo::None => Ok(Self::Decimal(None, None)),
470-
ExactNumberInfo::Precision(p) => Ok(Self::Decimal(Some(p as u8), None)),
471-
ExactNumberInfo::PrecisionAndScale(p, s) => {
472-
Ok(Self::Decimal(Some(p as u8), Some(s as u8)))
473-
}
468+
sqlparser::ast::DataType::Decimal(info)
469+
| sqlparser::ast::DataType::Dec(info)
470+
| sqlparser::ast::DataType::Numeric(info) => match info {
471+
ExactNumberInfo::None => Ok(Self::Decimal(None, None)),
472+
ExactNumberInfo::Precision(p) => Ok(Self::Decimal(Some(p as u8), None)),
473+
ExactNumberInfo::PrecisionAndScale(p, s) => {
474+
Ok(Self::Decimal(Some(p as u8), Some(s as u8)))
474475
}
475-
}
476+
},
476477
other => Err(DatabaseError::UnsupportedStmt(format!(
477478
"unsupported data type: {other}"
478479
))),

tests/slt/crdb/join.slt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,10 @@ null 43
174174
# query
175175
# SELECT * FROM onecolumn AS a NATURAL FULL OUTER JOIN othercolumn AS b ORDER BY x
176176

177-
# TODO: Join Values
178-
# query
179-
# SELECT * FROM (SELECT x FROM onecolumn ORDER BY x DESC) NATURAL JOIN (VALUES (42)) AS v(x) LIMIT 1
177+
query II
178+
SELECT * FROM (SELECT x FROM onecolumn ORDER BY x DESC) NATURAL JOIN (VALUES (42)) AS v(x) LIMIT 1
179+
----
180+
null 42
180181

181182
statement ok
182183
drop table if exists empty

0 commit comments

Comments
 (0)