DQL Query
Exposes an API to fetch records stored in Grail
npm install @dynatrace-sdk/client-query
queryAssistanceClient
import { queryAssistanceClient } from '@dynatrace-sdk/client-query';
queryAutocomplete
Get a structured list of suggestions for the query at the given position.
For information about the required permissions see the Bucket and table permissions in Grail documentation.
Overview
We provide a list of suggestions that may be used after the cursor position. The following queries will all provide the same results:
query: "f"query: "f", cursorPosition:1query: "fetch ", cursorPosition:1
Available fields:
| Field | Description |
|---|---|
| suggestions | a list of suggestions. Each item is a separate possible suggestion, despite they might have the same outputs. |
| optional | whether the suggestion is optional. If true, the query until the cursor position might work. If false, the query is definitely incomplete or invalid if cut at the cursor position. |
Fields in the suggestions
| Field | Description |
|---|---|
| suggestion | a string representing the whole suggestion. This information could also be derived from the parts. |
| alreadyTypedCharacters | how many characters of this suggestion have already been typed (and will be overridden by the suggestion). |
| parts | a list of semantically enriched information on what are the parts of a suggestion. |
Fields in parts
| Field | Description |
|---|---|
| suggestion | a string representing the current part of the suggestion. |
| type | current types: SPACE, PIPE, COMMAND (may be extended) |
The type helps to treat specific parts of the suggestion different to others; either by a different visualization,
a link to docs, etc.
Parameters
| Name | Type | Description |
|---|---|---|
| config.body*required | AutocompleteRequest | |
| config.dtClientContext | string | The dt-client-context header is an optional string parameter used for monitoring purposes. When included in a request, it helps retrieve information about the execution of the query. It shouldn't hold sensitive information. |
| config.enforceQueryConsumptionLimit | boolean | (DEPRECATED use body parameter 'enforceQueryConsumptionLimit' instead) If set, query consumption limit will be enforced. |
Returns
| Return type | Description |
|---|---|
| Promise<AutocompleteResponse> | A list of structured autocomplete suggestions. |
Throws
| Error Type | Error Message |
|---|---|
| ErrorEnvelopeError | The supplied request is wrong. Either the query itself or other parameters are wrong. | An internal server error has occurred. |
Code example
import { queryAssistanceClient } from "@dynatrace-sdk/client-query";
const data = await queryAssistanceClient.queryAutocomplete({
body: {
query:
'fetch events | filter event.type == "davis" AND davis.status != "CLOSED" | fields timestamp, davis.title, davis.underMaintenance, davis.status | sort timestamp | limit 10',
},
});
queryParse
Get a structured tree of the canonical form of the query.
For information about the required permissions see the Bucket and table permissions in Grail documentation.
Overview
Returns the parsed query as a tree, containing the structure of the canonical query. Tree-nodes can contain references to the token position where they originate from. This may help to provide hover effects, show canonical forms, mark optional items, and more.
Details
The query tree consists of nodes that contain different additional information (everything optional):
General Fields
| Field | Mandatory | Description |
|---|---|---|
| tokenPosition | no | optional. If present, it represents the position within the query string where the node refers to. |
| isOptional | no | whether this node could be left out and the result would still be the same query (semantically). |
tokenPosition
contains start (inclusive) and end (inclusive), both contain index (0 based; fur substrings), line
and column (both 1-based; for readability).
- If
tokenPositionis present, it always contains start and end with all fields - If
tokenPositionis not present, there might still be nested nodes that do contain a position - If
start == end, the position refers to a single character - If
start > end, we know for sure that something was inserted.
We can always check whether the canonical representation of a node matches the text in the tokenPosition to see whether something was inserted, removed, or changed.
isOptional
only present if it is true.
Optional nodes can e.g. be optional braces that make a query more readable, but are not necessary. This could be used to enter ghost braces and implicit functions in the user's input field; maybe with different formatting (using the tokenPosition of sibling nodes we can also check whether the user wrote these or not).
Advanced Token Types
each node is of one of following types and may contain more fields:
- Terminal Node
- ContainerNode
- Alternative Node
Terminal Node
can be identified by checking whether canonicalString is present
| Field | Mandatory | Description |
|---|---|---|
| type | yes | the type of the terminal node - do not confuse with the type of container nodes |
| canonicalString | yes | the canonical string representation. Concatenating the canonicalString of all nested terminal nodes provides the canonical form of the query. |
| isMandatoryOnUserOrder | no | may only be present if (type="BRACE_OPEN" or type="BRACE_CLOSE") and isOptional=true. For usage see section Special node type: PARAMETERS |
Current types of terminal nodes (list might grow):
- SPACE
- LINEBREAK
- INDENT
- PIPE
- DOT
- COLON
- COMMA
- BRACE_OPEN
- BRACE_CLOSE
- BRACKET_OPEN
- BRACKET_CLOSE
- PARENTHESIS_OPEN
- PARENTHESIS_CLOSE
- QUOTE
- SLASH
- BOOLEAN_TRUE
- BOOLEAN_FALSE
- NULL
- COMMAND_NAME
- PARAMETER_KEY
- PARAMETER_VALUE_SCOPE
- FUNCTION_NAME
- OPERATOR
- TRAVERSAL_OPERATOR
- TRAVERSAL_RELATION_NAME
- TRAVERSAL_HOP_COUNT
- SIMPLE_IDENTIFIER
- NUMBER
- STRING
- TIME_UNIT
- TIMESTAMP_VALUE
- METRIC_KEY
- VARIABLE
ContainerNode
can be identified by checking whether children is present
| Field | Mandatory | Description |
|---|---|---|
| type | yes | the type of the container node - do not confuse with the type of terminal nodes |
| children | yes | the children for the node. might be of any type |
Current types of container nodes (list might grow):
- QUERY
- EXECUTION_BLOCK
- COMMAND
- COMMAND_SEPARATOR
- PARAMETER_WITH_KEY
- GROUP
- PARAMETERS - check examples further down
- PARAMETER_NAMING
- PARAMETER_SEPARATOR
- FUNCTION
- FUNCTION_PART - check examples further down
- EXPRESSION
- IDENTIFIER
- SOURCE_ID
- DURATION
- TIMESTAMP
- TIMEFRAME
- TRAVERSAL_PATH
- TRAVERSAL_STEP
Special node type: PARAMETERS
can contain children representing the parameters. Every second child is of type PARAMETER_SEPARATOR.
You may reorder the children based on their tokenPosition to get the user order. However, in this case,
you need to consider isMandatoryOnUserOrder to determine whether the grouping braces are mandatory or not.
Example
For the query SORT a, {direction:"descending", b}, the canonical form is:
SORT a, {b, direction:"descending"}
This is the order, in which the parameters are returned in the query tree. Parameters are {a} and {{b} and {direction:"descending"}}. In this case, the braces are optional.
SORT a, {b, direction:"descending"} is equivalent to SORT a, b, direction:"descending"
However, if you reorder the children by tokenPosition, the braces are not optional, because
SORT a, direction:"descending", b is interpreted as SORT {a, direction:"descending"}, b
So, if the children in PARAMETERS are re-ordered by tokenPosition, braces (or in general: TerminalNodes)
are only optional if isOptional && !isMandatoryOnUserOrder.
Special node type: FUNCTION_PART
A container node of type FUNCTION may contain nodes of type FUNCTION_PART.
If those FUNCTION_PARTs are marked as optional, this means you have to either include all or none of these
optional function parts.
Example:
filter anyMatch(a.b == 1, input:a)
The optional function parts are anyMatch( and , input:a). If you leave out both, the command will still work:
filter a.b == 1 and return the same result. Using one of these optional function parts and removing the other will lead
to an invalid query.
Alternative Node
can be identified by checking whether alternatives is present
| Field | Mandatory | Description |
|---|---|---|
| alternatives | yes | Type: Map<AlternativeType, DQLNode> |
When displaying the query, pick one option. You may use the other options for hovering, replacing, and more.
Current values of AlternativeType (list might grow):
- CANONICAL: This node is the one we will use for our canonical form
- USER: An alternative that is also valid, but not canonical; and this version was picked by the user.
- INFO: only if the canonical version is not present
Examples:
CANONICALis not present,USERis present: user's nodes are optional, but not canonical (usually optional nodes are still canonical)CANONICALis present,USERis not present: same as if the canonical node was optional. If this happens, it is likely that there is also anINFOnodeCANONICALis present,USERis present: there are different alternativesINFOis present: usually ifCANONICALis not present (e.g. the parameter key forFILTER a == 1), there is an info node forFILTER condition:a == 1. Thiscondition:was neither written by the user nor is it canonical; but it might be used to help the user understand what this parameter means.
Parameters
| Name | Type | Description |
|---|---|---|
| config.body*required | ParseRequest | |
| config.dtClientContext | string | The dt-client-context header is an optional string parameter used for monitoring purposes. When included in a request, it helps retrieve information about the execution of the query. It shouldn't hold sensitive information. |
Returns
| Return type | Description |
|---|---|
| Promise<DQLNode> | A node containing more nodes, a node offering different (semantically equivalent) versions of the query parts, or a terminal node that shows the canonical form. |
Throws
| Error Type | Error Message |
|---|---|
| ErrorEnvelopeError | The supplied request is wrong. Either the query itself or other parameters are wrong. | An internal server error has occurred. |
Code example
import { queryAssistanceClient } from "@dynatrace-sdk/client-query";
const data = await queryAssistanceClient.queryParse({
body: {
query:
'fetch events | filter event.type == "davis" AND davis.status != "CLOSED" | fields timestamp, davis.title, davis.underMaintenance, davis.status | sort timestamp | limit 10',
},
});
queryVerify
Verifies a query without executing it.
For information about the required permissions see the Bucket and table permissions in Grail documentation.
Overview
Verifies the supplied query string and other query parameters for lack of any errors, but without actually submitting the query for execution.
Parameters
| Name | Type | Description |
|---|---|---|
| config.body*required | VerifyRequest | |
| config.dtClientContext | string | The dt-client-context header is an optional string parameter used for monitoring purposes. When included in a request, it helps retrieve information about the execution of the query. It shouldn't hold sensitive information. |
Returns
| Return type | Description |
|---|---|
| Promise<VerifyResponse> | Supplied query and parameters were verified. |
Throws
| Error Type | Error Message |
|---|---|
| ErrorEnvelopeError | The supplied request is wrong. | An internal server error has occurred. |
Code example
import { queryAssistanceClient } from "@dynatrace-sdk/client-query";
const data = await queryAssistanceClient.queryVerify({
body: {
query:
'fetch events | filter event.type == "davis" AND davis.status != "CLOSED" | fields timestamp, davis.title, davis.underMaintenance, davis.status | sort timestamp | limit 10',
},
});
queryExecutionClient
import { queryExecutionClient } from '@dynatrace-sdk/client-query';
queryCancel
Cancels the query and returns the result if the query was already finished, otherwise discards it.
For information about the required permissions see the Bucket and table permissions in Grail documentation.
Overview:
Cancels a running Grail query and returns a list of records if the query already finished.
The response format:
If the query was already finished, a response body including the result will be returned. Otherwise the response will contain no body.
The result has three main sections:
- the 'records' section contains the individual records, where each record consists of a set of fields and their corresponding values.
- the 'types' section describes the corresponding data types that a record field has.
- the 'metadata' section contains information about the query like 'analysisTimeframe', 'timezone' or 'locale'.
Every record has an implicit 'index' according to the position in the 'records' JSON array. The types section has a list of 1..N possible type 'buckets'. Each such bucket has an 'indexRange' which indicates which records will find their field types in which bucket. The index range has two values start & end and can be thought of as [startIndex, endIndex).
A field part of a record with index 'i' will find its corresponding field type by first locating the bucket that satisfies:
startIndex <= i <= endIndex
Once the bucket is found the 'mappings' object has an entry for all the fields that are part of that record with index 'i'.
Since enforcement of a particular schema is absent at ingestion time, it is possible to have records that share the same field name but their values are of a different type. This phenomenon will hence forth be named as a "collision". When a collision does occur, we will create a new type 'bucket' that will have a different index range where the new record field types will be placed. It is guaranteed that every field of every record will have a corresponding type. Clients should always take the included types into account when consuming records!
Parameters
| Name | Type | Description |
|---|---|---|
| config.dtClientContext | string | The dt-client-context header is an optional string parameter used for monitoring purposes. When included in a request, it helps retrieve information about the execution of the query. It shouldn't hold sensitive information. |
| config.enrich | string | If set additional data will be available in the metadata section. |
| config.requestToken*required | string | The request-token of the query. |