Home - Waterfall Grid T-Grid Console Builders Recent Builds Buildslaves Changesources - JSON API - About

Console View


Categories: connectors experimental galera main
Legend:   Passed Failed Warnings Failed Again Running Exception Offline No data

connectors experimental galera main
Sergei Golubchik
ssl_info_client without a password hash: COM_QUIT alone if not verified

Without a password hash the client cannot prove that it has verified
the server certificate, it can only say so. It sends COM_QUIT and
the version if it has verified the certificate, and COM_QUIT alone
if it has not.

Assisted-by: Claude:claude-opus-5-5
Vladislav Vaintroub
MDEV-38741 mtr: do not suppress the reason of a client disconnect

The global suppressions of "Aborted connection", in mariadb-test-run.pl
and mtr_warnings.sql, hid the line that the client disconnect watcher
writes when it aborts a command: "Aborted connection N to db: 'x' user:
'u' host: 'h' (Client disconnected)". Nothing showed when the watcher
aborted a connection that it should have left alone. main.locale found
one, because its server log is in German and the English entry did not
match.

Make the two entries skip a line that ends in "(Client disconnected)".
Other aborted connections are suppressed as before.

The tests that drop a client on purpose accept the reason:
have_disconnect_watcher.inc, which the tests of the watcher include,
and dirty_close, loaddata, sp_notembedded, ssl_timeout, mysqltest,
innodb_bug38231, innodb.xa_recovery, mysql_client_test,
mysql_client_test_nonblock, mysql_client_test_comp and
rpl_semi_sync_shutdown_await_ack.

A replica closes its connection on purpose when it is stopped, in any
phase of its setup, also while the master runs one of its first
queries. rpl_init.inc accepts the reason for every server of the
replication tests, without writing it to the binlog. A binlog dump
thread logs its disconnect with another message, and only with
log_warnings=4.

Assisted-by: Claude:claude-sonnet-5-5
Khaled Riyad
MDEV-37335: crash on re-parsing an sp_instr_set that does not own its LEX

A DECLARE of several variables with a common DEFAULT expression creates one
sp_instr_set per variable, all sharing a single LEX that only the last of
them owns. On re-parsing after a metadata change, a non-owning instruction
still has its LEX, and both parse_expr() and validate_lex_and_exec_core()
took a non-null LEX to mean a cursor LEX. The cursor-only code then
dereferenced the nullptr returned by get_lex_for_cursor() and the re-parsed
LEX was never adopted.

Branch on whether the LEX is a cursor LEX instead of whether it is non-null.
Oleksandr Byelkin
Merge branch '11.4' into 11.8
Vladislav Vaintroub
MDEV-38741 mtr: accept "Client disconnected" in more tests

spider/bugfix.mdev_35959 times out a Spider link on purpose, and
mariabackup.nolock_ddl_during_backup_end ends mariabackup in the middle
of a backup, so both abandon a connection with a statement running.

The Connector/C tests of the unit suite also close connections on
purpose, but cannot call mtr.add_suppression() themselves, so
suite.pm adds the suppression before it starts each test.

Assisted-by: Claude:claude-sonnet-5-5
Sergei Petrunia
MDEV-38274: Unexpectedly large pages_read_count in main.analyze_stmt_prefetch_count

The testcase checked the values of pages_prefetch_read_count and
pages_read_count that InnoDB reported for the query.

The numbers depend on how fast the prefetch thread is in comparison with
the query thread. It can also happen that we request to prefetch a page
but then still have to wait for it to be read, which is counted in
pages_read_count.

Replace the checks in the file with ones that will hold in all
circumstances.
Khaled Riyad
MDEV-37335: crash on re-parsing an sp_instr_set that does not own its LEX

A DECLARE of several variables with a common DEFAULT expression creates one
sp_instr_set per variable, all sharing a single LEX that only the last of
them owns. On re-parsing after a metadata change, a non-owning instruction
still has its LEX, and both parse_expr() and validate_lex_and_exec_core()
took a non-null LEX to mean a cursor LEX. The cursor-only code then
dereferenced the nullptr returned by get_lex_for_cursor() and the re-parsed
LEX was never adopted.

Branch on whether the LEX is a cursor LEX instead of whether it is non-null.
Sergei Golubchik
MDEV-40530 require_secure_transport=CLIENT

An account without a password hash (PAM, gssapi, empty password)
cannot prove that the client has verified the server certificate,
so with require_secure_transport=ON it cannot connect over TCP,
unless it requires a client certificate.

