chore: import upstream snapshot with attribution
CI / compile_and_lint (push) Failing after 0s
CI / docker_build (linux/amd64, -linux-amd64-duckdb, duckdb) (push) Failing after 0s
CI / docker_build (linux/arm64, -linux-arm64, minimal) (push) Failing after 2s
CI / docker_build (linux/arm64, -linux-arm64-duckdb, duckdb) (push) Failing after 1s
CI / docker_build (linux/amd64, minimal) (push) Failing after 1s
CI / test (, sqlite, sqlite::memory:) (push) Has been skipped
CI / test (mssql, mssql, mssql://root:Password123!@127.0.0.1/sqlpage) (push) Has been skipped
CI / test (mysql, mysql, mysql://root:Password123!@127.0.0.1/sqlpage) (push) Has been skipped
CI / test (oracle, oracle, Driver=Oracle 21 ODBC driver;Dbq=//127.0.0.1:1521/FREEPDB1;Uid=root;Pwd=Password123!) (push) Has been skipped
CI / test (postgres, odbc, Driver=PostgreSQL Unicode;Server=127.0.0.1;Port=5432;Database=sqlpage;UID=root;PWD=Password123!, true) (push) Has been skipped
CI / test (postgres, postgres, postgres://root:Password123!@127.0.0.1/sqlpage) (push) Has been skipped
CI / playwright (push) Has been skipped
CI / docker_build (linux/arm/v7, -linux-arm-v7, minimal) (push) Failing after 0s
CI / hurl_examples (push) Failing after 8s
deploy website / deploy_official_site (push) Failing after 1s
CI / hurl (${{ matrix.example }}) (push) Has been skipped
CI / docker_push (duckdb) (push) Has been cancelled
CI / docker_push (minimal) (push) Has been cancelled
CI / windows_test (push) Has been cancelled
CI / compile_and_lint (push) Failing after 0s
CI / docker_build (linux/amd64, -linux-amd64-duckdb, duckdb) (push) Failing after 0s
CI / docker_build (linux/arm64, -linux-arm64, minimal) (push) Failing after 2s
CI / docker_build (linux/arm64, -linux-arm64-duckdb, duckdb) (push) Failing after 1s
CI / docker_build (linux/amd64, minimal) (push) Failing after 1s
CI / test (, sqlite, sqlite::memory:) (push) Has been skipped
CI / test (mssql, mssql, mssql://root:Password123!@127.0.0.1/sqlpage) (push) Has been skipped
CI / test (mysql, mysql, mysql://root:Password123!@127.0.0.1/sqlpage) (push) Has been skipped
CI / test (oracle, oracle, Driver=Oracle 21 ODBC driver;Dbq=//127.0.0.1:1521/FREEPDB1;Uid=root;Pwd=Password123!) (push) Has been skipped
CI / test (postgres, odbc, Driver=PostgreSQL Unicode;Server=127.0.0.1;Port=5432;Database=sqlpage;UID=root;PWD=Password123!, true) (push) Has been skipped
CI / test (postgres, postgres, postgres://root:Password123!@127.0.0.1/sqlpage) (push) Has been skipped
CI / playwright (push) Has been skipped
CI / docker_build (linux/arm/v7, -linux-arm-v7, minimal) (push) Failing after 0s
CI / hurl_examples (push) Failing after 8s
deploy website / deploy_official_site (push) Failing after 1s
CI / hurl (${{ matrix.example }}) (push) Has been skipped
CI / docker_push (duckdb) (push) Has been cancelled
CI / docker_push (minimal) (push) Has been cancelled
CI / windows_test (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
BEGIN;
|
||||
CREATE TEMPORARY TABLE t(f VARCHAR(100) NOT NULL);
|
||||
INSERT INTO t(f) VALUES ($x);
|
||||
COMMIT;
|
||||
|
||||
select 'text' as component, f as contents from t;
|
||||
@@ -0,0 +1,6 @@
|
||||
BEGIN TRANSACTION;
|
||||
CREATE TABLE #t(f VARCHAR(100) NOT NULL);
|
||||
INSERT INTO #t(f) VALUES ($x);
|
||||
COMMIT TRANSACTION;
|
||||
|
||||
SELECT 'text' AS component, f AS contents FROM #t;
|
||||
@@ -0,0 +1,10 @@
|
||||
START TRANSACTION; -- mysql syntax
|
||||
CREATE TEMPORARY TABLE IF NOT EXISTS t(f VARCHAR(255) NOT NULL); -- mysql does not remove temporary tables on rollback
|
||||
INSERT INTO t(f) SELECT 'bad value' where $x is null;
|
||||
SELECT 'debug' as component, f from t;
|
||||
INSERT INTO t(f) VALUES ($x); -- this will fail if $x is null. And the transaction should be rolled back, so 'bad value' should not be in the table
|
||||
COMMIT;
|
||||
|
||||
select 'text' as component, $x as contents
|
||||
where not exists (select 1 from t where f = 'bad value');
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
use actix_web::{http::StatusCode, test};
|
||||
use sqlpage::webserver::{database::SupportedDatabase, http::main_handler};
|
||||
|
||||
use crate::common::{get_request_to_with_data, make_app_data};
|
||||
|
||||
#[actix_web::test]
|
||||
async fn test_transaction_error() -> actix_web::Result<()> {
|
||||
let data = make_app_data().await;
|
||||
let path = match data.db.info.database_type {
|
||||
SupportedDatabase::MySql => "/tests/transactions/failed_transaction_mysql.sql",
|
||||
SupportedDatabase::Mssql => "/tests/transactions/failed_transaction_mssql.sql",
|
||||
SupportedDatabase::Snowflake | SupportedDatabase::Oracle => {
|
||||
return Ok(()); //snowflake and oracle don't support transactions in this test way
|
||||
}
|
||||
_ => "/tests/transactions/failed_transaction.sql",
|
||||
};
|
||||
let req = get_request_to_with_data(path, data.clone())
|
||||
.await?
|
||||
.to_srv_request();
|
||||
let resp = main_handler(req).await?;
|
||||
let body = test::read_body(resp).await;
|
||||
let body_str = String::from_utf8(body.to_vec())
|
||||
.unwrap()
|
||||
.to_ascii_lowercase();
|
||||
assert!(
|
||||
body_str.contains("error") && body_str.contains("null"),
|
||||
"{body_str}\nexpected to contain: constraint failed"
|
||||
);
|
||||
// Now query again, with ?x=1447
|
||||
let path_with_param = path.to_string() + "?x=1447";
|
||||
let req = get_request_to_with_data(&path_with_param, data.clone())
|
||||
.await?
|
||||
.to_srv_request();
|
||||
let resp = main_handler(req).await?;
|
||||
let body = test::read_body(resp).await;
|
||||
let body_str = String::from_utf8(body.to_vec()).unwrap();
|
||||
assert!(
|
||||
body_str.contains("1447"),
|
||||
"{body_str}\nexpected to contain: 1447"
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
async fn test_failed_copy_followed_by_query() -> actix_web::Result<()> {
|
||||
let app_data = make_app_data().await;
|
||||
let big_csv = "col1,col2\nval1,val2\n".repeat(1000);
|
||||
let req = get_request_to_with_data(
|
||||
"/tests/sql_test_files/component_rendering/error_failed_to_import_the_csv.sql",
|
||||
app_data.clone(),
|
||||
)
|
||||
.await?
|
||||
.insert_header(("content-type", "multipart/form-data; boundary=1234567890"))
|
||||
.set_payload(format!(
|
||||
"--1234567890\r\n\
|
||||
Content-Disposition: form-data; name=\"recon_csv_file_input\"; filename=\"data.csv\"\r\n\
|
||||
Content-Type: text/csv\r\n\
|
||||
\r\n\
|
||||
{big_csv}\r\n\
|
||||
--1234567890--\r\n"
|
||||
))
|
||||
.to_srv_request();
|
||||
let resp = main_handler(req).await?;
|
||||
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
let body = test::read_body(resp).await;
|
||||
let body_str = String::from_utf8(body.to_vec()).unwrap();
|
||||
assert!(
|
||||
body_str.contains("error"),
|
||||
"{body_str}\nexpected to contain error message"
|
||||
);
|
||||
|
||||
// On postgres, the error message should contain "The postgres COPY FROM STDIN command failed"
|
||||
if matches!(app_data.db.to_string().to_lowercase().as_str(), "postgres") {
|
||||
assert!(
|
||||
body_str.contains("The postgres COPY FROM STDIN command failed"),
|
||||
"{body_str}\nexpected to contain: The postgres COPY FROM STDIN command failed"
|
||||
);
|
||||
}
|
||||
// Now make other requests to verify the connection is still usable
|
||||
for path in [
|
||||
"/tests/sql_test_files/component_rendering/simple.sql",
|
||||
"/tests/sql_test_files/component_rendering/text_markdown.sql",
|
||||
"/tests/sql_test_files/component_rendering/text_unsafe_markdown.sql",
|
||||
] {
|
||||
let req = get_request_to_with_data(path, app_data.clone())
|
||||
.await?
|
||||
.to_srv_request();
|
||||
let resp = main_handler(req).await?;
|
||||
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
let body = test::read_body(resp).await;
|
||||
let body_str = String::from_utf8(body.to_vec()).unwrap();
|
||||
assert!(
|
||||
body_str.contains("It works !"),
|
||||
"{body_str}\nexpected to contain: It works !"
|
||||
);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user