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

Enable the capture of metadata for empty resultsets #1341

Open
Yaytay opened this issue Jul 26, 2023 · 8 comments
Open

Enable the capture of metadata for empty resultsets #1341

Yaytay opened this issue Jul 26, 2023 · 8 comments
Milestone

Comments

@Yaytay
Copy link
Member

Yaytay commented Jul 26, 2023

Describe the feature

Currently clients using PreparedStatements get no data back from a call to createStream if the query returns no rows.
I would like to be able to report the metadata for calls like this, even if no data is provided.

The method RowStreamImpl::handle(AsyncResult<RowSet> ar) gets called when there is no data and the RowSet that it receives seems to have the information.
I propose doing something like this:

      RowSet rowSet = ar.result();
      synchronized (this) {
        readInProgress = false;
        RowIterator<Row> it = rowSet.iterator();
        if (it.hasNext()) {
          result = it;
        }
      }
      metadataPromise.tryComplete(rowSet);
      checkPending();

With associated scaffolding to give callers access to the metadataPromise.

I'm happy with an alternative solution that achieves the aim.

Use cases

When using the data for reporting it is useful to be able to present the empty result set, rather than just nothing.

Contribution

Happy to provide a PR.

@Yaytay
Copy link
Member Author

Yaytay commented Jul 27, 2023

It doesn't work very nicely as a promise, so I'm currently testing with a Handler<RowSet>:

      Handler<RowSet<Row>> handler = null;
      RowSet<Row> rowset = ar.result();
      synchronized (this) {
        readInProgress = false;
        RowIterator<Row> it = rowset.iterator();
        if (!metadataHandlerCalled) {
          metadataHandlerCalled = true;
          handler = metadataHandler;
        }
        if (it.hasNext()) {
          result = it;
        }
      }
      if (handler != null) {
        handler.handle(rowset);
      }

@vietj
Copy link
Member

vietj commented Jul 27, 2023

can't you use the stream endHandler of the stream that will always be called ?

@Yaytay
Copy link
Member Author

Yaytay commented Jul 27, 2023

RowStream#endHandler(Handler endHandler)
Doesn't provide any way to access the metadata.
Unless we capture the metadata in the RowStream and provide a getMetadata method that could be accessed from the endHandler:

      RowSet<Row> rowset = ar.result();
      synchronized (this) {
        readInProgress = false;
        RowIterator<Row> it = rowset.iterator();
        this.columnDescriptors = rowset.columnDescriptors();
        if (it.hasNext()) {
          result = it;
        }
      }
      checkPending();

With a getLastColumnDescriptors on the RowStream.
I think that would work quite nicely.

@vietj
Copy link
Member

vietj commented Jul 27, 2023

what are the metadata you are referring to ?

@vietj
Copy link
Member

vietj commented Jul 27, 2023

ah the column descriptor :-)

@vietj
Copy link
Member

vietj commented Jul 27, 2023

I propose we add the metadata on the rowstream interface which returns the metadata of the current rowset until end is called ?

@vietj vietj added this to the 5.0.0 milestone Jul 27, 2023
@Yaytay
Copy link
Member Author

Yaytay commented Jul 27, 2023

Works for me.
It'll need to be able to return it until the end handler has completed.

@vietj
Copy link
Member

vietj commented Jul 27, 2023

makes sense

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

No branches or pull requests

2 participants