Skip to content

Commit f480b88

Browse files
committed
Support alter table change column options
1 parent 10314d0 commit f480b88

7 files changed

Lines changed: 183 additions & 23 deletions

File tree

src/binder/alter_table.rs

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
use sqlparser::ast::{AlterColumnOperation, AlterTableOperation, ObjectName};
15+
use sqlparser::ast::{AlterColumnOperation, AlterTableOperation, ColumnOption, ObjectName};
1616

1717
use std::borrow::Cow;
1818
use std::sync::Arc;
@@ -27,7 +27,8 @@ use crate::planner::operator::alter_table::change_column::{
2727
};
2828
use crate::planner::operator::alter_table::drop_column::DropColumnOperator;
2929
use crate::planner::operator::Operator;
30-
use crate::planner::{Childrens, LogicalPlan};
30+
use crate::planner::Childrens;
31+
use crate::planner::LogicalPlan;
3132
use crate::storage::Transaction;
3233
use crate::types::value::DataValue;
3334
use crate::types::LogicalType;
@@ -50,6 +51,33 @@ impl<T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'_, '_, T, A>
5051
Ok(expr)
5152
}
5253

54+
fn bind_change_column_options(
55+
&mut self,
56+
options: &[ColumnOption],
57+
data_type: &LogicalType,
58+
) -> Result<(DefaultChange, NotNullChange), DatabaseError> {
59+
let mut default_change = DefaultChange::NoChange;
60+
let mut not_null_change = NotNullChange::NoChange;
61+
62+
for option in options {
63+
match option {
64+
ColumnOption::Null => not_null_change = NotNullChange::Drop,
65+
ColumnOption::NotNull => not_null_change = NotNullChange::Set,
66+
ColumnOption::Default(expr) => {
67+
default_change =
68+
DefaultChange::Set(self.bind_alter_default_expr(expr, data_type)?);
69+
}
70+
option => {
71+
return Err(DatabaseError::UnsupportedStmt(format!(
72+
"CHANGE/MODIFY COLUMN does not currently support this option: {option:?}"
73+
)))
74+
}
75+
}
76+
}
77+
78+
Ok((default_change, not_null_change))
79+
}
80+
5381
pub(crate) fn bind_alter_table(
5482
&mut self,
5583
name: &ObjectName,
@@ -200,24 +228,27 @@ impl<T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'_, '_, T, A>
200228
options,
201229
column_position,
202230
} => {
203-
if !options.is_empty() || column_position.is_some() {
231+
if column_position.is_some() {
204232
return Err(DatabaseError::UnsupportedStmt(
205-
"MODIFY COLUMN currently only supports changing the data type".to_string(),
233+
"MODIFY COLUMN does not currently support column positions".to_string(),
206234
));
207235
}
208236
let old_column_name = col_name.value.to_lowercase();
209237
let _ = table
210238
.get_column_by_name(&old_column_name)
211239
.ok_or_else(|| DatabaseError::column_not_found(old_column_name.clone()))?;
240+
let data_type = LogicalType::try_from(data_type.clone())?;
241+
let (default_change, not_null_change) =
242+
self.bind_change_column_options(options, &data_type)?;
212243

213244
LogicalPlan::new(
214245
Operator::ChangeColumn(ChangeColumnOperator {
215246
table_name,
216247
new_column_name: old_column_name.clone(),
217248
old_column_name,
218-
data_type: LogicalType::try_from(data_type.clone())?,
219-
default_change: DefaultChange::NoChange,
220-
not_null_change: NotNullChange::NoChange,
249+
data_type,
250+
default_change,
251+
not_null_change,
221252
}),
222253
Childrens::None,
223254
)
@@ -229,10 +260,9 @@ impl<T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'_, '_, T, A>
229260
options,
230261
column_position,
231262
} => {
232-
if !options.is_empty() || column_position.is_some() {
263+
if column_position.is_some() {
233264
return Err(DatabaseError::UnsupportedStmt(
234-
"CHANGE COLUMN currently only supports renaming and changing the data type"
235-
.to_string(),
265+
"CHANGE COLUMN does not currently support column positions".to_string(),
236266
));
237267
}
238268
let old_column_name = old_name.value.to_lowercase();
@@ -246,15 +276,18 @@ impl<T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'_, '_, T, A>
246276
"illegal column naming".to_string(),
247277
));
248278
}
279+
let data_type = LogicalType::try_from(data_type.clone())?;
280+
let (default_change, not_null_change) =
281+
self.bind_change_column_options(options, &data_type)?;
249282

