use super::*;
use crate::ast::SequenceOptionValue::{Absent, Integer, Text};
fn failure(declaration: &SequenceDeclaration, data_type: &ColumnType, identity: bool) -> String {
let error = declare_sequence(declaration, data_type, identity).unwrap_err();
format!("{} {error}", error.sqlstate().unwrap_or_default())
}
#[test]
fn omitted_options_follow_the_type_and_the_direction_of_the_increment() {
let ascending =
declare_sequence(&SequenceDeclaration::default(), &ColumnType::Integer, true).unwrap();
assert_eq!(
ascending.definition,
SequenceDefinition {
start: 1,
increment: 1,
data_type: SequenceDataType::Integer,
min_value: 1,
max_value: i64::from(i32::MAX),
cycle: false,
cache_size: 1,
}
);
assert_eq!(ascending.current, 1);
let descending = declare_sequence(
&SequenceDeclaration {
increment: Some(Integer(-2)),
min_value: Some(Absent),
..SequenceDeclaration::default()
},
&ColumnType::SmallInteger,
true,
)
.unwrap()
.definition;
assert_eq!(
(descending.min_value, descending.max_value, descending.start),
(i64::from(i16::MIN), -1, -1)
);
}
#[test]
fn restart_gives_the_first_value_without_moving_the_start() {
let declared = declare_sequence(
&SequenceDeclaration {
start: Some(Integer(5)),
restart: Some(Text("9".into())),
..SequenceDeclaration::default()
},
&ColumnType::BigInteger,
false,
)
.unwrap();
assert_eq!((declared.definition.start, declared.current), (5, 9));
let bare = declare_sequence(
&SequenceDeclaration {
start: Some(Integer(5)),
restart: Some(Absent),
..SequenceDeclaration::default()
},
&ColumnType::BigInteger,
false,
)
.unwrap();
assert_eq!(bare.current, 5);
}
#[test]
fn options_are_read_and_checked_in_postgresql_order() {
assert_eq!(
failure(
&SequenceDeclaration {
start: Some(Text("99999999999999999999".into())),
max_value: Some(Integer(5)),
min_value: Some(Integer(7)),
..SequenceDeclaration::default()
},
&ColumnType::BigInteger,
false,
),
"22023 MINVALUE (7) must be less than MAXVALUE (5)"
);
assert_eq!(
failure(
&SequenceDeclaration {
cache: Some(Integer(0)),
start: Some(Integer(0)),
..SequenceDeclaration::default()
},
&ColumnType::Integer,
false,
),
"22023 START value (0) cannot be less than MINVALUE (1)"
);
assert_eq!(
failure(
&SequenceDeclaration {
cache: Some(Integer(0)),
..SequenceDeclaration::default()
},
&ColumnType::Integer,
false,
),
"22023 CACHE (0) must be greater than zero"
);
assert_eq!(
failure(
&SequenceDeclaration {
start: Some(Text("1.5".into())),
..SequenceDeclaration::default()
},
&ColumnType::BigInteger,
false,
),
"22P02 invalid input syntax for type bigint: \"1.5\""
);
assert_eq!(
failure(
&SequenceDeclaration {
increment: Some(Integer(0)),
max_value: Some(Text("3000000000".into())),
..SequenceDeclaration::default()
},
&ColumnType::Integer,
false,
),
"22023 INCREMENT must not be zero"
);
}
#[test]
fn an_identity_sequence_reports_its_column_type() {
assert_eq!(
failure(&SequenceDeclaration::default(), &ColumnType::Text, true),
"22023 identity column type must be smallint, integer, or bigint"
);
assert_eq!(
failure(&SequenceDeclaration::default(), &ColumnType::Text, false),
"22023 sequence type must be smallint, integer, or bigint"
);
}
#[test]
fn a_change_keeps_what_it_omits_and_checks_the_current_value() {
let base = declare_sequence(&SequenceDeclaration::default(), &ColumnType::Integer, true)
.unwrap()
.definition;
let restarted = alter_declared_sequence(
&SequenceDeclaration {
restart: Some(Integer(40)),
..SequenceDeclaration::default()
},
&base,
1,
true,
)
.unwrap();
assert_eq!((restarted.definition, restarted.current), (base, 40));
let retyped = alter_declared_sequence(
&SequenceDeclaration {
data_type: Some(ColumnType::BigInteger),
..SequenceDeclaration::default()
},
&base,
5,
true,
)
.unwrap()
.definition;
assert_eq!(
(retyped.data_type, retyped.min_value, retyped.max_value),
(SequenceDataType::BigInt, 1, i64::MAX)
);
let error = alter_declared_sequence(
&SequenceDeclaration {
data_type: Some(ColumnType::SmallInteger),
..SequenceDeclaration::default()
},
&base,
40_000,
true,
)
.unwrap_err();
assert_eq!(
error.to_string(),
"RESTART value (40000) cannot be greater than MAXVALUE (32767)"
);
let error = alter_declared_sequence(
&SequenceDeclaration {
increment: Some(Integer(-1)),
max_value: Some(Absent),
min_value: Some(Absent),
..SequenceDeclaration::default()
},
&base,
1,
true,
)
.unwrap_err();
assert_eq!(
error.to_string(),
"START value (1) cannot be greater than MAXVALUE (-1)"
);
assert_eq!(
alter_declared_sequence(
&SequenceDeclaration {
data_type: Some(ColumnType::Text),
..SequenceDeclaration::default()
},
&base,
1,
true,
)
.unwrap_err()
.to_string(),
"identity column type must be smallint, integer, or bigint"
);
}