pub struct QueryResult { /* private fields */ }Expand description
The rows a query produced, with the names and types of its columns.
Materialized rather than streamed. A streaming result would have to hold the operator tree, which holds a borrow of the plan and of the catalog, and that would make a result set a value nobody can put in a struct. Section 7.5’s streaming result is the M1 answer and it arrives as a second type beside this one rather than as a change to it, because the overwhelming majority of queries somebody embeds a database to run produce a result that fits in memory and the API for those should not be the harder one.
The chunks are kept as chunks rather than flattened into rows. Anything that wants the columnar
form gets it without a transpose, which is what an Arrow export and a dataframe binding both
want, and anything that wants a row gets it through QueryResult::row.
Implementations§
Source§impl QueryResult
impl QueryResult
Sourcepub fn types(&self) -> &[LogicalType]
pub fn types(&self) -> &[LogicalType]
The column types, in order.
Sourcepub fn footprint(&self) -> u64
pub fn footprint(&self) -> u64
How many bytes this result is charged against the database’s memory limit.
The chunks, not the names and the types, and it is what
rudb_common::Memory::used stops counting when this is dropped. Worth reading for a
program deciding whether to keep a result or re-run the query for it.
Sourcepub fn metrics(&self) -> Option<&Document>
pub fn metrics(&self) -> Option<&Document>
What the execution measured about itself, for a result that came from one.
There is nothing here for a statement that ran no plan, which is a SET, a CREATE with no
query in it, or an EXPLAIN, since none of those execute anything to measure. Everything
else carries a document with a row per operator and a row per pipeline, which is what
EXPLAIN ANALYZE prints and what --metrics writes out as JSON.
It hangs off the result rather than off the connection because a result outlives the query and two of them can be held at once. Numbers kept on the connection would be the numbers of whichever query ran most recently, which is not a question anybody is asking when they are holding the result of a particular one.
Sourcepub fn column_name(&self, column: usize) -> &str
pub fn column_name(&self, column: usize) -> &str
The name of one column, or the empty string if there is no such column.
Sourcepub fn column_type(&self, column: usize) -> LogicalType
pub fn column_type(&self, column: usize) -> LogicalType
The type of one column, or NULL if there is no such column.
Sourcepub fn chunk_count(&self) -> usize
pub fn chunk_count(&self) -> usize
How many batches the result is in.
A caller that walks the columnar form walks this rather than the row count, which is the whole point of having it: a result of ten million rows is a few thousand chunks and reading it that way never builds a row.
Sourcepub fn chunk_iter(&self) -> impl ExactSizeIterator<Item = &Chunk>
pub fn chunk_iter(&self) -> impl ExactSizeIterator<Item = &Chunk>
The batches, one at a time.
The same walk as chunks().iter() and the name a caller looks for. What it is not is a
promise about where the rows came from: they are all here already, and a result that does
not materialize is section 7.5’s streaming result, which is a second type beside this one.
Sourcepub fn into_chunks(self) -> Vec<Chunk>
pub fn into_chunks(self) -> Vec<Chunk>
The batches, taken rather than borrowed.
For a caller that is turning the result into something else, an Arrow record batch or a table to append to, and would otherwise clone every chunk to do it.
Sourcepub fn value_at(&self, row: usize, column: usize) -> Value
pub fn value_at(&self, row: usize, column: usize) -> Value
One value, or null if the row or the column is past the end.
Null for a row that does not exist rather than an option, because every caller that asks for
a value in range would then have to unwrap one, and a query result is read in a loop over
QueryResult::len.
Sourcepub fn row(&self, row: usize) -> Option<Vec<Value>>
pub fn row(&self, row: usize) -> Option<Vec<Value>>
One row, left to right, or None if it is past the end.
Sourcepub fn rows(&self) -> impl Iterator<Item = Vec<Value>> + '_
pub fn rows(&self) -> impl Iterator<Item = Vec<Value>> + '_
Every row in order, which is the shape a test and a script both want.
Sourcepub fn column(&self, column: usize) -> impl Iterator<Item = Value> + '_
pub fn column(&self, column: usize) -> impl Iterator<Item = Value> + '_
One column, top to bottom, across every chunk.
Empty for a column that is not there. This is the read that matches how the rows are held, so a program summing a column or handing one to a plotting library never transposes anything.
Sourcepub fn arrow_schema(&self) -> Result<Schema>
pub fn arrow_schema(&self) -> Result<Schema>
The column names and Arrow types, without converting any values.
Separate from QueryResult::to_arrow because a result of no rows has no batches and still
has columns, and a consumer that reads the schema off the first batch would have nothing to
read it off. Cheap enough to call on its own: it looks at the types and never at the rows.
§Errors
For a column of a type Arrow has no counterpart for here yet.
Sourcepub fn to_arrow(&self) -> Result<Vec<RecordBatch>>
pub fn to_arrow(&self) -> Result<Vec<RecordBatch>>
The result as Arrow record batches, one per chunk.
One per chunk rather than one for the whole result, because the chunks are what the executor produced and concatenating them would mean copying every value a second time to build a single large batch that most consumers immediately walk in pieces anyway. A consumer that does want one batch has every column in hand to build it.
A result of no rows converts to no batches. The schema is QueryResult::arrow_schema, and
RecordBatch::empty turns it into the empty batch for a consumer that needs one.
§Errors
For a column of a type Arrow has no counterpart for here yet, and for a chunk whose values are not the layout its type says they are.
Trait Implementations§
Source§impl Clone for QueryResult
impl Clone for QueryResult
Source§fn clone(&self) -> QueryResult
fn clone(&self) -> QueryResult
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more