require_secure_transport=CLIENT trusts such clients, as
require_secure_transport did before ssl_info_client. Accounts with
a password hash still need a valid ssl_info_client.

my_getopt: an enum that starts with OFF,ON accepts TRUE and FALSE,
like a boolean does, so --require-secure-transport=TRUE still works.

Assisted-by: Claude:claude-opus-5-5
Vladislav Vaintroub
MDEV-30836 MTR hangs on Windows after warnings in the log at shutdown

Follow-up to the MDEV-30836 fix. With --force, parse_protocol()
returned 1 after a worker reported WARNINGS, so the manager went on
reading from the socket of that worker. A worker that was told to
exit with BYE sends WARNINGS and exits, and does not send anything
more.

On Windows Perl, non-blocking reads do not work, so the manager could
block in that read. It then never handled the results of the other
workers, and mtr hung after the last test.

Return 2 for such a worker, as for the other cases where the worker
needs no response, to continue with the next ready socket. The closed
socket is handled later, when it becomes readable.

A worker that was not told to exit also sends WARNINGS, before it
restarts servers or after a test with side effects, and then goes on
to send TESTRESULT. Keep reading from it, as before. The manager
remembers the workers it said BYE to.

Assisted-by: Claude:claude-sonnet-5-5
Monty
Enabling ha_videx causes 'drop table xxx' to not generate errors

Fixed by having videx_hton->drop_table return -1 (no table data attached
to this object)
Vladislav Vaintroub
MDEV-38741 Abort the running statement when its client disconnects

The server notices that a client is gone only when it reads from or
writes to the socket. A statement that waits, for example for an InnoDB
row lock, keeps running, and its transaction keeps its locks.

Watch the client socket from the end of login until the connection ends
or the client sends COM_QUIT, with epoll (Linux), kqueue (BSD, macOS),
or on Windows with WSAEventSelect and an I/O completion port, and the
exit of the client process for a named pipe. When the client has gone,
the watcher sets DISCONNECT_SIGNALED in THD::disconnect_flags. If a
command that expects an answer is running, it is aborted with
KILL_CONNECTION. If the connection is idle, the next such command is
aborted when it starts. COM_QUIT and COM_STMT_CLOSE are not aborted, a
client can send them and then quit.

A command that is only sending its reply is not aborted, there is
nothing left to interrupt: it sets DISCONNECT_UNINTERRUPTIBLE before
the reply is written, and the lost connection is then logged as usual.
The watcher and the connection thread order their accesses with atomic
read-modify-write operations on the flags, no lock is taken for a
command.

The socket is not shut down, the connection ends after the error is
sent, and the reason, "Client disconnected", is logged once. A
connection with the disconnect noted, idle or only finishing its reply,
shows that State in the processlist. Galera connections are not
aborted.

The global variable disconnect_watcher, ON by default, can be set OFF,
which also ends the watches that exist. It exists only where there is a
watcher: Linux, Windows, the BSDs and macOS, not the embedded server.

New tests: main.disconnect_*, sys_vars.disconnect_watcher_basic and
mysql_client_test test_disconnect_*. Some rpl and innodb tests are
adjusted to pass with the watcher ON and OFF.

Assisted-by: Claude:claude-sonnet-5-5
Oleksandr Byelkin
Merge branch '11.8' into 12.3
Oleksandr Byelkin
Merge branch 'br-11.8-merge' into bb-12.3-release
Vladislav Vaintroub
MDEV-30836 MTR hangs on Windows after warnings in the log at shutdown

Follow-up to the MDEV-30836 fix. With --force, parse_protocol()
returned 1 after a worker reported WARNINGS, so the manager went on
reading from the socket of that worker. A worker that was told to
exit with BYE sends WARNINGS and exits, and does not send anything
more.

On Windows Perl, non-blocking reads do not work, so the manager could
block in that read. It then never handled the results of the other
workers, and mtr hung after the last test.

Return 2 for such a worker, as for the other cases where the worker
needs no response, to continue with the next ready socket. The closed
socket is handled later, when it becomes readable.

A worker that was not told to exit also sends WARNINGS, before it
restarts servers or after a test with side effects, and then goes on
to send TESTRESULT. Keep reading from it, as before. The manager
remembers the workers it said BYE to.

