Skip to content

Commit f3dfbef

Browse files
wszhdshysKKould
andauthored
feat: support for Values (#286)
* Values are now supported by creating separate plans and changing aliases * Modified the method of determining the type of column in values to support automatic conversion of the maximum type. Added tests for values * fmt * temp_table_name added to represent the data source * Improve the logic * chore: codefmt --------- Co-authored-by: Kould <kould2333@gmail.com>
1 parent 13dc38b commit f3dfbef

File tree

4 files changed

+154
-22
lines changed

4 files changed

+154
-22
lines changed

src/binder/select.rs

Lines changed: 68 additions & 7 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;
@@ -59,6 +61,7 @@ impl<'a: 'b, 'b, T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'
5961
left,
6062
right,
6163
} => self.bind_set_operation(op, set_quantifier, left, right),
64+
SetExpr::Values(values) => self.bind_temp_values(&values.rows),
6265
expr => {
6366
return Err(DatabaseError::UnsupportedStmt(format!(
6467
"query body: {:?}",
@@ -156,6 +159,64 @@ impl<'a: 'b, 'b, T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'
156159
Ok(plan)
157160
}
158161

162+
fn bind_temp_values(
163+
&mut self,
164+
expr_rows: &Vec<Vec<Expr>>,
165+
) -> Result<LogicalPlan, DatabaseError> {
166+
let values_len = expr_rows[0].len();
167+
168+
let mut inferred_types: Vec<Option<LogicalType>> = vec![None; values_len];
169+
let mut rows = Vec::with_capacity(expr_rows.len());
170+
171+
for expr_row in expr_rows.iter() {
172+
if expr_row.len() != values_len {
173+
return Err(DatabaseError::ValuesLenMismatch(expr_row.len(), values_len));
174+
}
175+
176+
let mut row = Vec::with_capacity(values_len);
177+
178+
for (col_index, expr) in expr_row.iter().enumerate() {
179+
let mut expression = self.bind_expr(expr)?;
180+
ConstantCalculator.visit(&mut expression)?;
181+
182+
if let Constant(value) = expression {
183+
let value_type = value.logical_type();
184+
185+
inferred_types[col_index] = match &inferred_types[col_index] {
186+
Some(existing) => {
187+
Some(LogicalType::max_logical_type(existing, &value_type)?)
188+
}
189+
None => Some(value_type),
190+
};
191+
192+
row.push(value);
193+
} else {
194+
return Err(DatabaseError::ColumnsEmpty);
195+
}
196+
}
197+
198+
rows.push(row);
199+
}
200+
201+
let value_name = self.context.temp_table();
202+
let column_refs: Vec<ColumnRef> = inferred_types
203+
.into_iter()
204+
.enumerate()
205+
.map(|(col_index, typ)| {
206+
let typ = typ.ok_or(DatabaseError::InvalidType)?;
207+
let mut column_ref = ColumnCatalog::new(
208+
col_index.to_string(),
209+
false,
210+
ColumnDesc::new(typ, None, false, None)?,
211+
);
212+
column_ref.set_ref_table(value_name.clone(), ColumnId::default(), true);
213+
Ok(ColumnRef(Arc::new(column_ref)))
214+
})
215+
.collect::<Result<_, DatabaseError>>()?;
216+
217+
Ok(self.bind_values(rows, Arc::new(column_refs)))
218+
}
219+
159220
fn bind_set_cast(
160221
&self,
161222
mut left_plan: LogicalPlan,
@@ -356,9 +417,9 @@ impl<'a: 'b, 'b, T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'
356417
));
357418
}
358419
let table_alias = Arc::new(name.value.to_lowercase());
420+
let table = tables.pop().unwrap_or_else(|| self.context.temp_table());
359421

360-
plan =
361-
self.bind_alias(plan, alias_column, table_alias, tables.pop().unwrap())?;
422+
plan = self.bind_alias(plan, alias_column, table_alias, table)?;
362423
}
363424
plan
364425
}

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

tests/slt/values.slt

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
query I
2+
SELECT * FROM (VALUES (1), (2), (3));
3+
----
4+
1
5+
2
6+
3
7+
8+
query IT
9+
SELECT * FROM (VALUES (1, 'a'), (2, 'b'), (3, 'c'));
10+
----
11+
1 a
12+
2 b
13+
3 c
14+
15+
query II
16+
SELECT * FROM (VALUES (1, 2)) AS t(x, y);
17+
----
18+
1 2
19+
20+
query I rowsort
21+
SELECT * FROM (VALUES (4), (5), (6)) LIMIT 2;
22+
----
23+
4
24+
5
25+
26+
query I
27+
SELECT * FROM (VALUES (1), (NULL), (3));
28+
----
29+
1
30+
null
31+
3
32+
33+
statement ok
34+
CREATE TABLE t (x INT PRIMARY KEY);
35+
36+
statement ok
37+
INSERT INTO t VALUES (1), (2), (3);
38+
39+
query I rowsort
40+
SELECT * FROM t JOIN (VALUES (2), (3)) AS v(x) ON t.x = v.x;
41+
----
42+
2
43+
3
44+
45+
query I
46+
SELECT * FROM (VALUES (1), (2.5));
47+
----
48+
1.0
49+
2.5
50+
51+
query I rowsort
52+
SELECT * FROM (VALUES (1), (2)) UNION SELECT * FROM (VALUES (2), (3));
53+
----
54+
1
55+
2
56+
3
57+
58+
query I
59+
SELECT * FROM (VALUES (3), (1), (2)) AS v(x) ORDER BY v.x ASC;
60+
----
61+
1
62+
2
63+
3
64+
65+
query I
66+
SELECT t.y FROM (VALUES (10, 20), (30, 40)) AS t(x, y);
67+
----
68+
20
69+
40

0 commit comments

Comments
 (0)