250283
LogicalPlan::new(
251284
Operator::ChangeColumn(ChangeColumnOperator {
252285
table_name,
253286
old_column_name,
254287
new_column_name,
255-
data_type: LogicalType::try_from(data_type.clone())?,
256-
default_change: DefaultChange::NoChange,
257-
not_null_change: NotNullChange::NoChange,
288+
data_type,
289+
default_change,
290+
not_null_change,
258291
}),
259292
Childrens::None,
260293
)

src/execution/ddl/add_column.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,6 @@ impl AddColumn {
107107
&pk_ty,
108108
&old_deserializers,
109109
schema.len(),
110-
schema.len(),
111110
&serializers,
112111
|tuple| {
113112
if let Some(value) = &default_value {

src/execution/ddl/change_column.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,6 @@ impl ChangeColumn {
116116
&pk_ty,
117117
&old_deserializers,
118118
schema.len(),
119-
schema.len(),
120119
&serializers,
121120
|tuple| {
122121
tuple.values[column_index] =
@@ -136,7 +135,6 @@ impl ChangeColumn {
136135
&pk_ty,
137136
&old_deserializers,
138137
schema.len(),
139-
schema.len(),
140138
|tuple| {
141139
if tuple.values[column_index].is_null() {
142140
return Err(DatabaseError::not_null_column(target_column_name.clone()));

src/execution/ddl/drop_column.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ impl DropColumn {
9292
&pk_ty,
9393
&old_deserializers,
9494
tuple_columns.len(),
95-
tuple_columns.len(),
9695
&serializers,
9796
|tuple| {
9897
let _ = tuple.values.remove(column_index);

src/execution/ddl/mod.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ fn read_tuple_batch<T: Transaction>(
4141
pk_ty: &LogicalType,
4242
old_deserializers: &[TupleValueSerializableImpl],
4343
old_values_len: usize,
44-
old_total_len: usize,
4544
start_after: Option<&TupleId>,
4645
batch: &mut Vec<Tuple>,
4746
batch_size: usize,
@@ -85,7 +84,7 @@ fn read_tuple_batch<T: Transaction>(
8584
old_deserializers,
8685
Some(tuple_id),
8786
value,
88-
old_total_len,
87+
old_values_len,
8988
)?;
9089
len += 1;
9190
}
@@ -100,7 +99,6 @@ pub(crate) fn visit_table_in_batches<T, F>(
10099
pk_ty: &LogicalType,
101100
old_deserializers: &[TupleValueSerializableImpl],
102101
old_values_len: usize,
103-
old_total_len: usize,
104102
mut visit: F,
105103
) -> Result<(), DatabaseError>
106104
where
@@ -117,7 +115,6 @@ where
117115
pk_ty,
118116
old_deserializers,
119117
old_values_len,
120-
old_total_len,
121118
last_pk.as_ref(),
122119
&mut batch,
123120
REWRITE_BATCH_SIZE,
@@ -146,7 +143,6 @@ pub(crate) fn rewrite_table_in_batches<T, F, G>(
146143
pk_ty: &LogicalType,
147144
old_deserializers: &[TupleValueSerializableImpl],
148145
old_values_len: usize,
149-
old_total_len: usize,
150146
new_serializers: &[TupleValueSerializableImpl],
151147
mut rewrite: F,
152148
mut after_write: G,
@@ -166,7 +162,6 @@ where
166162
pk_ty,
167163
old_deserializers,
168164
old_values_len,
169-
old_total_len,
170165
last_pk.as_ref(),
171166
&mut batch,
172167
REWRITE_BATCH_SIZE,

tests/slt/alter_table.slt

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,59 @@ drop table t1
6262

6363
statement ok
6464
drop table t2
65+
66+
statement ok
67+
create table t3(id int primary key, v int)
68+
69+
statement ok
70+
insert into t3 values (1, 10), (2, 20)
71+
72+
query TTTTI
73+
describe t3
74+
----
75+
id Integer 4 false PRIMARY null
76+
v Integer 4 true EMPTY null
77+
78+
statement ok
79+
insert into t3 values (3, 10)
80+
81+
statement error
82+
alter table t3 alter column v type bigint using v + 1
83+
84+
statement error
85+
alter table t3 rename to t3_new
86+
87+
statement error
88+
alter table t3 drop column id, v
89+
90+
statement ok
91+
insert into t3 values (4, 10)
92+
93+
statement error
94+
alter table t3 modify column v int unique
95+
96+
statement error
97+
alter table t3 change column v v2 int unique
98+
99+
query III rowsort
100+
select * from t3
101+
----
102+
1 10
103+
2 20
104+
3 10
105+
4 10
106+
107+
query TTTTI
108+
describe t3
109+
----
110+
id Integer 4 false PRIMARY null
111+
v Integer 4 true EMPTY null
112+
113+
statement error
114+
alter table t3 modify column v int first
115+
116+
statement error
117+
alter table t3 change column v v int after id
118+
119+
statement ok
120+
drop table t3

tests/slt/change_column.slt

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,5 +115,85 @@ select value2 from alter_users where value2 is not null order by id
115115
999
116116
404
117117

118+
statement ok
119+
update alter_users set value2 = 606 where id = 6
120+
121+
statement ok
122+
alter table alter_users change column value2 value2 int not null
123+
124+
query TTTTI
125+
describe alter_users
126+
----
127+
id Integer 4 false PRIMARY null
128+
value1 Integer 4 true UNIQUE null
129+
value2 Integer 4 false EMPTY null
130+
131+
statement error
132+
insert into alter_users (id, value1) values (7, 77)
133+
134+
statement ok
135+
alter table alter_users change column value2 value2 int default 707
136+
137+
statement ok
138+
insert into alter_users (id, value1) values (7, 77)
139+
140+
query I
141+
select value2 from alter_users where id = 7
142+
----
143+
707
144+
145+
query TTTTI
146+
describe alter_users
147+
----
148+
id Integer 4 false PRIMARY null
149+
value1 Integer 4 true UNIQUE null
150+
value2 Integer 4 false EMPTY 707
151+
152+
statement ok
153+
alter table alter_users modify column value2 int null
154+
155+
statement ok
156+
insert into alter_users (id, value1) values (8, 88)
157+
158+
query I
159+
select value2 from alter_users where id = 8
160+
----
161+
707
162+
163+
query TTTTI
164+
describe alter_users
165+
----
166+
id Integer 4 false PRIMARY null
167+
value1 Integer 4 true UNIQUE null
168+
value2 Integer 4 true EMPTY 707
169+
170+
statement ok
171+
alter table alter_users modify column value2 int not null
172+
173+
query TTTTI
174+
describe alter_users
175+
----
176+
id Integer 4 false PRIMARY null
177+
value1 Integer 4 true UNIQUE null
178+
value2 Integer 4 false EMPTY 707
179+
180+
statement ok
181+
alter table alter_users modify column value2 int default 808
182+
183+
statement ok
184+
insert into alter_users (id, value1) values (9, 99)
185+
186+
query I
187+
select value2 from alter_users where id = 9
188+
----
189+
808
190+
191+
query TTTTI
192+
describe alter_users
193+
----
194+
id Integer 4 false PRIMARY null
195+
value1 Integer 4 true UNIQUE null
196+
value2 Integer 4 false EMPTY 808
197+
118198
statement ok
119199
drop table alter_users

0 commit comments

Comments
 (0)