Assisted-by: Claude:claude-sonnet-5-5
Sergei Golubchik
send ssl_info_client to prove the authentication was not relayed

A MitM can relay the authentication, let the client fail on ssl_info
and keep using the authenticated connection.

* MARIADB_CLIENT_SSL_INFO_CLIENT: set it whenever TLS is used
* after the authentication OK packet send ssl_info_client, the server
  does not reply (but might disconnect in case of active MitM).
Monty
MDEV-41811 Atomic CoR: a failed CREATE OR REPLACE ... SELECT NEXTVAL() loses the old table

The reason for this failure is commit
bb4dd70e7c6509ed9bf8c38d44dffb6d2fcca415 (MDEV-13005) which generated
a new error code in ha_discover_table() that ddl_log_revert() for
create or replace table cannot handle. The code also did not take
into account that share and thd->lex->query_tables are not guaranteed
to refer to the same table.

I removed the code for handling sequences from ha_discover_table() and
instead generate the correct error in open_table_error(). This
handles many cases the old code did not handle.

Changes:
- share->table_type == TABLE_TYPE_SEQUENCE is set early in open for
  sequences to be able to generate correct error messages
- share->table_type == TABLE_TYPE_VIEW is set for views during open
  This is mainly to make the table_type have an usable value for views.
Oleksandr Byelkin
Merge branch '11.4' into 11.8
Oleksandr Byelkin
Merge branch '11.8' into 12.3
Vladislav Vaintroub
MDEV-38741 Abort the running statement when its client disconnects

The server notices that a client is gone only when it reads from or
writes to the socket. A statement that waits, for example for an InnoDB
row lock, keeps running, and its transaction keeps its locks.

Watch the client socket from the end of login until the connection ends
or the client sends COM_QUIT, with epoll (Linux), kqueue (BSD, macOS),
or on Windows with WSAEventSelect and an I/O completion port, and the
exit of the client process for a named pipe. When the client has gone,
the watcher sets DISCONNECT_SIGNALED in THD::disconnect_flags. If a
command that expects an answer is running, it is aborted with
KILL_CONNECTION. If the connection is idle, the next such command is
aborted when it starts. COM_QUIT and COM_STMT_CLOSE are not aborted, a
client can send them and then quit.

A command whose last reply is being sent is not aborted, there is
nothing left to interrupt. Protocol::end_statement() sets
DISCONNECT_UNINTERRUPTIBLE when it sends the last reply of a command:
an error, or a reply with no more results to follow. A read-only SELECT
sends its result early, from select_send::send_eof(), and the client
can quit while the server still cleans up. COM_STATISTICS writes its
reply itself and sets the flag too. The lost connection is then logged
as usual. The watcher and the connection thread order their accesses
with atomic read-modify-write operations on the flags, no lock is taken
for a command.

A connection that is already being killed is left alone. KILL
CONNECTION shuts the socket of its victim, which the watcher reports,
and a second awake of the dying thread would wait for it in
abort_current_cond_wait() for up to 2 seconds.

The socket is not shut down, the connection ends after the error is
sent, and the reason, "Client disconnected", is logged once. A
binlog dump thread logs "BINLOG DUMP client disconnected", and only
with log_warnings=4: a replica closes the connection on purpose when it
stops. A connection with the disconnect noted, idle or only finishing
its reply, shows that State in the processlist. Galera connections are
not aborted.

The global variable disconnect_watcher, ON by default, can be set OFF,
which also ends the watches that exist. It exists only where there is a
watcher: Linux, Windows, the BSDs and macOS, not the embedded server.

New tests: main.disconnect_*, sys_vars.disconnect_watcher_basic,
rpl.rpl_dump_thread_disconnect and mysql_client_test
test_disconnect_*. Some rpl and innodb tests are adjusted to pass with
the watcher ON and OFF.

Assisted-by: Claude:claude-sonnet-5-5
Hemant Dangi
MDEV-42091: --prepare must not trust plugin_dir from backup-my.cnf

Issue:
backup-my.cnf is part of the backup/transfer directory and can arrive over
an untrusted channel (e.g. a Galera SST stream). --prepare honored its
plugin_dir value as-is, letting whoever supplied the backup redirect
plugin loading to a directory of their choosing.

