diff --git a/src/sql/src/statements.rs b/src/sql/src/statements.rs index 196e3b9c98..7568fcb24f 100644 --- a/src/sql/src/statements.rs +++ b/src/sql/src/statements.rs @@ -371,7 +371,20 @@ fn parse_column_default_constraint( // Always use lowercase for function expression ColumnDefaultConstraint::Function(func.to_lowercase()) } + ColumnOption::Default(Expr::UnaryOp { op, expr }) => { + // Specialized process for handling numerical inputs to prevent + // overflow errors during the parsing of negative numbers, + // See https://github.com/GreptimeTeam/greptimedb/issues/4351 + if let (UnaryOperator::Minus, Expr::Value(SqlValue::Number(n, _))) = + (op, expr.as_ref()) + { + return Ok(Some(ColumnDefaultConstraint::Value(sql_number_to_value( + data_type, + &format!("-{n}"), + )?))); + } + if let Expr::Value(v) = &**expr { let value = sql_value_to_value(column_name, data_type, v, timezone, Some(*op))?; ColumnDefaultConstraint::Value(value) @@ -1050,6 +1063,28 @@ mod tests { constraint, Some(ColumnDefaultConstraint::Value(Value::Boolean(true))) ); + + // Test negative number + let opts = vec![ColumnOptionDef { + name: None, + option: ColumnOption::Default(Expr::UnaryOp { + op: UnaryOperator::Minus, + expr: Box::new(Expr::Value(SqlValue::Number("32768".to_string(), false))), + }), + }]; + + let constraint = parse_column_default_constraint( + "coll", + &ConcreteDataType::int16_datatype(), + &opts, + None, + ) + .unwrap(); + + assert_matches!( + constraint, + Some(ColumnDefaultConstraint::Value(Value::Int16(-32768))) + ); } #[test] diff --git a/tests/cases/standalone/common/create/create.result b/tests/cases/standalone/common/create/create.result index 237873dee1..86a89483e8 100644 --- a/tests/cases/standalone/common/create/create.result +++ b/tests/cases/standalone/common/create/create.result @@ -54,6 +54,23 @@ CREATE TABLE 'N.~' (i TIMESTAMP TIME INDEX); Error: 1004(InvalidArguments), Invalid table name: N.~ +CREATE TABLE neg_default_value_min(i TIMESTAMP TIME INDEX, j SMALLINT DEFAULT -32768); + +Affected Rows: 0 + +DESC TABLE neg_default_value_min; + ++--------+----------------------+-----+------+---------+---------------+ +| Column | Type | Key | Null | Default | Semantic Type | ++--------+----------------------+-----+------+---------+---------------+ +| i | TimestampMillisecond | PRI | NO | | TIMESTAMP | +| j | Int16 | | YES | -32768 | FIELD | ++--------+----------------------+-----+------+---------+---------------+ + +DROP TABLE neg_default_value_min; + +Affected Rows: 0 + DESC TABLE integers; +--------+----------------------+-----+------+---------+---------------+ diff --git a/tests/cases/standalone/common/create/create.sql b/tests/cases/standalone/common/create/create.sql index 8aa1f48606..f5ae083318 100644 --- a/tests/cases/standalone/common/create/create.sql +++ b/tests/cases/standalone/common/create/create.sql @@ -26,6 +26,12 @@ CREATE TABLE test2 (i INTEGER, j TIMESTAMP TIME INDEX); CREATE TABLE 'N.~' (i TIMESTAMP TIME INDEX); +CREATE TABLE neg_default_value_min(i TIMESTAMP TIME INDEX, j SMALLINT DEFAULT -32768); + +DESC TABLE neg_default_value_min; + +DROP TABLE neg_default_value_min; + DESC TABLE integers; DESC TABLE test1;