Skip to content

Commit

Permalink
fix: cascade drop the entity in postgres
Browse files Browse the repository at this point in the history
  • Loading branch information
louisjoecodes committed May 13, 2024
1 parent b2dc692 commit d50e5a8
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 6 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions rust/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@ serde_yaml = "0.9.33"
chrono = "0.4.38"
assert_cmd = "2"
tempfile = "3"
testcontainers = "0.16.7"
testcontainers-modules = { version = "0.4.2", features = ["postgres"] }
70 changes: 69 additions & 1 deletion rust/cli/tests/cli_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ use quary_databases::databases_duckdb;
use quary_databases::databases_redshift;
use std::fs;
use tempfile::tempdir;

use testcontainers::runners::AsyncRunner;
use testcontainers::RunnableImage;
use testcontainers_modules::postgres::Postgres as TestcontainersPostgres;
#[test]
fn test_cli_in_memory() {
let name = "quary";
Expand Down Expand Up @@ -569,3 +571,69 @@ async fn test_redshift_snapshots() {
assert_eq!(current_date.date(), updated_quary_valid_from.date());
}
}

/// This test simulates a workflow where a model is built twice in a Postgres database.
/// In Postgres DROP TABLE IF EXISTS requires a CASCADE if there are view dependencies
/// Error we are trying to avoid: cannot drop view transform.model_1 because other objects depend on it
/// replace with materialized_view field in the schame to: view, materialized_view & table to test difference scenarios
#[tokio::test]
async fn test_postgres_build_model_twice() {
// Setup
let postgres = RunnableImage::from(TestcontainersPostgres::default())
.start()
.await;

let name = "quary";
let temp_dir = tempdir().unwrap();
let project_dir = temp_dir.path();

// create a .env file
let env_file_path = project_dir.join(".env");
let env_content = format!(
"PGHOST=localhost\nPGPORT={}\nPGUSER=postgres\nPGPASSWORD=postgres\nPGDATABASE=postgres",
postgres.get_host_port_ipv4(5432).await
);
fs::write(&env_file_path, env_content).unwrap();

// Create a model which reference a model
let models_dir: std::path::PathBuf = project_dir.join("models");
fs::create_dir_all(&models_dir).unwrap();
let model_1_file = models_dir.join("model_1.sql");
let model_1_content = "SELECT 100 as random_number";
let model_2_file = models_dir.join("model_2.sql");
let model_2_content = "SELECT * FROM q.model_1";
fs::write(&model_1_file, model_1_content).unwrap();
fs::write(&model_2_file, model_2_content).unwrap();

// Create quary.yaml file
let quary_yaml_content = "postgres:\n schema: public";
let quary_yaml_path = project_dir.join("quary.yaml");
fs::write(&quary_yaml_path, quary_yaml_content).unwrap();

// Create schema.yaml file
let schema_file = models_dir.join("schema.yaml");
let schema_content = r#"
models:
- name: model_1
materialization: view
- name: model_2
materialization: view
"#;
fs::write(&schema_file, schema_content).unwrap();
{
Command::cargo_bin(name)
.unwrap()
.current_dir(project_dir)
.args(vec!["build"])
.assert()
.success();
}
{
Command::cargo_bin(name)
.unwrap()
.current_dir(project_dir)
.args(vec!["build"])
.assert()
.success();
}
}
8 changes: 4 additions & 4 deletions rust/core/src/database_postgres.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,17 @@ impl DatabaseQueryGenerator for DatabaseQueryGeneratorPostgres {
let object_name = self.return_full_path_requirement(object_name);
let object_name = self.database_name_wrapper(&object_name);
match materialization_type {
None => Ok(format!("DROP VIEW IF EXISTS {}", object_name).to_string()),
None => Ok(format!("DROP VIEW IF EXISTS {} CASCADE", object_name).to_string()),
Some(materialization_type) if materialization_type == MATERIALIZATION_TYPE_VIEW => {
Ok(format!("DROP VIEW IF EXISTS {}", object_name).to_string())
Ok(format!("DROP VIEW IF EXISTS {} CASCADE", object_name).to_string())
}
Some(materialization_type) if materialization_type == MATERIALIZATION_TYPE_TABLE => {
Ok(format!("DROP TABLE IF EXISTS {}", object_name).to_string())
Ok(format!("DROP TABLE IF EXISTS {} CASCADE", object_name).to_string())
}
Some(materialization_type)
if materialization_type == MATERIALIZATION_TYPE_MATERIALIZED_VIEW =>
{
Ok(format!("DROP MATERIALIZED VIEW IF EXISTS {}", object_name).to_string())
Ok(format!("DROP MATERIALIZED VIEW IF EXISTS {} CASCADE", object_name).to_string())
}
Some(materialization_type) => Err(format!(
"Unsupported materialization type: {}",
Expand Down
2 changes: 1 addition & 1 deletion rust/quary-databases/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
mod databases_bigquery;
pub mod databases_connection;
pub mod databases_duckdb;
mod databases_postgres;
pub mod databases_postgres;
pub mod databases_redshift;
mod databases_snowflake;
mod databases_sqlite;

0 comments on commit d50e5a8

Please sign in to comment.