2018-12-21 16:25:54 -05:00
[role="xpack"]
[testenv="basic"]
[[sql-limitations]]
== SQL Limitations
2019-05-07 16:09:24 -04:00
[float]
[[large-parsing-trees]]
=== Large queries may throw `ParsingExpection`
Extremely large queries can consume too much memory during the parsing phase, in which case the {es-sql} engine will
abort parsing and throw an error. In such cases, consider reducing the query to a smaller size by potentially
simplifying it or splitting it into smaller queries.
2018-12-21 16:25:54 -05:00
[float]
2019-04-30 10:19:09 -04:00
[[sys-columns-describe-table-nested-fields]]
2018-12-21 16:25:54 -05:00
=== Nested fields in `SYS COLUMNS` and `DESCRIBE TABLE`
{es} has a special type of relationship fields called `nested` fields. In {es-sql} they can be used by referencing their inner
2019-03-01 08:23:15 -05:00
sub-fields. Even though `SYS COLUMNS` in non-driver mode (in the CLI and in REST calls) and `DESCRIBE TABLE` will still display
them as having the type `NESTED`, they cannot be used in a query. One can only reference its sub-fields in the form:
2018-12-21 16:25:54 -05:00
[source, sql]
--------------------------------------------------
[nested_field_name].[sub_field_name]
--------------------------------------------------
For example:
[source, sql]
--------------------------------------------------
SELECT dep.dep_name.keyword FROM test_emp GROUP BY languages;
--------------------------------------------------
[float]
=== Multi-nested fields
{es-sql} doesn't support multi-nested documents, so a query cannot reference more than one nested field in an index.
This applies to multi-level nested fields, but also multiple nested fields defined on the same level. For example, for this index:
[source, sql]
----------------------------------------------------
column | type | mapping
----------------------+---------------+-------------
nested_A |STRUCT |NESTED
nested_A.nested_X |STRUCT |NESTED
nested_A.nested_X.text|VARCHAR |KEYWORD
nested_A.text |VARCHAR |KEYWORD
nested_B |STRUCT |NESTED
nested_B.text |VARCHAR |KEYWORD
----------------------------------------------------
`nested_A` and `nested_B` cannot be used at the same time, nor `nested_A`/`nested_B` and `nested_A.nested_X` combination.
For such situations, {es-sql} will display an error message.
[float]
=== Paginating nested inner hits
When SELECTing a nested field, pagination will not work as expected, {es-sql} will return __at least__ the page size records.
This is because of the way nested queries work in {es}: the root nested field will be returned and it's matching inner nested fields as well,
pagination taking place on the **root nested document and not on its inner hits**.
[float]
2019-04-30 10:19:09 -04:00
[[normalized-keyword-fields]]
2018-12-21 16:25:54 -05:00
=== Normalized `keyword` fields
`keyword` fields in {es} can be normalized by defining a `normalizer`. Such fields are not supported in {es-sql}.
[float]
=== Array type of fields
Array fields are not supported due to the "invisible" way in which {es} handles an array of values: the mapping doesn't indicate whether
a field is an array (has multiple values) or not, so without reading all the data, {es-sql} cannot know whether a field is a single or multi value.
2019-03-18 08:56:00 -04:00
When multiple values are returned for a field, by default, {es-sql} will throw an exception. However, it is possible to change this behavior through `field_multi_value_leniency` parameter in REST (disabled by default) or
`field.multi.value.leniency` in drivers (enabled by default).
2018-12-21 16:25:54 -05:00
[float]
=== Sorting by aggregation
When doing aggregations (`GROUP BY`) {es-sql} relies on {es}'s `composite` aggregation for its support for paginating results.
2019-02-01 18:38:25 -05:00
However this type of aggregation does come with a limitation: sorting can only be applied on the key used for the aggregation's buckets.
{es-sql} overcomes this limitation by doing client-side sorting however as a safety measure, allows only up to *512* rows.
It is recommended to use `LIMIT` for queries that use sorting by aggregation, essentially indicating the top N results that are desired:
[source, sql]
--------------------------------------------------
SELECT * FROM test GROUP BY age ORDER BY COUNT(*) LIMIT 100;
--------------------------------------------------
2019-06-14 07:26:18 -04:00
It is possible to run the same queries without a `LIMIT` however in that case if the maximum size (*10000*) is passed,
an exception will be returned as {es-sql} is unable to track (and sort) all the results returned.
2019-01-07 03:08:51 -05:00
2019-02-01 09:13:51 -05:00
[float]
=== Using aggregation functions on top of scalar functions
Aggregation functions like <<sql-functions-aggs-min,`MIN`>>, <<sql-functions-aggs-max,`MAX`>>, etc. can only be used
directly on fields, and so queries like `SELECT MAX(abs(age)) FROM test` are not possible.
2019-01-07 03:08:51 -05:00
[float]
=== Using a sub-select
Using sub-selects (`SELECT X FROM (SELECT Y)`) is **supported to a small degree**: any sub-select that can be "flattened" into a single
`SELECT` is possible with {es-sql}. For example:
["source","sql",subs="attributes,macros"]
--------------------------------------------------
2019-03-25 09:22:59 -04:00
include-tagged::{sql-specs}/docs/docs.csv-spec[limitationSubSelect]
2019-01-07 03:08:51 -05:00
--------------------------------------------------
The query above is possible because it is equivalent with:
["source","sql",subs="attributes,macros"]
--------------------------------------------------
2019-03-25 09:22:59 -04:00
include-tagged::{sql-specs}/docs/docs.csv-spec[limitationSubSelectRewritten]
2019-01-07 03:08:51 -05:00
--------------------------------------------------
But, if the sub-select would include a `GROUP BY` or `HAVING` or the enclosing `SELECT` would be more complex than `SELECT X
FROM (SELECT ...) WHERE [simple_condition]`, this is currently **un-supported**.
2019-01-31 09:33:05 -05:00
[float]
2019-04-30 10:19:09 -04:00
[[first-last-agg-functions-having-clause]]
2019-02-01 09:13:51 -05:00
=== Using <<sql-functions-aggs-first, `FIRST`>>/<<sql-functions-aggs-last,`LAST`>> aggregation functions in `HAVING` clause
2019-01-31 09:33:05 -05:00
Using `FIRST` and `LAST` in the `HAVING` clause is not supported. The same applies to
<<sql-functions-aggs-min,`MIN`>> and <<sql-functions-aggs-max,`MAX`>> when their target column
is of type <<keyword, `keyword`>> as they are internally translated to `FIRST` and `LAST`.
2019-04-01 17:30:39 -04:00
[float]
2019-04-30 10:19:09 -04:00
[[group-by-time]]
2019-04-01 17:30:39 -04:00
=== Using TIME data type in GROUP BY or <<sql-functions-grouping-histogram>>
Using `TIME` data type as a grouping key is currently not supported. For example:
[source, sql]
-------------------------------------------------------------
SELECT count(*) FROM test GROUP BY CAST(date_created AS TIME);
-------------------------------------------------------------
On the other hand, it can still be used if it's wrapped with a scalar function that returns another data type,
for example:
[source, sql]
-------------------------------------------------------------
SELECT count(*) FROM test GROUP BY MINUTE((CAST(date_created AS TIME));
-------------------------------------------------------------
`TIME` data type is also currently not supported in histogram grouping function. For example:
[source, sql]
-------------------------------------------------------------
SELECT HISTOGRAM(CAST(birth_date AS TIME), INTERVAL '10' MINUTES) as h, COUNT(*) FROM t GROUP BY h
-------------------------------------------------------------
SQL: Add initial geo support (#42031) (#42135)
Adds an initial limited implementations of geo features to SQL. This implementation is based on the [OpenGIS® Implementation Standard for Geographic information - Simple feature access](http://www.opengeospatial.org/standards/sfs), which is the current standard for GIS system implementation. This effort is concentrate on SQL option AKA ISO 19125-2.
Queries that are supported as a result of this initial implementation
Metadata commands
- `DESCRIBE table` - returns the correct column types `GEOMETRY` for geo shapes and geo points.
- `SHOW FUNCTIONS` - returns a list that includes supported `ST_` functions
- `SYS TYPES` and `SYS COLUMNS` display correct types `GEO_SHAPE` and `GEO_POINT` for geo shapes and geo points accordingly.
Returning geoshapes and geopoints from elasticsearch
- `SELECT geom FROM table` - returns the geoshapes and geo_points as libs/geo objects in JDBC or as WKT strings in console.
- `SELECT ST_AsWKT(geom) FROM table;` and `SELECT ST_AsText(geom) FROM table;`- returns the geoshapes ang geopoints in their WKT representation;
Using geopoints to elasticsearch
- The following functions will be supported for geopoints in queries, sorting and aggregations: `ST_GeomFromText`, `ST_X`, `ST_Y`, `ST_Z`, `ST_GeometryType`, and `ST_Distance`. In most cases when used in queries, sorting and aggregations, these function are translated into script. These functions can be used in the SELECT clause for both geopoints and geoshapes.
- `SELECT * FROM table WHERE ST_Distance(ST_GeomFromText(POINT(1 2), point) < 10;` - returns all records for which `point` is located within 10m from the `POINT(1 2)`. In this case the WHERE clause is translated into a range query.
Limitations:
Geoshapes cannot be used in queries, sorting and aggregations as part of this initial effort. In order to fully take advantage of geoshapes we would need to have access to geoshape doc values, which is coming in #37206. `ST_Z` cannot be used on geopoints in queries, sorting and aggregations since we don't store altitude in geo_point doc values.
Relates to #29872
Backport of #42031
2019-05-14 19:57:12 -04:00
[float]
[[geo-sql-limitations]]
=== Geo-related functions
Since `geo_shape` fields don't have doc values these fields cannot be used for filtering, grouping or sorting.
By default,`geo_points` fields are indexed and have doc values. However only latitude and longitude are stored and
indexed with some loss of precision from the original values (4.190951585769653E-8 for the latitude and
8.381903171539307E-8 for longitude). The altitude component is accepted but not stored in doc values nor indexed.
Therefore calling `ST_Z` function in the filtering, grouping or sorting will return `null`.