Solution:
Pass the joiner's own, locally-resolved --plugin-dir on the --prepare
command line: it wins over whatever backup-my.cnf says, regardless of
content, unless the user already chose one explicitly via
inno-apply-opts, which takes priority as a deliberate local choice.
Resolve it by asking the joiner's own mariadbd, which is config- and
compiled-default-aware, falling back to a plain config lookup if that's
unavailable. Add a regression test driving the real SST joiner script
directly: deliver a backup stream whose backup-my.cnf claims an
attacker-chosen plugin_dir, and confirm that directory is never
referenced.
Alexey Yurchenko
MDEV-41851 register cache manager with SAVEPOINT handler list

MDEV-41851 happens because by the time SAVEPOINT is called there
exists no connection cache manager yet and it does not care to
create one. As a result the cache manger is lazily created later
but is missing from the SAVEPOINT's handler list and thus is not
fired on ROLLBACK TO SAVEPOINT keeping the event in the cache
which in turn is replicated on subsequent COMMIT and applied on
the replicas.
Make sure to create cache manager in wsrep_register_binlog_handler()
if it does not yet exist.
Vladislav Vaintroub
MDEV-38741 Abort the running statement when its client disconnects

The server notices that a client is gone only when it reads from or
writes to the socket. A statement that waits, for example for an InnoDB
row lock, keeps running, and its transaction keeps its locks.

Watch the client socket from the end of login until the connection ends
or the client sends COM_QUIT, with epoll (Linux), kqueue (BSD, macOS),
or on Windows with WSAEventSelect and an I/O completion port, and the
exit of the client process for a named pipe. When the client has gone,
the watcher sets DISCONNECT_SIGNALED in THD::disconnect_flags. If a
command that expects an answer is running, it is aborted with
KILL_CONNECTION. If the connection is idle, the next such command is
aborted when it starts. COM_QUIT and COM_STMT_CLOSE are not aborted, a
client can send them and then quit.

A command that is only sending its reply is not aborted, there is
nothing left to interrupt: it sets DISCONNECT_UNINTERRUPTIBLE before
the reply is written, and the lost connection is then logged as usual.
The watcher and the connection thread order their accesses with atomic
read-modify-write operations on the flags, no lock is taken for a
command.

The socket is not shut down, the connection ends after the error is
sent, and the reason, "Client disconnected", is logged once. A
connection with the disconnect noted, idle or only finishing its reply,
shows that State in the processlist. Galera connections are not
aborted.

The global variable disconnect_watcher, ON by default, can be set OFF,
which also ends the watches that exist. It exists only where there is a
watcher: Linux, Windows, the BSDs and macOS, not the embedded server.

New tests: main.disconnect_*, sys_vars.disconnect_watcher_basic and
mysql_client_test test_disconnect_*. Some rpl and innodb tests are
adjusted to pass with the watcher ON and OFF.

Assisted-by: Claude:claude-sonnet-5-5
Sergei Golubchik
MDEV-40530 Bind the client authentication response to the server certificate

MDEV-31855 introduced ssl_info that let the client verify
that it uses the correct certificate. But MitM could hijack the
connection after the authentication - the client will detect it
and disconnect but the server won't and will continue talking
to the attacker. Let's introduce ssl_info_client packet that
enables the server to verify that the client uses the correct
certificate.

When require_secure_transport=ON and the connection isn't local:
* the server sets MARIADB_CLIENT_SSL_INFO_CLIENT in the initial handshake
* the client sets it in the reply, if it understands it
* when both sides have it, the client sends ssl_info_client right
  after the OK packet, acl_authenticate() reads it before the session
  is used (init_connect, audit, etc)
* a connection is rejected unless ssl_info_client is valid, either
  for the server certificate fingerprint or for "CA" (the client
  verified the certificate itself)
* an account without a password hash (plugin has no hash_password()
  or empty password) is rejected unless the account REQUIRE a client
  certificate

Assisted-by: Claude:claude-opus-5-5
Vladislav Vaintroub
MDEV-38741 Abort the running statement when its client disconnects

The server notices that a client is gone only when it reads from or
writes to the socket. A statement that waits, for example for an InnoDB
row lock, keeps running, and its transaction keeps its locks.

Watch the client socket from the end of login until the connection ends
or the client sends COM_QUIT, with epoll (Linux), kqueue (BSD, macOS),
or on Windows with WSAEventSelect and an I/O completion port, and the
exit of the client process for a named pipe. When the client has gone,
the watcher sets DISCONNECT_SIGNALED in THD::disconnect_flags. If a
command that expects an answer is running, it is aborted with
KILL_CONNECTION. If the connection is idle, the next such command is
aborted when it starts. COM_QUIT and COM_STMT_CLOSE are not aborted, a
client can send them and then quit.

