Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions src/backend/mysql/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,10 +237,93 @@ impl TableBuilder for MysqlQueryBuilder {
}
}

fn prepare_partition_by(&self, partition_by: &PartitionBy, sql: &mut impl SqlWriter) {
match partition_by {
PartitionBy::Range(cols) => {
sql.write_str("RANGE (").unwrap();
self.prepare_partition_cols(cols, sql);
sql.write_char(')').unwrap();
}
PartitionBy::List(cols) => {
sql.write_str("LIST (").unwrap();
self.prepare_partition_cols(cols, sql);
sql.write_char(')').unwrap();
}
PartitionBy::Hash(cols) => {
sql.write_str("HASH (").unwrap();
self.prepare_partition_cols(cols, sql);
sql.write_char(')').unwrap();
}
PartitionBy::Key(cols) => {
sql.write_str("KEY (").unwrap();
self.prepare_partition_cols(cols, sql);
sql.write_char(')').unwrap();
}
}
}

fn prepare_partition_definition(
&self,
partition_definition: &PartitionDefinition,
sql: &mut impl SqlWriter,
) {
sql.write_str("PARTITION ").unwrap();
self.prepare_iden(&partition_definition.name, sql);
if let Some(values) = &partition_definition.values {
sql.write_str(" ").unwrap();
self.prepare_partition_values(values, sql);
}
}

fn prepare_partition_values(
&self,
partition_values: &PartitionValues,
sql: &mut impl SqlWriter,
) {
match partition_values {
PartitionValues::In(values) => {
sql.write_str("VALUES IN (").unwrap();
self.prepare_partition_exprs(values, sql);
sql.write_char(')').unwrap();
}
PartitionValues::FromTo(_, _) => panic!("MySQL does not support VALUES FROM ... TO"),
PartitionValues::LessThan(values) => {
sql.write_str("VALUES LESS THAN (").unwrap();
self.prepare_partition_exprs(values, sql);
sql.write_char(')').unwrap();
}
PartitionValues::With(_, _) => panic!("MySQL does not support VALUES WITH"),
}
}

/// column comment
fn column_comment(&self, comment: &str, sql: &mut impl SqlWriter) {
sql.write_str(" COMMENT '").unwrap();
self.write_escaped(sql, comment);
sql.write_str("'").unwrap();
}
}

impl MysqlQueryBuilder {
fn prepare_partition_cols(&self, cols: &[DynIden], sql: &mut impl SqlWriter) {
let mut first = true;
for col in cols {
if !first {
sql.write_str(", ").unwrap();
}
self.prepare_iden(col, sql);
first = false;
}
}

fn prepare_partition_exprs(&self, exprs: &[Expr], sql: &mut impl SqlWriter) {
let mut first = true;
for expr in exprs {
if !first {
sql.write_str(", ").unwrap();
}
self.prepare_expr(expr, sql);
first = false;
}
}
}
71 changes: 71 additions & 0 deletions src/backend/postgres/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,77 @@ impl TableBuilder for PostgresQueryBuilder {
self.prepare_table_ref_table_stmt(to_name, sql);
}
}

fn prepare_partition_by(&self, partition_by: &PartitionBy, sql: &mut impl SqlWriter) {
match partition_by {
PartitionBy::Range(cols) => {
sql.write_str("RANGE (").unwrap();
self.prepare_partition_cols(cols, sql);
sql.write_char(')').unwrap();
}
PartitionBy::List(cols) => {
sql.write_str("LIST (").unwrap();
self.prepare_partition_cols(cols, sql);
sql.write_char(')').unwrap();
}
PartitionBy::Hash(cols) => {
sql.write_str("HASH (").unwrap();
self.prepare_partition_cols(cols, sql);
sql.write_char(')').unwrap();
}
PartitionBy::Key(_) => panic!("Postgres does not support PARTITION BY KEY"),
}
}

fn prepare_partition_values(
&self,
partition_values: &PartitionValues,
sql: &mut impl SqlWriter,
) {
sql.write_str("FOR VALUES ").unwrap();
match partition_values {
PartitionValues::In(values) => {
sql.write_str("IN (").unwrap();
self.prepare_partition_exprs(values, sql);
sql.write_char(')').unwrap();
}
PartitionValues::FromTo(from, to) => {
sql.write_str("FROM (").unwrap();
self.prepare_partition_exprs(from, sql);
sql.write_str(") TO (").unwrap();
self.prepare_partition_exprs(to, sql);
sql.write_char(')').unwrap();
}
PartitionValues::LessThan(_) => panic!("Postgres does not support VALUES LESS THAN"),
PartitionValues::With(modulus, remainder) => {
write!(sql, "WITH (MODULUS {modulus}, REMAINDER {remainder})").unwrap();
}
}
}
}

