Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 24 additions & 10 deletions query.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,17 @@ import (
)

const (
keyQueryCount = "arangodb-query-count"
keyQueryBatchSize = "arangodb-query-batchSize"
keyQueryCache = "arangodb-query-cache"
keyQueryMemoryLimit = "arangodb-query-memoryLimit"
keyQueryTTL = "arangodb-query-ttl"
keyQueryOptSatSyncWait = "arangodb-query-opt-satSyncWait"
keyQueryOptFullCount = "arangodb-query-opt-fullCount"
keyQueryOptStream = "arangodb-query-opt-stream"
keyQueryOptProfile = "arangodb-query-opt-profile"
keyQueryOptMaxRuntime = "arangodb-query-opt-maxRuntime"
keyQueryCount = "arangodb-query-count"
keyQueryBatchSize = "arangodb-query-batchSize"
keyQueryCache = "arangodb-query-cache"
keyQueryMemoryLimit = "arangodb-query-memoryLimit"
keyQueryForceOneShardAttributeValue = "arangodb-query-ForceOneShardAttributeValue"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the rule here? Most are small case, but this starts with a capital F

keyQueryTTL = "arangodb-query-ttl"
keyQueryOptSatSyncWait = "arangodb-query-opt-satSyncWait"
keyQueryOptFullCount = "arangodb-query-opt-fullCount"
keyQueryOptStream = "arangodb-query-opt-stream"
keyQueryOptProfile = "arangodb-query-opt-profile"
keyQueryOptMaxRuntime = "arangodb-query-opt-maxRuntime"
)

// WithQueryCount is used to configure a context that will set the Count of a query request,
Expand Down Expand Up @@ -70,6 +71,11 @@ func WithQueryMemoryLimit(parent context.Context, value int64) context.Context {
return context.WithValue(contextOrBackground(parent), keyQueryMemoryLimit, value)
}

// WithQueryForceOneShardAttributeValue is used to configure a context that will set the ForceOneShardAttributeValue of a query request,
func WithQueryForceOneShardAttributeValue(parent context.Context, value string) context.Context {
return context.WithValue(contextOrBackground(parent), keyQueryForceOneShardAttributeValue, value)
}

// WithQueryTTL is used to configure a context that will set the TTL of a query request,
func WithQueryTTL(parent context.Context, value time.Duration) context.Context {
return context.WithValue(contextOrBackground(parent), keyQueryTTL, value)
Expand Down Expand Up @@ -146,6 +152,9 @@ type queryRequest struct {
// amount of time. This is useful to ensure garbage collection of cursors that are not fully fetched by clients.
// If not set, a server-defined value will be used.
TTL float64 `json:"ttl,omitempty"`
// ForceOneShardAttributeValue This query option can be used in complex queries in case the query optimizer cannot
// automatically detect that the query can be limited to only a single server (e.g. in a disjoint smart graph case).
ForceOneShardAttributeValue *string `json:"forceOneShardAttributeValue,omitempty"`
// contains the query string to be executed
Query string `json:"query"`
// key/value pairs representing the bind parameters.
Expand Down Expand Up @@ -207,6 +216,11 @@ func (q *queryRequest) applyContextSettings(ctx context.Context) {
q.MemoryLimit = value
}
}
if rawValue := ctx.Value(keyQueryForceOneShardAttributeValue); rawValue != nil {
if value, ok := rawValue.(string); ok {
q.ForceOneShardAttributeValue = &value
}
}
if rawValue := ctx.Value(keyQueryTTL); rawValue != nil {
if value, ok := rawValue.(time.Duration); ok {
q.TTL = value.Seconds()
Expand Down
38 changes: 38 additions & 0 deletions test/query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,3 +229,41 @@ func TestProfileQuery(t *testing.T) {
}
})
}

// TestForceOneShardAttributeValue test ForceOneShardAttributeValue query attribute.
func TestForceOneShardAttributeValue(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

c := createClientFromEnv(t, true)

EnsureVersion(t, ctx, c).CheckVersion(MinimumVersion("3.9.0")).Cluster().Enterprise()

db := ensureDatabase(ctx, c, "force_one_shard_attribute_value", nil, t)

db, clean := prepareQueryDatabase(t, ctx, c, "force_one_shard_attribute_value")
defer clean(t)

// Setup tests
tests := []profileQueryTest{
{
Query: "FOR d IN books SORT d.Title RETURN d",
},
{
Query: "FOR d IN books FILTER d.Title==@title SORT d.Title RETURN d",
BindVars: map[string]interface{}{
"title": "Book 16",
},
},
}

t.Run("With ForceOneShardAttributeValue", func(t *testing.T) {
for i, test := range tests {
t.Run(fmt.Sprintf("Run %d", i), func(t *testing.T) {
nCtx := driver.WithQueryForceOneShardAttributeValue(ctx, "value")
_, err := db.Query(nCtx, test.Query, test.BindVars)
require.NoError(t, err)
})
}
})
}