Skip to content

Commit 768e13c

Browse files
authored
Merge pull request #258 from TileDB-Inc/support-get-query-status-details
Add support for tiledb_query_get_status_details
2 parents 4fc3f9d + abf03b2 commit 768e13c

File tree

3 files changed

+197
-0
lines changed

3 files changed

+197
-0
lines changed

enums.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,34 @@ func (q QueryStatus) String() string {
571571
return C.GoString(cname)
572572
}
573573

574+
// QueryStatusDetailsReason indicates extended information about a returned query status in order to
575+
// allow improved client-side handling of buffers and potential resubmissions.
576+
type QueryStatusDetailsReason uint8
577+
578+
const (
579+
// TILEDB_REASON_NONE No additional details available
580+
TILEDB_REASON_NONE QueryStatusDetailsReason = C.TILEDB_REASON_NONE
581+
// TILEDB_REASON_USER_BUFFER_SIZE User buffers are too small
582+
TILEDB_REASON_USER_BUFFER_SIZE QueryStatusDetailsReason = C.TILEDB_REASON_USER_BUFFER_SIZE
583+
// TILEDB_REASON_MEMORY_BUDGET Exceeded memory budget: can resubmit without resize
584+
TILEDB_REASON_MEMORY_BUDGET QueryStatusDetailsReason = C.TILEDB_REASON_MEMORY_BUDGET
585+
)
586+
587+
// String returns string representation
588+
func (r QueryStatusDetailsReason) String() string {
589+
// TileDB does not provide tiledb_query_status_details_reason_to_str
590+
switch r {
591+
case TILEDB_REASON_NONE:
592+
return "REASON_NONE"
593+
case TILEDB_REASON_USER_BUFFER_SIZE:
594+
return "REASON_USER_BUFFER_SIZE"
595+
case TILEDB_REASON_MEMORY_BUDGET:
596+
return "REASON_MEMORY_BUDGET"
597+
}
598+
599+
return "REASON_UNKNOWN"
600+
}
601+
574602
// QueryType read or write query
575603
type QueryType int8
576604

query_experimental.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ import (
2020
"fmt"
2121
)
2222

