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() {

Reply via email to