Skip to content

Commit bbf32a9

Browse files
samjay000alamb
andauthored
Support create sequence with options INCREMENT, MINVALUE, MAXVALUE, START etc. (#681)
* Creat sequence options model [ INCREMENT [ BY ] increment ] [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ] [ START [ WITH ] start ] [ CACHE cache ] [ [ NO ] CYCLE ] [ OWNED BY { table_name.column_name | NONE } ] * Fix for format! not avalable in --target thumbv6m-none-eabi * Fix for format! not avalable in --target thumbv6m-none-eabi * Fix for format! not avalable in --target thumbv6m-none-eabi * Fix for format! not avalable in --target thumbv6m-none-eabi * Updated parser for sequence options * Updated parser for sequence options * Update src/ast/mod.rs Co-authored-by: Andrew Lamb <[email protected]> Co-authored-by: Andrew Lamb <[email protected]>
1 parent 93a050e commit bbf32a9

File tree

4 files changed

+235
-2
lines changed

4 files changed

+235
-2
lines changed

src/ast/mod.rs

Lines changed: 102 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1467,6 +1467,9 @@ pub enum Statement {
14671467
temporary: bool,
14681468
if_not_exists: bool,
14691469
name: ObjectName,
1470+
data_type: Option<DataType>,
1471+
sequence_options: Vec<SequenceOptions>,
1472+
owned_by: Option<ObjectName>,
14701473
},
14711474
}
14721475

@@ -2488,19 +2491,116 @@ impl fmt::Display for Statement {
24882491
temporary,
24892492
if_not_exists,
24902493
name,
2494+
data_type,
2495+
sequence_options,
2496+
owned_by,
24912497
} => {
2498+
let as_type: String = if let Some(dt) = data_type.as_ref() {
2499+
//Cannot use format!(" AS {}", dt), due to format! is not available in --target thumbv6m-none-eabi
2500+
// " AS ".to_owned() + &dt.to_string()
2501+
[" AS ", &dt.to_string()].concat()
2502+
} else {
2503+
"".to_string()
2504+
};
24922505
write!(
24932506
f,
2494-
"CREATE {temporary}SEQUENCE {if_not_exists}{name}",
2507+
"CREATE {temporary}SEQUENCE {if_not_exists}{name}{as_type}",
24952508
if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
24962509
temporary = if *temporary { "TEMPORARY " } else { "" },
2497-
name = name
2510+
name = name,
2511+
as_type = as_type
2512+
)?;
2513+
for sequence_option in sequence_options {
2514+
write!(f, "{}", sequence_option)?;
2515+
}
2516+
if let Some(ob) = owned_by.as_ref() {
2517+
write!(f, " OWNED BY {}", ob)?;
2518+
}
2519+
write!(f, "")
2520+
}
2521+
}
2522+
}
2523+
}
2524+
2525+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2526+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2527+
/// Can use to describe options in create sequence or table column type identity
2528+
/// [ INCREMENT [ BY ] increment ]
2529+
/// [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ]
2530+
/// [ START [ WITH ] start ] [ CACHE cache ] [ [ NO ] CYCLE ]
2531+
pub enum SequenceOptions {
2532+
IncrementBy(Expr, bool),
2533+
MinValue(MinMaxValue),
2534+
MaxValue(MinMaxValue),
2535+
StartWith(Expr, bool),
2536+
Cache(Expr),
2537+
Cycle(bool),
2538+
}
2539+
2540+
impl fmt::Display for SequenceOptions {
2541+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2542+
match self {
2543+
SequenceOptions::IncrementBy(increment, by) => {
2544+
write!(
2545+
f,
2546+
" INCREMENT{by} {increment}",
2547+
by = if *by { " BY" } else { "" },
2548+
increment = increment
24982549
)
24992550
}
2551+
SequenceOptions::MinValue(value) => match value {
2552+
MinMaxValue::Empty => {
2553+
write!(f, "")
2554+
}
2555+
MinMaxValue::None => {
2556+
write!(f, " NO MINVALUE")
2557+
}
2558+
MinMaxValue::Some(minvalue) => {
2559+
write!(f, " MINVALUE {minvalue}", minvalue = minvalue)
2560+
}
2561+
},
2562+
SequenceOptions::MaxValue(value) => match value {
2563+
MinMaxValue::Empty => {
2564+
write!(f, "")
2565+
}
2566+
MinMaxValue::None => {
2567+
write!(f, " NO MAXVALUE")
2568+
}
2569+
MinMaxValue::Some(maxvalue) => {
2570+
write!(f, " MAXVALUE {maxvalue}", maxvalue = maxvalue)
2571+
}
2572+
},
2573+
SequenceOptions::StartWith(start, with) => {
2574+
write!(
2575+
f,
2576+
" START{with} {start}",
2577+
with = if *with { " WITH" } else { "" },
2578+
start = start
2579+
)
2580+
}
2581+
SequenceOptions::Cache(cache) => {
2582+
write!(f, " CACHE {}", *cache)
2583+
}
2584+
SequenceOptions::Cycle(no) => {
2585+
write!(f, " {}CYCLE", if *no { "NO " } else { "" })
2586+
}
25002587
}
25012588
}
25022589
}
25032590

