Changed batch query body to from [...] to { queries: [...] } (#4975)

## Problem

It's nice if `single query : single response :: batch query : batch
response`.

But at present, in the single case we send `{ query: '', params: [] }`
and get back a single `{ rows: [], ... }` object, while in the batch
case we send an array of `{ query: '', params: [] }` objects and get
back not an array of `{ rows: [], ... }` objects but a `{ results: [ {
rows: [] , ... }, { rows: [] , ... }, ... ] }` object instead.

## Summary of changes

With this change, the batch query body becomes `{ queries: [{ query: '',
params: [] }, ... ] }`, which restores a consistent relationship between
the request and response bodies.
This commit is contained in:
George MacKerron
2023-08-14 16:07:33 +01:00
committed by GitHub
parent 4626d89eda
commit 1ca08cc523
2 changed files with 11 additions and 4 deletions

View File

@@ -27,11 +27,16 @@ struct QueryData {
params: Vec<serde_json::Value>,
}
#[derive(serde::Deserialize)]
struct BatchQueryData {
queries: Vec<QueryData>,
}
#[derive(serde::Deserialize)]
#[serde(untagged)]
enum Payload {
Single(QueryData),
Batch(Vec<QueryData>),
Batch(BatchQueryData),
}
pub const MAX_RESPONSE_SIZE: usize = 10 * 1024 * 1024; // 10 MB
@@ -233,7 +238,7 @@ pub async fn handle(
Payload::Single(query) => query_to_json(&client, query, raw_output, array_mode)
.await
.map(|x| (x, HashMap::default())),
Payload::Batch(queries) => {
Payload::Batch(batch_query) => {
let mut results = Vec::new();
let mut builder = client.build_transaction();
if let Some(isolation_level) = txn_isolation_level {
@@ -243,7 +248,7 @@ pub async fn handle(
builder = builder.read_only(true);
}
let transaction = builder.start().await?;
for query in queries {
for query in batch_query.queries {
let result = query_to_json(&transaction, query, raw_output, array_mode).await;
match result {
Ok(r) => results.push(r),

View File

@@ -269,7 +269,9 @@ def test_sql_over_http_batch(static_proxy: NeonProxy):
connstr = f"postgresql://http:http@{static_proxy.domain}:{static_proxy.proxy_port}/postgres"
response = requests.post(
f"https://{static_proxy.domain}:{static_proxy.external_http_port}/sql",
data=json.dumps(list(map(lambda x: {"query": x[0], "params": x[1] or []}, queries))),
data=json.dumps(
{"queries": list(map(lambda x: {"query": x[0], "params": x[1] or []}, queries))}
),
headers={
"Content-Type": "application/sql",
"Neon-Connection-String": connstr,