Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Basic SimpleQuery Handling #505

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

MahdiBM
Copy link
Contributor

@MahdiBM MahdiBM commented Aug 25, 2024

Resolves #499

Checklist

  • Implement basic SimpleQuery handling.
  • Tests.
  • Fix decoding rows from a SimpleQuery response with text format.

Decoding rows from a simple-query response seems to fail for now, although no-row queries do succeed. I think because as described in Postgres docs, the returned format of data for simple-query is text, and PostgresNIO doesn't properly support that.

EDIT: For SimpleQuery only, I removed the line that forced formats to be binary, and things are working now.
I'm not sure how well PostgresNIO supports the text format, but it works for strings and ints.

Not Implemented In This PR

  • Multiple statements in a single SimpleQuery.

Copy link

codecov bot commented Aug 25, 2024

Codecov Report

Attention: Patch coverage is 82.83019% with 91 lines in your changes missing coverage. Please review.

Project coverage is 62.71%. Comparing base (f2a6394) to head (1be6e94).

Files with missing lines Patch % Lines
...ection State Machine/SimpleQueryStateMachine.swift 80.27% 58 Missing ⚠️
...nection State Machine/ConnectionStateMachine.swift 83.07% 33 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #505      +/-   ##
==========================================
+ Coverage   61.77%   62.71%   +0.93%     
==========================================
  Files         125      126       +1     
  Lines       10072    10569     +497     
==========================================
+ Hits         6222     6628     +406     
- Misses       3850     3941      +91     
Files with missing lines Coverage Δ
...es/PostgresNIO/Connection/PostgresConnection.swift 45.43% <100.00%> (+2.67%) ⬆️
Sources/PostgresNIO/New/PSQLTask.swift 81.39% <100.00%> (+3.61%) ⬆️
...urces/PostgresNIO/New/PostgresChannelHandler.swift 84.70% <100.00%> (+0.19%) ⬆️
...stgresNIO/New/PostgresFrontendMessageEncoder.swift 100.00% <100.00%> (ø)
...nection State Machine/ConnectionStateMachine.swift 66.69% <83.07%> (+2.42%) ⬆️
...ection State Machine/SimpleQueryStateMachine.swift 80.27% <80.27%> (ø)

@MahdiBM MahdiBM changed the title Implement SimpleQuery Implement Basic SimpleQuery Handling Aug 25, 2024
Comment on lines +441 to +453
/// Run a simple text-only query on the Postgres server the connection is connected to.
/// WARNING: This function is not yet API and is incomplete.
/// The return type will change to another stream.
///
/// - Parameters:
/// - query: The simple query to run
/// - logger: The `Logger` to log into for the query
/// - file: The file, the query was started in. Used for better error reporting.
/// - line: The line, the query was started in. Used for better error reporting.
/// - Returns: A ``PostgresRowSequence`` containing the rows the server sent as the query result.
/// The sequence be discarded.
@discardableResult
public func __simpleQuery(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what will happen to this PR but the name is underscored for now so we can merge this PR as-is and I can then create follow-up PRs.


mutating func dataRowReceived(_ dataRow: DataRow) -> Action {
switch self.state {
case .rowDescriptionReceived(let queryContext, let columns):
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happens for queries with actual rows being returned.


mutating func commandCompletedReceived(_ commandTag: String) -> Action {
switch self.state {
case .messagesSent(let context):
Copy link
Contributor Author

@MahdiBM MahdiBM Aug 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happens for queries that do not return any rows.

return .succeedQuery(context.promise, with: result)
}

case .rowDescriptionReceived(let context, _):
Copy link
Contributor Author

@MahdiBM MahdiBM Aug 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happens for queries that do query some rows to be returned, but no rows matched the query.

demandStateMachine.receivedRow(dataRow)
state = .streaming(columns, demandStateMachine)
let result = QueryResult(value: .rowDescription(columns), logger: queryContext.logger)
return .succeedQuery(queryContext.promise, with: result)
Copy link
Contributor Author

@MahdiBM MahdiBM Aug 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to succeed the query here when we receive the first row and state is RowDescription, since we notice that there are rows to be read.

return self.avoidingStateMachineCoW { state -> Action in
state = .commandComplete(commandTag: commandTag)
let result = QueryResult(value: .noRows(.tag(commandTag)), logger: context.logger)
return .succeedQuery(context.promise, with: result)
Copy link
Contributor Author

@MahdiBM MahdiBM Aug 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to succeed the query here when we receive the command-complete row and state is RowDescription, since we notice that there are not rows to be read.

import Logging
@testable import PostgresNIO

class SimpleQueryStateMachineTests: XCTestCase {
Copy link
Contributor Author

@MahdiBM MahdiBM Aug 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly copy-pasted from extended-query state machine, though properly adjusted to simple-query state machine and the way it should behave.

@fabianfett
Copy link
Collaborator

I wonder if a better way is to build a dedicated SimpleQueryStateMachine? Wdyt?

@MahdiBM
Copy link
Contributor Author

MahdiBM commented Oct 9, 2024

@fabianfett i moved the stuff to that, mid-PR.
There is a SimpleQueryStateMachine file, though in GitHub UI you might need to chase it and push that "Load diff" button.

@MahdiBM
Copy link
Contributor Author

MahdiBM commented Oct 9, 2024

FWIW we're already using this function on prod and it's been working as it should.
Of course we're not querying rows with multiple queries because that's not implemented.
The tests should also be pretty good 🙂.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Unable to send multiple SQL commands in one simpleQuery
2 participants