1use std::fmt::{Display, Formatter};
16
17use common_time::{util, Timestamp};
18use serde::{Deserialize, Serialize};
19use snafu::{ensure, ResultExt};
20
21use crate::data_type::{ConcreteDataType, DataType};
22use crate::error::{self, Result};
23use crate::types::cast;
24use crate::value::Value;
25use crate::vectors::operations::VectorOp;
26use crate::vectors::{TimestampMillisecondVector, VectorRef};
27
28pub const CURRENT_TIMESTAMP: &str = "current_timestamp";
29pub const CURRENT_TIMESTAMP_FN: &str = "current_timestamp()";
30pub const NOW_FN: &str = "now()";
31
32#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
34pub enum ColumnDefaultConstraint {
35 Function(String),
38 Value(Value),
40}
41
42impl TryFrom<&[u8]> for ColumnDefaultConstraint {
43 type Error = error::Error;
44
45 fn try_from(bytes: &[u8]) -> Result<Self> {
46 let json = String::from_utf8_lossy(bytes);
47 serde_json::from_str(&json).context(error::DeserializeSnafu { json })
48 }
49}
50
51impl TryFrom<ColumnDefaultConstraint> for Vec<u8> {
52 type Error = error::Error;
53
54 fn try_from(value: ColumnDefaultConstraint) -> std::result::Result<Self, Self::Error> {
55 let s = serde_json::to_string(&value).context(error::SerializeSnafu)?;
56 Ok(s.into_bytes())
57 }
58}
59
60impl Display for ColumnDefaultConstraint {
61 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
62 match self {
63 ColumnDefaultConstraint::Function(expr) => write!(f, "{expr}"),
64 ColumnDefaultConstraint::Value(v) => write!(f, "{v}"),
65 }
66 }
67}
68
69impl ColumnDefaultConstraint {
70 pub fn null_value() -> ColumnDefaultConstraint {
72 ColumnDefaultConstraint::Value(Value::Null)
73 }
74
75 pub fn validate(&self, data_type: &ConcreteDataType, is_nullable: bool) -> Result<()> {
78 ensure!(is_nullable || !self.maybe_null(), error::NullDefaultSnafu);
79
80 match self {
81 ColumnDefaultConstraint::Function(expr) => {
82 ensure!(
83 expr == CURRENT_TIMESTAMP || expr == CURRENT_TIMESTAMP_FN || expr == NOW_FN,
84 error::UnsupportedDefaultExprSnafu { expr }
85 );
86 ensure!(
87 data_type.is_timestamp(),
88 error::DefaultValueTypeSnafu {
89 reason: "return value of the function must has timestamp type",
90 }
91 );
92 }
93 ColumnDefaultConstraint::Value(v) => {
94 if !v.is_null() {
95 ensure!(
98 value_type_match(data_type, v.data_type()),
99 error::DefaultValueTypeSnafu {
100 reason: format!(
101 "column has type {:?} but default value has type {:?}",
102 data_type.logical_type_id(),
103 v.logical_type_id()
104 ),
105 }
106 );
107 }
108 }
109 }
110
111 Ok(())
112 }
113
114 pub fn create_default_vector(
122 &self,
123 data_type: &ConcreteDataType,
124 is_nullable: bool,
125 num_rows: usize,
126 ) -> Result<VectorRef> {
127 assert!(num_rows > 0);
128
129 match self {
130 ColumnDefaultConstraint::Function(expr) => {
131 match &expr[..] {
134 CURRENT_TIMESTAMP | CURRENT_TIMESTAMP_FN | NOW_FN => {
137 create_current_timestamp_vector(data_type, num_rows)
138 }
139 _ => error::UnsupportedDefaultExprSnafu { expr }.fail(),
140 }
141 }
142 ColumnDefaultConstraint::Value(v) => {
143 ensure!(is_nullable || !v.is_null(), error::NullDefaultSnafu);
144
145 let mut mutable_vector = data_type.create_mutable_vector(1);
151 mutable_vector.try_push_value_ref(v.as_value_ref())?;
152 let base_vector = mutable_vector.to_vector();
153 Ok(base_vector.replicate(&[num_rows]))
154 }
155 }
156 }
157
158 pub fn create_default(&self, data_type: &ConcreteDataType, is_nullable: bool) -> Result<Value> {
163 match self {
164 ColumnDefaultConstraint::Function(expr) => {
165 match &expr[..] {
168 CURRENT_TIMESTAMP | CURRENT_TIMESTAMP_FN | NOW_FN => {
169 create_current_timestamp(data_type)
170 }
171 _ => error::UnsupportedDefaultExprSnafu { expr }.fail(),
172 }
173 }
174 ColumnDefaultConstraint::Value(v) => {
175 ensure!(is_nullable || !v.is_null(), error::NullDefaultSnafu);
176
177 Ok(v.clone())
178 }
179 }
180 }
181
182 pub fn cast_to_datatype(&self, data_type: &ConcreteDataType) -> Result<Self> {
184 match self {
185 ColumnDefaultConstraint::Value(v) => Ok(Self::Value(cast(v.clone(), data_type)?)),
186 ColumnDefaultConstraint::Function(expr) => match &expr[..] {
187 CURRENT_TIMESTAMP | CURRENT_TIMESTAMP_FN | NOW_FN => Ok(self.clone()),
189 _ => error::UnsupportedDefaultExprSnafu { expr }.fail(),
190 },
191 }
192 }
193
194 pub fn create_impure_default_vector(
198 &self,
199 data_type: &ConcreteDataType,
200 num_rows: usize,
201 ) -> Result<Option<VectorRef>> {
202 assert!(num_rows > 0);
203
204 match self {
205 ColumnDefaultConstraint::Function(expr) => {
206 match &expr[..] {
209 CURRENT_TIMESTAMP | CURRENT_TIMESTAMP_FN | NOW_FN => {
212 create_current_timestamp_vector(data_type, num_rows).map(Some)
213 }
214 _ => error::UnsupportedDefaultExprSnafu { expr }.fail(),
215 }
216 }
217 ColumnDefaultConstraint::Value(_) => Ok(None),
218 }
219 }
220
221 pub fn create_impure_default(&self, data_type: &ConcreteDataType) -> Result<Option<Value>> {
225 match self {
226 ColumnDefaultConstraint::Function(expr) => {
227 match &expr[..] {
230 CURRENT_TIMESTAMP | CURRENT_TIMESTAMP_FN | NOW_FN => {
231 create_current_timestamp(data_type).map(Some)
232 }
233 _ => error::UnsupportedDefaultExprSnafu { expr }.fail(),
234 }
235 }
236 ColumnDefaultConstraint::Value(_) => Ok(None),
237 }
238 }
239
240 fn maybe_null(&self) -> bool {
242 matches!(self, ColumnDefaultConstraint::Value(Value::Null))
245 }
246
247 pub fn is_function(&self) -> bool {
249 matches!(self, ColumnDefaultConstraint::Function(_))
250 }
251}
252
253fn create_current_timestamp(data_type: &ConcreteDataType) -> Result<Value> {
254 let Some(timestamp_type) = data_type.as_timestamp() else {
255 return error::DefaultValueTypeSnafu {
256 reason: format!("Not support to assign current timestamp to {data_type:?} type"),
257 }
258 .fail();
259 };
260
261 let unit = timestamp_type.unit();
262 Ok(Value::Timestamp(Timestamp::current_time(unit)))
263}
264
265fn create_current_timestamp_vector(
266 data_type: &ConcreteDataType,
267 num_rows: usize,
268) -> Result<VectorRef> {
269 let current_timestamp_vector = TimestampMillisecondVector::from_values(std::iter::repeat_n(
270 util::current_time_millis(),
271 num_rows,
272 ));
273 if data_type.is_timestamp() {
274 current_timestamp_vector.cast(data_type)
275 } else {
276 error::DefaultValueTypeSnafu {
277 reason: format!("Not support to assign current timestamp to {data_type:?} type",),
278 }
279 .fail()
280 }
281}
282
283fn value_type_match(column_type: &ConcreteDataType, value_type: ConcreteDataType) -> bool {
284 match (column_type, value_type) {
285 (ct, vt) if ct.logical_type_id() == vt.logical_type_id() => true,
286 (ConcreteDataType::Vector(_) | ConcreteDataType::Json(_), ConcreteDataType::Binary(_)) => {
288 true
289 }
290 _ => false,
291 }
292}
293
294#[cfg(test)]
295mod tests {
296 use std::sync::Arc;
297
298 use super::*;
299 use crate::error::Error;
300 use crate::vectors::Int32Vector;
301
302 #[test]
303 fn test_null_default_constraint() {
304 let constraint = ColumnDefaultConstraint::null_value();
305 assert!(constraint.maybe_null());
306 let constraint = ColumnDefaultConstraint::Value(Value::Int32(10));
307 assert!(!constraint.maybe_null());
308 }
309
310 #[test]
311 fn test_validate_null_constraint() {
312 let constraint = ColumnDefaultConstraint::null_value();
313 let data_type = ConcreteDataType::int32_datatype();
314 assert!(constraint.validate(&data_type, false).is_err());
315 constraint.validate(&data_type, true).unwrap();
316 }
317
318 #[test]
319 fn test_validate_value_constraint() {
320 let constraint = ColumnDefaultConstraint::Value(Value::Int32(10));
321 let data_type = ConcreteDataType::int32_datatype();
322 constraint.validate(&data_type, false).unwrap();
323 constraint.validate(&data_type, true).unwrap();
324
325 assert!(constraint
326 .validate(&ConcreteDataType::uint32_datatype(), true)
327 .is_err());
328 }
329
330 #[test]
331 fn test_validate_function_constraint() {
332 let constraint = ColumnDefaultConstraint::Function(CURRENT_TIMESTAMP.to_string());
333 constraint
334 .validate(&ConcreteDataType::timestamp_millisecond_datatype(), false)
335 .unwrap();
336 assert!(constraint
337 .validate(&ConcreteDataType::boolean_datatype(), false)
338 .is_err());
339
340 let constraint = ColumnDefaultConstraint::Function("hello()".to_string());
341 assert!(constraint
342 .validate(&ConcreteDataType::timestamp_millisecond_datatype(), false)
343 .is_err());
344 }
345
346 #[test]
347 fn test_create_default_vector_by_null() {
348 let constraint = ColumnDefaultConstraint::null_value();
349 let data_type = ConcreteDataType::int32_datatype();
350 assert!(constraint
351 .create_default_vector(&data_type, false, 10)
352 .is_err());
353
354 let constraint = ColumnDefaultConstraint::null_value();
355 let v = constraint
356 .create_default_vector(&data_type, true, 3)
357 .unwrap();
358 assert_eq!(3, v.len());
359 for i in 0..v.len() {
360 assert_eq!(Value::Null, v.get(i));
361 }
362 }
363
364 #[test]
365 fn test_create_default_by_value() {
366 let constraint = ColumnDefaultConstraint::Value(Value::Int32(10));
367 let data_type = ConcreteDataType::int32_datatype();
368 let v = constraint
369 .create_default_vector(&data_type, false, 4)
370 .unwrap();
371 let expect: VectorRef = Arc::new(Int32Vector::from_values(vec![10; 4]));
372 assert_eq!(expect, v);
373 let v = constraint.create_default(&data_type, false).unwrap();
374 assert_eq!(Value::Int32(10), v);
375 }
376
377 #[test]
378 fn test_create_default_vector_by_func() {
379 let constraint = ColumnDefaultConstraint::Function(CURRENT_TIMESTAMP.to_string());
380 let check_value = |v| {
381 assert!(
382 matches!(v, Value::Timestamp(_)),
383 "v {:?} is not timestamp",
384 v
385 );
386 };
387 let check_vector = |v: VectorRef| {
388 assert_eq!(4, v.len());
389 assert!(
390 matches!(v.get(0), Value::Timestamp(_)),
391 "v {:?} is not timestamp",
392 v.get(0)
393 );
394 };
395
396 let data_type = ConcreteDataType::timestamp_millisecond_datatype();
398 let v = constraint
399 .create_default_vector(&data_type, false, 4)
400 .unwrap();
401 check_vector(v);
402
403 let v = constraint.create_default(&data_type, false).unwrap();
404 check_value(v);
405
406 let data_type = ConcreteDataType::timestamp_second_datatype();
407 let v = constraint
408 .create_default_vector(&data_type, false, 4)
409 .unwrap();
410 check_vector(v);
411
412 let v = constraint.create_default(&data_type, false).unwrap();
413 check_value(v);
414
415 let data_type = ConcreteDataType::timestamp_microsecond_datatype();
416 let v = constraint
417 .create_default_vector(&data_type, false, 4)
418 .unwrap();
419 check_vector(v);
420
421 let v = constraint.create_default(&data_type, false).unwrap();
422 check_value(v);
423
424 let data_type = ConcreteDataType::timestamp_nanosecond_datatype();
425 let v = constraint
426 .create_default_vector(&data_type, false, 4)
427 .unwrap();
428 check_vector(v);
429
430 let v = constraint.create_default(&data_type, false).unwrap();
431 check_value(v);
432
433 let data_type = ConcreteDataType::int64_datatype();
435 let v = constraint.create_default_vector(&data_type, false, 4);
436 assert!(v.is_err());
437
438 let constraint = ColumnDefaultConstraint::Function("no".to_string());
439 let data_type = ConcreteDataType::timestamp_millisecond_datatype();
440 assert!(constraint
441 .create_default_vector(&data_type, false, 4)
442 .is_err());
443 assert!(constraint.create_default(&data_type, false).is_err());
444 }
445
446 #[test]
447 fn test_create_by_func_and_invalid_type() {
448 let constraint = ColumnDefaultConstraint::Function(CURRENT_TIMESTAMP.to_string());
449 let data_type = ConcreteDataType::boolean_datatype();
450 let err = constraint
451 .create_default_vector(&data_type, false, 4)
452 .unwrap_err();
453 assert!(matches!(err, Error::DefaultValueType { .. }), "{err:?}");
454 }
455}