23+
// QueryStatusDetails contains detailed information about the query status
24+
type QueryStatusDetails struct {
25+
IncompleteReason QueryStatusDetailsReason
26+
}
27+
2328
func (q *Query) RelevantFragmentNum() (uint64, error) {
2429
var num C.uint64_t
2530
if ret := C.tiledb_query_get_relevant_fragment_num(q.context.tiledbContext, q.tiledbQuery, &num); ret != C.TILEDB_OK {
@@ -28,3 +33,14 @@ func (q *Query) RelevantFragmentNum() (uint64, error) {
2833

2934
return uint64(num), nil
3035
}
36+
37+
// StatusDetails returns extended query status details.
38+
func (q *Query) StatusDetails() (QueryStatusDetails, error) {
39+
var details QueryStatusDetails
40+
var cDetails C.tiledb_query_status_details_t
41+
if ret := C.tiledb_query_get_status_details(q.context.tiledbContext, q.tiledbQuery, &cDetails); ret != C.TILEDB_OK {
42+
return details, fmt.Errorf("Error getting query status details: %s", q.context.LastError())
43+
}
44+
details.IncompleteReason = QueryStatusDetailsReason(cDetails.incomplete_reason)
45+
return details, nil
46+
}

query_experimental_test.go

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
//go:build experimental
2+
// +build experimental
3+
4+
package tiledb
5+
6+
import (
7+
"testing"
8+
9+
"github.com/stretchr/testify/assert"
10+
"github.com/stretchr/testify/require"
11+
)
12+
13+
func TestQueryStatusDetails(t *testing.T) {
14+
// Create an array
15+
16+
// Create configuration
17+
config, err := NewConfig()
18+
require.NoError(t, err)
19+
20+
// Create context with config
21+
context, err := NewContext(config)
22+
require.NoError(t, err)
23+
24+
// Create dimension
25+
dimension, err := NewDimension(context, "x", TILEDB_INT8, []int8{0, 9}, int8(5))
26+
require.NoError(t, err)
27+
assert.NotNil(t, dimension)
28+
29+
// Create domain
30+
domain, err := NewDomain(context)
31+
require.NoError(t, err)
32+
assert.NotNil(t, domain)
33+
34+
// Add dimension
35+
require.NoError(t, domain.AddDimensions(dimension))
36+
37+
// Create array schema
38+
arraySchema, err := NewArraySchema(context, TILEDB_DENSE)
39+
require.NoError(t, err)
40+
assert.NotNil(t, arraySchema)
41+
42+
// Create attribute to add to schema
43+
attribute, err := NewAttribute(context, "v", TILEDB_INT32)
44+
require.NoError(t, err)
45+
assert.NotNil(t, attribute)
46+
47+
// Add attribute to schema
48+
err = arraySchema.AddAttributes(attribute)
49+
require.NoError(t, err)
50+
51+
// Set Domain
52+
err = arraySchema.SetDomain(domain)
53+
require.NoError(t, err)
54+
55+
// Validate Schema
56+
err = arraySchema.Check()
57+
require.NoError(t, err)
58+
59+
// Create array on disk
60+
tmpArrayPath := t.TempDir()
61+
array, err := NewArray(context, tmpArrayPath)
62+
require.NoError(t, err)
63+
assert.NotNil(t, array)
64+
err = array.Create(arraySchema)
65+
require.NoError(t, err)
66+
67+
// Write to array
68+
69+
// Open array for writing
70+
err = array.Open(TILEDB_WRITE)
71+
require.NoError(t, err)
72+
73+
// Create write query
74+
query, err := NewQuery(context, array)
75+
require.NoError(t, err)
76+
assert.NotNil(t, query)
77+
err = query.SetSubArray([]int8{0, 9})
78+
require.NoError(t, err)
79+
80+
// Initialize the data buffer
81+
bufferV := []int32{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
82+
_, err = query.SetDataBuffer("v", bufferV)
83+
require.NoError(t, err)
84+
85+
// Submit write query
86+
err = query.Submit()
87+
require.NoError(t, err)
88+
89+
// Validate status, since query was used this is should be complete
90+
status, err := query.Status()
91+
require.NoError(t, err)
92+
assert.Equal(t, TILEDB_COMPLETED, status)
93+
94+
// close array
95+
err = array.Close()
96+
require.NoError(t, err)
97+
98+
// Read from the array. We will test an incomplete query
99+
// Open array for reading
100+
err = array.Open(TILEDB_READ)
101+
require.NoError(t, err)
102+
103+
// Create read query
104+
query, err = NewQuery(context, array)
105+
require.NoError(t, err)
106+
assert.NotNil(t, query)
107+
err = query.SetSubArray([]int8{0, 9}) // we want to read the whole array, 2 full tiles
108+
require.NoError(t, err)
109+
110+
// Initialize the data buffer
111+
// The buffer should be large enough for 1 tile but not for 2. Tile size is 5
112+
bufferV = []int32{0, 0, 0, 0, 0, 0}
113+
_, err = query.SetDataBuffer("v", bufferV)
114+
require.NoError(t, err)
115+
116+
// Submit read query
117+
err = query.Submit()
118+
require.NoError(t, err)
119+
120+
// verify query status
121+
status, err = query.Status()
122+
require.NoError(t, err)
123+
assert.Equal(t, TILEDB_INCOMPLETE, status)
124+
125+
// verify status details
126+
details, err := query.StatusDetails()
127+
require.NoError(t, err)
128+
assert.Equal(t, TILEDB_REASON_USER_BUFFER_SIZE, details.IncompleteReason)
129+
130+
// check that the first tile was returned
131+
assert.Equal(t, int32(1), bufferV[1])
132+
133+
// resubmit the query for the 2nd tile
134+
err = query.Submit()
135+
require.NoError(t, err)
136+
137+
// verify query status
138+
status, err = query.Status()
139+
require.NoError(t, err)
140+
assert.Equal(t, TILEDB_COMPLETED, status)
141+
142+
// check that the second tile was returned
143+
assert.Equal(t, int32(6), bufferV[1])
144+
145+
// verify status details
146+
details, err = query.StatusDetails()
147+
require.NoError(t, err)
148+
assert.Equal(t, TILEDB_REASON_NONE, details.IncompleteReason)
149+
150+
// close array
151+
err = array.Close()
152+
require.NoError(t, err)
153+
}

0 commit comments

Comments
 (0)