A command whose last reply is being sent is not aborted, there is
nothing left to interrupt. Protocol::end_statement() sets
DISCONNECT_UNINTERRUPTIBLE when it sends the last reply of a command:
an error, or a reply with no more results to follow. A read-only SELECT
sends its result early, from select_send::send_eof(), and the client
can quit while the server still cleans up. The lost connection is then
logged as usual. The watcher and the connection thread order their
accesses with atomic read-modify-write operations on the flags, no lock
is taken for a command.

A connection that is already being killed is left alone. KILL
CONNECTION shuts the socket of its victim, which the watcher reports,
and a second awake of the dying thread would wait for it in
abort_current_cond_wait() for up to 2 seconds.

The socket is not shut down, the connection ends after the error is
sent, and the reason, "Client disconnected", is logged once. A
connection with the disconnect noted, idle or only finishing its reply,
shows that State in the processlist. Galera connections are not
aborted.

The global variable disconnect_watcher, ON by default, can be set OFF,
which also ends the watches that exist. It exists only where there is a
watcher: Linux, Windows, the BSDs and macOS, not the embedded server.

The global suppressions of "Aborted connection" in mtr no longer hide
the reason: they hid the aborts of ordinary clients. The tests that
drop a client on purpose accept it, through have_disconnect_watcher.inc,
dirty_close and mysql_client_test.

New tests: main.disconnect_*, sys_vars.disconnect_watcher_basic and
mysql_client_test test_disconnect_*. Some rpl and innodb tests are
adjusted to pass with the watcher ON and OFF.

Assisted-by: Claude:claude-sonnet-5-5
Monty
MDEV-41811 Atomic CoR: a failed CREATE OR REPLACE ... SELECT NEXTVAL() loses the old table

The reason for this failure is commit
bb4dd70e7c6509ed9bf8c38d44dffb6d2fcca415 which generated a new error code
in ha_discover_table() that ddl_log_revert() for create and replace table
cannot handle. The code also did not take into account that share and
thd->lex->query_tables are not guaranteed to refer to the same table.

I removed the code for handling sequences from ha_discover_table() and did
instead generate the correct error in open_table_error(). This handles
many cases the old code did not handle.
Oleksandr Byelkin
Merge branch 'br-11.8-merge' into br-12.3-merge
Vladislav Vaintroub
MDEV-38741 Abort the running statement when its client disconnects

The server notices that a client is gone only when it reads from or
writes to the socket. A statement that waits, for example for an InnoDB
row lock, keeps running, and its transaction keeps its locks.

Watch the client socket from the end of login until the connection ends
or the client sends COM_QUIT, with epoll (Linux), kqueue (BSD, macOS),
or on Windows with WSAEventSelect and an I/O completion port, and the
exit of the client process for a named pipe. When the client has gone,
the watcher sets THD::client_gone. If a command that expects an answer
is running, it is aborted with KILL_CONNECTION. If the connection is
idle, the next such command is aborted when it starts. COM_QUIT and
COM_STMT_CLOSE are not aborted, a client can send them and then quit.
The watcher and the connection thread order their accesses with fences,
no lock is taken for a command. The socket is not shut down, the
connection ends after the error is sent, and the reason, "Client
disconnected", is logged once. An idle connection with the disconnect
noted shows that State in the processlist. Galera connections are not
aborted.

The global variable disconnect_watcher, ON by default, can be set OFF,
which also ends the watches that exist. It exists only where there is a
watcher: Linux, Windows, the BSDs and macOS, not the embedded server.

mysqltest dirty_close takes an optional linger or nolinger argument.

New tests: main.disconnect_*, sys_vars.disconnect_watcher_basic and
mysql_client_test test_disconnect_*. Some rpl and innodb tests are
adjusted to pass with the watcher ON and OFF.

Assisted-by: Claude:claude-sonnet-5-5
Oleksandr Byelkin
fix
Monty
Compiling ha_videx statically causes 'drop table xxx' to not generate errors

The issue was that ha_videx::delete_table() returns 0, which means that
the table was successfully deleted, which confused delete_table_force to
belive that the table was succesfully deleted, which in turn casued
the "Unknown table" error to not be given.
Vladislav Vaintroub
MDEV-30836 MTR hangs on Windows after warnings in the log at shutdown

