fix(oracle): defer XMLTYPE in manual transactions
This commit is contained in:
8 files changed
+209
-17
No files matched your search
@@ -4502,10 +4502,24 @@ pub async fn execute_in_manual_transaction(
|
||||
state: &AppState,
|
||||
txn_session_id: &str,
|
||||
sql: &str,
|
||||
_database: &str,
|
||||
_schema: Option<&str>,
|
||||
database: &str,
|
||||
schema: Option<&str>,
|
||||
max_rows: Option<usize>,
|
||||
) -> Result<Vec<db::QueryResult>, String> {
|
||||
execute_in_manual_transaction_with_options(state, txn_session_id, sql, database, schema, max_rows, false)
|
||||
.await
|
||||
.map(|results| results.into_iter().map(ExecuteMultiResult::into_query_result).collect())
|
||||
}
|
||||
|
||||
pub async fn execute_in_manual_transaction_with_options(
|
||||
state: &AppState,
|
||||
txn_session_id: &str,
|
||||
sql: &str,
|
||||
database: &str,
|
||||
schema: Option<&str>,
|
||||
max_rows: Option<usize>,
|
||||
table_data_preview: bool,
|
||||
) -> Result<Vec<ExecuteMultiResult>, String> {
|
||||
const TXN_IDLE_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(300);
|
||||
|
||||
// Resolve statements and validate before taking the per-session connection
|
||||
@@ -4525,7 +4539,10 @@ pub async fn execute_in_manual_transaction(
|
||||
|db_type| crate::sql::split_sql_statements_for_database(sql, db_type),
|
||||
);
|
||||
if statements.is_empty() {
|
||||
return Ok(vec![empty_query_result(0)]);
|
||||
return Ok(vec![ExecuteMultiResult::success_with_optional_server_large_values(
|
||||
empty_query_result(0),
|
||||
table_data_preview,
|
||||
)]);
|
||||
}
|
||||
|
||||
// Read-only check while the session is still in the map. If this fails the
|
||||
@@ -4577,11 +4594,25 @@ pub async fn execute_in_manual_transaction(
|
||||
}
|
||||
TxnConnection::Mysql(conn) => execute_manual_txn_mysql_statement(conn, statement, row_limit).await,
|
||||
TxnConnection::Agent { client, .. } => {
|
||||
execute_manual_txn_agent_statement(client, db_type, statement, _database, _schema, row_limit).await
|
||||
execute_manual_txn_agent_statement(
|
||||
client,
|
||||
db_type,
|
||||
statement,
|
||||
database,
|
||||
schema,
|
||||
row_limit,
|
||||
table_data_preview,
|
||||
)
|
||||
.await
|
||||
}
|
||||
};
|
||||
match result {
|
||||
Ok(query_result) => results.push(query_result),
|
||||
Ok(query_result) => {
|
||||
results.push(ExecuteMultiResult::success_with_optional_server_large_values(
|
||||
query_result,
|
||||
table_data_preview,
|
||||
));
|
||||
}
|
||||
Err(e) => {
|
||||
// Statement failure ends the transaction. If another cleanup path
|
||||
// already removed the session, it owns the final rollback.
|
||||
@@ -4792,6 +4823,10 @@ async fn release_manual_txn_agent_pool(state: &AppState, connection_id: &str, co
|
||||
}
|
||||
}
|
||||
|
||||
fn manual_txn_agent_query_options(row_limit: usize, table_data_preview: bool) -> QueryExecutionOptions {
|
||||
QueryExecutionOptions { max_rows: Some(row_limit.max(1)), table_data_preview, ..QueryExecutionOptions::default() }
|
||||
}
|
||||
|
||||
async fn execute_manual_txn_agent_statement(
|
||||
client: &Arc<crate::db::agent_driver::PooledAgentClient>,
|
||||
db_type: Option<DatabaseType>,
|
||||
@@ -4799,10 +4834,11 @@ async fn execute_manual_txn_agent_statement(
|
||||
database: &str,
|
||||
schema: Option<&str>,
|
||||
row_limit: usize,
|
||||
table_data_preview: bool,
|
||||
) -> Result<db::QueryResult, String> {
|
||||
let sql = sql_for_execution_context(db_type, statement, schema);
|
||||
let execution_schema = schema_for_execution_context(db_type, schema);
|
||||
let options = QueryExecutionOptions { max_rows: Some(row_limit.max(1)), ..QueryExecutionOptions::default() };
|
||||
let options = manual_txn_agent_query_options(row_limit, table_data_preview);
|
||||
let params =
|
||||
agent_execute_query_params(&sql, Some(database).filter(|value| !value.is_empty()), execution_schema, options);
|
||||
let mut locked = client.lock().await;
|
||||
@@ -7314,6 +7350,19 @@ for line in sys.stdin:
|
||||
assert_eq!(params["deferLobs"], true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn manual_transaction_agent_query_options_preserve_preview_mode() {
|
||||
let params = agent_execute_query_params(
|
||||
"SELECT * FROM documents",
|
||||
Some("ORCL"),
|
||||
Some("APP"),
|
||||
manual_txn_agent_query_options(250, true),
|
||||
);
|
||||
|
||||
assert_eq!(params["maxRows"], 250);
|
||||
assert_eq!(params["deferLobs"], true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn iris_execution_context_omits_schema() {
|
||||
assert_eq!(schema_for_execution_context(Some(DatabaseType::Iris), Some("SQLUser")), None);
|
||||
|
||||
Reference in new issue
Block a user