impl PostgresQueryBuilder {
fn prepare_partition_cols(&self, cols: &[DynIden], sql: &mut impl SqlWriter) {
let mut first = true;
for col in cols {
if !first {
sql.write_str(", ").unwrap();
}
self.prepare_iden(col, sql);
first = false;
}
}

fn prepare_partition_exprs(&self, exprs: &[Expr], sql: &mut impl SqlWriter) {
let mut first = true;
for expr in exprs {
if !first {
sql.write_str(", ").unwrap();
}
self.prepare_expr(expr, sql);
first = false;
}
}
}

impl PostgresQueryBuilder {
Expand Down
117 changes: 83 additions & 34 deletions src/backend/table_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,42 +21,80 @@ pub trait TableBuilder:
self.prepare_table_ref_table_stmt(table_ref, sql);
}

sql.write_str(" ( ").unwrap();
let mut first = true;
if let Some(partition_of) = &create.partition_of {
sql.write_str(" PARTITION OF ").unwrap();
self.prepare_table_ref_table_stmt(partition_of, sql);
}

create.columns.iter().for_each(|column_def| {
if !first {
sql.write_str(", ").unwrap();
}
self.prepare_column_def(column_def, sql);
first = false;
});
if !create.columns.is_empty()
|| !create.indexes.is_empty()
|| !create.foreign_keys.is_empty()
|| !create.check.is_empty()
{
sql.write_str(" ( ").unwrap();
let mut first = true;

create.columns.iter().for_each(|column_def| {
if !first {
sql.write_str(", ").unwrap();
}
self.prepare_column_def(column_def, sql);
first = false;
});

create.indexes.iter().for_each(|index| {
if !first {
sql.write_str(", ").unwrap();
}
self.prepare_table_index_expression(index, sql);
first = false;
});
create.indexes.iter().for_each(|index| {
if !first {
sql.write_str(", ").unwrap();
}
self.prepare_table_index_expression(index, sql);
first = false;
});

create.foreign_keys.iter().for_each(|foreign_key| {
if !first {
sql.write_str(", ").unwrap();
}
self.prepare_foreign_key_create_statement_internal(foreign_key, sql, Mode::Creation);
first = false;
});
create.foreign_keys.iter().for_each(|foreign_key| {
if !first {
sql.write_str(", ").unwrap();
}
self.prepare_foreign_key_create_statement_internal(
foreign_key,
sql,
Mode::Creation,
);
first = false;
});

create.check.iter().for_each(|check| {
if !first {
sql.write_str(", ").unwrap();
}
self.prepare_check_constraint(check, sql);
first = false;
});

create.check.iter().for_each(|check| {
if !first {
sql.write_str(", ").unwrap();
}
self.prepare_check_constraint(check, sql);
first = false;
});
sql.write_str(" )").unwrap();
}

sql.write_str(" )").unwrap();
if let Some(partition_values) = &create.partition_values {
sql.write_str(" ").unwrap();
self.prepare_partition_values(partition_values, sql);
}

if let Some(partition_by) = &create.partition_by {
sql.write_str(" PARTITION BY ").unwrap();
self.prepare_partition_by(partition_by, sql);
}

if !create.partitions.is_empty() {
sql.write_str(" ( ").unwrap();
let mut first = true;
for partition in create.partitions.iter() {
if !first {
sql.write_str(", ").unwrap();
}
self.prepare_partition_definition(partition, sql);
first = false;
}
sql.write_str(" )").unwrap();
}

self.prepare_table_opt(create, sql);

Expand Down Expand Up @@ -197,10 +235,21 @@ pub trait TableBuilder:
}
}

/// Translate [`TablePartition`] into SQL statement.
fn prepare_table_partition(
/// Translate [`PartitionBy`] into SQL statement.
fn prepare_partition_by(&self, _partition_by: &PartitionBy, _sql: &mut impl SqlWriter) {}

/// Translate [`PartitionValues`] into SQL statement.
fn prepare_partition_values(
&self,
_partition_values: &PartitionValues,
_sql: &mut impl SqlWriter,
) {
}

/// Translate [`PartitionDefinition`] into SQL statement.
fn prepare_partition_definition(
&self,
_table_partition: &TablePartition,
_partition_definition: &PartitionDefinition,
_sql: &mut impl SqlWriter,
) {
}
Expand Down
Loading
Loading