Skip to content
This repository has been archived by the owner on Oct 18, 2023. It is now read-only.

Commit

Permalink
forbid savepoints in legacy http
Browse files Browse the repository at this point in the history
  • Loading branch information
MarinPostma committed Oct 5, 2023
1 parent b5850bb commit 55012f6
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 2 deletions.
6 changes: 6 additions & 0 deletions sqld/src/http/user/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@ fn parse_queries(queries: Vec<QueryObject>) -> crate::Result<Vec<Query>> {
out.push(query);
}

// It's too complicated to predict the state of a transaction with savepoints in legacy http,
// forbid them instead.
if out.iter().any(|q| q.stmt.kind.is_release() || q.stmt.kind.is_release()) {
anyhow::bail!("savepoints are not supported in HTTP API, use hrana protocol instead");
}

match predict_final_state(State::Init, out.iter().map(|q| &q.stmt)) {
State::Txn => {
return Err(Error::QueryError(
Expand Down
21 changes: 19 additions & 2 deletions sqld/src/query_analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,22 @@ impl StmtKind {
},
}
}

/// Returns `true` if the stmt kind is [`Savepoint`].
///
/// [`Savepoint`]: StmtKind::Savepoint
#[must_use]
pub fn is_savepoint(&self) -> bool {
matches!(self, Self::Savepoint)
}

/// Returns `true` if the stmt kind is [`Release`].
///
/// [`Release`]: StmtKind::Release
#[must_use]
pub fn is_release(&self) -> bool {
matches!(self, Self::Release)
}
}

/// The state of a transaction for a series of statement
Expand All @@ -191,7 +207,8 @@ impl State {
(State::Txn, StmtKind::TxnEnd) => State::Init,
(state, StmtKind::Other | StmtKind::Write | StmtKind::Read) => state,
(State::Invalid, _) => State::Invalid,
(State::Init, StmtKind::TxnBegin | ) => State::Txn,
(State::Init, StmtKind::TxnBegin) => State::Txn,
_ => State::Invalid,
};
}

Expand Down Expand Up @@ -280,7 +297,7 @@ impl Statement {
pub fn is_read_only(&self) -> bool {
matches!(
self.kind,
StmtKind::Read | StmtKind::TxnEnd | StmtKind::TxnBegin
StmtKind::Read | StmtKind::TxnEnd | StmtKind::TxnBegin | StmtKind::Release | StmtKind::Savepoint
)
}
}
Expand Down

0 comments on commit 55012f6

Please sign in to comment.