Skip to content

Commit 82c03f1

Browse files
authored
fix: alter column with specify approx distinct (#18928)
* fix: alter column with approx distinct * fix * fix
1 parent 33c96fe commit 82c03f1

File tree

5 files changed

+78
-1
lines changed

5 files changed

+78
-1
lines changed

src/query/service/src/interpreters/interpreter_table_add_column.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,12 @@ impl Interpreter for AddTableColumnInterpreter {
134134
// need rebuild the table to generate stored computed column.
135135
if num_rows > 0 && matches!(field.computed_expr, Some(ComputedExpr::Stored(_))) {
136136
let fuse_table = FuseTable::try_from_table(tbl.as_ref())?;
137+
if fuse_table.change_tracking_enabled() {
138+
return Err(ErrorCode::AlterTableError(format!(
139+
"Cannot add stored computed column to table '{}' with change tracking enabled",
140+
table_info.desc
141+
)));
142+
}
137143
let base_snapshot = fuse_table.read_table_snapshot().await?;
138144
let prev_snapshot_id = base_snapshot.snapshot_id().map(|(id, _)| id);
139145
let table_meta_timestamps = self
@@ -165,6 +171,16 @@ impl Interpreter for AddTableColumnInterpreter {
165171
.await;
166172
}
167173

174+
let need_update = num_rows > 0 && !self.plan.is_deterministic;
175+
if need_update && tbl.change_tracking_enabled() {
176+
// Rebuild table while change tracking is active may break the consistency
177+
// of tracked changes, leading to incorrect change records.
178+
return Err(ErrorCode::AlterTableError(format!(
179+
"Cannot add non-deterministic default column to table '{}' with change tracking enabled",
180+
table_info.desc
181+
)));
182+
}
183+
168184
let new_table_meta = table_info.meta.clone();
169185
commit_table_meta(
170186
&self.ctx,
@@ -177,7 +193,7 @@ impl Interpreter for AddTableColumnInterpreter {
177193

178194
// If the column is not deterministic and table is non-empty,
179195
// update to refresh the value with default expr.
180-
if num_rows > 0 && !self.plan.is_deterministic {
196+
if need_update {
181197
self.ctx
182198
.evict_table_from_cache(catalog_name, db_name, tbl_name)?;
183199
let query = format!(

src/query/service/src/interpreters/interpreter_table_drop_column.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@ use databend_common_exception::Result;
2020
use databend_common_expression::DataSchema;
2121
use databend_common_meta_app::schema::DatabaseType;
2222
use databend_common_sql::plans::DropTableColumnPlan;
23+
use databend_common_sql::ApproxDistinctColumns;
2324
use databend_common_sql::BloomIndexColumns;
2425
use databend_common_storages_basic::view_table::VIEW_ENGINE;
2526
use databend_common_storages_stream::stream_table::STREAM_ENGINE;
27+
use databend_storages_common_table_meta::table::OPT_KEY_APPROX_DISTINCT_COLUMNS;
2628
use databend_storages_common_table_meta::table::OPT_KEY_BLOOM_INDEX_COLUMNS;
2729

2830
use crate::interpreters::common::check_referenced_computed_columns;
@@ -130,6 +132,17 @@ impl Interpreter for DropTableColumnInterpreter {
130132
}
131133
}
132134
}
135+
if let Some(value) = opts.get_mut(OPT_KEY_APPROX_DISTINCT_COLUMNS) {
136+
if let ApproxDistinctColumns::Specify(mut cols) =
137+
value.parse::<ApproxDistinctColumns>()?
138+
{
139+
if let Some(pos) = cols.iter().position(|x| *x == self.plan.column) {
140+
// remove from the approx distinct columns.
141+
cols.remove(pos);
142+
*value = cols.join(",");
143+
}
144+
}
145+
}
133146

134147
commit_table_meta(
135148
&self.ctx,

src/query/service/src/interpreters/interpreter_table_modify_column.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ use databend_common_sql::plans::ModifyColumnAction;
4444
use databend_common_sql::plans::ModifyTableColumnPlan;
4545
use databend_common_sql::plans::Plan;
4646
use databend_common_sql::resolve_type_name_by_str;
47+
use databend_common_sql::ApproxDistinctColumns;
4748
use databend_common_sql::BloomIndexColumns;
4849
use databend_common_sql::DefaultExprBinder;
4950
use databend_common_sql::Planner;
@@ -53,9 +54,11 @@ use databend_common_storages_stream::stream_table::STREAM_ENGINE;
5354
use databend_common_users::UserApiProvider;
5455
use databend_enterprise_data_mask_feature::get_datamask_handler;
5556
use databend_storages_common_index::BloomIndex;
57+
use databend_storages_common_index::RangeIndex;
5658
use databend_storages_common_table_meta::meta::SnapshotId;
5759
use databend_storages_common_table_meta::meta::TableMetaTimestamps;
5860
use databend_storages_common_table_meta::readers::snapshot_reader::TableSnapshotAccessor;
61+
use databend_storages_common_table_meta::table::OPT_KEY_APPROX_DISTINCT_COLUMNS;
5962
use databend_storages_common_table_meta::table::OPT_KEY_BLOOM_INDEX_COLUMNS;
6063

6164
use crate::interpreters::common::check_referenced_computed_columns;
@@ -246,6 +249,13 @@ impl ModifyTableColumnInterpreter {
246249
}
247250
}
248251

252+
let mut approx_distinct_cols = vec![];
253+
if let Some(v) = table_info.options().get(OPT_KEY_APPROX_DISTINCT_COLUMNS) {
254+
if let ApproxDistinctColumns::Specify(cols) = v.parse::<ApproxDistinctColumns>()? {
255+
approx_distinct_cols = cols;
256+
}
257+
}
258+
249259
let mut table_info = table.get_table_info().clone();
250260
table_info.meta.fill_field_comments();
251261
let mut modify_comment = false;
@@ -272,6 +282,16 @@ impl ModifyTableColumnInterpreter {
272282
field.data_type
273283
)));
274284
}
285+
if approx_distinct_cols
286+
.iter()
287+
.any(|v| v.as_str() == field.name)
288+
&& !RangeIndex::supported_table_type(&field.data_type)
289+
{
290+
return Err(ErrorCode::TableOptionInvalid(format!(
291+
"Unsupported data type '{}' for approx distinct columns",
292+
field.data_type
293+
)));
294+
}
275295
// If the column is inverted index column, the type can't be changed.
276296
if !table_info.meta.indexes.is_empty() {
277297
for (index_name, index) in &table_info.meta.indexes {

tests/sqllogictests/suites/base/05_ddl/05_0003_ddl_alter_table.test

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,31 @@ ALTER TABLE `05_0003_at_t3` MODIFY COLUMN c float not null
118118
statement ok
119119
DROP TABLE IF EXISTS `05_0003_at_t3`
120120

121+
statement ok
122+
CREATE OR REPLACE TABLE `05_0003_at_t6` ( a int, b string, c int) approx_distinct_columns = 'a,b' COMPRESSION='zstd' STORAGE_FORMAT='native'
123+
124+
statement ok
125+
ALTER TABLE `05_0003_at_t6` drop column a;
126+
127+
query TT
128+
SHOW CREATE TABLE `05_0003_at_t6`;
129+
----
130+
05_0003_at_t6 CREATE TABLE "05_0003_at_t6" ( b VARCHAR NULL, c INT NULL ) ENGINE=FUSE APPROX_DISTINCT_COLUMNS='b' COMPRESSION='zstd' ENABLE_AUTO_ANALYZE='1' STORAGE_FORMAT='native'
131+
132+
statement error 1301
133+
ALTER TABLE `05_0003_at_t6` MODIFY COLUMN b binary;
134+
135+
statement ok
136+
ALTER TABLE `05_0003_at_t6` drop column b;
137+
138+
query TT
139+
SHOW CREATE TABLE `05_0003_at_t6`;
140+
----
141+
05_0003_at_t6 CREATE TABLE "05_0003_at_t6" ( c INT NULL ) ENGINE=FUSE APPROX_DISTINCT_COLUMNS='' COMPRESSION='zstd' ENABLE_AUTO_ANALYZE='1' STORAGE_FORMAT='native'
142+
143+
statement ok
144+
DROP TABLE IF EXISTS `05_0003_at_t6`
145+
121146
statement ok
122147
set hide_options_in_show_create_table=1
123148

tests/sqllogictests/suites/ee/06_ee_stream/06_0009_stream_issue_18827.test

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ alter table t_18827 modify column b float64;
3232
statement ok
3333
alter table t_18827 modify column a binary;
3434

35+
statement error 1132
36+
alter table t_18827 add column c date default today();
37+
3538
query T
3639
select a, b from t_18827;
3740
----

0 commit comments

Comments
 (0)