Follow-up to the MDEV-30836 fix. With --force, parse_protocol()
returned 1 after a worker reported WARNINGS, so the manager went on
reading from the socket of that worker. The worker sends WARNINGS in
reply to BYE and exits, and does not send anything more.

On Windows Perl, non-blocking reads do not work, so the manager could
block in that read. It then never handled the results of the other
workers, and mtr hung after the last test.

Return 2, as for the other cases where the worker needs no response,
to continue with the next ready socket. The closed socket is handled
later, when it becomes readable.

Assisted-by: Claude:claude-sonnet-5-5
Monty
MDEV-41811 Atomic CoR: a failed CREATE OR REPLACE ... SELECT NEXTVAL() loses the old table

The reason for this failure is commit
bb4dd70e7c6509ed9bf8c38d44dffb6d2fcca415 (MDEV-13005) which generated
a new error code in ha_discover_table() that ddl_log_revert() for
create and replace table cannot handle. The code also did not take
into account that share and thd->lex->query_tables are not guaranteed
to refer to the same table.

I removed the code for handling sequences from ha_discover_table() and
instead generate the correct error in open_table_error(). This
handles many cases the old code did not handle.

Changes:
- share->table_type == TABLE_TYPE_SEQUENCE is set early in open for
  sequences to be able to generate correct error messages
- share->table_type == TABLE_TYPE_VIEW is now set for views during open
  This is mainly to make the table_type have an usable value for views.
Sergei Golubchik
MDEV-40530 require_secure_transport=CLIENT: the client says it has verified

With require_secure_transport=CLIENT a client without a password hash
must still set MARIADB_CLIENT_SSL_INFO_CLIENT and say that it has
verified the server certificate: ssl_info_client is COM_QUIT and the
version if it has, and COM_QUIT alone if it has not.

This is not a proof, a man in the middle can say it too, but a client
that does not verify the server certificate is rejected and an old
client that does not know ssl_info_client is rejected too.

A client cannot simply abort after the OK packet if it has not
verified the certificate: an account that requires a client
certificate does not need ssl_info_client.

Assisted-by: Claude:claude-opus-5-5
Vladislav Vaintroub
MDEV-30836 MTR hangs on Windows after warnings in the log at shutdown

Follow-up to the MDEV-30836 fix. With --force, parse_protocol()
returned 1 after a worker reported WARNINGS, so the manager went on
reading from the socket of that worker. The worker sends WARNINGS in
reply to BYE and exits, and does not send anything more.

On Windows Perl, non-blocking reads do not work, so the manager could
block in that read. It then never handled the results of the other
workers, and mtr hung after the last test.

Return 2, as for the other cases where the worker needs no response,
to continue with the next ready socket. The closed socket is handled
later, when it becomes readable.

Assisted-by: Claude:claude-sonnet-5-5
Hemant Dangi
MDEV-41158: authenticate the mariabackup SST backup-data stream too

Issue:
The joiner's per-transfer secret was only generated for
ssl-mode=VERIFY_*, and checked only on the small GTID stage: the
backup-data stage itself was accepted unauthenticated, letting any
TCP peer reaching the SST port supply a backup --prepare then runs.

Solution:
Generate the secret unconditionally and require it on the backup-data
stream too, built in lockstep with the existing encrypt/decompress/
progress wrapping so the check can't be silently skipped by it. Add
sst-mariabackup-allow-unauthenticated-donor for rolling upgrades,
failing closed on invalid values; VERIFY_*'s own pre-existing secret
check is unaffected by it. Add a regression test covering the
authenticated pipeline with that wrapping active.
Alexey (Holyfoot) Botchkov
MDEV-41821 XMLISVALID returns unexepected result, various corner cases.

Control of empty builtin types added.
complexType with only optional particles allows empty element.
maxOccurs now handled in <choice>.
No type in <element> now is allowed.
Oleksandr Byelkin
Merge branch '11.4' into 11.8
Oleksandr Byelkin
MDEV-38274 fix lost in 11.4->11.8 merge

The merge 0e86a0d055f kept the old 11.8 version of
main.analyze_stmt_prefetch_count. Take the 11.4 version and keep
"character set latin1" from MDEV-19123.

Assisted-by: Claude:claude-opus-5-5
Monty
Enabling ha_videx causes 'drop table xxx' to not generate errors

Fixed by having videx_hton->drop_table return -1 (no table data attached
to this object)