1use std::fmt::{Display, Formatter};
16
17use common_time::{Timestamp, util};
18use serde::{Deserialize, Serialize};
19use snafu::{ResultExt, ensure};
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::{Helper, 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 TryFrom<&ColumnDefaultConstraint> for Vec<u8> {
61 type Error = error::Error;
62
63 fn try_from(value: &ColumnDefaultConstraint) -> std::result::Result<Self, Self::Error> {
64 let s = serde_json::to_string(value).context(error::SerializeSnafu)?;
65 Ok(s.into_bytes())
66 }
67}
68
69impl Display for ColumnDefaultConstraint {
70 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
71 match self {
72 ColumnDefaultConstraint::Function(expr) => write!(f, "{expr}"),
73 ColumnDefaultConstraint::Value(v) => write!(f, "{v}"),
74 }
75 }
76}
77
78impl ColumnDefaultConstraint {
79 pub fn null_value() -> ColumnDefaultConstraint {
81 ColumnDefaultConstraint::Value(Value::Null)
82 }
83
84 pub fn validate(&self, data_type: &ConcreteDataType, is_nullable: bool) -> Result<()> {
87 ensure!(is_nullable || !self.maybe_null(), error::NullDefaultSnafu);
88
89 match self {
90 ColumnDefaultConstraint::Function(expr) => {
91 ensure!(
92 expr == CURRENT_TIMESTAMP || expr == CURRENT_TIMESTAMP_FN || expr == NOW_FN,
93 error::UnsupportedDefaultExprSnafu { expr }
94 );
95 ensure!(
96 data_type.is_timestamp(),
97 error::DefaultValueTypeSnafu {
98 reason: "return value of the function must has timestamp type",
99 }
100 );
101 }
102 ColumnDefaultConstraint::Value(v) => {
103 if !v.is_null() {
104 ensure!(
107 value_type_match(data_type, v.data_type()),
108 error::DefaultValueTypeSnafu {
109 reason: format!(
110 "column has type {:?} but default value has type {:?}",
111 data_type.logical_type_id(),
112 v.logical_type_id()
113 ),
114 }
115 );
116 }
117 }
118 }
119
120 Ok(())
121 }
122
123 pub fn create_default_vector(
131 &self,
132 data_type: &ConcreteDataType,
133 is_nullable: bool,
134 num_rows: usize,
135 ) -> Result<VectorRef> {
136 assert!(num_rows > 0);
137
138 match self {
139 ColumnDefaultConstraint::Function(expr) => {
140 match &expr[..] {
143 CURRENT_TIMESTAMP | CURRENT_TIMESTAMP_FN | NOW_FN => {
146 create_current_timestamp_vector(data_type, num_rows)
147 }
148 _ => error::UnsupportedDefaultExprSnafu { expr }.fail(),
149 }
150 }
151 ColumnDefaultConstraint::Value(v) => {
152 ensure!(is_nullable || !v.is_null(), error::NullDefaultSnafu);
153
154 if let Ok(vector) = v.try_to_scalar_value(data_type).and_then(|scalar| {
155 Helper::try_from_scalar_value(scalar, num_rows, Some(data_type))
156 }) {
157 return Ok(vector);
158 }
159
160 let mut mutable_vector = data_type.create_mutable_vector(num_rows);
164 for _ in 0..num_rows {
165 mutable_vector.try_push_value_ref(&v.as_value_ref())?;
166 }
167 Ok(mutable_vector.to_vector())
168 }
169 }
170 }
171
172 pub fn create_default(&self, data_type: &ConcreteDataType, is_nullable: bool) -> Result<Value> {
177 match self {
178 ColumnDefaultConstraint::Function(expr) => {
179 match &expr[..] {
182 CURRENT_TIMESTAMP | CURRENT_TIMESTAMP_FN | NOW_FN => {
183 create_current_timestamp(data_type)
184 }
185 _ => error::UnsupportedDefaultExprSnafu { expr }.fail(),
186 }
187 }
188 ColumnDefaultConstraint::Value(v) => {
189 ensure!(is_nullable || !v.is_null(), error::NullDefaultSnafu);
190
191 Ok(v.clone())
192 }
193 }
194 }
195
196 pub fn cast_to_datatype(&self, data_type: &ConcreteDataType) -> Result<Self> {
198 match self {
199 ColumnDefaultConstraint::Value(v) => Ok(Self::Value(cast(v.clone(), data_type)?)),
200 ColumnDefaultConstraint::Function(expr) => match &expr[..] {
201 CURRENT_TIMESTAMP | CURRENT_TIMESTAMP_FN | NOW_FN => Ok(self.clone()),
203 _ => error::UnsupportedDefaultExprSnafu { expr }.fail(),
204 },
205 }
206 }
207
208 pub fn create_impure_default_vector(
212 &self,
213 data_type: &ConcreteDataType,
214 num_rows: usize,
215 ) -> Result<Option<VectorRef>> {
216 assert!(num_rows > 0);
217
218 match self {
219 ColumnDefaultConstraint::Function(expr) => {
220 match &expr[..] {
223 CURRENT_TIMESTAMP | CURRENT_TIMESTAMP_FN | NOW_FN => {
226 create_current_timestamp_vector(data_type, num_rows).map(Some)
227 }
228 _ => error::UnsupportedDefaultExprSnafu { expr }.fail(),
229 }
230 }
231 ColumnDefaultConstraint::Value(_) => Ok(None),
232 }
233 }
234
235 pub fn create_impure_default(&self, data_type: &ConcreteDataType) -> Result<Option<Value>> {
239 match self {
240 ColumnDefaultConstraint::Function(expr) => {
241 match &expr[..] {
244 CURRENT_TIMESTAMP | CURRENT_TIMESTAMP_FN | NOW_FN => {
245 create_current_timestamp(data_type).map(Some)
246 }
247 _ => error::UnsupportedDefaultExprSnafu { expr }.fail(),
248 }
249 }
250 ColumnDefaultConstraint::Value(_) => Ok(None),
251 }
252 }
253
254 fn maybe_null(&self) -> bool {
256 matches!(self, ColumnDefaultConstraint::Value(Value::Null))
259 }
260
261 pub fn is_function(&self) -> bool {
263 matches!(self, ColumnDefaultConstraint::Function(_))
264 }
265}
266
267fn create_current_timestamp(data_type: &ConcreteDataType) -> Result<Value> {
268 let Some(timestamp_type) = data_type.as_timestamp() else {
269 return error::DefaultValueTypeSnafu {
270 reason: format!("Not support to assign current timestamp to {data_type:?} type"),
271 }
272 .fail();
273 };
274
275 let unit = timestamp_type.unit();
276 Ok(Value::Timestamp(Timestamp::current_time(unit)))
277}
278
279fn create_current_timestamp_vector(
280 data_type: &ConcreteDataType,
281 num_rows: usize,
282) -> Result<VectorRef> {
283 let current_timestamp_vector = TimestampMillisecondVector::from_values(std::iter::repeat_n(
284 util::current_time_millis(),
285 num_rows,
286 ));
287 if data_type.is_timestamp() {
288 current_timestamp_vector.cast(data_type)
289 } else {
290 error::DefaultValueTypeSnafu {
291 reason: format!("Not support to assign current timestamp to {data_type:?} type",),
292 }
293 .fail()
294 }
295}
296
297fn value_type_match(column_type: &ConcreteDataType, value_type: ConcreteDataType) -> bool {
298 match (column_type, value_type) {
299 (ct, vt) if ct.logical_type_id() == vt.logical_type_id() => true,
300 (ConcreteDataType::Vector(_) | ConcreteDataType::Json(_), ConcreteDataType::Binary(_)) => {
302 true
303 }
304 _ => false,
305 }
306}
307
308#[cfg(test)]
309mod tests {
310 use std::sync::Arc;
311
312 use super::*;
313 use crate::error::Error;
314 use crate::vectors::Int32Vector;
315
316 #[test]
317 fn test_null_default_constraint() {
318 let constraint = ColumnDefaultConstraint::null_value();
319 assert!(constraint.maybe_null());
320 let constraint = ColumnDefaultConstraint::Value(Value::Int32(10));
321 assert!(!constraint.maybe_null());
322 }
323
324 #[test]
325 fn test_validate_null_constraint() {
326 let constraint = ColumnDefaultConstraint::null_value();
327 let data_type = ConcreteDataType::int32_datatype();
328 assert!(constraint.validate(&data_type, false).is_err());
329 constraint.validate(&data_type, true).unwrap();
330 }
331
332 #[test]
333 fn test_validate_value_constraint() {
334 let constraint = ColumnDefaultConstraint::Value(Value::Int32(10));
335 let data_type = ConcreteDataType::int32_datatype();
336 constraint.validate(&data_type, false).unwrap();
337 constraint.validate(&data_type, true).unwrap();
338
339 assert!(
340 constraint
341 .validate(&ConcreteDataType::uint32_datatype(), true)
342 .is_err()
343 );
344 }
345
346 #[test]
347 fn test_validate_function_constraint() {
348 let constraint = ColumnDefaultConstraint::Function(CURRENT_TIMESTAMP.to_string());
349 constraint
350 .validate(&ConcreteDataType::timestamp_millisecond_datatype(), false)
351 .unwrap();
352 assert!(
353 constraint
354 .validate(&ConcreteDataType::boolean_datatype(), false)
355 .is_err()
356 );
357
358 let constraint = ColumnDefaultConstraint::Function("hello()".to_string());
359 assert!(
360 constraint
361 .validate(&ConcreteDataType::timestamp_millisecond_datatype(), false)
362 .is_err()
363 );
364 }
365
366 #[test]
367 fn test_create_default_vector_by_null() {
368 let constraint = ColumnDefaultConstraint::null_value();
369 let data_type = ConcreteDataType::int32_datatype();
370 assert!(
371 constraint
372 .create_default_vector(&data_type, false, 10)
373 .is_err()
374 );
375
376 let constraint = ColumnDefaultConstraint::null_value();
377 let v = constraint
378 .create_default_vector(&data_type, true, 3)
379 .unwrap();
380 assert_eq!(3, v.len());
381 for i in 0..v.len() {
382 assert_eq!(Value::Null, v.get(i));
383 }
384 }
385
386 #[test]
387 fn test_create_default_by_value() {
388 let constraint = ColumnDefaultConstraint::Value(Value::Int32(10));
389 let data_type = ConcreteDataType::int32_datatype();
390 let v = constraint
391 .create_default_vector(&data_type, false, 4)
392 .unwrap();
393 let expect: VectorRef = Arc::new(Int32Vector::from_values(vec![10; 4]));
394 assert_eq!(expect, v);
395 let v = constraint.create_default(&data_type, false).unwrap();
396 assert_eq!(Value::Int32(10), v);
397 }
398
399 #[test]
400 fn test_struct_default_null_fields_and_json() {
401 use crate::types::{StructField, StructType};
402 use crate::value::StructValue;
403
404 let inner_type = StructType::from([StructField::new(
405 "x",
406 ConcreteDataType::int32_datatype(),
407 true,
408 )]);
409 let inner = Value::Struct(StructValue::new(vec![Value::Null], inner_type));
410 let json = crate::json::JsonSettings::default()
411 .encode(serde_json::json!({"answer": 42}))
412 .unwrap();
413 let nested_type = StructType::from([StructField::new("nested", inner.data_type(), true)]);
414 let json_type = StructType::from([StructField::new("json", json.data_type(), true)]);
415 let values = [
416 inner.clone(),
417 Value::Struct(StructValue::new(vec![inner], nested_type)),
418 Value::Struct(StructValue::new(vec![], StructType::default())),
419 Value::Struct(StructValue::new(vec![json], json_type)),
420 ];
421 for value in values {
422 let data_type = value.data_type();
423 let expected = serde_json::Value::try_from(value.clone()).unwrap();
425 for num_rows in [1, 3] {
426 let vector = ColumnDefaultConstraint::Value(value.clone())
427 .create_default_vector(&data_type, false, num_rows)
428 .unwrap();
429 assert_eq!(data_type, vector.data_type());
430 assert_eq!(
431 data_type.as_arrow_type(),
432 *vector.to_arrow_array().data_type()
433 );
434 assert_eq!(num_rows, vector.len());
435 assert_eq!(0, vector.null_count());
436 for row in 0..num_rows {
437 assert_eq!(
438 expected,
439 serde_json::Value::try_from(vector.get(row)).unwrap()
440 );
441 }
442 }
443 }
444 }
445
446 #[test]
447 fn test_string_default_preserves_batch_schema() {
448 use arrow::datatypes::{Field, Schema};
449 use arrow::record_batch::RecordBatch;
450
451 for data_type in [
452 ConcreteDataType::large_string_datatype(),
453 ConcreteDataType::utf8_view_datatype(),
454 ] {
455 let schema = Arc::new(Schema::new(vec![Field::new(
456 "tag",
457 data_type.as_arrow_type(),
458 true,
459 )]));
460 for value in [Value::from("greptime"), Value::Null] {
461 let vector = ColumnDefaultConstraint::Value(value.clone())
462 .create_default_vector(&data_type, true, 3)
463 .unwrap();
464 let batch =
465 RecordBatch::try_new(schema.clone(), vec![vector.to_arrow_array()]).unwrap();
466 assert_eq!(3, batch.num_rows());
467 assert_eq!(data_type, vector.data_type());
468 for row in 0..batch.num_rows() {
469 assert_eq!(value, vector.get(row));
470 }
471 }
472 }
473 }
474
475 #[test]
476 fn test_create_default_vector_by_func() {
477 let constraint = ColumnDefaultConstraint::Function(CURRENT_TIMESTAMP.to_string());
478 let check_value = |v| {
479 assert!(
480 matches!(v, Value::Timestamp(_)),
481 "v {:?} is not timestamp",
482 v
483 );
484 };
485 let check_vector = |v: VectorRef| {
486 assert_eq!(4, v.len());
487 assert!(
488 matches!(v.get(0), Value::Timestamp(_)),
489 "v {:?} is not timestamp",
490 v.get(0)
491 );
492 };
493
494 let data_type = ConcreteDataType::timestamp_millisecond_datatype();
496 let v = constraint
497 .create_default_vector(&data_type, false, 4)
498 .unwrap();
499 check_vector(v);
500
501 let v = constraint.create_default(&data_type, false).unwrap();
502 check_value(v);
503
504 let data_type = ConcreteDataType::timestamp_second_datatype();
505 let v = constraint
506 .create_default_vector(&data_type, false, 4)
507 .unwrap();
508 check_vector(v);
509
510 let v = constraint.create_default(&data_type, false).unwrap();
511 check_value(v);
512
513 let data_type = ConcreteDataType::timestamp_microsecond_datatype();
514 let v = constraint
515 .create_default_vector(&data_type, false, 4)
516 .unwrap();
517 check_vector(v);
518
519 let v = constraint.create_default(&data_type, false).unwrap();
520 check_value(v);
521
522 let data_type = ConcreteDataType::timestamp_nanosecond_datatype();
523 let v = constraint
524 .create_default_vector(&data_type, false, 4)
525 .unwrap();
526 check_vector(v);
527
528 let v = constraint.create_default(&data_type, false).unwrap();
529 check_value(v);
530
531 let data_type = ConcreteDataType::int64_datatype();
533 let v = constraint.create_default_vector(&data_type, false, 4);
534 assert!(v.is_err());
535
536 let constraint = ColumnDefaultConstraint::Function("no".to_string());
537 let data_type = ConcreteDataType::timestamp_millisecond_datatype();
538 assert!(
539 constraint
540 .create_default_vector(&data_type, false, 4)
541 .is_err()
542 );
543 assert!(constraint.create_default(&data_type, false).is_err());
544 }
545
546 #[test]
547 fn test_create_by_func_and_invalid_type() {
548 let constraint = ColumnDefaultConstraint::Function(CURRENT_TIMESTAMP.to_string());
549 let data_type = ConcreteDataType::boolean_datatype();
550 let err = constraint
551 .create_default_vector(&data_type, false, 4)
552 .unwrap_err();
553 assert!(matches!(err, Error::DefaultValueType { .. }), "{err:?}");
554 }
555}