2591+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2592+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2593+
/// Can use to describe options in create sequence or table column type identity
2594+
/// [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ]
2595+
pub enum MinMaxValue {
2596+
// clause is not specified
2597+
Empty,
2598+
// NO MINVALUE/NO MAXVALUE
2599+
None,
2600+
// MINVALUE <expr> / MAXVALUE <expr>
2601+
Some(Expr),
2602+
}
2603+
25042604
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
25052605
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
25062606
#[non_exhaustive]

src/keywords.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ define_keywords!(
277277
IGNORE,
278278
ILIKE,
279279
IN,
280+
INCREMENT,
280281
INDEX,
281282
INDICATOR,
282283
INHERIT,
@@ -328,6 +329,7 @@ define_keywords!(
328329
MATCHED,
329330
MATERIALIZED,
330331
MAX,
332+
MAXVALUE,
331333
MEDIUMINT,
332334
MEMBER,
333335
MERGE,
@@ -341,6 +343,7 @@ define_keywords!(
341343
MILLISECONDS,
342344
MIN,
343345
MINUTE,
346+
MINVALUE,
344347
MOD,
345348
MODIFIES,
346349
MODULE,
@@ -397,6 +400,7 @@ define_keywords!(
397400
OVERLAPS,
398401
OVERLAY,
399402
OVERWRITE,
403+
OWNED,
400404
PARAMETER,
401405
PARQUET,
402406
PARTITION,

src/parser.rs

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5510,12 +5510,98 @@ impl<'a> Parser<'a> {
55105510
let if_not_exists = self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
55115511
//name
55125512
let name = self.parse_object_name()?;
5513+
//[ AS data_type ]
5514+
let mut data_type: Option<DataType> = None;
5515+
if self.parse_keywords(&[Keyword::AS]) {
5516+
data_type = Some(self.parse_data_type()?)
5517+
}
5518+
let sequence_options = self.parse_create_sequence_options()?;
5519+
// [ OWNED BY { table_name.column_name | NONE } ]
5520+
let owned_by = if self.parse_keywords(&[Keyword::OWNED, Keyword::BY]) {
5521+
if self.parse_keywords(&[Keyword::NONE]) {
5522+
Some(ObjectName(vec![Ident::new("NONE")]))
5523+
} else {
5524+
Some(self.parse_object_name()?)
5525+
}
5526+
} else {
5527+
None
5528+
};
55135529
Ok(Statement::CreateSequence {
55145530
temporary,
55155531
if_not_exists,
55165532
name,
5533+
data_type,
5534+
sequence_options,
5535+
owned_by,
55175536
})
55185537
}
5538+
5539+
fn parse_create_sequence_options(&mut self) -> Result<Vec<SequenceOptions>, ParserError> {
5540+
let mut sequence_options = vec![];
5541+
//[ INCREMENT [ BY ] increment ]
5542+
if self.parse_keywords(&[Keyword::INCREMENT]) {
5543+
if self.parse_keywords(&[Keyword::BY]) {
5544+
sequence_options.push(SequenceOptions::IncrementBy(
5545+
Expr::Value(self.parse_number_value()?),
5546+
true,
5547+
));
5548+
} else {
5549+
sequence_options.push(SequenceOptions::IncrementBy(
5550+
Expr::Value(self.parse_number_value()?),
5551+
false,
5552+
));
5553+
}
5554+
}
5555+
//[ MINVALUE minvalue | NO MINVALUE ]
5556+
if self.parse_keyword(Keyword::MINVALUE) {
5557+
sequence_options.push(SequenceOptions::MinValue(MinMaxValue::Some(Expr::Value(
5558+
self.parse_number_value()?,
5559+
))));
5560+
} else if self.parse_keywords(&[Keyword::NO, Keyword::MINVALUE]) {
5561+
sequence_options.push(SequenceOptions::MinValue(MinMaxValue::None));
5562+
} else {
5563+
sequence_options.push(SequenceOptions::MinValue(MinMaxValue::Empty));
5564+
}
5565+
//[ MAXVALUE maxvalue | NO MAXVALUE ]
5566+
if self.parse_keywords(&[Keyword::MAXVALUE]) {
5567+
sequence_options.push(SequenceOptions::MaxValue(MinMaxValue::Some(Expr::Value(
5568+
self.parse_number_value()?,
5569+
))));
5570+
} else if self.parse_keywords(&[Keyword::NO, Keyword::MAXVALUE]) {
5571+
sequence_options.push(SequenceOptions::MaxValue(MinMaxValue::None));
5572+
} else {
5573+
sequence_options.push(SequenceOptions::MaxValue(MinMaxValue::Empty));
5574+
}
5575+
//[ START [ WITH ] start ]
5576+
if self.parse_keywords(&[Keyword::START]) {
5577+
if self.parse_keywords(&[Keyword::WITH]) {
5578+
sequence_options.push(SequenceOptions::StartWith(
5579+
Expr::Value(self.parse_number_value()?),
5580+
true,
5581+
));
5582+
} else {
5583+
sequence_options.push(SequenceOptions::StartWith(
5584+
Expr::Value(self.parse_number_value()?),
5585+
false,
5586+
));
5587+
}
5588+
}
5589+
//[ CACHE cache ]
5590+
if self.parse_keywords(&[Keyword::CACHE]) {
5591+
sequence_options.push(SequenceOptions::Cache(Expr::Value(
5592+
self.parse_number_value()?,
5593+
)));
5594+
}
5595+
// [ [ NO ] CYCLE ]
5596+
if self.parse_keywords(&[Keyword::NO]) {
5597+
if self.parse_keywords(&[Keyword::CYCLE]) {
5598+
sequence_options.push(SequenceOptions::Cycle(true));
5599+
}
5600+
} else if self.parse_keywords(&[Keyword::CYCLE]) {
5601+
sequence_options.push(SequenceOptions::Cycle(false));
5602+
}
5603+
Ok(sequence_options)
5604+
}
55195605
}
55205606

55215607
impl Word {

tests/sqlparser_postgres.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,49 @@ fn parse_create_sequence() {
3737

3838
let sql4 = "CREATE TEMPORARY SEQUENCE name0";
3939
pg().one_statement_parses_to(sql4, "CREATE TEMPORARY SEQUENCE name0");
40+
41+
let sql2 = "CREATE TEMPORARY SEQUENCE IF NOT EXISTS name1
42+
AS BIGINT
43+
INCREMENT BY 1
44+
MINVALUE 1 MAXVALUE 20
45+
START WITH 10";
46+
pg().one_statement_parses_to(
47+
sql2,
48+
"CREATE TEMPORARY SEQUENCE IF NOT EXISTS name1 AS BIGINT INCREMENT BY 1 MINVALUE 1 MAXVALUE 20 START WITH 10", );
49+
50+
let sql3 = "CREATE SEQUENCE IF NOT EXISTS name2
51+
AS BIGINT
52+
INCREMENT 1
53+
MINVALUE 1 MAXVALUE 20
54+
START WITH 10 CACHE 2 NO CYCLE";
55+
pg().one_statement_parses_to(
56+
sql3,
57+
"CREATE SEQUENCE IF NOT EXISTS name2 AS BIGINT INCREMENT 1 MINVALUE 1 MAXVALUE 20 START WITH 10 CACHE 2 NO CYCLE",
58+
);
59+
60+
let sql4 = "CREATE TEMPORARY SEQUENCE IF NOT EXISTS name3
61+
INCREMENT 1
62+
NO MINVALUE MAXVALUE 20 CACHE 2 CYCLE";
63+
pg().one_statement_parses_to(
64+
sql4,
65+
"CREATE TEMPORARY SEQUENCE IF NOT EXISTS name3 INCREMENT 1 NO MINVALUE MAXVALUE 20 CACHE 2 CYCLE",
66+
);
67+
68+
let sql5 = "CREATE TEMPORARY SEQUENCE IF NOT EXISTS name3
69+
INCREMENT 1
70+
NO MINVALUE MAXVALUE 20 OWNED BY public.table01";
71+
pg().one_statement_parses_to(
72+
sql5,
73+
"CREATE TEMPORARY SEQUENCE IF NOT EXISTS name3 INCREMENT 1 NO MINVALUE MAXVALUE 20 OWNED BY public.table01",
74+
);
75+
76+
let sql6 = "CREATE TEMPORARY SEQUENCE IF NOT EXISTS name3
77+
INCREMENT 1
78+
NO MINVALUE MAXVALUE 20 OWNED BY NONE";
79+
pg().one_statement_parses_to(
80+
sql6,
81+
"CREATE TEMPORARY SEQUENCE IF NOT EXISTS name3 INCREMENT 1 NO MINVALUE MAXVALUE 20 OWNED BY NONE",
82+
);
4083
}
4184

4285
#[test]

0 commit comments

Comments
 (0)