diff --git a/src/binder/create_table.rs b/src/binder/create_table.rs index 93755bdc..2208d0ba 100644 --- a/src/binder/create_table.rs +++ b/src/binder/create_table.rs @@ -36,8 +36,8 @@ impl<'a, T: Transaction> Binder<'a, T> { let mut set = HashSet::new(); for col in columns.iter() { let col_name = &col.name.value; - if !set.insert(col_name.clone()) { - return Err(DatabaseError::AmbiguousColumn(col_name.to_string())); + if !set.insert(col_name) { + return Err(DatabaseError::DuplicateColumn(col_name.clone())); } if !is_valid_identifier(col_name) { return Err(DatabaseError::InvalidColumn( @@ -122,7 +122,9 @@ impl<'a, T: Transaction> Binder<'a, T> { DataValue::clone(&value).cast(&column_desc.column_datatype)?; column_desc.default = Some(Arc::new(cast_value)); } else { - unreachable!("'default' only for constant") + return Err(DatabaseError::UnsupportedStmt( + "'default' only for constant".to_string(), + )); } } _ => todo!(), diff --git a/src/binder/expr.rs b/src/binder/expr.rs index dca6e527..d50354f7 100644 --- a/src/binder/expr.rs +++ b/src/binder/expr.rs @@ -9,7 +9,7 @@ use sqlparser::ast::{ use std::slice; use std::sync::Arc; -use super::{lower_ident, Binder}; +use super::{lower_ident, Binder, QueryBindStep}; use crate::expression::function::{FunctionSummary, ScalarFunction}; use crate::expression::{AliasType, ScalarExpression}; use crate::storage::Transaction; @@ -27,6 +27,14 @@ macro_rules! try_alias { }; } +macro_rules! try_default { + ($table_name:expr, $column_name:expr) => { + if let (None, "default") = ($table_name, $column_name.as_str()) { + return Ok(ScalarExpression::Empty); + } + }; +} + impl<'a, T: Transaction> Binder<'a, T> { pub(crate) fn bind_expr(&mut self, expr: &Expr) -> Result { match expr { @@ -102,17 +110,21 @@ impl<'a, T: Transaction> Binder<'a, T> { )); } let column = sub_query_schema[0].clone(); - let mut alias_column = ColumnCatalog::clone(&column); - alias_column.set_table_name(self.context.temp_table()); - self.context.sub_query(sub_query); - Ok(ScalarExpression::Alias { - expr: Box::new(ScalarExpression::ColumnRef(column)), - alias: AliasType::Expr(Box::new(ScalarExpression::ColumnRef(Arc::new( - alias_column, - )))), - }) + if self.context.is_step(&QueryBindStep::Where) { + let mut alias_column = ColumnCatalog::clone(&column); + alias_column.set_table_name(self.context.temp_table()); + + Ok(ScalarExpression::Alias { + expr: Box::new(ScalarExpression::ColumnRef(column)), + alias: AliasType::Expr(Box::new(ScalarExpression::ColumnRef(Arc::new( + alias_column, + )))), + }) + } else { + Ok(ScalarExpression::ColumnRef(column)) + } } Expr::Tuple(exprs) => { let mut bond_exprs = Vec::with_capacity(exprs.len()); @@ -215,8 +227,11 @@ impl<'a, T: Transaction> Binder<'a, T> { )) } }; + try_alias!(self.context, column_name); + if self.context.allow_default { + try_default!(&table_name, column_name); + } if let Some(table) = table_name.or(bind_table_name) { - try_alias!(self.context, column_name); let table_catalog = self .context .table(Arc::new(table.clone())) @@ -227,10 +242,9 @@ impl<'a, T: Transaction> Binder<'a, T> { .ok_or_else(|| DatabaseError::NotFound("column", column_name))?; Ok(ScalarExpression::ColumnRef(column_catalog.clone())) } else { - try_alias!(self.context, column_name); // handle col syntax let mut got_column = None; - for (table_catalog, _) in self.context.bind_table.values() { + for table_catalog in self.context.bind_table.values() { if let Some(column_catalog) = table_catalog.get_column_by_name(&column_name) { got_column = Some(column_catalog); } diff --git a/src/binder/insert.rs b/src/binder/insert.rs index 4231bbc8..95e44399 100644 --- a/src/binder/insert.rs +++ b/src/binder/insert.rs @@ -20,6 +20,8 @@ impl<'a, T: Transaction> Binder<'a, T> { expr_rows: &Vec>, is_overwrite: bool, ) -> Result { + // FIXME: Make it better to detect the current BindStep + self.context.allow_default = true; let table_name = Arc::new(lower_case_name(name)?); if let Some(table) = self.context.table(table_name.clone()) { @@ -43,7 +45,7 @@ impl<'a, T: Transaction> Binder<'a, T> { Some(table_name.to_string()), )? { ScalarExpression::ColumnRef(catalog) => columns.push(catalog), - _ => unreachable!(), + _ => return Err(DatabaseError::UnsupportedStmt(ident.to_string())), } } if values_len != columns.len() { @@ -53,6 +55,7 @@ impl<'a, T: Transaction> Binder<'a, T> { } let schema_ref = _schema_ref.ok_or(DatabaseError::ColumnsEmpty)?; let mut rows = Vec::with_capacity(expr_rows.len()); + for expr_row in expr_rows { if expr_row.len() != values_len { return Err(DatabaseError::ValuesLenMismatch(expr_row.len(), values_len)); @@ -60,30 +63,33 @@ impl<'a, T: Transaction> Binder<'a, T> { let mut row = Vec::with_capacity(expr_row.len()); for (i, expr) in expr_row.iter().enumerate() { - match &self.bind_expr(expr)? { - ScalarExpression::Constant(value) => { + let mut expression = self.bind_expr(expr)?; + + expression.constant_calculation()?; + match expression { + ScalarExpression::Constant(mut value) => { + let ty = schema_ref[i].datatype(); // Check if the value length is too long - value.check_len(schema_ref[i].datatype())?; - let cast_value = - DataValue::clone(value).cast(schema_ref[i].datatype())?; - row.push(Arc::new(cast_value)) - } - ScalarExpression::Unary { expr, op, .. } => { - if let ScalarExpression::Constant(value) = expr.as_ref() { - row.push(Arc::new( - DataValue::unary_op(value, op)? - .cast(schema_ref[i].datatype())?, - )) - } else { - unreachable!() + value.check_len(ty)?; + + if value.logical_type() != *ty { + value = Arc::new(DataValue::clone(&value).cast(ty)?); } + row.push(value); + } + ScalarExpression::Empty => { + row.push(schema_ref[i].default_value().ok_or_else(|| { + DatabaseError::InvalidColumn( + "column does not exist default".to_string(), + ) + })?); } - _ => unreachable!(), + _ => return Err(DatabaseError::UnsupportedStmt(expr.to_string())), } } - rows.push(row); } + self.context.allow_default = false; let values_plan = self.bind_values(rows, schema_ref); Ok(LogicalPlan::new( @@ -94,10 +100,7 @@ impl<'a, T: Transaction> Binder<'a, T> { vec![values_plan], )) } else { - Err(DatabaseError::InvalidTable(format!( - "not found table {}", - table_name - ))) + Err(DatabaseError::TableNotFound) } } diff --git a/src/binder/mod.rs b/src/binder/mod.rs index b83dce7c..ecf30b51 100644 --- a/src/binder/mod.rs +++ b/src/binder/mod.rs @@ -16,7 +16,7 @@ mod truncate; mod update; use sqlparser::ast::{Ident, ObjectName, ObjectType, SetExpr, Statement}; -use std::collections::HashMap; +use std::collections::{BTreeMap, HashMap}; use std::sync::Arc; use crate::catalog::{TableCatalog, TableName}; @@ -50,7 +50,8 @@ pub enum QueryBindStep { pub struct BinderContext<'a, T: Transaction> { functions: &'a Functions, pub(crate) transaction: &'a T, - pub(crate) bind_table: HashMap)>, + // Tips: When there are multiple tables and Wildcard, use BTreeMap to ensure that the order of the output tables is certain. + pub(crate) bind_table: BTreeMap<(TableName, Option), &'a TableCatalog>, // alias expr_aliases: HashMap, table_aliases: HashMap, @@ -62,6 +63,7 @@ pub struct BinderContext<'a, T: Transaction> { sub_queries: HashMap>, temp_table_id: usize, + pub(crate) allow_default: bool, } impl<'a, T: Transaction> BinderContext<'a, T> { @@ -77,6 +79,7 @@ impl<'a, T: Transaction> BinderContext<'a, T> { bind_step: QueryBindStep::From, sub_queries: Default::default(), temp_table_id: 0, + allow_default: false, } } @@ -89,6 +92,10 @@ impl<'a, T: Transaction> BinderContext<'a, T> { self.bind_step = bind_step; } + pub fn is_step(&self, bind_step: &QueryBindStep) -> bool { + &self.bind_step == bind_step + } + pub fn sub_query(&mut self, sub_query: LogicalPlan) { self.sub_queries .entry(self.bind_step) @@ -120,12 +127,8 @@ impl<'a, T: Transaction> BinderContext<'a, T> { } .ok_or(DatabaseError::TableNotFound)?; - let old_table = self - .bind_table - .insert(table_name.clone(), (table, join_type)); - if matches!(old_table, Some((_, Some(_)))) { - return Err(DatabaseError::Duplicated("table", table_name.to_string())); - } + self.bind_table + .insert((table_name.clone(), join_type), table); Ok(table) } diff --git a/src/binder/select.rs b/src/binder/select.rs index a2a7c5c8..035f3d7b 100644 --- a/src/binder/select.rs +++ b/src/binder/select.rs @@ -14,7 +14,7 @@ use crate::{ types::value::DataValue, }; -use super::{lower_case_name, lower_ident, Binder, QueryBindStep}; +use super::{lower_case_name, lower_ident, Binder, BinderContext, QueryBindStep}; use crate::catalog::{ColumnCatalog, ColumnSummary, TableName}; use crate::errors::DatabaseError; @@ -338,7 +338,10 @@ impl<'a, T: Transaction> Binder<'a, T> { let scan_op = ScanOperator::build(table_name.clone(), table_catalog); if let Some(TableAlias { name, columns }) = alias { - self.register_alias(columns, name.value.to_lowercase(), table_name.clone())?; + let alias = lower_ident(name); + self.register_alias(columns, alias.clone(), table_name.clone())?; + + return Ok((Arc::new(alias), scan_op)); } Ok((table_name, scan_op)) @@ -371,7 +374,7 @@ impl<'a, T: Transaction> Binder<'a, T> { }); } SelectItem::Wildcard(_) => { - for table_name in self.context.bind_table.keys() { + for (table_name, _) in self.context.bind_table.keys() { self.bind_table_column_refs(&mut select_items, table_name.clone())?; } } @@ -443,19 +446,16 @@ impl<'a, T: Transaction> Binder<'a, T> { }; let (right_table, right) = self.bind_single_table_ref(relation, Some(join_type))?; let right_table = Self::unpack_name(right_table, false); + let fn_table = |context: &BinderContext<_>, table| { + context + .table(table) + .map(|table| table.schema_ref()) + .cloned() + .ok_or(DatabaseError::TableNotFound) + }; - let left_table = self - .context - .table(left_table) - .map(|table| table.schema_ref()) - .cloned() - .ok_or(DatabaseError::TableNotFound)?; - let right_table = self - .context - .table(right_table) - .map(|table| table.schema_ref()) - .cloned() - .ok_or(DatabaseError::TableNotFound)?; + let left_table = fn_table(&self.context, left_table.clone())?; + let right_table = fn_table(&self.context, right_table.clone())?; let on = match joint_condition { Some(constraint) => self.bind_join_constraint(&left_table, &right_table, constraint)?, @@ -605,7 +605,7 @@ impl<'a, T: Transaction> Binder<'a, T> { let mut left_table_force_nullable = false; let mut left_table = None; - for (table, join_option) in bind_tables.values() { + for ((_, join_option), table) in bind_tables { if let Some(join_type) = join_option { let (left_force_nullable, right_force_nullable) = joins_nullable(join_type); table_force_nullable.push((table, right_force_nullable)); @@ -671,6 +671,31 @@ impl<'a, T: Transaction> Binder<'a, T> { filter: join_filter, }) } + JoinConstraint::Using(idents) => { + let mut on_keys: Vec<(ScalarExpression, ScalarExpression)> = vec![]; + let fn_column = |schema: &Schema, ident: &Ident| { + schema + .iter() + .find(|column| column.name() == lower_ident(ident)) + .map(|column| ScalarExpression::ColumnRef(column.clone())) + }; + + for ident in idents { + if let (Some(left_column), Some(right_column)) = ( + fn_column(left_schema, ident), + fn_column(right_schema, ident), + ) { + on_keys.push((left_column, right_column)); + } else { + return Err(DatabaseError::InvalidColumn("not found column".to_string()))?; + } + } + Ok(JoinCondition::On { + on: on_keys, + filter: None, + }) + } + JoinConstraint::None => Ok(JoinCondition::None), _ => unimplemented!("not supported join constraint {:?}", constraint), } } diff --git a/src/binder/update.rs b/src/binder/update.rs index 3ff925ca..3172878b 100644 --- a/src/binder/update.rs +++ b/src/binder/update.rs @@ -5,7 +5,7 @@ use crate::planner::operator::update::UpdateOperator; use crate::planner::operator::Operator; use crate::planner::LogicalPlan; use crate::storage::Transaction; -use crate::types::value::ValueRef; +use crate::types::value::DataValue; use sqlparser::ast::{Assignment, Expr, TableFactor, TableWithJoins}; use std::slice; use std::sync::Arc; @@ -17,6 +17,8 @@ impl<'a, T: Transaction> Binder<'a, T> { selection: &Option, assignments: &[Assignment], ) -> Result { + // FIXME: Make it better to detect the current BindStep + self.context.allow_default = true; if let TableFactor::Table { name, .. } = &to.relation { let table_name = Arc::new(lower_case_name(name)?); @@ -29,27 +31,43 @@ impl<'a, T: Transaction> Binder<'a, T> { let mut columns = Vec::with_capacity(assignments.len()); let mut row = Vec::with_capacity(assignments.len()); - for assignment in assignments { - let value = match self.bind_expr(&assignment.value)? { - ScalarExpression::Constant(value) => Ok::(value), - _ => unreachable!(), - }?; + for Assignment { id, value } in assignments { + let mut expression = self.bind_expr(value)?; + expression.constant_calculation()?; - for ident in &assignment.id { + for ident in id { match self.bind_column_ref_from_identifiers( slice::from_ref(ident), Some(table_name.to_string()), )? { - ScalarExpression::ColumnRef(catalog) => { - value.check_len(catalog.datatype())?; - columns.push(catalog); - row.push(value.clone()); + ScalarExpression::ColumnRef(column) => { + match &expression { + ScalarExpression::Constant(value) => { + let ty = column.datatype(); + // Check if the value length is too long + value.check_len(ty)?; + + if value.logical_type() != *ty { + row.push(Arc::new(DataValue::clone(value).cast(ty)?)); + } + row.push(value.clone()); + } + ScalarExpression::Empty => { + row.push(column.default_value().ok_or_else(|| { + DatabaseError::InvalidColumn( + "column does not exist default".to_string(), + ) + })?); + } + _ => return Err(DatabaseError::UnsupportedStmt(value.to_string())), + } + columns.push(column); } - _ => unreachable!(), + _ => return Err(DatabaseError::InvalidColumn(ident.to_string())), } } } - + self.context.allow_default = false; let values_plan = self.bind_values(vec![row], Arc::new(columns)); Ok(LogicalPlan::new( diff --git a/src/db.rs b/src/db.rs index 729b409e..76e6f030 100644 --- a/src/db.rs +++ b/src/db.rs @@ -440,13 +440,13 @@ mod test { .await?; let _ = fnck_sql .run_on_query( - "insert into t3 (a, b) values (1, 1111), (2, 2.01), (3, 3.00)", + "insert into t3 (a, b) values (1, 99), (2, 2.01), (3, 3.00)", query_execute, ) .await?; let _ = fnck_sql .run_on_query( - "insert into t3 (a, b) values (4, 4444), (5, 5222), (6, 1.00)", + "insert into t3 (a, b) values (4, 44), (5, 52), (6, 1.00)", query_execute, ) .await?; diff --git a/src/errors.rs b/src/errors.rs index e6dad3fe..19966f73 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -15,7 +15,7 @@ pub enum DatabaseError { EmptyStatement, #[error("invalid type")] InvalidType, - #[error("must contain PrimaryKey!")] + #[error("must contain primary key!")] PrimaryKeyNotFound, #[error("not implemented sqlparser datatype: {0}")] NotImplementedSqlparserDataType(String), @@ -99,8 +99,8 @@ pub enum DatabaseError { DuplicateUniqueValue, #[error("the table not found")] TableNotFound, - #[error("the some column already exists")] - DuplicateColumn, + #[error("the some column: {0} already exists")] + DuplicateColumn(String), #[error("add column must be nullable or specify a default value")] NeedNullAbleOrDefault, #[error("the table already exists")] @@ -148,8 +148,6 @@ pub enum DatabaseError { InvalidTable(String), #[error("invalid column: {0}")] InvalidColumn(String), - #[error("ambiguous column: {0}")] - AmbiguousColumn(String), #[error("values length not match, expect {0}, got {1}")] ValuesLenMismatch(usize, usize), #[error("binary operator types mismatch: {0} != {1}")] diff --git a/src/execution/volcano/dml/insert.rs b/src/execution/volcano/dml/insert.rs index 4f25a62e..8cde6afa 100644 --- a/src/execution/volcano/dml/insert.rs +++ b/src/execution/volcano/dml/insert.rs @@ -50,39 +50,37 @@ impl Insert { input, is_overwrite, } = self; - let mut primary_key_index = None; + let mut primary_key_id = None; let mut unique_values = HashMap::new(); let mut tuple_values = Vec::new(); - let mut tuple_schema_ref = None; if let Some(table_catalog) = transaction.table(table_name.clone()).cloned() { - let _ = tuple_schema_ref.get_or_insert_with(|| table_catalog.schema_ref().clone()); + let tuple_schema_ref = table_catalog.schema_ref(); + #[for_await] for tuple in build_read(input, transaction) { let Tuple { schema_ref, values, .. } = tuple?; - let mut tuple_map = HashMap::new(); - for (i, value) in values.into_iter().enumerate() { - let column = &schema_ref[i]; - if let Some(column_id) = column.id() { - tuple_map.insert(column_id, value); - } - } - let primary_col_id = primary_key_index.get_or_insert_with(|| { - schema_ref + if primary_key_id.is_none() { + let id = schema_ref .iter() .find(|col| col.desc.is_primary) - .map(|col| col.id().unwrap()) - .unwrap() - }); - let tuple_id = tuple_map.get(primary_col_id).cloned().unwrap(); + .map(|col| col.id()) + .ok_or_else(|| DatabaseError::NotNull)?; + primary_key_id = Some(id); + } + let mut tuple_map = HashMap::new(); + for (i, value) in values.into_iter().enumerate() { + tuple_map.insert(schema_ref[i].id(), value); + } + let tuple_id = tuple_map.get(&primary_key_id.unwrap()).cloned().unwrap(); let mut values = Vec::with_capacity(table_catalog.columns_len()); for col in table_catalog.columns() { let value = tuple_map - .remove(&col.id().unwrap()) + .remove(&col.id()) .or_else(|| col.default_value()) .unwrap_or_else(|| Arc::new(DataValue::none(col.datatype()))); @@ -99,8 +97,7 @@ impl Insert { } tuple_values.push((tuple_id, values)); } - let tuple_schema_ref = tuple_schema_ref.ok_or(DatabaseError::ColumnsEmpty)?; - let tuple_builder = TupleBuilder::new(&tuple_schema_ref); + let tuple_builder = TupleBuilder::new(tuple_schema_ref); // Unique Index for (col_id, values) in unique_values { diff --git a/src/planner/operator/join.rs b/src/planner/operator/join.rs index 9b23ffe2..ce4fdaef 100644 --- a/src/planner/operator/join.rs +++ b/src/planner/operator/join.rs @@ -7,7 +7,7 @@ use strum_macros::Display; use super::Operator; -#[derive(Debug, Display, PartialEq, Eq, Clone, Copy, Hash)] +#[derive(Debug, Display, PartialEq, Eq, Clone, Copy, Hash, Ord, PartialOrd)] pub enum JoinType { Inner, Left, diff --git a/src/storage/kip.rs b/src/storage/kip.rs index 0e249fcc..9807998d 100644 --- a/src/storage/kip.rs +++ b/src/storage/kip.rs @@ -212,7 +212,7 @@ impl Transaction for KipTransaction { return if if_not_exists { Ok(col.id().unwrap()) } else { - Err(DatabaseError::DuplicateColumn) + Err(DatabaseError::DuplicateColumn(column.name().to_string())) }; } } diff --git a/src/types/value.rs b/src/types/value.rs index 8e579b7c..8c654c19 100644 --- a/src/types/value.rs +++ b/src/types/value.rs @@ -593,7 +593,7 @@ impl DataValue { } pub fn cast(self, to: &LogicalType) -> Result { - match self { + let value = match self { DataValue::Null => match to { LogicalType::Invalid => Err(DatabaseError::CastFail), LogicalType::SqlNull => Ok(DataValue::Null), @@ -951,7 +951,9 @@ impl DataValue { LogicalType::Tuple => Ok(DataValue::Tuple(values)), _ => Err(DatabaseError::CastFail), }, - } + }?; + value.check_len(to)?; + Ok(value) } pub fn common_prefix_length(&self, target: &DataValue) -> Option { diff --git a/tests/slt/insert.slt b/tests/slt/insert.slt index caf0754f..6a1d529c 100644 --- a/tests/slt/insert.slt +++ b/tests/slt/insert.slt @@ -56,9 +56,21 @@ insert into t1 values (1) statement ok insert into t1 values (2) +statement ok +insert into t1 values (3, DEFAULT) + +statement ok +insert into t1 values (4, 0) + +statement ok +insert into t1 (v1, id) values (DEFAULT, 5) + query III rowsort select * from t1 ---- 0 233 1 233 -2 233 \ No newline at end of file +2 233 +3 233 +4 0 +5 233 \ No newline at end of file diff --git a/tests/slt/join.slt b/tests/slt/join.slt index 9b191fbb..9cf96475 100644 --- a/tests/slt/join.slt +++ b/tests/slt/join.slt @@ -113,4 +113,18 @@ query IIIII rowsort select v1, v2, v3, v4, v5 from a join b on v1 = v3 and v2 = v4 and v1 < v5; ---- 1 1 1 1 5 -3 3 3 3 4 \ No newline at end of file +3 3 3 3 4 + +query IIIII rowsort +select * from a join b using (id) +---- +0 1 1 0 1 1 1 +1 2 2 1 2 2 2 +2 3 3 2 3 3 4 + +query IIIIII rowsort +select a.*, c.* from a inner join a as c using (id) +---- +0 1 1 0 1 1 +1 2 2 1 2 2 +2 3 3 2 3 3 diff --git a/tests/slt/sql_2016/F041_01.slt b/tests/slt/sql_2016/F041_01.slt index 9972e93a..8bcae3d0 100644 --- a/tests/slt/sql_2016/F041_01.slt +++ b/tests/slt/sql_2016/F041_01.slt @@ -15,8 +15,8 @@ CREATE TABLE TABLE_F041_01_01_021 ( ID INT PRIMARY KEY, A INTEGER ); statement ok CREATE TABLE TABLE_F041_01_01_022 ( ID INT PRIMARY KEY, A INTEGER ); -# TODO: Support `USING ()` on `JOIN` -# SELECT TABLE_F041_01_01_021.A, TABLE_F041_01_01_022.A FROM TABLE_F041_01_01_021 JOIN TABLE_F041_01_01_022 USING ( A ) +query II +SELECT TABLE_F041_01_01_021.A, TABLE_F041_01_01_022.A FROM TABLE_F041_01_01_021 JOIN TABLE_F041_01_01_022 USING ( A ) statement ok CREATE TABLE TABLE_F041_01_01_031 ( ID INT PRIMARY KEY, A INTEGER ); @@ -24,5 +24,6 @@ CREATE TABLE TABLE_F041_01_01_031 ( ID INT PRIMARY KEY, A INTEGER ); statement ok CREATE TABLE TABLE_F041_01_01_032 ( ID INT PRIMARY KEY, A INTEGER ); -# TODO: Support Aliases the result set +# sqlparser-rs unsupported +# query II # SELECT TABLE_F041_01_01_031.A, TABLE_F041_01_01_032.A FROM TABLE_F041_01_01_031 JOIN TABLE_F041_01_01_032 USING ( A ) AS FOO diff --git a/tests/slt/sql_2016/F041_02.slt b/tests/slt/sql_2016/F041_02.slt index 0bb578ce..0865c4fc 100644 --- a/tests/slt/sql_2016/F041_02.slt +++ b/tests/slt/sql_2016/F041_02.slt @@ -15,8 +15,8 @@ CREATE TABLE TABLE_F041_02_01_021 ( ID INT PRIMARY KEY, A INTEGER ); statement ok CREATE TABLE TABLE_F041_02_01_022 ( ID INT PRIMARY KEY, A INTEGER ); -# TODO: Support `USING ()` on `JOIN` -# SELECT TABLE_F041_02_01_021.A, TABLE_F041_02_01_022.A FROM TABLE_F041_02_01_021 INNER JOIN TABLE_F041_02_01_022 USING ( A ) +query II +SELECT TABLE_F041_02_01_021.A, TABLE_F041_02_01_022.A FROM TABLE_F041_02_01_021 INNER JOIN TABLE_F041_02_01_022 USING ( A ) statement ok CREATE TABLE TABLE_F041_02_01_031 ( ID INT PRIMARY KEY, A INTEGER ); @@ -24,5 +24,6 @@ CREATE TABLE TABLE_F041_02_01_031 ( ID INT PRIMARY KEY, A INTEGER ); statement ok CREATE TABLE TABLE_F041_02_01_032 ( ID INT PRIMARY KEY, A INTEGER ); -# TODO: Support Aliases the result set +# sqlparser-rs unsupported +# query II # SELECT TABLE_F041_02_01_031.A, TABLE_F041_02_01_032.A FROM TABLE_F041_02_01_031 INNER JOIN TABLE_F041_02_01_032 USING ( A ) AS FOO diff --git a/tests/slt/sql_2016/F041_03.slt b/tests/slt/sql_2016/F041_03.slt index e3a92a6d..cdc1ea62 100644 --- a/tests/slt/sql_2016/F041_03.slt +++ b/tests/slt/sql_2016/F041_03.slt @@ -15,8 +15,8 @@ CREATE TABLE TABLE_F041_03_01_021 ( ID INT PRIMARY KEY, A INTEGER ); statement ok CREATE TABLE TABLE_F041_03_01_022 ( ID INT PRIMARY KEY, A INTEGER ); -# TODO: Support Aliases the result set -# SELECT TABLE_F041_03_01_021.A, TABLE_F041_03_01_022.A FROM TABLE_F041_03_01_021 LEFT JOIN TABLE_F041_03_01_022 USING ( A ) +query II +SELECT TABLE_F041_03_01_021.A, TABLE_F041_03_01_022.A FROM TABLE_F041_03_01_021 LEFT JOIN TABLE_F041_03_01_022 USING ( A ) statement ok CREATE TABLE TABLE_F041_03_01_031 ( ID INT PRIMARY KEY, A INTEGER ); @@ -24,7 +24,8 @@ CREATE TABLE TABLE_F041_03_01_031 ( ID INT PRIMARY KEY, A INTEGER ); statement ok CREATE TABLE TABLE_F041_03_01_032 ( ID INT PRIMARY KEY, A INTEGER ); -# TODO: Support Aliases the result set +# sqlparser-rs unsupported +# query II # SELECT TABLE_F041_03_01_031.A, TABLE_F041_03_01_032.A FROM TABLE_F041_03_01_031 LEFT JOIN TABLE_F041_03_01_032 USING ( A ) AS FOO statement ok @@ -42,8 +43,8 @@ CREATE TABLE TABLE_F041_03_01_051 ( ID INT PRIMARY KEY, A INTEGER ); statement ok CREATE TABLE TABLE_F041_03_01_052 ( ID INT PRIMARY KEY, A INTEGER ); -# TODO: Support Aliases the result set -# SELECT TABLE_F041_03_01_051.A, TABLE_F041_03_01_052.A FROM TABLE_F041_03_01_051 LEFT OUTER JOIN TABLE_F041_03_01_052 USING ( A ) +query II +SELECT TABLE_F041_03_01_051.A, TABLE_F041_03_01_052.A FROM TABLE_F041_03_01_051 LEFT OUTER JOIN TABLE_F041_03_01_052 USING ( A ) statement ok CREATE TABLE TABLE_F041_03_01_061 ( ID INT PRIMARY KEY, A INTEGER ); @@ -51,5 +52,6 @@ CREATE TABLE TABLE_F041_03_01_061 ( ID INT PRIMARY KEY, A INTEGER ); statement ok CREATE TABLE TABLE_F041_03_01_062 ( ID INT PRIMARY KEY, A INTEGER ); -# TODO: Support Aliases the result set +# sqlparser-rs unsupported +# query II # SELECT TABLE_F041_03_01_061.A, TABLE_F041_03_01_062.A FROM TABLE_F041_03_01_061 LEFT OUTER JOIN TABLE_F041_03_01_062 USING ( A ) AS FOO diff --git a/tests/slt/sql_2016/F041_04.slt b/tests/slt/sql_2016/F041_04.slt index f804cc1a..873bbb9e 100644 --- a/tests/slt/sql_2016/F041_04.slt +++ b/tests/slt/sql_2016/F041_04.slt @@ -15,8 +15,8 @@ CREATE TABLE TABLE_F041_04_01_021 ( ID INT PRIMARY KEY, A INTEGER ); statement ok CREATE TABLE TABLE_F041_04_01_022 ( ID INT PRIMARY KEY, A INTEGER ); -# TODO: Support Aliases the result set -# SELECT TABLE_F041_04_01_021.A, TABLE_F041_04_01_022.A FROM TABLE_F041_04_01_021 RIGHT JOIN TABLE_F041_04_01_022 USING ( A ) +query II +SELECT TABLE_F041_04_01_021.A, TABLE_F041_04_01_022.A FROM TABLE_F041_04_01_021 RIGHT JOIN TABLE_F041_04_01_022 USING ( A ) statement ok CREATE TABLE TABLE_F041_04_01_031 ( ID INT PRIMARY KEY, A INTEGER ); @@ -24,7 +24,8 @@ CREATE TABLE TABLE_F041_04_01_031 ( ID INT PRIMARY KEY, A INTEGER ); statement ok CREATE TABLE TABLE_F041_04_01_032 ( ID INT PRIMARY KEY, A INTEGER ); -# TODO: Support Aliases the result set +# sqlparser-rs unsupported +# query II # SELECT TABLE_F041_04_01_031.A, TABLE_F041_04_01_032.A FROM TABLE_F041_04_01_031 RIGHT JOIN TABLE_F041_04_01_032 USING ( A ) AS FOO statement ok @@ -42,8 +43,8 @@ CREATE TABLE TABLE_F041_04_01_051 ( ID INT PRIMARY KEY, A INTEGER ); statement ok CREATE TABLE TABLE_F041_04_01_052 ( ID INT PRIMARY KEY, A INTEGER ); -# TODO: Support Aliases the result set -# SELECT TABLE_F041_04_01_051.A, TABLE_F041_04_01_052.A FROM TABLE_F041_04_01_051 RIGHT OUTER JOIN TABLE_F041_04_01_052 USING ( A ) +query II +SELECT TABLE_F041_04_01_051.A, TABLE_F041_04_01_052.A FROM TABLE_F041_04_01_051 RIGHT OUTER JOIN TABLE_F041_04_01_052 USING ( A ) statement ok CREATE TABLE TABLE_F041_04_01_061 ( ID INT PRIMARY KEY, A INTEGER ); @@ -51,5 +52,6 @@ CREATE TABLE TABLE_F041_04_01_061 ( ID INT PRIMARY KEY, A INTEGER ); statement ok CREATE TABLE TABLE_F041_04_01_062 ( ID INT PRIMARY KEY, A INTEGER ); -# TODO: Support Aliases the result set +# sqlparser-rs unsupported +# query II # SELECT TABLE_F041_04_01_061.A, TABLE_F041_04_01_062.A FROM TABLE_F041_04_01_061 RIGHT OUTER JOIN TABLE_F041_04_01_062 USING ( A ) AS FOO diff --git a/tests/slt/sql_2016/F041_07.slt b/tests/slt/sql_2016/F041_07.slt index be78d423..bae01f16 100644 --- a/tests/slt/sql_2016/F041_07.slt +++ b/tests/slt/sql_2016/F041_07.slt @@ -1,33 +1,39 @@ # F041-07: The inner table in a left or right outer join can also be used in an inner join -# TODO: The inner table in a left or right outer join can also be used in an inner join +statement ok +CREATE TABLE TABLE_F041_07_01_011 ( ID INT PRIMARY KEY, A INTEGER ); -# statement ok -# CREATE TABLE TABLE_F041_07_01_011 ( ID INT PRIMARY KEY, A INTEGER ); +query I +SELECT TABLE_F041_07_01_011.A FROM TABLE_F041_07_01_011 INNER JOIN TABLE_F041_07_01_011 AS TABLE_F041_07_01_012 ON TABLE_F041_07_01_011.A = TABLE_F041_07_01_012.A -# SELECT TABLE_F041_07_01_011.A FROM TABLE_F041_07_01_011 INNER JOIN TABLE_F041_07_01_011 AS TABLE_F041_07_01_012 ON TABLE_F041_07_01_011.A = TABLE_F041_07_01_012.A +statement ok +CREATE TABLE TABLE_F041_07_01_021 ( ID INT PRIMARY KEY, A INTEGER ); -# statement ok -# CREATE TABLE TABLE_F041_07_01_021 ( ID INT PRIMARY KEY, A INTEGER ); +query I +SELECT TABLE_F041_07_01_021.A FROM TABLE_F041_07_01_021 INNER JOIN TABLE_F041_07_01_021 AS TABLE_F041_07_01_022 USING ( A ) -# SELECT TABLE_F041_07_01_021.A FROM TABLE_F041_07_01_021 INNER JOIN TABLE_F041_07_01_021 AS TABLE_F041_07_01_022 USING ( A ) - -# statement ok -# CREATE TABLE TABLE_F041_07_01_031 ( ID INT PRIMARY KEY, A INTEGER ); +statement ok +CREATE TABLE TABLE_F041_07_01_031 ( ID INT PRIMARY KEY, A INTEGER ); +# sqlparser-rs unsupported +# query I # SELECT TABLE_F041_07_01_031.A FROM TABLE_F041_07_01_031 INNER JOIN TABLE_F041_07_01_031 AS TABLE_F041_07_01_032 USING ( A ) AS FOO -# statement ok -# CREATE TABLE TABLE_F041_07_01_041 ( ID INT PRIMARY KEY, A INTEGER ); +statement ok +CREATE TABLE TABLE_F041_07_01_041 ( ID INT PRIMARY KEY, A INTEGER ); -# SELECT TABLE_F041_07_01_041.A FROM TABLE_F041_07_01_041 JOIN TABLE_F041_07_01_041 AS TABLE_F041_07_01_042 ON TABLE_F041_07_01_041.A = TABLE_F041_07_01_042.A +query I +SELECT TABLE_F041_07_01_041.A FROM TABLE_F041_07_01_041 JOIN TABLE_F041_07_01_041 AS TABLE_F041_07_01_042 ON TABLE_F041_07_01_041.A = TABLE_F041_07_01_042.A -# statement ok -# CREATE TABLE TABLE_F041_07_01_051 ( ID INT PRIMARY KEY, A INTEGER ); +statement ok +CREATE TABLE TABLE_F041_07_01_051 ( ID INT PRIMARY KEY, A INTEGER ); -# SELECT TABLE_F041_07_01_051.A FROM TABLE_F041_07_01_051 JOIN TABLE_F041_07_01_051 AS TABLE_F041_07_01_052 USING ( A ) +query I +SELECT TABLE_F041_07_01_051.A FROM TABLE_F041_07_01_051 JOIN TABLE_F041_07_01_051 AS TABLE_F041_07_01_052 USING ( A ) -# statement ok -# CREATE TABLE TABLE_F041_07_01_061 ( ID INT PRIMARY KEY, A INTEGER ); +statement ok +CREATE TABLE TABLE_F041_07_01_061 ( ID INT PRIMARY KEY, A INTEGER ); +# sqlparser-rs unsupported +# query I # SELECT TABLE_F041_07_01_061.A FROM TABLE_F041_07_01_061 JOIN TABLE_F041_07_01_061 AS TABLE_F041_07_01_062 USING ( A ) AS FOO diff --git a/tests/slt/sql_2016/F221.slt b/tests/slt/sql_2016/F221.slt index 77cf5f7f..bb845b0f 100644 --- a/tests/slt/sql_2016/F221.slt +++ b/tests/slt/sql_2016/F221.slt @@ -1,15 +1,13 @@ # F221: Explicit defaults -# TODO: Explicit defaults +statement ok +CREATE TABLE TABLE_F221_01_011 ( ID INT PRIMARY KEY, A INTEGER DEFAULT 123 ); -# statement ok -# CREATE TABLE TABLE_F221_01_011 ( ID INT PRIMARY KEY, A INTEGER DEFAULT 123 ); +statement ok +INSERT INTO TABLE_F221_01_011 ( ID, A ) VALUES ( 0, DEFAULT ) -# statement ok -# INSERT INTO TABLE_F221_01_011 ( A ) VALUES ( DEFAULT ) +statement ok +CREATE TABLE TABLE_F221_02_011 ( ID INT PRIMARY KEY, A INTEGER DEFAULT 123 ); -# statement ok -# CREATE TABLE TABLE_F221_02_011 ( ID INT PRIMARY KEY, A INTEGER DEFAULT 123 ); - -# statement ok -# UPDATE TABLE_F221_02_011 SET A = DEFAULT +statement ok +UPDATE TABLE_F221_02_011 SET A = DEFAULT diff --git a/tests/slt/update b/tests/slt/update index 7ad629b0..b2c52456 100644 --- a/tests/slt/update +++ b/tests/slt/update @@ -1,5 +1,5 @@ statement ok -create table t(id int primary key, v1 int, v2 int, v3 int) +create table t(id int primary key, v1 int, v2 int, v3 int default 233) statement ok insert into t values (0,1,10,100) @@ -10,7 +10,7 @@ insert into t values (1,1,10,100), (2,2,20,200), (3,3,30,300), (4,4,40,400) statement ok update t set v2 = 9 where v1 = 1 -query III rowsort +query IIII rowsort select * from t; ---- 1 1 9 100 @@ -21,7 +21,7 @@ select * from t; statement ok update t set v2 = 9 -query III rowsort +query IIII rowsort select * from t ---- 1 1 9 100 @@ -29,5 +29,16 @@ select * from t 3 3 9 300 4 4 9 400 +statement ok +update t set v2 = default + +query IIII rowsort +select * from t +---- +1 1 9 233 +2 2 9 233 +3 3 9 233 +4 4 9 233 + statement ok drop table t \ No newline at end of file