This is an automated email from the ASF dual-hosted git repository.
zeroshade pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow.git
The following commit(s) were added to refs/heads/main by this push:
new 76e0f6254b GH-43764: [Go][FlightSQL] Add NewPreparedStatement function
(#43781)
76e0f6254b is described below
commit 76e0f6254b75509d83e44fe8997bd14007907c4f
Author: Matt Topol <[email protected]>
AuthorDate: Thu Aug 22 15:37:09 2024 -0400
GH-43764: [Go][FlightSQL] Add NewPreparedStatement function (#43781)
### Rationale for this change
Allowing creation of the prepared statement object outside of the client
allows for logging, proxying, and handing off prepared statements if necessary.
### Are these changes tested?
Yes
* GitHub Issue: #43764
Authored-by: Matt Topol <[email protected]>
Signed-off-by: Matt Topol <[email protected]>
---
go/arrow/flight/flightsql/client.go | 9 +++++++++
go/arrow/flight/flightsql/client_test.go | 21 +++++++++++++++++----
2 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/go/arrow/flight/flightsql/client.go
b/go/arrow/flight/flightsql/client.go
index 4a600e5253..4c9dc50135 100644
--- a/go/arrow/flight/flightsql/client.go
+++ b/go/arrow/flight/flightsql/client.go
@@ -1102,6 +1102,15 @@ type PreparedStatement struct {
closed bool
}
+// NewPreparedStatement creates a prepared statement object bound to the
provided
+// client using the given handle. In general, it should be sufficient to use
the
+// Prepare function a client and this wouldn't be needed. But this can be used
+// to propagate a prepared statement from one client to another if needed or if
+// proxying requests.
+func NewPreparedStatement(client *Client, handle []byte) *PreparedStatement {
+ return &PreparedStatement{client: client, handle: handle}
+}
+
// Execute executes the prepared statement on the server and returns a
FlightInfo
// indicating where to retrieve the response. If SetParameters has been called
// then the parameter bindings will be sent before execution.
diff --git a/go/arrow/flight/flightsql/client_test.go
b/go/arrow/flight/flightsql/client_test.go
index 7604b554cb..d060161f94 100644
--- a/go/arrow/flight/flightsql/client_test.go
+++ b/go/arrow/flight/flightsql/client_test.go
@@ -378,8 +378,10 @@ func (s *FlightSqlClientSuite)
TestPreparedStatementExecute() {
createRsp := &mockDoActionClient{}
defer createRsp.AssertExpectations(s.T())
createRsp.On("Recv").Return(&pb.Result{Body: data}, nil).Once()
- createRsp.On("Recv").Return(&pb.Result{}, io.EOF)
- createRsp.On("CloseSend").Return(nil)
+ createRsp.On("Recv").Return(&pb.Result{}, io.EOF).Once()
+ createRsp.On("Recv").Return(&pb.Result{Body: data}, nil).Once()
+ createRsp.On("Recv").Return(&pb.Result{}, io.EOF).Once()
+ createRsp.On("CloseSend").Return(nil).Twice()
closeRsp := &mockDoActionClient{}
defer closeRsp.AssertExpectations(s.T())
@@ -387,13 +389,13 @@ func (s *FlightSqlClientSuite)
TestPreparedStatementExecute() {
closeRsp.On("CloseSend").Return(nil)
s.mockClient.On("DoAction",
flightsql.CreatePreparedStatementActionType, action.Body, s.callOpts).
- Return(createRsp, nil)
+ Return(createRsp, nil).Twice()
s.mockClient.On("DoAction", flightsql.ClosePreparedStatementActionType,
closeAct.Body, s.callOpts).
Return(closeRsp, nil)
infoCmd := &pb.CommandPreparedStatementQuery{PreparedStatementHandle:
[]byte(query)}
desc := getDesc(infoCmd)
- s.mockClient.On("GetFlightInfo", desc.Type, desc.Cmd,
s.callOpts).Return(&emptyFlightInfo, nil)
+ s.mockClient.On("GetFlightInfo", desc.Type, desc.Cmd,
s.callOpts).Return(&emptyFlightInfo, nil).Twice()
prepared, err := s.sqlClient.Prepare(context.TODO(), query,
s.callOpts...)
s.NoError(err)
@@ -404,6 +406,17 @@ func (s *FlightSqlClientSuite)
TestPreparedStatementExecute() {
info, err := prepared.Execute(context.TODO(), s.callOpts...)
s.NoError(err)
s.Equal(&emptyFlightInfo, info)
+
+ prepared, err = s.sqlClient.Prepare(context.TODO(), query,
s.callOpts...)
+ s.NoError(err)
+
+ secondPrepare := flightsql.NewPreparedStatement(&s.sqlClient,
prepared.Handle())
+ s.Equal(string(secondPrepare.Handle()), "query")
+ defer secondPrepare.Close(context.TODO(), s.callOpts...)
+
+ info, err = secondPrepare.Execute(context.TODO(), s.callOpts...)
+ s.NoError(err)
+ s.Equal(&emptyFlightInfo, info)
}
func (s *FlightSqlClientSuite) TestPreparedStatementExecuteParamBinding() {