1// Code generated by smithy-go-codegen DO NOT EDIT.
2
3package dynamodb
4
5import (
6	"context"
7	"fmt"
8	awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
9	"github.com/aws/aws-sdk-go-v2/aws/signer/v4"
10	"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
11	"github.com/aws/smithy-go/middleware"
12	smithyhttp "github.com/aws/smithy-go/transport/http"
13)
14
15// The Query operation finds items based on primary key values. You can query any
16// table or secondary index that has a composite primary key (a partition key and a
17// sort key). Use the KeyConditionExpression parameter to provide a specific value
18// for the partition key. The Query operation will return all of the items from the
19// table or index with that partition key value. You can optionally narrow the
20// scope of the Query operation by specifying a sort key value and a comparison
21// operator in KeyConditionExpression. To further refine the Query results, you can
22// optionally provide a FilterExpression. A FilterExpression determines which items
23// within the results should be returned to you. All of the other results are
24// discarded. A Query operation always returns a result set. If no matching items
25// are found, the result set will be empty. Queries that do not return results
26// consume the minimum number of read capacity units for that type of read
27// operation. DynamoDB calculates the number of read capacity units consumed based
28// on item size, not on the amount of data that is returned to an application. The
29// number of capacity units consumed will be the same whether you request all of
30// the attributes (the default behavior) or just some of them (using a projection
31// expression). The number will also be the same whether or not you use a
32// FilterExpression. Query results are always sorted by the sort key value. If the
33// data type of the sort key is Number, the results are returned in numeric order;
34// otherwise, the results are returned in order of UTF-8 bytes. By default, the
35// sort order is ascending. To reverse the order, set the ScanIndexForward
36// parameter to false. A single Query operation will read up to the maximum number
37// of items set (if using the Limit parameter) or a maximum of 1 MB of data and
38// then apply any filtering to the results using FilterExpression. If
39// LastEvaluatedKey is present in the response, you will need to paginate the
40// result set. For more information, see Paginating the Results
41// (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Query.html#Query.Pagination)
42// in the Amazon DynamoDB Developer Guide. FilterExpression is applied after a
43// Query finishes, but before the results are returned. A FilterExpression cannot
44// contain partition key or sort key attributes. You need to specify those
45// attributes in the KeyConditionExpression. A Query operation can return an empty
46// result set and a LastEvaluatedKey if all the items read for the page of results
47// are filtered out. You can query a table, a local secondary index, or a global
48// secondary index. For a query on a table or on a local secondary index, you can
49// set the ConsistentRead parameter to true and obtain a strongly consistent
50// result. Global secondary indexes support eventually consistent reads only, so do
51// not specify ConsistentRead when querying a global secondary index.
52func (c *Client) Query(ctx context.Context, params *QueryInput, optFns ...func(*Options)) (*QueryOutput, error) {
53	if params == nil {
54		params = &QueryInput{}
55	}
56
57	result, metadata, err := c.invokeOperation(ctx, "Query", params, optFns, addOperationQueryMiddlewares)
58	if err != nil {
59		return nil, err
60	}
61
62	out := result.(*QueryOutput)
63	out.ResultMetadata = metadata
64	return out, nil
65}
66
67// Represents the input of a Query operation.
68type QueryInput struct {
69
70	// The name of the table containing the requested items.
71	//
72	// This member is required.
73	TableName *string
74
75	// This is a legacy parameter. Use ProjectionExpression instead. For more
76	// information, see AttributesToGet
77	// (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.AttributesToGet.html)
78	// in the Amazon DynamoDB Developer Guide.
79	AttributesToGet []string
80
81	// This is a legacy parameter. Use FilterExpression instead. For more information,
82	// see ConditionalOperator
83	// (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.ConditionalOperator.html)
84	// in the Amazon DynamoDB Developer Guide.
85	ConditionalOperator types.ConditionalOperator
86
87	// Determines the read consistency model: If set to true, then the operation uses
88	// strongly consistent reads; otherwise, the operation uses eventually consistent
89	// reads. Strongly consistent reads are not supported on global secondary indexes.
90	// If you query a global secondary index with ConsistentRead set to true, you will
91	// receive a ValidationException.
92	ConsistentRead *bool
93
94	// The primary key of the first item that this operation will evaluate. Use the
95	// value that was returned for LastEvaluatedKey in the previous operation. The data
96	// type for ExclusiveStartKey must be String, Number, or Binary. No set data types
97	// are allowed.
98	ExclusiveStartKey map[string]types.AttributeValue
99
100	// One or more substitution tokens for attribute names in an expression. The
101	// following are some use cases for using ExpressionAttributeNames:
102	//
103	// * To access an
104	// attribute whose name conflicts with a DynamoDB reserved word.
105	//
106	// * To create a
107	// placeholder for repeating occurrences of an attribute name in an expression.
108	//
109	// *
110	// To prevent special characters in an attribute name from being misinterpreted in
111	// an expression.
112	//
113	// Use the # character in an expression to dereference an attribute
114	// name. For example, consider the following attribute name:
115	//
116	// * Percentile
117	//
118	// The
119	// name of this attribute conflicts with a reserved word, so it cannot be used
120	// directly in an expression. (For the complete list of reserved words, see
121	// Reserved Words
122	// (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ReservedWords.html)
123	// in the Amazon DynamoDB Developer Guide). To work around this, you could specify
124	// the following for ExpressionAttributeNames:
125	//
126	// * {"#P":"Percentile"}
127	//
128	// You could
129	// then use this substitution in an expression, as in this example:
130	//
131	// * #P =
132	// :val
133	//
134	// Tokens that begin with the : character are expression attribute values,
135	// which are placeholders for the actual value at runtime. For more information on
136	// expression attribute names, see Specifying Item Attributes
137	// (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.AccessingItemAttributes.html)
138	// in the Amazon DynamoDB Developer Guide.
139	ExpressionAttributeNames map[string]string
140
141	// One or more values that can be substituted in an expression. Use the : (colon)
142	// character in an expression to dereference an attribute value. For example,
143	// suppose that you wanted to check whether the value of the ProductStatus
144	// attribute was one of the following: Available | Backordered | Discontinued You
145	// would first need to specify ExpressionAttributeValues as follows: {
146	// ":avail":{"S":"Available"}, ":back":{"S":"Backordered"},
147	// ":disc":{"S":"Discontinued"} } You could then use these values in an expression,
148	// such as this: ProductStatus IN (:avail, :back, :disc) For more information on
149	// expression attribute values, see Specifying Conditions
150	// (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.SpecifyingConditions.html)
151	// in the Amazon DynamoDB Developer Guide.
152	ExpressionAttributeValues map[string]types.AttributeValue
153
154	// A string that contains conditions that DynamoDB applies after the Query
155	// operation, but before the data is returned to you. Items that do not satisfy the
156	// FilterExpression criteria are not returned. A FilterExpression does not allow
157	// key attributes. You cannot define a filter expression based on a partition key
158	// or a sort key. A FilterExpression is applied after the items have already been
159	// read; the process of filtering does not consume any additional read capacity
160	// units. For more information, see Filter Expressions
161	// (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryAndScan.html#FilteringResults)
162	// in the Amazon DynamoDB Developer Guide.
163	FilterExpression *string
164
165	// The name of an index to query. This index can be any local secondary index or
166	// global secondary index on the table. Note that if you use the IndexName
167	// parameter, you must also provide TableName.
168	IndexName *string
169
170	// The condition that specifies the key values for items to be retrieved by the
171	// Query action. The condition must perform an equality test on a single partition
172	// key value. The condition can optionally perform one of several comparison tests
173	// on a single sort key value. This allows Query to retrieve one item with a given
174	// partition key value and sort key value, or several items that have the same
175	// partition key value but different sort key values. The partition key equality
176	// test is required, and must be specified in the following format:
177	// partitionKeyName = :partitionkeyval If you also want to provide a condition for
178	// the sort key, it must be combined using AND with the condition for the sort key.
179	// Following is an example, using the = comparison operator for the sort key:
180	// partitionKeyName
181	//     =
182	//
183	//     :partitionkeyval
184	//
185	//     AND
186	//
187	//     sortKeyName
188	//
189	//
190	// =
191	//
192	// :sortkeyval Valid comparisons for the sort key condition are as follows:
193	//
194	// *
195	// sortKeyName=:sortkeyval - true if the sort key value is equal to :sortkeyval.
196	//
197	// *
198	// sortKeyName<:sortkeyval - true if the sort key value is less than
199	// :sortkeyval.
200	//
201	// * sortKeyName<=:sortkeyval - true if the sort key value is less
202	// than or equal to :sortkeyval.
203	//
204	// * sortKeyName>:sortkeyval - true if the sort key
205	// value is greater than :sortkeyval.
206	//
207	// * sortKeyName>= :sortkeyval - true if the
208	// sort key value is greater than or equal to :sortkeyval.
209	//
210	// *
211	// sortKeyNameBETWEEN:sortkeyval1AND:sortkeyval2 - true if the sort key value is
212	// greater than or equal to :sortkeyval1, and less than or equal to
213	// :sortkeyval2.
214	//
215	// * begins_with (sortKeyName, :sortkeyval) - true if the sort key
216	// value begins with a particular operand. (You cannot use this function with a
217	// sort key that is of type Number.) Note that the function name begins_with is
218	// case-sensitive.
219	//
220	// Use the ExpressionAttributeValues parameter to replace tokens
221	// such as :partitionval and :sortval with actual values at runtime. You can
222	// optionally use the ExpressionAttributeNames parameter to replace the names of
223	// the partition key and sort key with placeholder tokens. This option might be
224	// necessary if an attribute name conflicts with a DynamoDB reserved word. For
225	// example, the following KeyConditionExpression parameter causes an error because
226	// Size is a reserved word:
227	//
228	// * Size = :myval
229	//
230	// To work around this, define a
231	// placeholder (such a #S) to represent the attribute name Size.
232	// KeyConditionExpression then is as follows:
233	//
234	// * #S = :myval
235	//
236	// For a list of
237	// reserved words, see Reserved Words
238	// (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ReservedWords.html)
239	// in the Amazon DynamoDB Developer Guide. For more information on
240	// ExpressionAttributeNames and ExpressionAttributeValues, see Using Placeholders
241	// for Attribute Names and Values
242	// (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ExpressionPlaceholders.html)
243	// in the Amazon DynamoDB Developer Guide.
244	KeyConditionExpression *string
245
246	// This is a legacy parameter. Use KeyConditionExpression instead. For more
247	// information, see KeyConditions
248	// (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.KeyConditions.html)
249	// in the Amazon DynamoDB Developer Guide.
250	KeyConditions map[string]types.Condition
251
252	// The maximum number of items to evaluate (not necessarily the number of matching
253	// items). If DynamoDB processes the number of items up to the limit while
254	// processing the results, it stops the operation and returns the matching values
255	// up to that point, and a key in LastEvaluatedKey to apply in a subsequent
256	// operation, so that you can pick up where you left off. Also, if the processed
257	// dataset size exceeds 1 MB before DynamoDB reaches this limit, it stops the
258	// operation and returns the matching values up to the limit, and a key in
259	// LastEvaluatedKey to apply in a subsequent operation to continue the operation.
260	// For more information, see Query and Scan
261	// (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryAndScan.html)
262	// in the Amazon DynamoDB Developer Guide.
263	Limit *int32
264
265	// A string that identifies one or more attributes to retrieve from the table.
266	// These attributes can include scalars, sets, or elements of a JSON document. The
267	// attributes in the expression must be separated by commas. If no attribute names
268	// are specified, then all attributes will be returned. If any of the requested
269	// attributes are not found, they will not appear in the result. For more
270	// information, see Accessing Item Attributes
271	// (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.AccessingItemAttributes.html)
272	// in the Amazon DynamoDB Developer Guide.
273	ProjectionExpression *string
274
275	// This is a legacy parameter. Use FilterExpression instead. For more information,
276	// see QueryFilter
277	// (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.QueryFilter.html)
278	// in the Amazon DynamoDB Developer Guide.
279	QueryFilter map[string]types.Condition
280
281	// Determines the level of detail about provisioned throughput consumption that is
282	// returned in the response:
283	//
284	// * INDEXES - The response includes the aggregate
285	// ConsumedCapacity for the operation, together with ConsumedCapacity for each
286	// table and secondary index that was accessed. Note that some operations, such as
287	// GetItem and BatchGetItem, do not access any indexes at all. In these cases,
288	// specifying INDEXES will only return ConsumedCapacity information for
289	// table(s).
290	//
291	// * TOTAL - The response includes only the aggregate ConsumedCapacity
292	// for the operation.
293	//
294	// * NONE - No ConsumedCapacity details are included in the
295	// response.
296	ReturnConsumedCapacity types.ReturnConsumedCapacity
297
298	// Specifies the order for index traversal: If true (default), the traversal is
299	// performed in ascending order; if false, the traversal is performed in descending
300	// order. Items with the same partition key value are stored in sorted order by
301	// sort key. If the sort key data type is Number, the results are stored in numeric
302	// order. For type String, the results are stored in order of UTF-8 bytes. For type
303	// Binary, DynamoDB treats each byte of the binary data as unsigned. If
304	// ScanIndexForward is true, DynamoDB returns the results in the order in which
305	// they are stored (by sort key value). This is the default behavior. If
306	// ScanIndexForward is false, DynamoDB reads the results in reverse order by sort
307	// key value, and then returns the results to the client.
308	ScanIndexForward *bool
309
310	// The attributes to be returned in the result. You can retrieve all item
311	// attributes, specific item attributes, the count of matching items, or in the
312	// case of an index, some or all of the attributes projected into the index.
313	//
314	// *
315	// ALL_ATTRIBUTES - Returns all of the item attributes from the specified table or
316	// index. If you query a local secondary index, then for each matching item in the
317	// index, DynamoDB fetches the entire item from the parent table. If the index is
318	// configured to project all item attributes, then all of the data can be obtained
319	// from the local secondary index, and no fetching is required.
320	//
321	// *
322	// ALL_PROJECTED_ATTRIBUTES - Allowed only when querying an index. Retrieves all
323	// attributes that have been projected into the index. If the index is configured
324	// to project all attributes, this return value is equivalent to specifying
325	// ALL_ATTRIBUTES.
326	//
327	// * COUNT - Returns the number of matching items, rather than the
328	// matching items themselves.
329	//
330	// * SPECIFIC_ATTRIBUTES - Returns only the attributes
331	// listed in AttributesToGet. This return value is equivalent to specifying
332	// AttributesToGet without specifying any value for Select. If you query or scan a
333	// local secondary index and request only attributes that are projected into that
334	// index, the operation will read only the index and not the table. If any of the
335	// requested attributes are not projected into the local secondary index, DynamoDB
336	// fetches each of these attributes from the parent table. This extra fetching
337	// incurs additional throughput cost and latency. If you query or scan a global
338	// secondary index, you can only request attributes that are projected into the
339	// index. Global secondary index queries cannot fetch attributes from the parent
340	// table.
341	//
342	// If neither Select nor AttributesToGet are specified, DynamoDB defaults
343	// to ALL_ATTRIBUTES when accessing a table, and ALL_PROJECTED_ATTRIBUTES when
344	// accessing an index. You cannot use both Select and AttributesToGet together in a
345	// single request, unless the value for Select is SPECIFIC_ATTRIBUTES. (This usage
346	// is equivalent to specifying AttributesToGet without any value for Select.) If
347	// you use the ProjectionExpression parameter, then the value for Select can only
348	// be SPECIFIC_ATTRIBUTES. Any other value for Select will return an error.
349	Select types.Select
350}
351
352// Represents the output of a Query operation.
353type QueryOutput struct {
354
355	// The capacity units consumed by the Query operation. The data returned includes
356	// the total provisioned throughput consumed, along with statistics for the table
357	// and any indexes involved in the operation. ConsumedCapacity is only returned if
358	// the ReturnConsumedCapacity parameter was specified. For more information, see
359	// Provisioned Throughput
360	// (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ProvisionedThroughputIntro.html)
361	// in the Amazon DynamoDB Developer Guide.
362	ConsumedCapacity *types.ConsumedCapacity
363
364	// The number of items in the response. If you used a QueryFilter in the request,
365	// then Count is the number of items returned after the filter was applied, and
366	// ScannedCount is the number of matching items before the filter was applied. If
367	// you did not use a filter in the request, then Count and ScannedCount are the
368	// same.
369	Count int32
370
371	// An array of item attributes that match the query criteria. Each element in this
372	// array consists of an attribute name and the value for that attribute.
373	Items []map[string]types.AttributeValue
374
375	// The primary key of the item where the operation stopped, inclusive of the
376	// previous result set. Use this value to start a new operation, excluding this
377	// value in the new request. If LastEvaluatedKey is empty, then the "last page" of
378	// results has been processed and there is no more data to be retrieved. If
379	// LastEvaluatedKey is not empty, it does not necessarily mean that there is more
380	// data in the result set. The only way to know when you have reached the end of
381	// the result set is when LastEvaluatedKey is empty.
382	LastEvaluatedKey map[string]types.AttributeValue
383
384	// The number of items evaluated, before any QueryFilter is applied. A high
385	// ScannedCount value with few, or no, Count results indicates an inefficient Query
386	// operation. For more information, see Count and ScannedCount
387	// (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryAndScan.html#Count)
388	// in the Amazon DynamoDB Developer Guide. If you did not use a filter in the
389	// request, then ScannedCount is the same as Count.
390	ScannedCount int32
391
392	// Metadata pertaining to the operation's result.
393	ResultMetadata middleware.Metadata
394}
395
396func addOperationQueryMiddlewares(stack *middleware.Stack, options Options) (err error) {
397	err = stack.Serialize.Add(&awsAwsjson10_serializeOpQuery{}, middleware.After)
398	if err != nil {
399		return err
400	}
401	err = stack.Deserialize.Add(&awsAwsjson10_deserializeOpQuery{}, middleware.After)
402	if err != nil {
403		return err
404	}
405	if err = addSetLoggerMiddleware(stack, options); err != nil {
406		return err
407	}
408	if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil {
409		return err
410	}
411	if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil {
412		return err
413	}
414	if err = addResolveEndpointMiddleware(stack, options); err != nil {
415		return err
416	}
417	if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil {
418		return err
419	}
420	if err = addRetryMiddlewares(stack, options); err != nil {
421		return err
422	}
423	if err = addHTTPSignerV4Middleware(stack, options); err != nil {
424		return err
425	}
426	if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil {
427		return err
428	}
429	if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil {
430		return err
431	}
432	if err = addClientUserAgent(stack); err != nil {
433		return err
434	}
435	if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {
436		return err
437	}
438	if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil {
439		return err
440	}
441	if err = addOpQueryValidationMiddleware(stack); err != nil {
442		return err
443	}
444	if err = stack.Initialize.Add(newServiceMetadataMiddleware_opQuery(options.Region), middleware.Before); err != nil {
445		return err
446	}
447	if err = addRequestIDRetrieverMiddleware(stack); err != nil {
448		return err
449	}
450	if err = addResponseErrorMiddleware(stack); err != nil {
451		return err
452	}
453	if err = addValidateResponseChecksum(stack, options); err != nil {
454		return err
455	}
456	if err = addAcceptEncodingGzip(stack, options); err != nil {
457		return err
458	}
459	if err = addRequestResponseLogging(stack, options); err != nil {
460		return err
461	}
462	return nil
463}
464
465// QueryAPIClient is a client that implements the Query operation.
466type QueryAPIClient interface {
467	Query(context.Context, *QueryInput, ...func(*Options)) (*QueryOutput, error)
468}
469
470var _ QueryAPIClient = (*Client)(nil)
471
472// QueryPaginatorOptions is the paginator options for Query
473type QueryPaginatorOptions struct {
474	// The maximum number of items to evaluate (not necessarily the number of matching
475	// items). If DynamoDB processes the number of items up to the limit while
476	// processing the results, it stops the operation and returns the matching values
477	// up to that point, and a key in LastEvaluatedKey to apply in a subsequent
478	// operation, so that you can pick up where you left off. Also, if the processed
479	// dataset size exceeds 1 MB before DynamoDB reaches this limit, it stops the
480	// operation and returns the matching values up to the limit, and a key in
481	// LastEvaluatedKey to apply in a subsequent operation to continue the operation.
482	// For more information, see Query and Scan
483	// (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryAndScan.html)
484	// in the Amazon DynamoDB Developer Guide.
485	Limit int32
486}
487
488// QueryPaginator is a paginator for Query
489type QueryPaginator struct {
490	options   QueryPaginatorOptions
491	client    QueryAPIClient
492	params    *QueryInput
493	nextToken map[string]types.AttributeValue
494	firstPage bool
495}
496
497// NewQueryPaginator returns a new QueryPaginator
498func NewQueryPaginator(client QueryAPIClient, params *QueryInput, optFns ...func(*QueryPaginatorOptions)) *QueryPaginator {
499	if params == nil {
500		params = &QueryInput{}
501	}
502
503	options := QueryPaginatorOptions{}
504	if params.Limit != nil {
505		options.Limit = *params.Limit
506	}
507
508	for _, fn := range optFns {
509		fn(&options)
510	}
511
512	return &QueryPaginator{
513		options:   options,
514		client:    client,
515		params:    params,
516		firstPage: true,
517	}
518}
519
520// HasMorePages returns a boolean indicating whether more pages are available
521func (p *QueryPaginator) HasMorePages() bool {
522	return p.firstPage || p.nextToken != nil
523}
524
525// NextPage retrieves the next Query page.
526func (p *QueryPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*QueryOutput, error) {
527	if !p.HasMorePages() {
528		return nil, fmt.Errorf("no more pages available")
529	}
530
531	params := *p.params
532	params.ExclusiveStartKey = p.nextToken
533
534	var limit *int32
535	if p.options.Limit > 0 {
536		limit = &p.options.Limit
537	}
538	params.Limit = limit
539
540	result, err := p.client.Query(ctx, &params, optFns...)
541	if err != nil {
542		return nil, err
543	}
544	p.firstPage = false
545
546	prevToken := p.nextToken
547	p.nextToken = result.LastEvaluatedKey
548
549	_ = prevToken
550
551	return result, nil
552}
553
554func newServiceMetadataMiddleware_opQuery(region string) *awsmiddleware.RegisterServiceMetadata {
555	return &awsmiddleware.RegisterServiceMetadata{
556		Region:        region,
557		ServiceID:     ServiceID,
558		SigningName:   "dynamodb",
559		OperationName: "Query",
560	}
561}
562