dependabot[bot] opened a new pull request, #45318:
URL: https://github.com/apache/superset/pull/45318

   Bumps 
[elasticsearch-dbapi](https://github.com/preset-io/elasticsearch-dbapi) from 
0.2.13 to 0.3.0.
   <details>
   <summary>Release notes</summary>
   <p><em>Sourced from <a 
href="https://github.com/preset-io/elasticsearch-dbapi/releases";>elasticsearch-dbapi's
 releases</a>.</em></p>
   <blockquote>
   <h2>0.3.0</h2>
   <ul>
   <li>feat: OpenSearch 3 support (<a 
href="https://redirect.github.com/preset-io/elasticsearch-dbapi/issues/124";>#124</a>)
 [Amin Ghadersohi]. The OpenSearch dialect uses <code>_plugins/_sql</code> by 
default (OpenSearch 3 removed <code>_opendistro/_sql</code>) and falls back 
once to <code>_opendistro/_sql</code> for Open Distro / Elasticsearch 7.10; 
single-table columns compile unqualified; aliases are listed as views in v2 
mode.</li>
   <li>fix: SQLAlchemy 2 and DB-API correctness fixes found by live testing (<a 
href="https://redirect.github.com/preset-io/elasticsearch-dbapi/issues/124";>#124</a>)
 [Amin Ghadersohi]
   <ul>
   <li>follow the SQL cursor across pages on Elasticsearch and OpenSearch, so 
results larger than <code>fetch_size</code> are no longer cut to the first 
page; Elasticsearch cursor pagination by Evan Rusackas (from <a 
href="https://redirect.github.com/preset-io/elasticsearch-dbapi/issues/123";>#123</a>)</li>
   <li>never render the dummy <code>default</code> schema, including on 
projected columns</li>
   <li>reflect byte/short as <code>SmallInteger</code>, unsigned_long as 
<code>BigInteger</code> and date_nanos as <code>DateTime</code>; unknown result 
types no longer raise <code>KeyError</code></li>
   <li>table/view listing and the OpenSearch <code>SELECT 1</code> ping work 
without cluster privileges; <code>has_table</code> is true for aliases</li>
   <li><code>server_version_info</code> from the cluster; SQL compilation cache 
enabled</li>
   <li>boolean URL arguments (<code>v2</code>, <code>verify_certs</code>, ...) 
accept <code>true/1/yes/on</code> and <code>false/0/no/off</code></li>
   </ul>
   </li>
   <li>fix: reflected columns report the field's type (<code>DOUBLE</code>, 
<code>FLOAT</code>, <code>INTEGER</code>, <code>LONG</code>, 
<code>BOOLEAN</code>) instead of <code>LONG</code>/<code>FLOAT</code> for every 
numeric and boolean field (<a 
href="https://redirect.github.com/preset-io/elasticsearch-dbapi/issues/126";>#126</a>)
 [Amin Ghadersohi]. Reflected types retain their generic SQLAlchemy compilation 
on other dialects, including when copying a table to another database.</li>
   </ul>
   <h4>Behaviour changes / upgrade notes</h4>
   <ul>
   <li>
   <p><strong><code>time_zone</code> on the OpenSearch dialect 
(<code>odelasticsearch</code>)</strong> is logged as ignored and dropped (UTC, 
<code>Z</code> and <code>+00:00</code> silently). The SQL plugin always ignored 
it and returns UTC. <em>Migration:</em> none required; remove 
<code>time_zone</code> from the URL to silence the warning and convert to local 
time in the application.</p>
   </li>
   <li>
   <p><strong>Supported SQL temporal values are decoded to 
<code>datetime.datetime</code> / <code>datetime.date</code> / 
<code>datetime.time</code></strong> instead of strings. Timezone-aware 
Elasticsearch values are normalised to UTC to avoid applying one row's DST 
offset to an entire result column; decoded OpenSearch timestamps remain naive 
UTC. This is not a guarantee that every date-mapped column returns an object: 
conversion depends on the SQL engine's result type and value, and nanosecond or 
unrecognised representations remain strings. In particular, legacy OpenSearch 
results can label a full timestamp as <code>date</code>; previously even 
<code>v2=true</code> queries with LIMIT could take that legacy path. LIMIT 
queries on a v2 connection now stay on v2, preserving its functions and 
timestamp result types. <em>Migration:</em> accept both temporal objects and 
preserved strings; use objects directly (or 
<code>str()</code>/<code>isoformat()</code> them), and do not discard precis
 ion when parsing preserved strings. Convert UTC-aware values to the desired 
display timezone explicitly.</p>
   </li>
   <li>
   <p><strong><code>double</code>, <code>float</code>, <code>half_float</code> 
and <code>scaled_float</code> columns are reflected as 
<code>Float</code></strong> (Python <code>float</code>) instead of 
<code>Numeric</code> (<code>Decimal</code> rounded to 10 places). 
<em>Migration:</em> code expecting <code>Decimal</code> should convert 
explicitly.</p>
   </li>
   <li>
   <p><strong>Client exceptions are raised as DB-API exceptions</strong> from 
<code>es.exceptions</code>: connection and TLS errors, 
authentication/authorization errors as <code>OperationalError</code>; 
<code>RequestError</code> and <code>NotFoundError</code> as 
<code>ProgrammingError</code>; every other <code>TransportError</code> as 
<code>DatabaseError</code>. The original <code>elasticsearch.*</code> / 
<code>opensearchpy.*</code> exception is chained as <code>__cause__</code>. 
<em>Migration:</em> catch <code>es.exceptions.*</code> (or the DB-API classes) 
instead of <code>elasticsearch.exceptions.*</code> / 
<code>opensearchpy.exceptions.*</code>, or inspect <code>__cause__</code>.</p>
   </li>
   <li>
   <p><strong>The default OpenSearch <code>sql_path</code> is 
<code>_plugins/_sql</code></strong>, with one fallback to 
<code>_opendistro/_sql</code> when the cluster has no 
<code>_plugins/_sql</code> endpoint (<code>no handler found</code>, or 
Elasticsearch 7.10's <code>invalid_index_name_exception</code> for 
<code>_plugins</code>, which is <code>index_not_found_exception</code> with 
<code>action.auto_create_index=false</code>). A proxy or IAM policy that only 
allows <code>_opendistro/_sql</code> answers 403, which is not a missing 
endpoint, so there is no fallback. <em>Migration:</em> add 
<code>sql_path=_opendistro/_sql</code> to the URL in that case (an explicit 
<code>sql_path</code> is never replaced).</p>
   </li>
   <li>
   <p><strong>An unpaged OpenSearch result that may have been cut at 
<code>plugins.query.size_limit</code> raises <code>DataError</code></strong> 
instead of returning partial rows. <em>Migration:</em> add a <code>LIMIT</code> 
of at most the size limit, or narrow the query.</p>
   </li>
   <li>
   <p><strong>Full result sets are held in memory.</strong> A DB-API 
<code>SELECT</code> without <code>LIMIT</code> used to return at most 
<code>fetch_size</code> (10 000) rows; every page is now fetched. 
<em>Migration:</em> add a <code>LIMIT</code> to queries over large indices.</p>
   </li>
   <li>
   <p><strong>Single-table columns compile unqualified on OpenSearch</strong> 
(<code>SELECT a FROM t ORDER BY a</code>), which OpenSearch 3 requires. A 
column keeps its table qualifier when a label of another expression in the same 
select has its name. <em>Migration:</em> none expected; raw SQL is not 
affected.</p>
   </li>
   <li>
   <p><strong>In v2 mode, GROUP BY, DISTINCT, aggregates, joins and other 
statements the SQL plugin cannot page are sent without 
<code>fetch_size</code></strong>, avoiding the legacy engine's default top-200 
result. This does <strong>not</strong> mean the v2 engine returns every bucket: 
unpaged aggregations stop at a backend bucket ceiling and cannot be 
cursor-paged. That ceiling is 1000 buckets on Open Distro and OpenSearch 1.x; 
OpenSearch 2.x/3.x also stop at <code>plugins.query.size_limit</code> when it 
is below 1000, which is the default on 2.11–2.15 (200), on either 
<code>sql_path</code>. A result at the applicable ceiling without an explicit 
LIMIT of at most that ceiling now raises <code>DataError</code> instead of 
silently returning a partial answer, so exactly 200 groups raise on OpenSearch 
2.11–2.15 at the default size limit (or when the server version cannot be 
read), and are accepted where 200 is not a ceiling (Open Distro, OpenSearch 
1.x, and 2.19/3.x at their default
  size limit). Plain SELECTs without LIMIT are still paged on OpenSearch 
(<code>_plugins/_sql</code>); on Open Distro (<code>_opendistro/_sql</code>), 
whose v2 engine cannot page, v2 statements are sent unpaged as in 0.2.13, and 
if OpenSearch refuses a paged request for lack of privileges it is retried once 
unpaged. <code>v2=false</code> from a URL now means false (it used to switch v2 
mode on) and keeps the legacy engine; an aggregation that reaches the legacy 
engine's 200-bucket cap is asked of the v2 engine, rather than assuming those 
200 groups are complete. <em>Migration:</em> narrow high-cardinality 
aggregations or use an explicit bounded LIMIT; do not assume an unpaged 
aggregate is complete merely because v2 is enabled.</p>
   </li>
   <li>
   <p><strong>Statements over subqueries return correct results</strong> (e.g. 
Superset virtual datasets). A subquery without a LIMIT used to stop at the size 
limit (200 rows on Open Distro) and silently drop rows from the outer result; 
the legacy engine (v2 off) ignored the outer WHERE; and Open Distro dropped a 
row when an outer WHERE and LIMIT met without ORDER BY. Subqueries now get an 
explicit LIMIT of one search window, run on the v2 engine, and on Open Distro 
the outer LIMIT is applied to the rows.</p>
   </li>
   <li>
   <p><strong>A Superset virtual dataset (or any statement over a subquery) 
whose subquery returns more than 10000 rows raises 
<code>DataError</code></strong> on OpenSearch and Open Distro, e.g. a virtual 
dataset of <code>SELECT * FROM idx</code> over an index with 10k+ documents. 
0.2.13 answered these with silently wrong results (a filtered 
<code>COUNT</code> of 0 where the true count was 9). The SQL plugin cannot page 
a subquery, so no complete answer exists. On Open Distro, which refuses to 
count past the window, a subquery of exactly 10000 rows raises too. 
<em>Migration:</em> narrow the subquery (the virtual dataset's SQL) with a 
WHERE, an aggregation or a LIMIT of at most 10000, or use a physical 
dataset.</p>
   </li>
   <li>
   <p><strong>Reflected column types render differently.</strong> 
<code>double</code>, <code>float</code>, <code>integer</code>, 
<code>long</code> and <code>boolean</code> fields report <code>DOUBLE</code>, 
<code>FLOAT</code>, <code>INTEGER</code>, <code>LONG</code> and 
<code>BOOLEAN</code>; 0.2.13 reported <code>LONG</code> for 
<code>double</code>, <code>integer</code>, <code>long</code> and 
<code>boolean</code>. <code>byte</code> and <code>short</code> report 
<code>INTEGER</code>, <code>half_float</code> <code>FLOAT</code>, 
<code>scaled_float</code> <code>DOUBLE</code> and <code>unsigned_long</code> 
<code>LONG</code> (0.2.13 reported <code>STRING</code> for all but 
<code>half_float</code>): the SQL plugins cannot <code>CAST</code> to their own 
names, and Superset's default <code>column_type_mappings</code> do not know 
them. Superset recognises every rendered name, so these numeric fields are now 
numeric and boolean fields are boolean rather than numeric. <em>Migration:</em> 
none fo
 r Superset; code comparing the rendered type strings should expect the new 
names.</p>
   </li>
   <li>
   <p><strong>An explicit <code>LIMIT</code> on a v2 plain SELECT bypasses 
<code>plugins.query.size_limit</code></strong>, so only the 10000-row search 
window is checked (an exactly-200-row answer to <code>LIMIT 1001</code> is 
complete, not truncated). A plain SELECT whose LIMIT is above 10000 is replayed 
without the LIMIT through SQL cursors and cut at its LIMIT locally; if cursors 
are unavailable (including a limited cursor whose next page is empty) it raises 
<code>DataError</code>. <em>Migration:</em> none; results above 10000 rows need 
SQL cursors on the cluster.</p>
   </li>
   <li>
   <p><strong>Grouped top-N on the v2 engine is validated.</strong> The v2 
engine sorts <code>GROUP BY ... ORDER BY COUNT(*) DESC LIMIT 5</code> only 
after its capped composite aggregation, so it can return the wrong five groups. 
The driver probes the unsorted group listing (one additional SQL request) and 
raises <code>DataError</code> when that listing reaches its bucket ceiling. 
Ordering only by grouped fields (<code>GROUP BY k ORDER BY k DESC LIMIT 
3</code>) is sorted inside the aggregation, so it is not probed. 
<em>Migration:</em> narrow the grouping, or use <code>v2=false</code> for 
legacy top-N.</p>
   </li>
   <li>
   <p><strong>OFFSET is an exception to the grouped-field ordering 
shortcut:</strong> <code>SELECT k, COUNT(*) FROM t GROUP BY k ORDER BY k LIMIT 
3 OFFSET 999</code> is probed and raises <code>DataError</code> at the bucket 
ceiling instead of silently returning one row from 5000 groups.</p>
   </li>
   <li>
   <p><strong>OpenSearch 1.x v2 plain SELECTs stay on the v2 engine</strong> 
(paging them would hand them to the legacy engine), preserving floating values 
and timestamp objects. The server version is discovered once per connection, 
best effort; when it cannot be read, unpaged v2 semantics are preferred to 
legacy paging.</p>
   </li>
   <li>
   <p><strong>The legacy engine no longer confuses a table-qualified column 
with a select-list alias of the same name</strong> (<code>ORDER BY grp.k</code> 
next to <code>v AS k</code> sorted by <code>v</code>): such aliases are renamed 
in the statement sent and restored in the result.</p>
   </li>
   <li>
   <p><strong>Open Distro returns every row of a plain SELECT.</strong> Open 
Distro 1.13 stops a SELECT without its own LIMIT at 
<code>opendistro.query.size_limit</code> (200) and has SQL cursors off by 
default; 0.2.13 returned those 200 rows silently. A capped answer is now asked 
for again with an explicit LIMIT of the 10000-row search window, and beyond 
that paged with the SQL cursor. A plain SELECT whose own LIMIT is past that 
window (e.g. SQL Lab's <code>LIMIT 100001</code>), which Open Distro refuses, 
is answered the same way and cut at its LIMIT. <em>Migration:</em> results 
above 10000 rows need <code>opendistro.sql.cursor.enabled: true</code> on the 
cluster, otherwise the query raises <code>DataError</code> saying so.</p>
   </li>
   <li>
   <p>OpenSearch 2.11/2.15 v2 aggregations can stop at 
<code>plugins.query.size_limit</code>
   (200 by default), on either SQL endpoint. Ambiguous full buckets now raise
   <code>DataError</code>, rather than silently returning incomplete groups. 
Exactly 200
   remains accepted on Open Distro and OpenSearch 1.x, and on newer servers at
   their default size limit. A custom size limit below 1000 is also checked on
   OpenSearch 2.x/3.x.</p>
   </li>
   <li>
   <p>An explicit v2 SELECT <code>LIMIT</code> bypasses the query size limit; 
only the search
   window is checked. Plain SELECTs with a LIMIT above 10000 are replayed 
without
   LIMIT using SQL cursors, then capped locally; unavailable cursors raise
   <code>DataError</code>, including a limited cursor whose next page is 
empty.</p>
   </li>
   <li>
   <p>The v2 engine sorts grouped top-N results <strong>after</strong> its 
capped composite
   aggregation, so <code>GROUP BY ... ORDER BY COUNT(*) DESC LIMIT 5</code> can 
select the
   wrong groups even though only five rows are returned. The driver now probes
   the underlying group listing and raises <code>DataError</code> at its bucket 
ceiling.
   Narrow the grouping or use <code>v2=false</code> for legacy top-N. Safe 
small listings
   incur one additional SQL request. Ordering only by grouped fields (e.g.
   <code>GROUP BY k ORDER BY k DESC LIMIT 3</code>) is sorted inside the 
aggregation and is
   not probed.</p>
   </li>
   </ul>
   <!-- raw HTML omitted -->
   </blockquote>
   <p>... (truncated)</p>
   </details>
   <details>
   <summary>Changelog</summary>
   <p><em>Sourced from <a 
href="https://github.com/preset-io/elasticsearch-dbapi/blob/master/CHANGELOG.md";>elasticsearch-dbapi's
 changelog</a>.</em></p>
   <blockquote>
   <h3>0.3.0</h3>
   <ul>
   <li>feat: OpenSearch 3 support (<a 
href="https://redirect.github.com/preset-io/elasticsearch-dbapi/issues/124";>#124</a>)
 [Amin Ghadersohi]. The OpenSearch dialect uses <code>_plugins/_sql</code> by 
default (OpenSearch 3 removed <code>_opendistro/_sql</code>) and falls back 
once to <code>_opendistro/_sql</code> for Open Distro / Elasticsearch 7.10; 
single-table columns compile unqualified; aliases are listed as views in v2 
mode.</li>
   <li>fix: SQLAlchemy 2 and DB-API correctness fixes found by live testing (<a 
href="https://redirect.github.com/preset-io/elasticsearch-dbapi/issues/124";>#124</a>)
 [Amin Ghadersohi]
   <ul>
   <li>follow the SQL cursor across pages on Elasticsearch and OpenSearch, so 
results larger than <code>fetch_size</code> are no longer cut to the first 
page; Elasticsearch cursor pagination by Evan Rusackas (from <a 
href="https://redirect.github.com/preset-io/elasticsearch-dbapi/issues/123";>#123</a>)</li>
   <li>never render the dummy <code>default</code> schema, including on 
projected columns</li>
   <li>reflect byte/short as <code>SmallInteger</code>, unsigned_long as 
<code>BigInteger</code> and date_nanos as <code>DateTime</code>; unknown result 
types no longer raise <code>KeyError</code></li>
   <li>table/view listing and the OpenSearch <code>SELECT 1</code> ping work 
without cluster privileges; <code>has_table</code> is true for aliases</li>
   <li><code>server_version_info</code> from the cluster; SQL compilation cache 
enabled</li>
   <li>boolean URL arguments (<code>v2</code>, <code>verify_certs</code>, ...) 
accept <code>true/1/yes/on</code> and <code>false/0/no/off</code></li>
   </ul>
   </li>
   <li>fix: reflected columns report the field's type (<code>DOUBLE</code>, 
<code>FLOAT</code>, <code>INTEGER</code>, <code>LONG</code>, 
<code>BOOLEAN</code>) instead of <code>LONG</code>/<code>FLOAT</code> for every 
numeric and boolean field (<a 
href="https://redirect.github.com/preset-io/elasticsearch-dbapi/issues/126";>#126</a>)
 [Amin Ghadersohi]. Reflected types retain their generic SQLAlchemy compilation 
on other dialects, including when copying a table to another database.</li>
   </ul>
   <h4>Behaviour changes / upgrade notes</h4>
   <ul>
   <li>
   <p><strong><code>time_zone</code> on the OpenSearch dialect 
(<code>odelasticsearch</code>)</strong> is logged as ignored and dropped (UTC, 
<code>Z</code> and <code>+00:00</code> silently). The SQL plugin always ignored 
it and returns UTC. <em>Migration:</em> none required; remove 
<code>time_zone</code> from the URL to silence the warning and convert to local 
time in the application.</p>
   </li>
   <li>
   <p><strong>Supported SQL temporal values are decoded to 
<code>datetime.datetime</code> / <code>datetime.date</code> / 
<code>datetime.time</code></strong> instead of strings. Timezone-aware 
Elasticsearch values are normalised to UTC to avoid applying one row's DST 
offset to an entire result column; decoded OpenSearch timestamps remain naive 
UTC. This is not a guarantee that every date-mapped column returns an object: 
conversion depends on the SQL engine's result type and value, and nanosecond or 
unrecognised representations remain strings. In particular, legacy OpenSearch 
results can label a full timestamp as <code>date</code>; previously even 
<code>v2=true</code> queries with LIMIT could take that legacy path. LIMIT 
queries on a v2 connection now stay on v2, preserving its functions and 
timestamp result types. <em>Migration:</em> accept both temporal objects and 
preserved strings; use objects directly (or 
<code>str()</code>/<code>isoformat()</code> them), and do not discard precis
 ion when parsing preserved strings. Convert UTC-aware values to the desired 
display timezone explicitly.</p>
   </li>
   <li>
   <p><strong><code>double</code>, <code>float</code>, <code>half_float</code> 
and <code>scaled_float</code> columns are reflected as 
<code>Float</code></strong> (Python <code>float</code>) instead of 
<code>Numeric</code> (<code>Decimal</code> rounded to 10 places). 
<em>Migration:</em> code expecting <code>Decimal</code> should convert 
explicitly.</p>
   </li>
   <li>
   <p><strong>Client exceptions are raised as DB-API exceptions</strong> from 
<code>es.exceptions</code>: connection and TLS errors, 
authentication/authorization errors as <code>OperationalError</code>; 
<code>RequestError</code> and <code>NotFoundError</code> as 
<code>ProgrammingError</code>; every other <code>TransportError</code> as 
<code>DatabaseError</code>. The original <code>elasticsearch.*</code> / 
<code>opensearchpy.*</code> exception is chained as <code>__cause__</code>. 
<em>Migration:</em> catch <code>es.exceptions.*</code> (or the DB-API classes) 
instead of <code>elasticsearch.exceptions.*</code> / 
<code>opensearchpy.exceptions.*</code>, or inspect <code>__cause__</code>.</p>
   </li>
   <li>
   <p><strong>The default OpenSearch <code>sql_path</code> is 
<code>_plugins/_sql</code></strong>, with one fallback to 
<code>_opendistro/_sql</code> when the cluster has no 
<code>_plugins/_sql</code> endpoint (<code>no handler found</code>, or 
Elasticsearch 7.10's <code>invalid_index_name_exception</code> for 
<code>_plugins</code>, which is <code>index_not_found_exception</code> with 
<code>action.auto_create_index=false</code>). A proxy or IAM policy that only 
allows <code>_opendistro/_sql</code> answers 403, which is not a missing 
endpoint, so there is no fallback. <em>Migration:</em> add 
<code>sql_path=_opendistro/_sql</code> to the URL in that case (an explicit 
<code>sql_path</code> is never replaced).</p>
   </li>
   <li>
   <p><strong>An unpaged OpenSearch result that may have been cut at 
<code>plugins.query.size_limit</code> raises <code>DataError</code></strong> 
instead of returning partial rows. <em>Migration:</em> add a <code>LIMIT</code> 
of at most the size limit, or narrow the query.</p>
   </li>
   <li>
   <p><strong>Full result sets are held in memory.</strong> A DB-API 
<code>SELECT</code> without <code>LIMIT</code> used to return at most 
<code>fetch_size</code> (10 000) rows; every page is now fetched. 
<em>Migration:</em> add a <code>LIMIT</code> to queries over large indices.</p>
   </li>
   <li>
   <p><strong>Single-table columns compile unqualified on OpenSearch</strong> 
(<code>SELECT a FROM t ORDER BY a</code>), which OpenSearch 3 requires. A 
column keeps its table qualifier when a label of another expression in the same 
select has its name. <em>Migration:</em> none expected; raw SQL is not 
affected.</p>
   </li>
   <li>
   <p><strong>In v2 mode, GROUP BY, DISTINCT, aggregates, joins and other 
statements the SQL plugin cannot page are sent without 
<code>fetch_size</code></strong>, avoiding the legacy engine's default top-200 
result. This does <strong>not</strong> mean the v2 engine returns every bucket: 
unpaged aggregations stop at a backend bucket ceiling and cannot be 
cursor-paged. That ceiling is 1000 buckets on Open Distro and OpenSearch 1.x; 
OpenSearch 2.x/3.x also stop at <code>plugins.query.size_limit</code> when it 
is below 1000, which is the default on 2.11–2.15 (200), on either 
<code>sql_path</code>. A result at the applicable ceiling without an explicit 
LIMIT of at most that ceiling now raises <code>DataError</code> instead of 
silently returning a partial answer, so exactly 200 groups raise on OpenSearch 
2.11–2.15 at the default size limit (or when the server version cannot be 
read), and are accepted where 200 is not a ceiling (Open Distro, OpenSearch 
1.x, and 2.19/3.x at their default
  size limit). Plain SELECTs without LIMIT are still paged on OpenSearch 
(<code>_plugins/_sql</code>); on Open Distro (<code>_opendistro/_sql</code>), 
whose v2 engine cannot page, v2 statements are sent unpaged as in 0.2.13, and 
if OpenSearch refuses a paged request for lack of privileges it is retried once 
unpaged. <code>v2=false</code> from a URL now means false (it used to switch v2 
mode on) and keeps the legacy engine; an aggregation that reaches the legacy 
engine's 200-bucket cap is asked of the v2 engine, rather than assuming those 
200 groups are complete. <em>Migration:</em> narrow high-cardinality 
aggregations or use an explicit bounded LIMIT; do not assume an unpaged 
aggregate is complete merely because v2 is enabled.</p>
   </li>
   <li>
   <p><strong>Statements over subqueries return correct results</strong> (e.g. 
Superset virtual datasets). A subquery without a LIMIT used to stop at the size 
limit (200 rows on Open Distro) and silently drop rows from the outer result; 
the legacy engine (v2 off) ignored the outer WHERE; and Open Distro dropped a 
row when an outer WHERE and LIMIT met without ORDER BY. Subqueries now get an 
explicit LIMIT of one search window, run on the v2 engine, and on Open Distro 
the outer LIMIT is applied to the rows.</p>
   </li>
   <li>
   <p><strong>A Superset virtual dataset (or any statement over a subquery) 
whose subquery returns more than 10000 rows raises 
<code>DataError</code></strong> on OpenSearch and Open Distro, e.g. a virtual 
dataset of <code>SELECT * FROM idx</code> over an index with 10k+ documents. 
0.2.13 answered these with silently wrong results (a filtered 
<code>COUNT</code> of 0 where the true count was 9). The SQL plugin cannot page 
a subquery, so no complete answer exists. On Open Distro, which refuses to 
count past the window, a subquery of exactly 10000 rows raises too. 
<em>Migration:</em> narrow the subquery (the virtual dataset's SQL) with a 
WHERE, an aggregation or a LIMIT of at most 10000, or use a physical 
dataset.</p>
   </li>
   <li>
   <p><strong>Reflected column types render differently.</strong> 
<code>double</code>, <code>float</code>, <code>integer</code>, 
<code>long</code> and <code>boolean</code> fields report <code>DOUBLE</code>, 
<code>FLOAT</code>, <code>INTEGER</code>, <code>LONG</code> and 
<code>BOOLEAN</code>; 0.2.13 reported <code>LONG</code> for 
<code>double</code>, <code>integer</code>, <code>long</code> and 
<code>boolean</code>. <code>byte</code> and <code>short</code> report 
<code>INTEGER</code>, <code>half_float</code> <code>FLOAT</code>, 
<code>scaled_float</code> <code>DOUBLE</code> and <code>unsigned_long</code> 
<code>LONG</code> (0.2.13 reported <code>STRING</code> for all but 
<code>half_float</code>): the SQL plugins cannot <code>CAST</code> to their own 
names, and Superset's default <code>column_type_mappings</code> do not know 
them. Superset recognises every rendered name, so these numeric fields are now 
numeric and boolean fields are boolean rather than numeric. <em>Migration:</em> 
none fo
 r Superset; code comparing the rendered type strings should expect the new 
names.</p>
   </li>
   <li>
   <p><strong>An explicit <code>LIMIT</code> on a v2 plain SELECT bypasses 
<code>plugins.query.size_limit</code></strong>, so only the 10000-row search 
window is checked (an exactly-200-row answer to <code>LIMIT 1001</code> is 
complete, not truncated). A plain SELECT whose LIMIT is above 10000 is replayed 
without the LIMIT through SQL cursors and cut at its LIMIT locally; if cursors 
are unavailable (including a limited cursor whose next page is empty) it raises 
<code>DataError</code>. <em>Migration:</em> none; results above 10000 rows need 
SQL cursors on the cluster.</p>
   </li>
   <li>
   <p><strong>Grouped top-N on the v2 engine is validated.</strong> The v2 
engine sorts <code>GROUP BY ... ORDER BY COUNT(*) DESC LIMIT 5</code> only 
after its capped composite aggregation, so it can return the wrong five groups. 
The driver probes the unsorted group listing (one additional SQL request) and 
raises <code>DataError</code> when that listing reaches its bucket ceiling. 
Ordering only by grouped fields (<code>GROUP BY k ORDER BY k DESC LIMIT 
3</code>) is sorted inside the aggregation, so it is not probed. 
<em>Migration:</em> narrow the grouping, or use <code>v2=false</code> for 
legacy top-N.</p>
   </li>
   <li>
   <p><strong>OFFSET is an exception to the grouped-field ordering 
shortcut:</strong> <code>SELECT k, COUNT(*) FROM t GROUP BY k ORDER BY k LIMIT 
3 OFFSET 999</code> is probed and raises <code>DataError</code> at the bucket 
ceiling instead of silently returning one row from 5000 groups.</p>
   </li>
   <li>
   <p><strong>OpenSearch 1.x v2 plain SELECTs stay on the v2 engine</strong> 
(paging them would hand them to the legacy engine), preserving floating values 
and timestamp objects. The server version is discovered once per connection, 
best effort; when it cannot be read, unpaged v2 semantics are preferred to 
legacy paging.</p>
   </li>
   <li>
   <p><strong>The legacy engine no longer confuses a table-qualified column 
with a select-list alias of the same name</strong> (<code>ORDER BY grp.k</code> 
next to <code>v AS k</code> sorted by <code>v</code>): such aliases are renamed 
in the statement sent and restored in the result.</p>
   </li>
   <li>
   <p><strong>Open Distro returns every row of a plain SELECT.</strong> Open 
Distro 1.13 stops a SELECT without its own LIMIT at 
<code>opendistro.query.size_limit</code> (200) and has SQL cursors off by 
default; 0.2.13 returned those 200 rows silently. A capped answer is now asked 
for again with an explicit LIMIT of the 10000-row search window, and beyond 
that paged with the SQL cursor. A plain SELECT whose own LIMIT is past that 
window (e.g. SQL Lab's <code>LIMIT 100001</code>), which Open Distro refuses, 
is answered the same way and cut at its LIMIT. <em>Migration:</em> results 
above 10000 rows need <code>opendistro.sql.cursor.enabled: true</code> on the 
cluster, otherwise the query raises <code>DataError</code> saying so.</p>
   </li>
   <li>
   <p>OpenSearch 2.11/2.15 v2 aggregations can stop at 
<code>plugins.query.size_limit</code>
   (200 by default), on either SQL endpoint. Ambiguous full buckets now raise
   <code>DataError</code>, rather than silently returning incomplete groups. 
Exactly 200
   remains accepted on Open Distro and OpenSearch 1.x, and on newer servers at
   their default size limit. A custom size limit below 1000 is also checked on
   OpenSearch 2.x/3.x.</p>
   </li>
   <li>
   <p>An explicit v2 SELECT <code>LIMIT</code> bypasses the query size limit; 
only the search
   window is checked. Plain SELECTs with a LIMIT above 10000 are replayed 
without
   LIMIT using SQL cursors, then capped locally; unavailable cursors raise
   <code>DataError</code>, including a limited cursor whose next page is 
empty.</p>
   </li>
   <li>
   <p>The v2 engine sorts grouped top-N results <strong>after</strong> its 
capped composite
   aggregation, so <code>GROUP BY ... ORDER BY COUNT(*) DESC LIMIT 5</code> can 
select the
   wrong groups even though only five rows are returned. The driver now probes
   the underlying group listing and raises <code>DataError</code> at its bucket 
ceiling.
   Narrow the grouping or use <code>v2=false</code> for legacy top-N. Safe 
small listings
   incur one additional SQL request. Ordering only by grouped fields (e.g.
   <code>GROUP BY k ORDER BY k DESC LIMIT 3</code>) is sorted inside the 
aggregation and is</p>
   </li>
   </ul>
   <!-- raw HTML omitted -->
   </blockquote>
   <p>... (truncated)</p>
   </details>
   <details>
   <summary>Commits</summary>
   <ul>
   <li><a 
href="https://github.com/preset-io/elasticsearch-dbapi/commit/83fd3c392ebb5c1fbb2a569b2251c6ffb6d4d053";><code>83fd3c3</code></a>
 release: 0.3.0 (<a 
href="https://redirect.github.com/preset-io/elasticsearch-dbapi/issues/125";>#125</a>)</li>
   <li><a 
href="https://github.com/preset-io/elasticsearch-dbapi/commit/2303279b514c0855f38104ce2e7bf03b4f37b623";><code>2303279</code></a>
 fix: SQLAlchemy 2 and DB-API correctness fixes found by live testing (<a 
href="https://redirect.github.com/preset-io/elasticsearch-dbapi/issues/124";>#124</a>)</li>
   <li>See full diff in <a 
href="https://github.com/preset-io/elasticsearch-dbapi/compare/0.2.13...0.3.0";>compare
 view</a></li>
   </ul>
   </details>
   <br />
   
   
   [![Dependabot compatibility 
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=elasticsearch-dbapi&package-manager=pip&previous-version=0.2.13&new-version=0.3.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
   
   Dependabot will resolve any conflicts with this PR as long as you don't 
alter it yourself. You can also trigger a rebase manually by commenting 
`@dependabot rebase`.
   
   [//]: # (dependabot-automerge-start)
   [//]: # (dependabot-automerge-end)
   
   ---
   
   <details>
   <summary>Dependabot commands and options</summary>
   <br />
   
   You can trigger Dependabot actions by commenting on this PR:
   - `@dependabot rebase` will rebase this PR
   - `@dependabot recreate` will recreate this PR, overwriting any edits that 
have been made to it
   - `@dependabot show <dependency name> ignore conditions` will show all of 
the ignore conditions of the specified dependency
   - `@dependabot ignore this major version` will close this PR and stop 
Dependabot creating any more for this major version (unless you reopen the PR 
or upgrade to it yourself)
   - `@dependabot ignore this minor version` will close this PR and stop 
Dependabot creating any more for this minor version (unless you reopen the PR 
or upgrade to it yourself)
   - `@dependabot ignore this dependency` will close this PR and stop 
Dependabot creating any more for this dependency (unless you reopen the PR or 
upgrade to it yourself)
   
   
   </details>


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to