1
0
mirror of https://github.com/MariaDB/server.git synced 2026-10-23 18:49:29 +03:00

Merge branch '11.8' into 12.3

This commit is contained in:
Oleksandr Byelkin
2026-08-20 08:27:14 +02:00
481 changed files with 12950 additions and 2698 deletions

114
.github/copilot-instructions.md vendored Normal file
View File

@@ -0,0 +1,114 @@
# MariaDB Server — Code Review Instructions
You are reviewing a change to MariaDB Server, a large C/C++ codebase with
strict conventions. **Correctness** comes first, but style matters too: no
automated formatter runs on this repo, so review is the only gate that
enforces the coding style — flag style violations as well as bugs.
## Priorities (in order)
1. Correctness bugs and crashes (see checklist below).
2. Backward/forward compatibility (on-disk formats, protocol, replication).
3. Performance and scalability — but only where it plausibly matters (a hot
path, or large/unbounded data), not speculative micro-optimization. Look
for:
- Wrong algorithmic complexity for the expected scale — e.g. an O(N²) loop
where a hash or sort gives O(N)/O(N log N) and N can be large. Conversely,
do NOT flag a simple O(N²) over small, bounded input where a heavier data
structure would be slower and less readable — call out the trade-off, not
just the asymptotics.
- Expensive or blocking work inside a critical section — disk/network I/O,
`fsync`, memory allocation, logging, or acquiring another lock while
holding a mutex/latch/rwlock. Shrink the critical section instead.
- Avoidable per-row cost in a hot loop — repeated allocation, redundant
recomputation of a loop-invariant, needless charset/string conversion, or
a full scan where an index lookup exists.
- Unnecessary copying of large records/buffers where a reference, move, or
in-place operation suffices.
4. Missing or inadequate test coverage.
5. Style deviations from CODING_STANDARDS.md. These are NOT enforced by any
automated formatter, so review is the only gate — do flag them, as nits.
## MariaDB-specific bug checklist
- **Memory lifetime.** Allocator must match lifetime: `MEM_ROOT`
(`new (thd->mem_root) T`, `alloc_root`) for query-scoped; `my_malloc`/plain
`new` for large or long-lived. Flag: pointers into a `MEM_ROOT`/`String`/`blob_heap`
buffer that survive `free_root` or a record re-read; mismatched alloc/free
families — handing `MEM_ROOT` memory to `free`/`my_free` (it is bulk-freed at
`free_root`), or `my_free`-ing something from `new`. Note `delete obj` on a
`MEM_ROOT` object is fine and often required — classes like `Item` make
`operator delete` a no-op, so `delete` runs the destructor without freeing.
- **Prepared-statement arena.** Objects that must survive re-execution belong
on `thd->stmt_arena` (`Query_arena_stmt`), not the runtime mem_root.
Statements whose shape can change need `CF_REEXECUTION_FRAGILE` /
`needs_reprepare`, or PS reuse crashes or returns stale results. Item
tree changes are either permanent on the stmt_arena or temporary
and must be registered.
- **Error contract.** `bool`: false=success, true=error; int: 0=success.
Every fallible call checked; `my_error()` issued before returning true;
error path frees what it allocated (`goto err`).
- **Scoped error interception.** `thd->is_error()` checked after an operation,
or `thd->clear_error()`, is usually an anti-pattern: both act on the whole
THD, so they also see (or wipe) a legitimate error raised *before* this
operation. To detect or suppress errors from a specific bounded operation,
push an `Internal_error_handler` (`thd->push_internal_handler()` /
`pop_internal_handler()`) around exactly that scope.
- **NULL.** SQL NULL (`null_value`/`is_null()`) vs C NULL pointer; `maybe_null`
propagation; `val_str()`/`val_*` may return NULL. `item->null_value` /
`is_null()` is valid ONLY after the item has been evaluated by a `val_*()`
call in the current row — it is set as a side effect of evaluation, so
checking it before (or without) evaluating reads a stale/undefined flag.
- **Replication.** Non-deterministic constructs and their SBR vs RBR logging
safety; binlog side effects; cross-version compatibility.
- **Concurrency.** Mutex acquisition order and init order; `LOCK_*` globals;
init-once races. Respect `thd->killed`, `thd->check_killed()` is preferred.
- **Compatibility.** `.frm`, redo/undo, system-table schema, wire protocol,
sysvar defaults — a format change without upgrade handling is blocking.
- **Portability.** No `long`/`ulong` (use fixed-width or `size_t`); don't rely
on char being signed; alignment, endianness; integer overflow/truncation in
size arithmetic.
- **Assertions.** `DBUG_ASSERT` is compiled out in release — for invariants
only, never to validate external/untrusted input. Use them also as a
self-enforcing code documentation ("note, ptr is never NULL here").
## Testing
- Expect an `mysql-test/` `.test`; it must FAIL without the code change
(demonstrate the regression), not merely pass with it.
- **Check the test is adequate, not just present.** It must exercise the
logic the fix actually adds. For every new condition/branch, expect a case
that hits each side — a fix guarded by `if (value is NULL)` needs both a
NULL case (takes the new path) and a non-NULL case (doesn't). A new loop
bound, error path, or type case is untested until an input reaches it. Flag
new conditionals with no covering test.
- **A `.result`-only change is a red flag, not noise.** When a `.test` is
unchanged but its `.result` is, ask: (1) Is the new output actually
correct, or does it silently bless a regression? (2) Did the change gut the
test — e.g. an `EXPLAIN` that once exercised a specific optimizer path now
shows a different plan, so the test no longer covers what it was written to
cover? Flag both.
## PR hygiene
- Subject line starts with `MDEV-NNNNN`; body wrapped at 72 cols.
- Bug fix targets the oldest maintained branch that reproduces (≤3y since GA);
new feature targets the main branch.
- Bug fix commit is minimal; cleanups (unrelated and related - prerequisite
cleanups) belong in separate commits, even if they are allowed to be in the
same PR
## Do NOT
- Restate what the diff does.
- Report pure compiler/CI failures (they are already visible) — but style is
NOT auto-enforced here, so style review is expected, not redundant.
- Suggest STL/`std::` replacements — this codebase uses `List<T>`,
`Dynamic_array`, `Hash_set`, `String`, `LEX_CSTRING`, etc. by policy.
- Assert about code outside the diff — ask a question instead. Do not invent
API/symbol names; verify against the code shown.
## Output
- Cite `file:line`. Tag each finding **blocking / should-fix / nit**.
- Prefer a few high-confidence findings over many speculative ones.
## Skip
Submodules and bundled third-party code (`zlib/`).
Note: `.result` files are NOT skipped — see Testing.
See CODING_STANDARDS.md for full style rules.

View File

@@ -1751,7 +1751,6 @@ static char *my_case_str(const char *str,
static int switch_db_collation(FILE *sql_file,
const char *db_name,
const char *delimiter,
const char *current_db_cl_name,
const char *required_db_cl_name,
int *db_cl_altered)
@@ -1767,11 +1766,10 @@ static int switch_db_collation(FILE *sql_file,
return 1;
fprintf(sql_file,
"ALTER DATABASE %s CHARACTER SET %s COLLATE %s %s\n",
"ALTER DATABASE %s CHARACTER SET %s COLLATE %s ;\n",
(const char *) quoted_db_name,
(const char *) db_cl->cs_name.str,
(const char *) db_cl->coll_name.str,
(const char *) delimiter);
(const char *) db_cl->coll_name.str);
*db_cl_altered= 1;
@@ -1786,7 +1784,6 @@ static int switch_db_collation(FILE *sql_file,
static int restore_db_collation(FILE *sql_file,
const char *db_name,
const char *delimiter,
const char *db_cl_name)
{
char quoted_db_buf[NAME_LEN * 2 + 3];
@@ -1798,100 +1795,71 @@ static int restore_db_collation(FILE *sql_file,
return 1;
fprintf(sql_file,
"ALTER DATABASE %s CHARACTER SET %s COLLATE %s %s\n",
"ALTER DATABASE %s CHARACTER SET %s COLLATE %s ;\n",
(const char *) quoted_db_name,
(const char *) db_cl->cs_name.str,
(const char *) db_cl->coll_name.str,
(const char *) delimiter);
(const char *) db_cl->coll_name.str);
return 0;
}
static void switch_cs_variables(FILE *sql_file,
const char *delimiter,
const char *character_set_client,
const char *character_set_results,
const char *collation_connection)
{
fprintf(sql_file,
"/*!50003 SET @saved_cs_client = @@character_set_client */ %s\n"
"/*!50003 SET @saved_cs_results = @@character_set_results */ %s\n"
"/*!50003 SET @saved_col_connection = @@collation_connection */ %s\n"
"/*!50003 SET character_set_client = %s */ %s\n"
"/*!50003 SET character_set_results = %s */ %s\n"
"/*!50003 SET collation_connection = %s */ %s\n",
(const char *) delimiter,
(const char *) delimiter,
(const char *) delimiter,
"/*!50003 SET @saved_cs_client = @@character_set_client */ ;\n"
"/*!50003 SET @saved_cs_results = @@character_set_results */ ;\n"
"/*!50003 SET @saved_col_connection = @@collation_connection */ ;\n"
"/*!50003 SET character_set_client = %s */ ;\n"
"/*!50003 SET character_set_results = %s */ ;\n"
"/*!50003 SET collation_connection = %s */ ;\n",
(const char *) character_set_client,
(const char *) delimiter,
(const char *) character_set_results,
(const char *) delimiter,
(const char *) collation_connection,
(const char *) delimiter);
(const char *) collation_connection);
}
static void restore_cs_variables(FILE *sql_file,
const char *delimiter)
static void restore_cs_variables(FILE *sql_file)
{
fprintf(sql_file,
"/*!50003 SET character_set_client = @saved_cs_client */ %s\n"
"/*!50003 SET character_set_results = @saved_cs_results */ %s\n"
"/*!50003 SET collation_connection = @saved_col_connection */ %s\n",
(const char *) delimiter,
(const char *) delimiter,
(const char *) delimiter);
"/*!50003 SET character_set_client = @saved_cs_client */ ;\n"
"/*!50003 SET character_set_results = @saved_cs_results */ ;\n"
"/*!50003 SET collation_connection = @saved_col_connection */ ;\n");
}
static void switch_sql_mode(FILE *sql_file,
const char *delimiter,
const char *sql_mode)
static void switch_sql_mode(FILE *sql_file, const char *sql_mode)
{
fprintf(sql_file,
"/*!50003 SET @saved_sql_mode = @@sql_mode */ %s\n"
"/*!50003 SET sql_mode = '%s' */ %s\n",
(const char *) delimiter,
(const char *) sql_mode,
(const char *) delimiter);
"/*!50003 SET @saved_sql_mode = @@sql_mode */ ;\n"
"/*!50003 SET sql_mode = '%s' */ ;\n",
(const char *) sql_mode);
}
static void restore_sql_mode(FILE *sql_file,
const char *delimiter)
static void restore_sql_mode(FILE *sql_file)
{
fprintf(sql_file,
"/*!50003 SET sql_mode = @saved_sql_mode */ %s\n",
(const char *) delimiter);
"/*!50003 SET sql_mode = @saved_sql_mode */ ;\n");
}
static void switch_time_zone(FILE *sql_file,
const char *delimiter,
const char *time_zone)
static void switch_time_zone(FILE *sql_file, const char *time_zone)
{
fprintf(sql_file,
"/*!50003 SET @saved_time_zone = @@time_zone */ %s\n"
"/*!50003 SET time_zone = '%s' */ %s\n",
(const char *) delimiter,
(const char *) time_zone,
(const char *) delimiter);
"/*!50003 SET @saved_time_zone = @@time_zone */ ;\n"
"/*!50003 SET time_zone = '%s' */ ;\n",
(const char *) time_zone);
}
static void restore_time_zone(FILE *sql_file,
const char *delimiter)
static void restore_time_zone(FILE *sql_file)
{
fprintf(sql_file,
"/*!50003 SET time_zone = @saved_time_zone */ %s\n",
(const char *) delimiter);
"/*!50003 SET time_zone = @saved_time_zone */ ;\n");
}
@@ -2684,44 +2652,6 @@ static void print_comment(FILE *sql_file, my_bool is_error, const char *format,
print_xml_comment(sql_file, strlen(comment_buff), comment_buff);
}
/*
create_delimiter
Generate a new (null-terminated) string that does not exist in query
and is therefore suitable for use as a query delimiter. Store this
delimiter in delimiter_buff .
This is quite simple in that it doesn't even try to parse statements as an
interpreter would. It merely returns a string that is not in the query, which
is much more than adequate for constructing a delimiter.
RETURN
ptr to the delimiter on Success
NULL on Failure
*/
static char *create_delimiter(char *query, char *delimiter_buff,
int delimiter_max_size)
{
int proposed_length;
char *presence;
delimiter_buff[0]= ';'; /* start with one semicolon, and */
for (proposed_length= 2; proposed_length < delimiter_max_size;
delimiter_max_size++) {
delimiter_buff[proposed_length-1]= ';'; /* add semicolons, until */
delimiter_buff[proposed_length]= '\0';
presence = strstr(query, delimiter_buff);
if (presence == NULL) { /* the proposed delimiter is not in the query. */
return delimiter_buff;
}
}
return NULL; /* but if we run out of space, return nothing at all. */
}
/*
dump_events_for_db
-- retrieves list of events for a given db, and prints out
@@ -2736,7 +2666,6 @@ static uint dump_events_for_db(char *db)
char query_buff[QUERY_LENGTH];
char db_name_buff[NAME_LEN*2+3], name_buff[NAME_LEN*2+3];
char *event_name;
char delimiter[QUERY_LENGTH];
FILE *sql_file= md_result_file;
MYSQL_RES *event_res= NULL, *event_list_res= NULL;
MYSQL_ROW row, event_list_row;
@@ -2764,7 +2693,6 @@ static uint dump_events_for_db(char *db)
if (mysql_query_with_error_report(mysql, &event_list_res, "show events"))
DBUG_RETURN(0);
safe_strcpy(delimiter, sizeof(delimiter), ";");
if (mysql_num_rows(event_list_res) > 0)
{
if (opt_xml)
@@ -2810,25 +2738,16 @@ static uint dump_events_for_db(char *db)
char *query_str;
if (opt_drop)
fprintf(sql_file, "/*!50106 DROP EVENT IF EXISTS %s */%s\n",
event_name, delimiter);
if (create_delimiter(row[3], delimiter, sizeof(delimiter)) == NULL)
{
fprintf(stderr, "%s: Warning: Can't create delimiter for event '%s'\n",
my_progname_short, event_name);
goto err;
}
fprintf(sql_file, "DELIMITER %s\n", delimiter);
fprintf(sql_file, "/*!50106 DROP EVENT IF EXISTS %s */;\n",
event_name);
if (mysql_num_fields(event_res) >= 7)
{
if (switch_db_collation(sql_file, db_name_buff, delimiter,
if (switch_db_collation(sql_file, db_name_buff,
db_cl_name, row[6], &db_cl_altered))
goto err;
switch_cs_variables(sql_file, delimiter,
switch_cs_variables(sql_file,
row[4], /* character_set_client */
row[4], /* character_set_results */
row[5]); /* collation_connection */
@@ -2851,32 +2770,31 @@ static uint dump_events_for_db(char *db)
"--\n");
}
switch_sql_mode(sql_file, delimiter, row[1]);
switch_sql_mode(sql_file, row[1]);
switch_time_zone(sql_file, delimiter, row[2]);
switch_time_zone(sql_file, row[2]);
query_str= cover_definer_clause(row[3], strlen(row[3]),
C_STRING_WITH_LEN("50117"),
C_STRING_WITH_LEN("50106"),
C_STRING_WITH_LEN(" EVENT"));
fprintf(sql_file,
"/*!50106 %s \n*/ %s\n",
(const char *) (query_str != NULL ? query_str : row[3]),
(const char *) delimiter);
fprintf(sql_file, "DELIMITER ;;\n"
"/*!50106 %s \n*/ ;;\n"
"DELIMITER ;\n",
(const char *) (query_str != NULL ? query_str : row[3]));
my_free(query_str);
restore_time_zone(sql_file, delimiter);
restore_sql_mode(sql_file, delimiter);
restore_time_zone(sql_file);
restore_sql_mode(sql_file);
if (mysql_num_fields(event_res) >= 7)
{
restore_cs_variables(sql_file, delimiter);
restore_cs_variables(sql_file);
if (db_cl_altered)
{
if (restore_db_collation(sql_file, db_name_buff, delimiter,
db_cl_name))
if (restore_db_collation(sql_file, db_name_buff, db_cl_name))
goto err;
}
}
@@ -2893,7 +2811,6 @@ static uint dump_events_for_db(char *db)
}
else
{
fprintf(sql_file, "DELIMITER ;\n");
fprintf(sql_file, "/*!50106 SET TIME_ZONE= @save_time_zone */ ;\n");
}
@@ -3053,7 +2970,7 @@ static uint dump_routines_for_db(char *db)
continue;
}
switch_sql_mode(sql_file, ";", row[1]);
switch_sql_mode(sql_file, row[1]);
if (opt_drop)
fprintf(sql_file, "/*!50003 DROP %s IF EXISTS %s */;\n",
@@ -3061,7 +2978,7 @@ static uint dump_routines_for_db(char *db)
if (mysql_num_fields(routine_res) >= 6)
{
if (switch_db_collation(sql_file, db, ";",
if (switch_db_collation(sql_file, db,
db_cl_name, row[5], &db_cl_altered))
{
mysql_free_result(routine_res);
@@ -3070,7 +2987,7 @@ static uint dump_routines_for_db(char *db)
DBUG_RETURN(1);
}
switch_cs_variables(sql_file, ";",
switch_cs_variables(sql_file,
row[3], /* character_set_client */
row[3], /* character_set_results */
row[4]); /* collation_connection */
@@ -3101,15 +3018,15 @@ static uint dump_routines_for_db(char *db)
"DELIMITER ;\n",
(const char *) row[2]);
restore_sql_mode(sql_file, ";");
restore_sql_mode(sql_file);
if (mysql_num_fields(routine_res) >= 6)
{
restore_cs_variables(sql_file, ";");
restore_cs_variables(sql_file);
if (db_cl_altered)
{
if (restore_db_collation(sql_file, db, ";", db_cl_name))
if (restore_db_collation(sql_file, db, db_cl_name))
{
mysql_free_result(routine_res);
mysql_free_result(routine_list_res);
@@ -4015,16 +3932,16 @@ static int dump_trigger(FILE *sql_file, MYSQL_RES *show_create_trigger_rs,
continue;
}
if (switch_db_collation(sql_file, db_name, ";",
if (switch_db_collation(sql_file, db_name,
db_cl_name, row[5], &db_cl_altered))
DBUG_RETURN(TRUE);
switch_cs_variables(sql_file, ";",
switch_cs_variables(sql_file,
row[3], /* character_set_client */
row[3], /* character_set_results */
row[4]); /* collation_connection */
switch_sql_mode(sql_file, ";", row[1]);
switch_sql_mode(sql_file, row[1]);
if (opt_drop_trigger)
fprintf(sql_file, "/*!50032 DROP TRIGGER IF EXISTS %s */;\n",
@@ -4042,12 +3959,12 @@ static int dump_trigger(FILE *sql_file, MYSQL_RES *show_create_trigger_rs,
my_free(query_str);
restore_sql_mode(sql_file, ";");
restore_cs_variables(sql_file, ";");
restore_sql_mode(sql_file);
restore_cs_variables(sql_file);
if (db_cl_altered)
{
if (restore_db_collation(sql_file, db_name, ";", db_cl_name))
if (restore_db_collation(sql_file, db_name, db_cl_name))
DBUG_RETURN(TRUE);
}
}

View File

@@ -854,6 +854,7 @@ static void lock_table(MYSQL *mysql, int tablecount, char **raw_tablename)
}
if (mysql_real_query(mysql, query.str, (ulong)query.length-1))
db_error(mysql); /* We shall continue here, if --force was given */
dynstr_free(&query);
}
@@ -1315,9 +1316,9 @@ int main(int argc, char **argv)
}
else
{
for (; *argv != NULL; argv++)
for (char **t=argv; *t != NULL; t++)
{
table_load_params p(*argv, "", current_db, 0);
table_load_params p(*t, "", current_db, 0);
files_to_load.push_back(p);
}
}

View File

@@ -207,7 +207,7 @@ static char TMPDIR[FN_REFLEN];
static char global_subst_from[200];
static char global_subst_to[200];
static char *global_subst= NULL;
static char *read_command_buf= NULL;
static char *read_command_buf= NULL, *read_command_buf_end;
static MEM_ROOT require_file_root;
static const my_bool my_true= 1;
static const my_bool my_false= 0;
@@ -3887,9 +3887,24 @@ end:
#endif
if (error)
{
uint status= WEXITSTATUS(error);
uint status;
int i;
#ifdef _WIN32
status= WEXITSTATUS(error);
#else
/* WEXITSTATUS() is only valid for a normal exit; a process killed by an
uncaught signal must be translated using the shell's 128+signal
convention, or the real error is silently lost as status 0. */
if (WIFEXITED(error))
status= WEXITSTATUS(error);
else if (WIFSIGNALED(error))
status= 128 + WTERMSIG(error);
else
status= error;
#endif
if (command->abort_on_error)
{
report_or_die("exec of '%s' failed, error: %d, status: %d, errno: %d\n"
@@ -5699,7 +5714,7 @@ static void primary(Expression_value *result, const char **s)
enum func_type func_type= get_expr_function_type(start,
end - start);
if (func_type == FUNC_UNKNOWN)
die("Syntax error: Unknown function");
die("Syntax error: Unknown function '%.*s'", (int) (end - start), start);
*s= end + 1; // skip '('
handle_expr_function_call(func_type, result, s);
@@ -6146,47 +6161,48 @@ static void expr(Expression_value *result, const char **s)
static struct {
const char *name;
size_t length;
enum func_type type;
} function_table[]= {
// Numeric functions
{"abs", FUNC_ABS},
{"bin", FUNC_BIN},
{"conv", FUNC_CONV},
{"hex", FUNC_HEX},
{"oct", FUNC_OCT},
{STRING_WITH_LEN("abs"), FUNC_ABS},
{STRING_WITH_LEN("bin"), FUNC_BIN},
{STRING_WITH_LEN("conv"), FUNC_CONV},
{STRING_WITH_LEN("hex"), FUNC_HEX},
{STRING_WITH_LEN("oct"), FUNC_OCT},
// String functions
{"concat", FUNC_CONCAT},
{"concat_ws", FUNC_CONCAT_WS},
{"greatest", FUNC_GREATEST},
{"insert", FUNC_INSERT},
{"instr", FUNC_INSTR},
{"lcase", FUNC_LOWER},
{"least", FUNC_LEAST},
{"length", FUNC_LENGTH},
{"locate", FUNC_LOCATE},
{"lower", FUNC_LOWER},
{"lpad", FUNC_LPAD},
{"ltrim", FUNC_LTRIM},
{"repeat", FUNC_REPEAT},
{"replace", FUNC_REPLACE},
{"reverse", FUNC_REVERSE},
{"rpad", FUNC_RPAD},
{"rtrim", FUNC_RTRIM},
{"substr", FUNC_SUBSTR},
{"substring", FUNC_SUBSTR},
{"substring_index", FUNC_SUBSTR_IDX},
{"trim", FUNC_TRIM},
{"ucase", FUNC_UPPER},
{"upper", FUNC_UPPER},
{STRING_WITH_LEN("concat"), FUNC_CONCAT},
{STRING_WITH_LEN("concat_ws"), FUNC_CONCAT_WS},
{STRING_WITH_LEN("greatest"), FUNC_GREATEST},
{STRING_WITH_LEN("insert"), FUNC_INSERT},
{STRING_WITH_LEN("instr"), FUNC_INSTR},
{STRING_WITH_LEN("lcase"), FUNC_LOWER},
{STRING_WITH_LEN("least"), FUNC_LEAST},
{STRING_WITH_LEN("length"), FUNC_LENGTH},
{STRING_WITH_LEN("locate"), FUNC_LOCATE},
{STRING_WITH_LEN("lower"), FUNC_LOWER},
{STRING_WITH_LEN("lpad"), FUNC_LPAD},
{STRING_WITH_LEN("ltrim"), FUNC_LTRIM},
{STRING_WITH_LEN("repeat"), FUNC_REPEAT},
{STRING_WITH_LEN("replace"), FUNC_REPLACE},
{STRING_WITH_LEN("reverse"), FUNC_REVERSE},
{STRING_WITH_LEN("rpad"), FUNC_RPAD},
{STRING_WITH_LEN("rtrim"), FUNC_RTRIM},
{STRING_WITH_LEN("substr"), FUNC_SUBSTR},
{STRING_WITH_LEN("substring"), FUNC_SUBSTR},
{STRING_WITH_LEN("substring_index"), FUNC_SUBSTR_IDX},
{STRING_WITH_LEN("trim"), FUNC_TRIM},
{STRING_WITH_LEN("ucase"), FUNC_UPPER},
{STRING_WITH_LEN("upper"), FUNC_UPPER},
// Regexp functions
{"regexp_instr", FUNC_REGEXP_INSTR},
{"regexp_replace", FUNC_REGEXP_REPLACE},
{"regexp_substr", FUNC_REGEXP_SUBSTR},
{STRING_WITH_LEN("regexp_instr"), FUNC_REGEXP_INSTR},
{STRING_WITH_LEN("regexp_replace"), FUNC_REGEXP_REPLACE},
{STRING_WITH_LEN("regexp_substr"), FUNC_REGEXP_SUBSTR},
// Null functions
{"coalesce", FUNC_COALESCE},
{"ifnull", FUNC_IFNULL},
{"nullif", FUNC_NULLIF},
{NULL, FUNC_UNKNOWN}
{STRING_WITH_LEN("coalesce"), FUNC_COALESCE},
{STRING_WITH_LEN("ifnull"), FUNC_IFNULL},
{STRING_WITH_LEN("nullif"), FUNC_NULLIF},
{NULL, 0, FUNC_UNKNOWN}
};
@@ -6426,9 +6442,9 @@ void func_oct(Expression_value args[], int count, Expression_value *result)
@param[out] result Expression_value to store result
@details
Converts a number to hexadecimal representation.
HEX(N) returns a string representation of the hexadecimal value of N.
This is equivalent to CONV(N, 10, 16).
HEX(str) returns a hexadecimal representation of the bytes of str.
@note Dies if argument count != 1
*/
@@ -6438,7 +6454,15 @@ void func_hex(Expression_value args[], int count, Expression_value *result)
if (count != 1)
die("hex() expects 1 argument, got %d", count);
convert_base_helper(args[0].to_string(), 10, 16, result);
if (args[0].is_numeric)
convert_base_helper(args[0].to_string(), 10, 16, result);
else
{
My_string str= args[0].to_string();
My_string hex_str;
hex_str.set_hex(str.ptr(), str.length());
result->set_string(hex_str.ptr(), hex_str.length());
}
}
@@ -7694,7 +7718,8 @@ enum func_type get_expr_function_type(const char *name, size_t len)
{
for (int i= 0; function_table[i].name; ++i)
{
if (!strncasecmp(function_table[i].name, name, len))
if (function_table[i].length == len &&
!strncasecmp(function_table[i].name, name, len))
return function_table[i].type;
}
return FUNC_UNKNOWN;
@@ -9800,7 +9825,7 @@ int read_line()
*p= 0;
DBUG_PRINT("exit", ("Found delimiter '%s' at line %d",
delimiter, cur_file->lineno));
DBUG_RETURN(0);
goto ret;
}
else if ((c == '{' &&
(!my_strnncoll_simple(charset_info, (const uchar*) "while", 5,
@@ -9813,7 +9838,7 @@ int read_line()
*p= 0;
DBUG_PRINT("exit", ("Found '{' indicating start of block at line %d",
cur_file->lineno));
DBUG_RETURN(0);
goto ret;
}
else if (c == '\'' || c == '"' || c == '`')
{
@@ -9860,7 +9885,7 @@ int read_line()
*p= 0;
DBUG_PRINT("exit", ("Found newline in comment at line: %d",
cur_file->lineno));
DBUG_RETURN(0);
goto ret;
}
break;
@@ -9880,7 +9905,7 @@ int read_line()
DBUG_PRINT("info", ("Found two new lines in a row"));
*p++= c;
*p= 0;
DBUG_RETURN(0);
goto ret;
}
/* Query hasn't started yet */
@@ -9897,7 +9922,7 @@ int read_line()
*p= 0;
DBUG_PRINT("exit", ("Found delimiter '%s' at line: %d",
delimiter, cur_file->lineno));
DBUG_RETURN(0);
goto ret;
}
else if (c == '}')
{
@@ -9906,7 +9931,7 @@ int read_line()
*p= 0;
DBUG_PRINT("exit", ("Found '}' in beginning of a line at line: %d",
cur_file->lineno));
DBUG_RETURN(0);
goto ret;
}
else if (c == '\'' || c == '"' || c == '`')
{
@@ -9973,6 +9998,8 @@ int read_line()
}
}
}
ret:
read_command_buf_end= p;
DBUG_RETURN(0);
}
@@ -9988,14 +10015,13 @@ int read_line()
*/
void convert_to_format_v1(char* query)
void convert_to_format_v1(char* query, char **end)
{
int last_c_was_quote= 0;
char *p= query, *to= query;
char *end= strend(query);
char last_c;
while (p <= end)
while (p <= *end)
{
if (*p == '\n' && !last_c_was_quote)
{
@@ -10026,6 +10052,7 @@ void convert_to_format_v1(char* query)
last_c_was_quote= 0;
}
}
*end= to;
}
@@ -10142,9 +10169,9 @@ int read_command(struct st_command** command_ptr)
}
if (opt_result_format_version == 1)
convert_to_format_v1(read_command_buf);
convert_to_format_v1(read_command_buf, &read_command_buf_end);
char *p= read_command_buf;
char *p= read_command_buf, *end= read_command_buf_end;
DBUG_PRINT("info", ("query: '%s'", read_command_buf));
if (*p == '#')
{
@@ -10161,29 +10188,32 @@ int read_command(struct st_command** command_ptr)
}
/* Skip leading spaces */
while (*p && my_isspace(charset_info, *p))
while (p < end && my_isspace(charset_info, *p))
p++;
if (!(command->query_buf= command->query= my_strdup(PSI_NOT_INSTRUMENTED, p, MYF(MY_WME))))
if (!(command->query_buf= command->query=
(char*)my_memdup(PSI_NOT_INSTRUMENTED, p, end - p, MYF(MY_WME))))
die("Out of memory");
command->query_len= (int)(end - p - 1);
command->end= command->query + command->query_len;
p= command->query;
end= command->end;
/*
Calculate first word length(the command), terminated
by 'space' , '(' or 'delimiter' */
p= command->query;
while (*p && !my_isspace(charset_info, *p) && *p != '(' && !is_delimiter(p))
by 'space' , '(' or 'delimiter'
*/
while (p < end && !my_isspace(charset_info, *p) && *p != '(' && !is_delimiter(p))
p++;
command->first_word_len= (uint) (p - command->query);
DBUG_PRINT("info", ("first_word: %.*s",
command->first_word_len, command->query));
/* Skip spaces between command and first argument */
while (*p && my_isspace(charset_info, *p))
while (p < end && my_isspace(charset_info, *p))
p++;
command->first_argument= p;
command->end= strend(command->query);
command->query_len= (int)(command->end - command->query);
parser.read_lines++;
DBUG_RETURN(0);
}
@@ -12480,7 +12510,7 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags)
else
{
query = command->query;
query_len = strlen(query);
query_len = command->query_len;
}
/*
@@ -12870,6 +12900,7 @@ void get_command_type(struct st_command* command)
if (type == Q_QUERY)
{
/* Skip the "query" part */
command->query_len-= (int)(command->first_argument - command->query);
command->query= command->first_argument;
}
}
@@ -13430,7 +13461,8 @@ int main(int argc, char **argv)
if (command->query == command->query_buf)
{
/* Skip the first part of command, i.e query_xxx */
command->query= command->first_argument;
command->query_len-= (int)(command->first_argument - command->query);
command->query= command->first_argument;
command->first_word_len= 0;
}
/* fall through */
@@ -13492,7 +13524,10 @@ int main(int argc, char **argv)
/* Remove "send" if this is first iteration */
if (command->query == command->query_buf)
{
command->query_len-= (int)(command->first_argument - command->query);
command->query= command->first_argument;
}
/*
run_query() can execute a query partially, depending on the flags.

View File

@@ -273,7 +273,7 @@ IF(WITH_WSREP)
"MariaDB-server >= ${SERVER_VERSION}"
"galera-4" "rsync" "grep" "gawk" "iproute"
"coreutils" "findutils" "tar")
SETA(CPACK_RPM_server-galera_PACKAGE_RECOMMENDS "lsof" "socat" "pv")
SETA(CPACK_RPM_server-galera_PACKAGE_RECOMMENDS "lsof" "socat" "pv" "stunnel")
SETA(CPACK_RPM_server-galera_PACKAGE_CONFLICTS
"MariaDB-server <= 12.3.2")
ENDIF()

View File

@@ -71,5 +71,8 @@ EXECUTE_PROCESS (
)
IF(NOT RESULT EQUAL 0)
MESSAGE(FATAL_ERROR "Could not create initial database \n ${OUT} \n ${ERR}")
MESSAGE(FATAL_ERROR
"Could not create initial database, result: ${RESULT}\n"
"stdout:\n${OUT}\n"
"stderr:\n${ERR}")
ENDIF()

View File

@@ -64,6 +64,9 @@
#
# - INSTALL_UNIX_ADDRDIR (path to mysql.sock)
#
# - INSTALL_RUNDIR (runtime state files that mariadbd must not write,
# e.g. what systemd reads as EnvironmentFile)
#
IF(NOT INSTALL_LAYOUT)
IF(DEB)
@@ -163,7 +166,7 @@ SET(INSTALL_UNIX_ADDRDIR_RPM "${INSTALL_MYSQLDATADIR_RPM}/mysql.sock"
SET(INSTALL_SYSTEMD_UNITDIR_RPM "/usr/lib/systemd/system")
SET(INSTALL_SYSTEMD_SYSUSERSDIR_RPM "/usr/lib/sysusers.d")
SET(INSTALL_SYSTEMD_TMPFILESDIR_RPM "/usr/lib/tmpfiles.d")
SET(INSTALL_RUNDATADIR_RPM "/run/mariadb")
SET(INSTALL_RUNDIR_RPM "/run")
SET(INSTALL_PAMDIR_RPM "/usr/${INSTALL_LIBDIR_RPM}/security")
IF(RPM MATCHES "^(opensuse|sles)([0-9]+)$")
IF(CMAKE_MATCH_2 LESS_EQUAL 1507)
@@ -199,8 +202,8 @@ SET(INSTALL_SUPPORTFILESDIR_DEB "share/mariadb")
#
SET(INSTALL_MYSQLDATADIR_DEB "/var/lib/mysql")
SET(INSTALL_RUNDATADIR_DEB "/run/mysqld")
SET(INSTALL_UNIX_ADDRDIR_DEB "${INSTALL_RUNDATADIR_DEB}/mysqld.sock")
SET(INSTALL_RUNDIR_DEB "/run")
SET(INSTALL_UNIX_ADDRDIR_DEB "${INSTALL_RUNDIR_DEB}/mysqld/mysqld.sock")
SET(INSTALL_SYSTEMD_UNITDIR_DEB "/usr/lib/systemd/system")
SET(INSTALL_SYSTEMD_SYSUSERSDIR_DEB "/usr/lib/sysusers.d")
SET(INSTALL_SYSTEMD_TMPFILESDIR_DEB "/usr/lib/tmpfiles.d")
@@ -264,7 +267,10 @@ IF(NOT MYSQL_UNIX_ADDR)
SET(MYSQL_UNIX_ADDR ${INSTALL_UNIX_ADDRDIR})
ENDIF()
IF(NOT INSTALL_RUNDATADIR)
IF(NOT INSTALL_RUNDIR)
# No /run in a tarball installation - fall back to the socket directory.
# Note that mariadbd can write there, so the isolation that /run gives to
# packages (see EnvironmentFile= in mariadb.service) is not achieved.
get_filename_component(MYSQL_UNIX_DIR ${MYSQL_UNIX_ADDR} DIRECTORY)
SET(INSTALL_RUNDATADIR "${MYSQL_UNIX_DIR}" CACHE FILEPATH "Rundata installation directory" ${FORCE})
SET(INSTALL_RUNDIR "${MYSQL_UNIX_DIR}" CACHE FILEPATH "Runtime state directory" ${FORCE})
ENDIF()

View File

@@ -1,5 +1,6 @@
/* Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2026, MariaDB plc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
@@ -184,6 +185,7 @@
#cmakedefine HAVE_MMAP 1
#cmakedefine HAVE_MMAP64 1
#cmakedefine HAVE_MPROTECT 1
#cmakedefine HAVE_RO_AFTER_INIT 1
#cmakedefine HAVE_PERROR 1
#cmakedefine HAVE_POLL 1
#cmakedefine HAVE_POSIX_FALLOCATE 1

View File

@@ -1,5 +1,6 @@
# Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
#
# Copyright (c) 2026, MariaDB plc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
@@ -370,6 +371,24 @@ CHECK_FUNCTION_EXISTS (mmap HAVE_MMAP)
CHECK_FUNCTION_EXISTS (mmap64 HAVE_MMAP64)
CHECK_FUNCTION_EXISTS (mprotect HAVE_MPROTECT)
CHECK_FUNCTION_EXISTS (perror HAVE_PERROR)
IF(HAVE_SYS_MMAN_H AND HAVE_MPROTECT)
SET(SAVE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
SET(CMAKE_REQUIRED_FLAGS
"${CMAKE_REQUIRED_FLAGS} -Wl,-T,${CMAKE_SOURCE_DIR}/sql/mysqld_ro.lds")
CHECK_C_SOURCE_COMPILES("
#include <sys/mman.h>
__attribute__((section(\"ro_after_init\"))) int hardened= 1;
extern char __ro_after_init_start[] __attribute__((weak));
extern char __ro_after_init_end[] __attribute__((weak));
int main(void) {
size_t size= __ro_after_init_end - __ro_after_init_start;
mprotect(__ro_after_init_start, size, PROT_READ | PROT_WRITE);
return (int)size + hardened;
}" HAVE_RO_AFTER_INIT)
SET(CMAKE_REQUIRED_FLAGS "${SAVE_CMAKE_REQUIRED_FLAGS}")
ENDIF()
CHECK_FUNCTION_EXISTS (poll HAVE_POLL)
CHECK_FUNCTION_EXISTS (posix_fallocate HAVE_POSIX_FALLOCATE)
CHECK_FUNCTION_EXISTS (pread HAVE_PREAD)

View File

@@ -179,9 +179,12 @@ then
fi
# Enable DuckDB storage engine plugin packaging
if grep -q "$architecture" storage/duckdb/debian/control
if grep -q "$architecture" storage/duckdb/debian/control && \
[[ ! -f debian/mariadb-plugin-duckdb.install ]]
then
cat storage/duckdb/debian/mariadb-plugin-duckdb.install >> debian/mariadb-server.install
echo >> debian/control
cat storage/duckdb/debian/control >> debian/control
cp -v storage/duckdb/debian/mariadb-plugin-duckdb.install debian/
fi
if [ -n "${AUTOBAKE_PREP_CONTROL_RULES_ONLY:-}" ]

1
debian/control vendored
View File

@@ -983,6 +983,7 @@ Depends:
${shlibs:Depends},
Recommends:
pv,
stunnel,
Conflicts:
mariadb-galera-server-10.0,
mariadb-galera-server-5.5,

View File

@@ -88,6 +88,25 @@ static mysql_cond_t kill_query_thread_stop;
bool sql_thread_started = false;
char *mysql_slave_position = NULL;
char *mysql_binlog_position = NULL;
/*
MDEV-38147: the exact binary log file name that
write_current_binlog_file() rotated to and shipped into the backup under
--galera-info. Remembered here so that write_binlog_info() records the very
same file name in xtrabackup_binlog_info, i.e. the file the SST joiner looks
for is guaranteed to be the file that was actually sent (no rotation race).
*/
char *mysql_binlog_file = NULL;
/*
Position and GTID of that shipped binary log, captured together with
mysql_binlog_file at flush time (see write_current_binlog_file()). Used by
write_binlog_info() so that, if a rotation intervenes, the whole coordinate
tuple it records stays consistent with the file that was actually shipped -
which matters for a manual --galera-info backup used as a replication seed,
not only for the SST joiner (which reads just the file name).
*/
static char *mysql_binlog_file_pos = NULL;
static char *mysql_binlog_file_gtid_executed = NULL;
static char *mysql_binlog_file_gtid_current_pos = NULL;
char *buffer_pool_filename = NULL;
/* History on server */
@@ -348,6 +367,30 @@ read_mysql_one_value(MYSQL *mysql, const char *query)
return read_mysql_one_value(mysql, query, 0/*offset*/, 1/*total columns*/);
}
/** Poll InnoDB's durably flushed redo LSN from the running server.
Log copier uses this as its parse limit; it never accepts a redo log
record whose end exceeds this LSN
@param connection MariaDB client connection
@retval 0 on failure, lsn on success */
uint64_t get_log_flushed_lsn(MYSQL *connection) noexcept
{
if (!connection)
return 0;
uint64_t lsn= 0;
MYSQL_RES *res= xb_mysql_query(connection,
"SHOW STATUS LIKE 'Innodb_lsn_flushed'",
true, false);
if (!res)
return 0;
if (MYSQL_ROW row= mysql_fetch_row(res))
if (row[1])
lsn= strtoull(row[1], nullptr, 10);
mysql_free_result(res);
return lsn;
}
static
bool
@@ -1515,6 +1558,23 @@ write_galera_info(ds_ctxt *datasink, MYSQL *connection)
domain_id ? domain_id : domain_id55);
}
/*
MDEV-38147: Flush and copy the donor's current binary log into
the backup so that it is shipped to the SST joiner.
A new joiner discards this file and starts a fresh binary log seeded from
the storage-engine checkpoint (see wsrep_seed_binlog_gtid_state() in
sql/log.cc and the joiner code in scripts/wsrep_sst_mariabackup.sh), which
avoids error 1950 with gtid_strict_mode=ON. The file is still shipped for
backward compatibility with an old joiner that expects it, and so that a
new joiner can deterministically identify and remove exactly the file that
was sent instead of colliding with it.
write_current_binlog_file() remembers the rotated file name in
mysql_binlog_file so that write_binlog_info() records the same file in
xtrabackup_binlog_info - closing the old race where a concurrent rotation
could make the shipped file and the recorded file diverge.
*/
if (result)
write_current_binlog_file(datasink, connection);
@@ -1535,13 +1595,25 @@ cleanup:
/*********************************************************************//**
Flush and copy the current binary log file into the backup,
if GTID is enabled */
if GTID is enabled.
MDEV-38147: the file name that FLUSH BINARY LOGS rotates to is
remembered in the global mysql_binlog_file. write_binlog_info() then records
that exact name in xtrabackup_binlog_info, so the file the SST joiner looks
for is guaranteed to be the file that was shipped. Previously the shipped file
(determined here) and the recorded file (determined independently later by
write_binlog_info()) were read by two separate SHOW MASTER STATUS calls; a
binary log rotation happening in between made them diverge and the wrong file
was sent. */
bool
write_current_binlog_file(ds_ctxt *datasink, MYSQL *connection)
{
char *executed_gtid_set = NULL;
char *gtid_binlog_state = NULL;
char *gtid_current_pos = NULL;
char *log_bin_file = NULL;
char *log_bin_pos = NULL;
char *log_bin_gtid_executed = NULL;
char *log_bin_dir = NULL;
bool gtid_exists;
bool result = true;
@@ -1552,13 +1624,18 @@ write_current_binlog_file(ds_ctxt *datasink, MYSQL *connection)
{NULL, NULL}
};
/* Capture the shipped file's coordinates together, right after the flush,
so they describe exactly the file that is copied below. */
mysql_variable status_after_flush[] = {
{"File", &log_bin_file},
{"Position", &log_bin_pos},
{"Executed_Gtid_Set", &log_bin_gtid_executed},
{NULL, NULL}
};
mysql_variable vars[] = {
{"gtid_binlog_state", &gtid_binlog_state},
{"gtid_current_pos", &gtid_current_pos},
{"log_bin_basename", &log_bin_dir},
{NULL, NULL}
};
@@ -1588,6 +1665,32 @@ write_current_binlog_file(ds_ctxt *datasink, MYSQL *connection)
log_bin_dir = strdup("./");
}
if (log_bin_dir == NULL || log_bin_file == NULL) {
msg("Failed to get master binlog coordinates from "
"SHOW MASTER STATUS");
result = false;
goto cleanup;
}
/*
Remember the file we just rotated to (before any further
rotation can happen), together with its position and GTID, so
that write_binlog_info() records this very file - and a matching
position/GTID - in xtrabackup_binlog_info, and the joiner looks
for exactly the file that is shipped below.
*/
free(mysql_binlog_file);
mysql_binlog_file = strdup(log_bin_file);
free(mysql_binlog_file_pos);
mysql_binlog_file_pos =
log_bin_pos ? strdup(log_bin_pos) : NULL;
free(mysql_binlog_file_gtid_executed);
mysql_binlog_file_gtid_executed =
log_bin_gtid_executed ? strdup(log_bin_gtid_executed) : NULL;
free(mysql_binlog_file_gtid_current_pos);
mysql_binlog_file_gtid_current_pos =
gtid_current_pos ? strdup(gtid_current_pos) : NULL;
dirname_part(log_bin_dir, log_bin_dir, &log_bin_dir_length);
/* strip final slash if it is not the only path component */
@@ -1596,13 +1699,6 @@ write_current_binlog_file(ds_ctxt *datasink, MYSQL *connection)
log_bin_dir[log_bin_dir_length - 1] = 0;
}
if (log_bin_dir == NULL || log_bin_file == NULL) {
msg("Failed to get master binlog coordinates from "
"SHOW MASTER STATUS");
result = false;
goto cleanup;
}
snprintf(filepath, sizeof(filepath), "%s%c%s",
log_bin_dir, FN_LIBCHAR, log_bin_file);
result = datasink->copy_file(filepath, log_bin_file, 0);
@@ -1624,11 +1720,15 @@ bool
write_binlog_info(ds_ctxt *datasink, MYSQL *connection)
{
char *filename = NULL;
const char *out_filename;
const char *out_position;
const char *out_gtid_executed;
const char *out_gtid_current_pos;
char *position = NULL;
char *gtid_mode = NULL;
char *gtid_current_pos = NULL;
char *gtid_executed = NULL;
char *gtid = NULL;
const char *gtid = NULL;
bool result;
bool mysql_gtid;
bool mariadb_gtid;
@@ -1656,25 +1756,53 @@ write_binlog_info(ds_ctxt *datasink, MYSQL *connection)
goto cleanup;
}
mysql_gtid = ((gtid_mode != NULL) && (strcmp(gtid_mode, "ON") == 0));
mariadb_gtid = (gtid_current_pos != NULL);
/*
MDEV-38147: if write_current_binlog_file() already rotated
and shipped a binary log under --galera-info, record that exact file
name here rather than whatever SHOW MASTER STATUS reports now. The two
are normally identical, but a binary log rotation between the two
SHOW MASTER STATUS calls would otherwise make mariadb_backup_binlog_info
name a file different from the one that was shipped, so the SST joiner
would look for a file that is not there. Use a separate pointer so the
string owned by the status[] array is still freed at cleanup.
*/
out_filename = filename;
out_position = position;
out_gtid_executed = gtid_executed;
out_gtid_current_pos = gtid_current_pos;
if (mysql_binlog_file != NULL && strcmp(filename, mysql_binlog_file)) {
msg("Binary log rotated to '%s' after '%s' was shipped; recording "
"the shipped file and its coordinates in "
MB_BINLOG_INFO, filename, mysql_binlog_file);
/* Record the whole tuple from the shipped file, not just its name,
so file/position/GTID stay consistent (the position and GTID from
the SHOW MASTER STATUS above belong to the current, newer file). */
out_filename = mysql_binlog_file;
out_position = mysql_binlog_file_pos;
out_gtid_executed = mysql_binlog_file_gtid_executed;
out_gtid_current_pos = mysql_binlog_file_gtid_current_pos;
}
gtid = (gtid_executed != NULL ? gtid_executed : gtid_current_pos);
mysql_gtid = ((gtid_mode != NULL) && (strcmp(gtid_mode, "ON") == 0));
mariadb_gtid = (out_gtid_current_pos != NULL);
gtid = (out_gtid_executed != NULL ? out_gtid_executed
: out_gtid_current_pos);
if (mariadb_gtid || mysql_gtid) {
ut_a(asprintf(&mysql_binlog_position,
"filename '%s', position '%s', "
"GTID of the last change '%s'",
filename, position, gtid) != -1);
out_filename, out_position, gtid) != -1);
result = datasink->backup_file_printf(MB_BINLOG_INFO,
"%s\t%s\t%s\n", filename, position,
"%s\t%s\t%s\n", out_filename, out_position,
gtid);
} else {
ut_a(asprintf(&mysql_binlog_position,
"filename '%s', position '%s'",
filename, position) != -1);
out_filename, out_position) != -1);
result = datasink->backup_file_printf(MB_BINLOG_INFO,
"%s\t%s\n", filename, position);
"%s\t%s\n", out_filename, out_position);
}
cleanup:
@@ -2008,6 +2136,10 @@ backup_cleanup()
{
free(mysql_slave_position);
free(mysql_binlog_position);
free(mysql_binlog_file);
free(mysql_binlog_file_pos);
free(mysql_binlog_file_gtid_executed);
free(mysql_binlog_file_gtid_current_pos);
free(buffer_pool_filename);
if (mysql_connection) {

View File

@@ -2,6 +2,7 @@
#define XTRABACKUP_BACKUP_MYSQL_H
#include <mysql.h>
#include <cstdint>
#include <string>
#include <unordered_set>
#include "datasink.h"
@@ -26,6 +27,7 @@ extern time_t history_lock_time;
extern bool sql_thread_started;
extern char *mysql_slave_position;
extern char *mysql_binlog_position;
extern char *mysql_binlog_file;
extern char *buffer_pool_filename;
/** connection to mysql server */
@@ -97,4 +99,6 @@ bool
write_slave_info(ds_ctxt *datasink, MYSQL *connection);
ulonglong get_current_lsn(MYSQL *connection);
uint64_t get_log_flushed_lsn(MYSQL *connection) noexcept;
#endif

View File

@@ -205,7 +205,7 @@ struct xb_filter_entry_t{
/** whether log_copying_thread() is active; protected by recv_sys.mutex */
static bool log_copying_running;
/** the log parsing function for --backup */
static recv_sys_t::parser backup_log_parse;
static recv_sys_t::parser backup_log_parse_low;
/** for --backup, target LSN to copy the log to; protected by recv_sys.mutex */
lsn_t metadata_to_lsn;
@@ -251,6 +251,7 @@ const char *defaults_group = "mysqld";
#define HA_INNOBASE_ROWS_IN_TABLE 10000 /* to get optimization right */
#define HA_INNOBASE_RANGE_COUNT 100
#define METADATA_LSN_ERROR 1
/* The default values for the following, type long or longlong, start-up
parameters are declared in mysqld.cc: */
@@ -3499,6 +3500,41 @@ skip:
return(FALSE);
}
/* Maximum LSN the copier may parse up to.
Usually derived from the server's durably-flushed redo LSN.
When a final target LSN is set, this limit is raised to that
target so the last partial block can be copied in full.
The copier refuses to accept a mini-transaction whose end
exceeds this, so it never parses the volatile tail block
the server is still rewriting
(which mmap can read torn, leading to a mis-computed mtr
length and permanent mid-mtr drift). A pread() of the same
still-being-written tail block can likewise return a torn read
which can be observed on ext4, though not on XFS).
Read/written only under recv_sys.mutex. */
static lsn_t max_parse_lsn;
/* Set by backup_log_parse() when the last parse was
rejected because the mtr crossed max_parse_lsn. It means
"caught up, wait" condition, not a stall. */
static bool reached_parse_limit;
static recv_sys_t::parse_mtr_result backup_log_parse()
{
const lsn_t prev_lsn= recv_sys.lsn;
const size_t prev_offset= recv_sys.offset;
reached_parse_limit= false;
recv_sys_t::parse_mtr_result r= backup_log_parse_low(false);
if (r == recv_sys_t::OK && max_parse_lsn && recv_sys.lsn > max_parse_lsn)
{
recv_sys.lsn= prev_lsn;
recv_sys.offset= prev_offset;
reached_parse_limit= true;
return recv_sys_t::GOT_EOF;
}
return r;
}
static int
xtrabackup_copy_mmap_snippet(ds_file_t *ds, const byte *start, const byte *end)
{
@@ -3524,7 +3560,7 @@ static bool xtrabackup_copy_mmap_logfile()
const byte *start= &log_sys.buf[recv_sys.offset];
ut_d(recv_sys_t::parse_mtr_result r);
if ((ut_d(r=) backup_log_parse(false)) == recv_sys_t::OK)
if ((ut_d(r=) backup_log_parse()) == recv_sys_t::OK)
{
do
{
@@ -3542,7 +3578,7 @@ static bool xtrabackup_copy_mmap_logfile()
start = seq + 1;
}
}
while ((ut_d(r=) backup_log_parse(false)) == recv_sys_t::OK);
while ((ut_d(r=) backup_log_parse()) == recv_sys_t::OK);
if (xtrabackup_copy_mmap_snippet(dst_log_file, start,
&log_sys.buf[recv_sys.offset]))
@@ -3615,7 +3651,7 @@ static bool xtrabackup_copy_logfile(bool early_exit)
if (log_sys.buf[recv_sys.offset] <= 1)
break;
if (backup_log_parse(false) == recv_sys_t::OK)
if (backup_log_parse() == recv_sys_t::OK)
{
do
{
@@ -3625,7 +3661,7 @@ static bool xtrabackup_copy_logfile(bool early_exit)
sequence_offset));
*seq= 1;
}
while ((r= backup_log_parse(false)) == recv_sys_t::OK);
while ((r= backup_log_parse()) == recv_sys_t::OK);
if (ds_write(dst_log_file, log_sys.buf + start_offset,
recv_sys.offset - start_offset))
@@ -3655,6 +3691,9 @@ static bool xtrabackup_copy_logfile(bool early_exit)
if (retry_count == 100)
break;
if (reached_parse_limit)
break;
mysql_mutex_unlock(&recv_sys.mutex);
if (!retry_count++)
msg("Retrying read of log at LSN=" LSN_PF, recv_sys.lsn);
@@ -3669,13 +3708,32 @@ static bool xtrabackup_copy_logfile(bool early_exit)
return false;
}
/** Handles backup log copy timeout or incomplete LSN copy.
Checks if the target LSN was reached. If not,
logs diagnostic messages advising whether to increase
innodb_log_file_size (log wrapped around) or to check
server/backup configuration mismatches.
@param lsn Target LSN expected by the backup.
@param last_lsn Actual maximum LSN copied so far.
@return true if target LSN was reached, false otherwise. */
static bool backup_wait_timeout(lsn_t lsn, lsn_t last_lsn)
{
if (last_lsn >= lsn)
return true;
const lsn_t checkpoint_lsn= log_sys.last_checkpoint_lsn.load();
const lsn_t capacity= log_sys.file_size - log_sys.START_OFFSET;
const lsn_t needed= lsn - checkpoint_lsn;
msg("Was only able to copy log from " LSN_PF " to " LSN_PF
", not " LSN_PF "; try increasing innodb_log_file_size",
log_sys.last_checkpoint_lsn.load(), last_lsn, lsn);
", not " LSN_PF, checkpoint_lsn, last_lsn, lsn);
if (needed <= capacity)
msg("mariabackup: The required redo still fits within the log "
"capacity, so it has not been overwritten; check whether the "
"server and backup configuration are the same.");
else
msg("mariabackup: Try increasing the innodb_log_file_size.");
return false;
}
@@ -3730,16 +3788,93 @@ static bool backup_wait_for_lsn(lsn_t lsn)
static void log_copying_thread()
{
my_thread_init();
mysql_mutex_lock(&recv_sys.mutex);
while (!xtrabackup_copy_logfile(false) &&
(!metadata_last_lsn || metadata_last_lsn > recv_sys.lsn))
MYSQL *limit_con= xb_mysql_connect();
if (!limit_con)
{
/* Without this connection we cannot poll the durably-flushed
LSN, so max_parse_lsn could never advance and the copier
would either stall or parse the volatile tail block.
Fail the copy gracefully and let the main thread report
it via backup_wait_timeout(). */
msg("mariabackup: Error: cannot open a server connection for "
"the log copying thread; the backup will fail.");
mysql_mutex_lock(&recv_sys.mutex);
log_copying_running= false;
pthread_cond_broadcast(&scanned_lsn_cond);
mysql_mutex_unlock(&recv_sys.mutex);
my_thread_end();
return;
}
/*
This thread polls Innodb_lsn_flushed via SHOW STATUS on its own connection.
On a Galera donor wsrep_sync_wait may include SHOW, which would make that
poll wait until the node has applied the latest cluster transactions. During
a backup the donor's commit position can legitimately lag (e.g. a transaction
sitting between its binary log write and engine commit), so the poll could
block indefinitely and stall the redo log copier - failing the backup with a
misleading "Was only able to copy log ..." error. The main backup connection
already disables wsrep_sync_wait for the same reason, so do the same here.
*/
if (have_galera_enabled)
xb_mysql_query(limit_con, "SET SESSION wsrep_sync_wait=0", false);
mysql_mutex_lock(&recv_sys.mutex);
for (;;)
{
/* metadata_last_lsn is set to 1 when error was encountered.
Abort the log copier if an error was signaled */
if (metadata_last_lsn == METADATA_LSN_ERROR)
break;
/* Refresh the max_parse_lsn before each copy pass */
const lsn_t final_target= metadata_last_lsn > metadata_to_lsn
? metadata_last_lsn : metadata_to_lsn;
if (final_target)
/* Final phase (BLOCK_DDL/BLOCK_COMMIT): fence at the exact target
instead of the polled flushed LSN. This is only safe because the
target was derived from get_current_lsn(), which runs
FLUSH ENGINE LOGS and thus makes the redo durable up to at least
final_target; so final_target <= Innodb_lsn_flushed holds here and
the bytes up to it are stable. Do not feed this branch an LSN that
has not been flushed by the server, or the copier will parse the
volatile tail block again (MDEV-39468). */
max_parse_lsn= final_target;
else
{
mysql_mutex_unlock(&recv_sys.mutex);
lsn_t flushed= get_log_flushed_lsn(limit_con);
mysql_mutex_lock(&recv_sys.mutex);
if (flushed > log_sys.get_first_lsn())
max_parse_lsn= flushed;
else if (!max_parse_lsn)
{
/* We could not obtain a flushed LSN and none was seeded before,
so the parse limit is unset and the copier would fall back to
parsing the volatile tail block (the MDEV-39468 failure). Warn
once so this is diagnosable rather than a silent stall. */
static bool warned;
if (!warned)
{
warned= true;
msg("mariabackup: Warning: could not read Innodb_lsn_flushed; "
"the redo log copier has no parse limit.");
}
}
}
if (xtrabackup_copy_logfile(false))
break;
if (final_target && final_target <= recv_sys.lsn)
break;
timespec abstime;
set_timespec_nsec(abstime, 1000000ULL * xtrabackup_log_copy_interval);
mysql_cond_timedwait(&log_copying_stop, &recv_sys.mutex, &abstime);
}
log_copying_running= false;
mysql_mutex_unlock(&recv_sys.mutex);
if (limit_con)
mysql_close(limit_con);
my_thread_end();
}
@@ -4944,7 +5079,7 @@ static bool backup_wait_for_commit_lsn()
else
{
msg("Error: recv_sys.find_checkpoint() failed.");
metadata_last_lsn= 1;
metadata_last_lsn= METADATA_LSN_ERROR;
stop_backup_threads();
mysql_mutex_unlock(&recv_sys.mutex);
return false;
@@ -5571,7 +5706,7 @@ static bool xtrabackup_backup_func()
fail:
if (log_copying_running) {
mysql_mutex_lock(&recv_sys.mutex);
metadata_last_lsn = 1;
metadata_last_lsn = METADATA_LSN_ERROR;
stop_backup_threads();
mysql_mutex_unlock(&recv_sys.mutex);
}
@@ -5699,9 +5834,15 @@ fail:
/* copy log file by current position */
mysql_mutex_lock(&recv_sys.mutex);
backup_log_parse = recv_sys.get_backup_parser();
backup_log_parse_low = recv_sys.get_backup_parser();
recv_sys.lsn = log_sys.last_checkpoint_lsn;
if (lsn_t flushed= get_log_flushed_lsn(mysql_connection))
{
if (flushed > log_sys.get_first_lsn())
max_parse_lsn= flushed;
}
const bool log_copy_failed = xtrabackup_copy_logfile(true);
mysql_mutex_unlock(&recv_sys.mutex);

View File

@@ -30,7 +30,6 @@ extern "C" {
#include <my_pthread.h>
#include <thr_lock.h>
#include "my_compare.h"
#include "my_tree.h"
/* defines used by heap-functions */
@@ -109,6 +108,7 @@ typedef struct st_heap_block
} HP_BLOCK;
struct st_heap_info; /* For reference */
struct st_HA_KEYSEG;
typedef struct st_hp_keydef /* Key definition with open */
{
@@ -116,7 +116,7 @@ typedef struct st_hp_keydef /* Key definition with open */
uint keysegs; /* Number of key-segment */
uint length; /* Length of key (automatic) */
uint8 algorithm; /* HASH / BTREE */
HA_KEYSEG *seg;
struct st_HA_KEYSEG *seg;
HP_BLOCK block; /* Where keys are saved */
/*
Number of buckets used in hash table. Used only to provide

View File

@@ -133,6 +133,7 @@ typedef struct st_json_path_t
} json_path_t;
__attribute__((nonnull, warn_unused_result))
int json_path_setup(json_path_t *p,
CHARSET_INFO *i_cs, const uchar *str, const uchar *end);

View File

@@ -1,6 +1,6 @@
/*
Copyright (c) 2001, 2013, Oracle and/or its affiliates.
Copyright (c) 2009, 2022, MariaDB Corporation.
Copyright (c) 2009, 2026, MariaDB plc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -815,6 +815,7 @@ typedef long long my_ptrdiff_t;
#define MY_ALIGN(A,L) (((A) + (L) - 1) & ~((L) - 1))
#define MY_ALIGN_DOWN(A,L) ((A) & ~((L) - 1))
#define ALIGN_SIZE(A) MY_ALIGN((A),sizeof(double))
#define ALIGN_MAX_UNIT (sizeof(double))
/* Size to make addressable obj. */
@@ -1016,6 +1017,20 @@ typedef ulong myf; /* Type of MyFlags in my_funcs */
#endif
#endif
/*
Tag a global variable as "read-only after init". It'll be made read-only
just before the server starts accepting connection. All READ_ONLY sysvars
must be tagged this way.
*/
#if defined(HAVE_RO_AFTER_INIT) && !defined(EMBEDDED_LIBRARY)
#define READ_ONLY_SYSVAR __attribute__((section("ro_after_init")))
#elif defined(_MSC_VER) && !defined(EMBEDDED_LIBRARY)
#pragma section("ro_after_init$m", read, write)
#define READ_ONLY_SYSVAR __declspec(allocate("ro_after_init$m"))
#else
#define READ_ONLY_SYSVAR
#endif
#include <my_dbug.h>
/* Some helper macros */

View File

@@ -93,7 +93,7 @@ C_MODE_START
#define MY_SYNC 4096U /* my_copy(): sync dst file */
#define MY_SYNC_DIR 32768U /* my_create/delete/rename: sync directory */
#define MY_THREAD_SPECIFIC 0x10000U /* my_malloc(): thread specific */
#define MY_ROOT_USE_MPROTECT 0x20000U /* init_alloc_root: read only segments */
#define MY_ROOT_USE_VMEM 0x20000U /* init_alloc_root: use my_virtual_mem_commit */
/* Tree that should delete things automatically */
#define MY_TREE_WITH_DELETE 0x40000U
#define MY_TRACK 0x80000U /* Track tmp usage */

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2025, MariaDB
/* Copyright (c) 2025, 2026, MariaDB plc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -24,12 +24,13 @@
extern "C" {
#endif
#ifdef _WIN32
enum my_vmem_prot { MY_VMEM_READONLY= 0, MY_VMEM_READWRITE };
char *my_virtual_mem_reserve(size_t *size);
#endif
char *my_virtual_mem_commit(char *ptr, size_t size);
void my_virtual_mem_decommit(char *ptr, size_t size);
void my_virtual_mem_release(char *ptr, size_t size);
void my_virtual_mem_protect(void *ptr, size_t size, enum my_vmem_prot prot);
#ifdef __cplusplus
}

View File

@@ -321,4 +321,13 @@ drop table t1;
#
# End of 10.5 tests
#
#
# MDEV-31808 Server crash upon altering table with NEXTVAL for default under exclusive lock
#
CREATE SEQUENCE s ENGINE=Aria;
CREATE TABLE t (a INT DEFAULT(NEXTVAL(s)), b INT);
ALTER TABLE t FORCE, ALGORITHM=COPY, LOCK=EXCLUSIVE;
DROP TABLE t;
DROP SEQUENCE s;
# End of 10.6 tests
set @@default_storage_engine= @save_default_engine;

View File

@@ -260,4 +260,18 @@ drop table t1;
--echo # End of 10.5 tests
--echo #
--echo #
--echo # MDEV-31808 Server crash upon altering table with NEXTVAL for default under exclusive lock
--echo #
CREATE SEQUENCE s ENGINE=Aria;
CREATE TABLE t (a INT DEFAULT(NEXTVAL(s)), b INT);
ALTER TABLE t FORCE, ALGORITHM=COPY, LOCK=EXCLUSIVE;
# Cleanup
DROP TABLE t;
DROP SEQUENCE s;
--echo # End of 10.6 tests
set @@default_storage_engine= @save_default_engine;

View File

@@ -0,0 +1 @@
FOUND 3 /[Uu]nknown [Ee]vent/ in invalid_row_v2_tag.sql

View File

@@ -0,0 +1,14 @@
# MDEV-39485 Heap-buffer-overflow upon read in `Rows_log_event` constructor
#
# This binlog file contains a normal Format Description
# Event followed by 3 malformed v2 Write Rows Events:
# 1. A tag followed by no data
# 2. An undersized tagged data followed by an unrecognized tag
# 3. A tag followed by a length longer than the entire event
--source include/not_embedded.inc
--let SEARCH_PATTERN= [Uu]nknown [Ee]vent
--let SEARCH_FILE= $MYSQLTEST_VARDIR/tmp/invalid_row_v2_tag.sql
--exec $MYSQL_BINLOG --force-read --verbose std_data/binlog_invalid_row_v2_tag.001 > $SEARCH_FILE
--source include/search_pattern_in_file.inc

View File

@@ -3255,9 +3255,21 @@ HEX(a) HEX(b)
61 62
61 0061
DROP TABLE t1;
0x00 in the beginning of a value of a non-last ENUM/SET causes an error:
0x00 in the beginning of a value of a non-last ENUM/SET (fixed by MDEV-28498):
CREATE TABLE t1 (a ENUM('a',0x0061), b ENUM('b')) CHARSET=latin1;
ERROR HY000: Incorrect information in file: 'DIR/t1.frm'
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` enum('a','\0a') DEFAULT NULL,
`b` enum('b') DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
INSERT INTO t1 VALUES (1,1);
INSERT INTO t1 VALUES (2,1);
SELECT HEX(a), HEX(b) FROM t1 ORDER BY a, b;
HEX(a) HEX(b)
61 62
0061 62
DROP TABLE t1;
#
# End of 10.1 tests
#

View File

@@ -116,10 +116,13 @@ INSERT INTO t1 VALUES (1,2);
SELECT HEX(a), HEX(b) FROM t1 ORDER BY a, b;
DROP TABLE t1;
--echo 0x00 in the beginning of a value of a non-last ENUM/SET causes an error:
--replace_regex /'.*t1.frm'/'DIR\/t1.frm'/
--error ER_NOT_FORM_FILE
--echo 0x00 in the beginning of a value of a non-last ENUM/SET (fixed by MDEV-28498):
CREATE TABLE t1 (a ENUM('a',0x0061), b ENUM('b')) CHARSET=latin1;
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES (1,1);
INSERT INTO t1 VALUES (2,1);
SELECT HEX(a), HEX(b) FROM t1 ORDER BY a, b;
DROP TABLE t1;
--echo #

View File

@@ -2509,18 +2509,18 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest1` /*!40100 DEFAULT CHARACTER
USE `mysqltest1`;
/*!50106 SET @save_time_zone= @@TIME_ZONE */ ;
ALTER DATABASE `mysqltest1` CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci ;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
/*!50003 SET character_set_client = koi8r */ ;
/*!50003 SET character_set_results = koi8r */ ;
/*!50003 SET collation_connection = koi8r_general_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = '' */ ;
/*!50003 SET @saved_time_zone = @@time_zone */ ;
/*!50003 SET time_zone = 'SYSTEM' */ ;
DELIMITER ;;
ALTER DATABASE `mysqltest1` CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci ;;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;;
/*!50003 SET character_set_client = koi8r */ ;;
/*!50003 SET character_set_results = koi8r */ ;;
/*!50003 SET collation_connection = koi8r_general_ci */ ;;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;;
/*!50003 SET sql_mode = '' */ ;;
/*!50003 SET @saved_time_zone = @@time_zone */ ;;
/*!50003 SET time_zone = 'SYSTEM' */ ;;
/*!50106 CREATE*/ /*!50117 DEFINER=`root`@`localhost`*/ /*!50106 EVENT `ev1` ON SCHEDULE AT '1970-01-02 00:00:00' ON COMPLETION PRESERVE DISABLE DO BEGIN
DECLARE ÐÅÒÅÍ1 CHAR(10);
SELECT
@@ -2532,24 +2532,25 @@ COLLATION(_utf8 'текст') AS c4,
@@character_set_client AS c6;
END
*/ ;;
/*!50003 SET time_zone = @saved_time_zone */ ;;
/*!50003 SET sql_mode = @saved_sql_mode */ ;;
/*!50003 SET character_set_client = @saved_cs_client */ ;;
/*!50003 SET character_set_results = @saved_cs_results */ ;;
/*!50003 SET collation_connection = @saved_col_connection */ ;;
ALTER DATABASE `mysqltest1` CHARACTER SET cp866 COLLATE cp866_general_ci ;;
DELIMITER ;
/*!50003 SET time_zone = @saved_time_zone */ ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
ALTER DATABASE `mysqltest1` CHARACTER SET cp866 COLLATE cp866_general_ci ;
ALTER DATABASE `mysqltest1` CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci ;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
/*!50003 SET character_set_client = koi8r */ ;
/*!50003 SET character_set_results = koi8r */ ;
/*!50003 SET collation_connection = koi8r_general_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = '' */ ;
/*!50003 SET @saved_time_zone = @@time_zone */ ;
/*!50003 SET time_zone = 'SYSTEM' */ ;
DELIMITER ;;
ALTER DATABASE `mysqltest1` CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci ;;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;;
/*!50003 SET character_set_client = koi8r */ ;;
/*!50003 SET character_set_results = koi8r */ ;;
/*!50003 SET collation_connection = koi8r_general_ci */ ;;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;;
/*!50003 SET sql_mode = '' */ ;;
/*!50003 SET @saved_time_zone = @@time_zone */ ;;
/*!50003 SET time_zone = 'SYSTEM' */ ;;
/*!50106 CREATE*/ /*!50117 DEFINER=`root`@`localhost`*/ /*!50106 EVENT `ev2` ON SCHEDULE AT '1970-01-02 00:00:00' ON COMPLETION PRESERVE DISABLE DO BEGIN
DECLARE ÐÅÒÅÍ1 CHAR(10) CHARACTER SET utf8;
SELECT
@@ -2561,13 +2562,13 @@ COLLATION(_utf8 'текст') AS c4,
@@character_set_client AS c6;
END
*/ ;;
/*!50003 SET time_zone = @saved_time_zone */ ;;
/*!50003 SET sql_mode = @saved_sql_mode */ ;;
/*!50003 SET character_set_client = @saved_cs_client */ ;;
/*!50003 SET character_set_results = @saved_cs_results */ ;;
/*!50003 SET collation_connection = @saved_col_connection */ ;;
ALTER DATABASE `mysqltest1` CHARACTER SET cp866 COLLATE cp866_general_ci ;;
DELIMITER ;
/*!50003 SET time_zone = @saved_time_zone */ ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
ALTER DATABASE `mysqltest1` CHARACTER SET cp866 COLLATE cp866_general_ci ;
/*!50106 SET TIME_ZONE= @save_time_zone */ ;
---> Dumping mysqltest1 to ddl_i18n_koi8r.events.mysqltest1.sql
@@ -2579,18 +2580,18 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest2` /*!40100 DEFAULT CHARACTER
USE `mysqltest2`;
/*!50106 SET @save_time_zone= @@TIME_ZONE */ ;
ALTER DATABASE `mysqltest2` CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci ;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
/*!50003 SET character_set_client = koi8r */ ;
/*!50003 SET character_set_results = koi8r */ ;
/*!50003 SET collation_connection = koi8r_general_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = '' */ ;
/*!50003 SET @saved_time_zone = @@time_zone */ ;
/*!50003 SET time_zone = 'SYSTEM' */ ;
DELIMITER ;;
ALTER DATABASE `mysqltest2` CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci ;;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;;
/*!50003 SET character_set_client = koi8r */ ;;
/*!50003 SET character_set_results = koi8r */ ;;
/*!50003 SET collation_connection = koi8r_general_ci */ ;;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;;
/*!50003 SET sql_mode = '' */ ;;
/*!50003 SET @saved_time_zone = @@time_zone */ ;;
/*!50003 SET time_zone = 'SYSTEM' */ ;;
/*!50106 CREATE*/ /*!50117 DEFINER=`root`@`localhost`*/ /*!50106 EVENT `ev3` ON SCHEDULE AT '1970-01-02 00:00:00' ON COMPLETION PRESERVE DISABLE DO BEGIN
DECLARE ÐÅÒÅÍ1 CHAR(10) CHARACTER SET utf8;
SELECT
@@ -2602,24 +2603,25 @@ COLLATION(_utf8 'текст') AS c4,
@@character_set_client AS c6;
END
*/ ;;
/*!50003 SET time_zone = @saved_time_zone */ ;;
/*!50003 SET sql_mode = @saved_sql_mode */ ;;
/*!50003 SET character_set_client = @saved_cs_client */ ;;
/*!50003 SET character_set_results = @saved_cs_results */ ;;
/*!50003 SET collation_connection = @saved_col_connection */ ;;
ALTER DATABASE `mysqltest2` CHARACTER SET cp866 COLLATE cp866_general_ci ;;
DELIMITER ;
/*!50003 SET time_zone = @saved_time_zone */ ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
ALTER DATABASE `mysqltest2` CHARACTER SET cp866 COLLATE cp866_general_ci ;
ALTER DATABASE `mysqltest2` CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci ;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
/*!50003 SET character_set_client = koi8r */ ;
/*!50003 SET character_set_results = koi8r */ ;
/*!50003 SET collation_connection = koi8r_general_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = '' */ ;
/*!50003 SET @saved_time_zone = @@time_zone */ ;
/*!50003 SET time_zone = 'SYSTEM' */ ;
DELIMITER ;;
ALTER DATABASE `mysqltest2` CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci ;;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;;
/*!50003 SET character_set_client = koi8r */ ;;
/*!50003 SET character_set_results = koi8r */ ;;
/*!50003 SET collation_connection = koi8r_general_ci */ ;;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;;
/*!50003 SET sql_mode = '' */ ;;
/*!50003 SET @saved_time_zone = @@time_zone */ ;;
/*!50003 SET time_zone = 'SYSTEM' */ ;;
/*!50106 CREATE*/ /*!50117 DEFINER=`root`@`localhost`*/ /*!50106 EVENT `ev4` ON SCHEDULE AT '1970-01-02 00:00:00' ON COMPLETION PRESERVE DISABLE DO BEGIN
DECLARE ÐÅÒÅÍ1 CHAR(10) CHARACTER SET utf8;
SELECT
@@ -2631,13 +2633,13 @@ COLLATION(_utf8 'текст') AS c4,
@@character_set_client AS c6;
END
*/ ;;
/*!50003 SET time_zone = @saved_time_zone */ ;;
/*!50003 SET sql_mode = @saved_sql_mode */ ;;
/*!50003 SET character_set_client = @saved_cs_client */ ;;
/*!50003 SET character_set_results = @saved_cs_results */ ;;
/*!50003 SET collation_connection = @saved_col_connection */ ;;
ALTER DATABASE `mysqltest2` CHARACTER SET cp866 COLLATE cp866_general_ci ;;
DELIMITER ;
/*!50003 SET time_zone = @saved_time_zone */ ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
ALTER DATABASE `mysqltest2` CHARACTER SET cp866 COLLATE cp866_general_ci ;
/*!50106 SET TIME_ZONE= @save_time_zone */ ;
---> Dumping mysqltest2 to ddl_i18n_koi8r.events.mysqltest2.sql

View File

@@ -2509,18 +2509,18 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest1` /*!40100 DEFAULT CHARACTER
USE `mysqltest1`;
/*!50106 SET @save_time_zone= @@TIME_ZONE */ ;
ALTER DATABASE `mysqltest1` CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci ;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
/*!50003 SET character_set_client = utf8mb3 */ ;
/*!50003 SET character_set_results = utf8mb3 */ ;
/*!50003 SET collation_connection = utf8mb3_uca1400_ai_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = '' */ ;
/*!50003 SET @saved_time_zone = @@time_zone */ ;
/*!50003 SET time_zone = 'SYSTEM' */ ;
DELIMITER ;;
ALTER DATABASE `mysqltest1` CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci ;;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;;
/*!50003 SET character_set_client = utf8mb3 */ ;;
/*!50003 SET character_set_results = utf8mb3 */ ;;
/*!50003 SET collation_connection = utf8mb3_uca1400_ai_ci */ ;;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;;
/*!50003 SET sql_mode = '' */ ;;
/*!50003 SET @saved_time_zone = @@time_zone */ ;;
/*!50003 SET time_zone = 'SYSTEM' */ ;;
/*!50106 CREATE*/ /*!50117 DEFINER=`root`@`localhost`*/ /*!50106 EVENT `ev1` ON SCHEDULE AT '1970-01-02 00:00:00' ON COMPLETION PRESERVE DISABLE DO BEGIN
DECLARE перем1 CHAR(10);
SELECT
@@ -2532,24 +2532,25 @@ COLLATION(_koi8r '
@@character_set_client AS c6;
END
*/ ;;
/*!50003 SET time_zone = @saved_time_zone */ ;;
/*!50003 SET sql_mode = @saved_sql_mode */ ;;
/*!50003 SET character_set_client = @saved_cs_client */ ;;
/*!50003 SET character_set_results = @saved_cs_results */ ;;
/*!50003 SET collation_connection = @saved_col_connection */ ;;
ALTER DATABASE `mysqltest1` CHARACTER SET cp866 COLLATE cp866_general_ci ;;
DELIMITER ;
/*!50003 SET time_zone = @saved_time_zone */ ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
ALTER DATABASE `mysqltest1` CHARACTER SET cp866 COLLATE cp866_general_ci ;
ALTER DATABASE `mysqltest1` CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci ;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
/*!50003 SET character_set_client = utf8mb3 */ ;
/*!50003 SET character_set_results = utf8mb3 */ ;
/*!50003 SET collation_connection = utf8mb3_uca1400_ai_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = '' */ ;
/*!50003 SET @saved_time_zone = @@time_zone */ ;
/*!50003 SET time_zone = 'SYSTEM' */ ;
DELIMITER ;;
ALTER DATABASE `mysqltest1` CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci ;;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;;
/*!50003 SET character_set_client = utf8mb3 */ ;;
/*!50003 SET character_set_results = utf8mb3 */ ;;
/*!50003 SET collation_connection = utf8mb3_uca1400_ai_ci */ ;;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;;
/*!50003 SET sql_mode = '' */ ;;
/*!50003 SET @saved_time_zone = @@time_zone */ ;;
/*!50003 SET time_zone = 'SYSTEM' */ ;;
/*!50106 CREATE*/ /*!50117 DEFINER=`root`@`localhost`*/ /*!50106 EVENT `ev2` ON SCHEDULE AT '1970-01-02 00:00:00' ON COMPLETION PRESERVE DISABLE DO BEGIN
DECLARE перем1 CHAR(10) CHARACTER SET utf8;
SELECT
@@ -2561,13 +2562,13 @@ COLLATION(_koi8r '
@@character_set_client AS c6;
END
*/ ;;
/*!50003 SET time_zone = @saved_time_zone */ ;;
/*!50003 SET sql_mode = @saved_sql_mode */ ;;
/*!50003 SET character_set_client = @saved_cs_client */ ;;
/*!50003 SET character_set_results = @saved_cs_results */ ;;
/*!50003 SET collation_connection = @saved_col_connection */ ;;
ALTER DATABASE `mysqltest1` CHARACTER SET cp866 COLLATE cp866_general_ci ;;
DELIMITER ;
/*!50003 SET time_zone = @saved_time_zone */ ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
ALTER DATABASE `mysqltest1` CHARACTER SET cp866 COLLATE cp866_general_ci ;
/*!50106 SET TIME_ZONE= @save_time_zone */ ;
---> Dumping mysqltest1 to ddl_i18n_utf8events.mysqltest1.sql
@@ -2579,18 +2580,18 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest2` /*!40100 DEFAULT CHARACTER
USE `mysqltest2`;
/*!50106 SET @save_time_zone= @@TIME_ZONE */ ;
ALTER DATABASE `mysqltest2` CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci ;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
/*!50003 SET character_set_client = utf8mb3 */ ;
/*!50003 SET character_set_results = utf8mb3 */ ;
/*!50003 SET collation_connection = utf8mb3_uca1400_ai_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = '' */ ;
/*!50003 SET @saved_time_zone = @@time_zone */ ;
/*!50003 SET time_zone = 'SYSTEM' */ ;
DELIMITER ;;
ALTER DATABASE `mysqltest2` CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci ;;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;;
/*!50003 SET character_set_client = utf8mb3 */ ;;
/*!50003 SET character_set_results = utf8mb3 */ ;;
/*!50003 SET collation_connection = utf8mb3_uca1400_ai_ci */ ;;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;;
/*!50003 SET sql_mode = '' */ ;;
/*!50003 SET @saved_time_zone = @@time_zone */ ;;
/*!50003 SET time_zone = 'SYSTEM' */ ;;
/*!50106 CREATE*/ /*!50117 DEFINER=`root`@`localhost`*/ /*!50106 EVENT `ev3` ON SCHEDULE AT '1970-01-02 00:00:00' ON COMPLETION PRESERVE DISABLE DO BEGIN
DECLARE перем1 CHAR(10) CHARACTER SET utf8;
SELECT
@@ -2602,24 +2603,25 @@ COLLATION(_koi8r '
@@character_set_client AS c6;
END
*/ ;;
/*!50003 SET time_zone = @saved_time_zone */ ;;
/*!50003 SET sql_mode = @saved_sql_mode */ ;;
/*!50003 SET character_set_client = @saved_cs_client */ ;;
/*!50003 SET character_set_results = @saved_cs_results */ ;;
/*!50003 SET collation_connection = @saved_col_connection */ ;;
ALTER DATABASE `mysqltest2` CHARACTER SET cp866 COLLATE cp866_general_ci ;;
DELIMITER ;
/*!50003 SET time_zone = @saved_time_zone */ ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
ALTER DATABASE `mysqltest2` CHARACTER SET cp866 COLLATE cp866_general_ci ;
ALTER DATABASE `mysqltest2` CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci ;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
/*!50003 SET character_set_client = utf8mb3 */ ;
/*!50003 SET character_set_results = utf8mb3 */ ;
/*!50003 SET collation_connection = utf8mb3_uca1400_ai_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = '' */ ;
/*!50003 SET @saved_time_zone = @@time_zone */ ;
/*!50003 SET time_zone = 'SYSTEM' */ ;
DELIMITER ;;
ALTER DATABASE `mysqltest2` CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci ;;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;;
/*!50003 SET character_set_client = utf8mb3 */ ;;
/*!50003 SET character_set_results = utf8mb3 */ ;;
/*!50003 SET collation_connection = utf8mb3_uca1400_ai_ci */ ;;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;;
/*!50003 SET sql_mode = '' */ ;;
/*!50003 SET @saved_time_zone = @@time_zone */ ;;
/*!50003 SET time_zone = 'SYSTEM' */ ;;
/*!50106 CREATE*/ /*!50117 DEFINER=`root`@`localhost`*/ /*!50106 EVENT `ev4` ON SCHEDULE AT '1970-01-02 00:00:00' ON COMPLETION PRESERVE DISABLE DO BEGIN
DECLARE перем1 CHAR(10) CHARACTER SET utf8;
SELECT
@@ -2631,13 +2633,13 @@ COLLATION(_koi8r '
@@character_set_client AS c6;
END
*/ ;;
/*!50003 SET time_zone = @saved_time_zone */ ;;
/*!50003 SET sql_mode = @saved_sql_mode */ ;;
/*!50003 SET character_set_client = @saved_cs_client */ ;;
/*!50003 SET character_set_results = @saved_cs_results */ ;;
/*!50003 SET collation_connection = @saved_col_connection */ ;;
ALTER DATABASE `mysqltest2` CHARACTER SET cp866 COLLATE cp866_general_ci ;;
DELIMITER ;
/*!50003 SET time_zone = @saved_time_zone */ ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
ALTER DATABASE `mysqltest2` CHARACTER SET cp866 COLLATE cp866_general_ci ;
/*!50106 SET TIME_ZONE= @save_time_zone */ ;
---> Dumping mysqltest2 to ddl_i18n_utf8events.mysqltest2.sql

View File

@@ -26,7 +26,8 @@ CREATE EVENT e
# Wait until the event worker appears in PROCESSLIST for the current user
let $wait_condition= SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST
WHERE INFO LIKE '%SLEEP(10000)%' AND ID <> CONNECTION_ID();
WHERE INFO LIKE '%SLEEP(10000)%' AND ID <> CONNECTION_ID()
AND STATE='User sleep';
--source include/wait_condition.inc
# Check that show processlist works

View File

@@ -2980,6 +2980,133 @@ NULL
SELECT JSON_OVERLAPS(JSON_ARRAY_INSERT(NULL,'$[0]',1), '[]') AS x;
x
NULL
#
# MDEV-32331 JSON path functions with no charset on path crash server
#
SELECT 1 FROM
(SELECT CASE WHEN x * x THEN x END as a
FROM ( SELECT json_array_append ( 'x' , ( 'x' % 'x' ) , 1 , 'x' , 1 ) as x ) dt2
) dt
WHERE a;
1
Warnings:
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
SELECT 1 FROM (SELECT CASE WHEN x * x THEN x END as a FROM ( SELECT json_array_append ( 'x' , ( 'x' % 'x' ) , 1 , 'x' , 1 ) as x ) dt2 ) dt WHERE a;
1
Warnings:
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
SELECT 1 FROM (SELECT CASE WHEN x * x THEN x END as a FROM ( SELECT json_array_insert ( '[1]' , ( 'x' % 'x' ) , 1 , '$[0]' , 9 ) as x ) dt2 ) dt WHERE a;
1
Warnings:
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
SELECT 1 FROM (SELECT CASE WHEN x * x THEN x END as a FROM ( SELECT json_insert ( '1' , ( 'x' % 'x' ) , 1 , '$.a' , 2 ) as x ) dt2 ) dt WHERE a;
1
Warnings:
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
SELECT 1 FROM (SELECT CASE WHEN x * x THEN x END as a FROM ( SELECT json_remove ( '[1,2]' , ( 'x' % 'x' ) , '$[0]' ) as x ) dt2 ) dt WHERE a;
1
Warnings:
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
SELECT 1 FROM (SELECT CASE WHEN x * x THEN x END as a FROM ( SELECT json_replace ( '1' , ( 'x' % 'x' ) , 1 , '$.a' , 2 ) as x ) dt2 ) dt WHERE a;
1
Warnings:
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
SELECT 1 FROM (SELECT CASE WHEN x * x THEN x END as a FROM ( SELECT json_set ( '1' , ( 'x' % 'x' ) , 1 , '$.a' , 2 ) as x ) dt2 ) dt WHERE a;
1
Warnings:
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
SELECT x FROM (SELECT 1 AS x UNION SELECT 2) AS t WHERE x IN ( SELECT JSON_REPLACE('1', UPPER(CAST(NULL AS CHAR)), 100));
x
SELECT ( WITH RECURSIVE x ( x ) AS (WITH RECURSIVE x ( x ) AS ( SELECT 1 UNION SELECT x + 1 FROM x ) SELECT json_array_append ( '[[], [], []]' , NOT ( NULL LIKE 'ABC%' ) , 315 )) SELECT x FROM x WHERE x > 10 AND x < 1) AS x;
x
NULL
SELECT 1 FROM (SELECT JSON_REMOVE(46, DATE(NULL)) AS x EXCEPT SELECT 1) AS d WHERE NOT(NOT(x > 10)) AND (x < 1 OR x > 1);
1
#
# MDEV-40572 SIGSEGV in JSON_OVERLAPS() on a truncated nested JSON object with different character sets/collations
#
SET @col=@@collation_connection;
SET @char=@@character_set_connection;
SET collation_connection=ucs2_general_ci;
SELECT JSON_OVERLAPS ('{"B":{}}', '{"B":{') AS exp_ucs2;
exp_ucs2
0
Warnings:
Warning 4037 Unexpected end of JSON text in argument 2 to function 'json_overlaps'
SET character_set_connection=utf16;
SELECT JSON_OVERLAPS ('{"B":{}}', '{"B":{') AS exp_utf16;
exp_utf16
0
Warnings:
Warning 4037 Unexpected end of JSON text in argument 2 to function 'json_overlaps'
SET @@collation_connection=@col;
SET @@character_set_connection=@char;
#
# MDEV-40165 JSON_EQUAL/JSON_NORMALIZE/JSON_CONTAINS error handling
#
CREATE TABLE t(c1 JSON, c2 JSON);
INSERT INTO t VALUES ('{"a":1,"b":2}', '{"b":2E0, "a":1E0}'),
(NULL, '["a", "b"]'),
('{"r": 1}', NULL),
('[{"a": 3}, {"d": [1, 2, 3]}]', '[{"d": [1E0, 2E0, 3E0]}, {"a":3E0}]');
SELECT c1, JSON_EQUALS(c1, '{"r": 1E0}') AS je_c1_const FROM t;
c1 je_c1_const
{"a":1,"b":2} 0
NULL NULL
{"r": 1} 1
[{"a": 3}, {"d": [1, 2, 3]}] 0
SELECT c1, c2, JSON_EQUALS(c1, c2) AS je_c1_c2 FROM t;
c1 c2 je_c1_c2
{"a":1,"b":2} {"b":2E0, "a":1E0} 1
NULL ["a", "b"] NULL
{"r": 1} NULL NULL
[{"a": 3}, {"d": [1, 2, 3]}] [{"d": [1E0, 2E0, 3E0]}, {"a":3E0}] 0
SELECT c1, JSON_CONTAINS(c1, '{"r": 1E0}') AS jc_c1_const FROM t;
c1 jc_c1_const
{"a":1,"b":2} 0
NULL NULL
{"r": 1} 1
[{"a": 3}, {"d": [1, 2, 3]}] 0
SELECT c1, c2, JSON_CONTAINS(c1, c2) AS jc_c1_c2 FROM t;
c1 c2 jc_c1_c2
{"a":1,"b":2} {"b":2E0, "a":1E0} 1
NULL ["a", "b"] NULL
{"r": 1} NULL NULL
[{"a": 3}, {"d": [1, 2, 3]}] [{"d": [1E0, 2E0, 3E0]}, {"a":3E0}] 1
SELECT c1, JSON_OVERLAPS(c1, '{"r": 1E0}') AS jo_c1_const FROM t;
c1 jo_c1_const
{"a":1,"b":2} 0
NULL NULL
{"r": 1} 1
[{"a": 3}, {"d": [1, 2, 3]}] 0
SELECT c1, c2, JSON_OVERLAPS(c1, c2) AS jo_c1_c2 FROM t;
c1 c2 jo_c1_c2
{"a":1,"b":2} {"b":2E0, "a":1E0} 1
NULL ["a", "b"] NULL
{"r": 1} NULL NULL
[{"a": 3}, {"d": [1, 2, 3]}] [{"d": [1E0, 2E0, 3E0]}, {"a":3E0}] 1
DROP TABLE t;
# End of 10.11 Test
#
# MDEV-32007: JSON_VALUE and JSON_EXTRACT doesn't handle dash (-)

View File

@@ -2114,6 +2114,61 @@ SELECT JSON_ARRAY_INSERT (0,NULL,1) as j;
SELECT JSON_EQUALS('[]', JSON_ARRAY_INSERT(NULL,'$[0]',1)) AS x;
SELECT JSON_OVERLAPS(JSON_ARRAY_INSERT(NULL,'$[0]',1), '[]') AS x;
--echo #
--echo # MDEV-32331 JSON path functions with no charset on path crash server
--echo #
SELECT 1 FROM
(SELECT CASE WHEN x * x THEN x END as a
FROM ( SELECT json_array_append ( 'x' , ( 'x' % 'x' ) , 1 , 'x' , 1 ) as x ) dt2
) dt
WHERE a;
SELECT 1 FROM (SELECT CASE WHEN x * x THEN x END as a FROM ( SELECT json_array_append ( 'x' , ( 'x' % 'x' ) , 1 , 'x' , 1 ) as x ) dt2 ) dt WHERE a;
SELECT 1 FROM (SELECT CASE WHEN x * x THEN x END as a FROM ( SELECT json_array_insert ( '[1]' , ( 'x' % 'x' ) , 1 , '$[0]' , 9 ) as x ) dt2 ) dt WHERE a;
SELECT 1 FROM (SELECT CASE WHEN x * x THEN x END as a FROM ( SELECT json_insert ( '1' , ( 'x' % 'x' ) , 1 , '$.a' , 2 ) as x ) dt2 ) dt WHERE a;
SELECT 1 FROM (SELECT CASE WHEN x * x THEN x END as a FROM ( SELECT json_remove ( '[1,2]' , ( 'x' % 'x' ) , '$[0]' ) as x ) dt2 ) dt WHERE a;
SELECT 1 FROM (SELECT CASE WHEN x * x THEN x END as a FROM ( SELECT json_replace ( '1' , ( 'x' % 'x' ) , 1 , '$.a' , 2 ) as x ) dt2 ) dt WHERE a;
SELECT 1 FROM (SELECT CASE WHEN x * x THEN x END as a FROM ( SELECT json_set ( '1' , ( 'x' % 'x' ) , 1 , '$.a' , 2 ) as x ) dt2 ) dt WHERE a;
SELECT x FROM (SELECT 1 AS x UNION SELECT 2) AS t WHERE x IN ( SELECT JSON_REPLACE('1', UPPER(CAST(NULL AS CHAR)), 100));
SELECT ( WITH RECURSIVE x ( x ) AS (WITH RECURSIVE x ( x ) AS ( SELECT 1 UNION SELECT x + 1 FROM x ) SELECT json_array_append ( '[[], [], []]' , NOT ( NULL LIKE 'ABC%' ) , 315 )) SELECT x FROM x WHERE x > 10 AND x < 1) AS x;
SELECT 1 FROM (SELECT JSON_REMOVE(46, DATE(NULL)) AS x EXCEPT SELECT 1) AS d WHERE NOT(NOT(x > 10)) AND (x < 1 OR x > 1);
--echo #
--echo # MDEV-40572 SIGSEGV in JSON_OVERLAPS() on a truncated nested JSON object with different character sets/collations
--echo #
SET @col=@@collation_connection;
SET @char=@@character_set_connection;
SET collation_connection=ucs2_general_ci;
SELECT JSON_OVERLAPS ('{"B":{}}', '{"B":{') AS exp_ucs2;
SET character_set_connection=utf16;
SELECT JSON_OVERLAPS ('{"B":{}}', '{"B":{') AS exp_utf16;
SET @@collation_connection=@col;
SET @@character_set_connection=@char;
--echo #
--echo # MDEV-40165 JSON_EQUAL/JSON_NORMALIZE/JSON_CONTAINS error handling
--echo #
CREATE TABLE t(c1 JSON, c2 JSON);
INSERT INTO t VALUES ('{"a":1,"b":2}', '{"b":2E0, "a":1E0}'),
(NULL, '["a", "b"]'),
('{"r": 1}', NULL),
('[{"a": 3}, {"d": [1, 2, 3]}]', '[{"d": [1E0, 2E0, 3E0]}, {"a":3E0}]');
SELECT c1, JSON_EQUALS(c1, '{"r": 1E0}') AS je_c1_const FROM t;
SELECT c1, c2, JSON_EQUALS(c1, c2) AS je_c1_c2 FROM t;
SELECT c1, JSON_CONTAINS(c1, '{"r": 1E0}') AS jc_c1_const FROM t;
SELECT c1, c2, JSON_CONTAINS(c1, c2) AS jc_c1_c2 FROM t;
SELECT c1, JSON_OVERLAPS(c1, '{"r": 1E0}') AS jo_c1_const FROM t;
SELECT c1, c2, JSON_OVERLAPS(c1, c2) AS jo_c1_c2 FROM t;
DROP TABLE t;
--echo # End of 10.11 Test
--echo #

View File

@@ -459,13 +459,8 @@ select sformat('{:f}', @a);
sformat('{:f}', @a)
3.140000
set names latin1;
#
# End of 10.7 tests
#
#
# Start of 10.8 tests
#
#
# MDEV-29646 sformat('Num [{:20}]', 42) gives incorrect result in view
#
create view v1 as select sformat('Num [{:20}]', 42);
@@ -498,4 +493,36 @@ bar 2
foo 1
drop view v;
drop table t;
#
# MDEV-40411 SFORMAT ignores max_allowed_packet
#
set @old_max_allowed_packet=@@global.max_allowed_packet;
set @@global.max_allowed_packet=512*1024;
connect u,localhost,root;
select length(sformat('{:2147483647}', 1));
length(sformat('{:2147483647}', 1))
NULL
select length(sformat('{:524288}', 1));
length(sformat('{:524288}', 1))
524288
select length(sformat('{:524289}', 1));
length(sformat('{:524289}', 1))
NULL
select length(sformat('{:524287}.', 1));
length(sformat('{:524287}.', 1))
524288
select length(sformat('{:524287}..', 1));
length(sformat('{:524287}..', 1))
NULL
disconnect u;
connection default;
set @@global.max_allowed_packet= @old_max_allowed_packet;
set max_session_mem_used=512*1024;
select length(sformat('{:524288}', 1));
length(sformat('{:524288}', 1))
524288
select length(sformat('{:524289}', 1));
length(sformat('{:524289}', 1))
NULL
set max_session_mem_used=default;
# End of 10.11 tests

View File

@@ -236,13 +236,7 @@ set @a=3.14;
select sformat('{:f}', @a);
set names latin1;
echo #;
echo # End of 10.7 tests;
echo #;
echo #;
echo # Start of 10.8 tests;
echo #;
echo #;
echo # MDEV-29646 sformat('Num [{:20}]', 42) gives incorrect result in view;
@@ -274,4 +268,30 @@ select * from v where a != sformat('{}', 'qux');
drop view v;
drop table t;
echo #;
echo # MDEV-40411 SFORMAT ignores max_allowed_packet;
echo #;
set @old_max_allowed_packet=@@global.max_allowed_packet;
set @@global.max_allowed_packet=512*1024;
connect u,localhost,root;
# these three case: fmt allocates the requested size at once
select length(sformat('{:2147483647}', 1));
select length(sformat('{:524288}', 1));
select length(sformat('{:524289}', 1));
# here it allocates 524287 and then grows by *1.5
select length(sformat('{:524287}.', 1));
select length(sformat('{:524287}..', 1));
disconnect u;
connection default;
set @@global.max_allowed_packet= @old_max_allowed_packet;
disable_cursor_protocol;
disable_view_protocol;
set max_session_mem_used=512*1024;
select length(sformat('{:524288}', 1));
select length(sformat('{:524289}', 1));
set max_session_mem_used=default;
enable_view_protocol;
enable_cursor_protocol;
echo # End of 10.11 tests;

View File

@@ -110,6 +110,8 @@ Warning 4076 Incorrect GeoJSON format - empty 'coordinates' array.
SELECT ST_GEOMFROMGEOJSON("{ \"type\": \"Feature\", \"geometry\": [10, 20] }") as exp;
exp
NULL
Warnings:
Warning 4048 Incorrect GeoJSON format specified for st_geomfromgeojson function.
SELECT ST_ASTEXT (ST_GEOMFROMGEOJSON ('{ "type": "GEOMETRYCOLLECTION", "coordinates": [102.0, 0.0]}')) as exp;
exp
NULL
@@ -123,6 +125,125 @@ Warning 4048 Incorrect GeoJSON format specified for st_geomfromgeojson function.
#
# End of 10.2 tests
#
# Boundary condition: foreign-member nesting at depth 32
SET @geom := '{"type":"Point","coordinates":[1,2]}';
SET @doc := CONCAT(
REPEAT('{"x":', 29),
@geom,
REPEAT('}', 29)
);
SELECT ST_ASTEXT( ST_GeomFromGeoJSON(@doc) ) AS expr;
expr
NULL
Warnings:
Warning 4048 Incorrect GeoJSON format specified for st_geomfromgeojson function.
# Foreign-member nesting exceeds depth 32
SET @geom := '{"type":"Point","coordinates":[1,2]}';
SET @doc := CONCAT(
REPEAT('{"x":', 30),
@geom,
REPEAT('}', 30)
);
SELECT ST_GeomFromGeoJSON(@doc) AS expr;
expr
NULL
Warnings:
Warning 4048 Incorrect GeoJSON format specified for st_geomfromgeojson function.
# Deep foreign member attached to otherwise valid GeoJSON
SET @foreign := CONCAT(
REPEAT('{"x":', 28),
'{"leaf":1}',
REPEAT('}', 28)
);
SET @doc := CONCAT(
'{"type":"Point","coordinates":[10,20],"foreign":',
@foreign,
'}'
);
SELECT ST_ASTEXT(ST_GeomFromGeoJSON(@doc)) AS expr;
expr
POINT(10 20)
# Foreign member exceeds depth limit
SET @foreign := CONCAT(
REPEAT('{"x":', 29),
'{"leaf":1}',
REPEAT('}', 29)
);
SET @doc := CONCAT(
'{"type":"Point","coordinates":[10,20],"foreign":',
@foreign,
'}'
);
SELECT ST_ASTEXT(ST_GeomFromGeoJSON(@doc)) AS expr;
expr
POINT(10 20)
# GeometryCollection containing 33 valid GeoJSON Point objects
SET @point := '{"type":"Point","coordinates":[1,2]}';
SET @geoms := CONCAT(
@point, ',', @point, ',', @point, ',', @point, ',', @point, ',',
@point, ',', @point, ',', @point, ',', @point, ',', @point, ',',
@point, ',', @point, ',', @point, ',', @point, ',', @point, ',',
@point, ',', @point, ',', @point, ',', @point, ',', @point, ',',
@point, ',', @point, ',', @point, ',', @point, ',', @point, ',',
@point, ',', @point, ',', @point, ',', @point, ',', @point, ',',
@point, ',', @point, ',', @point, ',', @point, ',', @point, ',',
@point, ',', @point, ',', @point
);
SET @doc := CONCAT(
'{"type":"GeometryCollection","geometries":[',
@geoms,
']}'
);
SELECT ST_AsText(ST_GeomFromGeoJSON(@doc)) AS expr;
expr
GEOMETRYCOLLECTION(POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2))
#
# MDEV-39981: ST_GEOMFROMGEOJSON returns wrong result with reversed key order
#
# GeometryCollection: type before geometries (baseline)
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"type":"GeometryCollection","geometries":[]}')) as expr;
expr
GEOMETRYCOLLECTION EMPTY
# GeometryCollection: geometries before type (empty)
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"geometries":[],"type":"GeometryCollection"}')) as expr;
expr
GEOMETRYCOLLECTION EMPTY
# GeometryCollection: geometries before type (non-empty)
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"geometries":[{"type":"Point","coordinates":[0,1]}],"type":"GeometryCollection"}')) as expr;
expr
GEOMETRYCOLLECTION(POINT(0 1))
# GeometryCollection: multiple geometries before type
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"geometries":[{"type":"Point","coordinates":[1,2]},{"type":"Point","coordinates":[3,4]}],"type":"GeometryCollection"}')) as expr;
expr
GEOMETRYCOLLECTION(POINT(1 2),POINT(3 4))
# Point: coordinates before type
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"coordinates":[0,1],"type":"Point"}')) as expr;
expr
POINT(0 1)
# LineString: coordinates before type
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"coordinates":[[0,0],[1,1],[2,2]],"type":"LineString"}')) as expr;
expr
LINESTRING(0 0,1 1,2 2)
# Polygon: coordinates before type
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"coordinates":[[[0,0],[1,0],[1,1],[0,1],[0,0]]],"type":"Polygon"}')) as expr;
expr
POLYGON((0 0,1 0,1 1,0 1,0 0))
# FeatureCollection: features before type
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"features":[{"geometry":{"type":"Point","coordinates":[5,6]},"type":"Feature","properties":{}}],"type":"FeatureCollection"}')) as expr;
expr
GEOMETRYCOLLECTION(POINT(5 6))
# Feature: geometry before type
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"geometry":{"coordinates":[7,8],"type":"Point"},"type":"Feature","properties":{}}')) as expr;
expr
POINT(7 8)
# Unknown keys interspersed (should be ignored)
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"foo":"bar","geometries":[],"type":"GeometryCollection","extra":123}')) as expr;
expr
GEOMETRYCOLLECTION EMPTY
# Deeply nested geometries before type
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"geometries":[{"geometries":[{"type":"Point","coordinates":[9,10]}],"type":"GeometryCollection"}],"type":"GeometryCollection"}')) as expr;
expr
GEOMETRYCOLLECTION(GEOMETRYCOLLECTION(POINT(9 10)))
# End of 10.6 tests
#
# MDEV-34079: ST_AsGeoJSON returns incorrect value for empty geometry

View File

@@ -60,6 +60,120 @@ SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"type": ["POINT"], "coINates": [0,0] }'))
--echo #
--echo # Boundary condition: foreign-member nesting at depth 32
SET @geom := '{"type":"Point","coordinates":[1,2]}';
SET @doc := CONCAT(
REPEAT('{"x":', 29),
@geom,
REPEAT('}', 29)
);
SELECT ST_ASTEXT( ST_GeomFromGeoJSON(@doc) ) AS expr;
--echo # Foreign-member nesting exceeds depth 32
SET @geom := '{"type":"Point","coordinates":[1,2]}';
SET @doc := CONCAT(
REPEAT('{"x":', 30),
@geom,
REPEAT('}', 30)
);
SELECT ST_GeomFromGeoJSON(@doc) AS expr;
--echo # Deep foreign member attached to otherwise valid GeoJSON
SET @foreign := CONCAT(
REPEAT('{"x":', 28),
'{"leaf":1}',
REPEAT('}', 28)
);
SET @doc := CONCAT(
'{"type":"Point","coordinates":[10,20],"foreign":',
@foreign,
'}'
);
SELECT ST_ASTEXT(ST_GeomFromGeoJSON(@doc)) AS expr;
--echo # Foreign member exceeds depth limit
SET @foreign := CONCAT(
REPEAT('{"x":', 29),
'{"leaf":1}',
REPEAT('}', 29)
);
SET @doc := CONCAT(
'{"type":"Point","coordinates":[10,20],"foreign":',
@foreign,
'}'
);
SELECT ST_ASTEXT(ST_GeomFromGeoJSON(@doc)) AS expr;
--echo # GeometryCollection containing 33 valid GeoJSON Point objects
SET @point := '{"type":"Point","coordinates":[1,2]}';
SET @geoms := CONCAT(
@point, ',', @point, ',', @point, ',', @point, ',', @point, ',',
@point, ',', @point, ',', @point, ',', @point, ',', @point, ',',
@point, ',', @point, ',', @point, ',', @point, ',', @point, ',',
@point, ',', @point, ',', @point, ',', @point, ',', @point, ',',
@point, ',', @point, ',', @point, ',', @point, ',', @point, ',',
@point, ',', @point, ',', @point, ',', @point, ',', @point, ',',
@point, ',', @point, ',', @point, ',', @point, ',', @point, ',',
@point, ',', @point, ',', @point
);
SET @doc := CONCAT(
'{"type":"GeometryCollection","geometries":[',
@geoms,
']}'
);
SELECT ST_AsText(ST_GeomFromGeoJSON(@doc)) AS expr;
--echo #
--echo # MDEV-39981: ST_GEOMFROMGEOJSON returns wrong result with reversed key order
--echo #
--echo # GeometryCollection: type before geometries (baseline)
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"type":"GeometryCollection","geometries":[]}')) as expr;
--echo # GeometryCollection: geometries before type (empty)
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"geometries":[],"type":"GeometryCollection"}')) as expr;
--echo # GeometryCollection: geometries before type (non-empty)
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"geometries":[{"type":"Point","coordinates":[0,1]}],"type":"GeometryCollection"}')) as expr;
--echo # GeometryCollection: multiple geometries before type
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"geometries":[{"type":"Point","coordinates":[1,2]},{"type":"Point","coordinates":[3,4]}],"type":"GeometryCollection"}')) as expr;
--echo # Point: coordinates before type
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"coordinates":[0,1],"type":"Point"}')) as expr;
--echo # LineString: coordinates before type
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"coordinates":[[0,0],[1,1],[2,2]],"type":"LineString"}')) as expr;
--echo # Polygon: coordinates before type
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"coordinates":[[[0,0],[1,0],[1,1],[0,1],[0,0]]],"type":"Polygon"}')) as expr;
--echo # FeatureCollection: features before type
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"features":[{"geometry":{"type":"Point","coordinates":[5,6]},"type":"Feature","properties":{}}],"type":"FeatureCollection"}')) as expr;
--echo # Feature: geometry before type
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"geometry":{"coordinates":[7,8],"type":"Point"},"type":"Feature","properties":{}}')) as expr;
--echo # Unknown keys interspersed (should be ignored)
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"foo":"bar","geometries":[],"type":"GeometryCollection","extra":123}')) as expr;
--echo # Deeply nested geometries before type
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"geometries":[{"geometries":[{"type":"Point","coordinates":[9,10]}],"type":"GeometryCollection"}],"type":"GeometryCollection"}')) as expr;
--echo # End of 10.6 tests
--echo #

View File

@@ -881,6 +881,66 @@ SELECT ST_CROSSES( ST_GEOMFROMTEXT('POLYGON ((59 18,67 18,67 13,59 13,59 18)) ')
a
NULL
#
# MDEV-40584 ST_CROSSES always returns 0 for geometries of different dimensions
#
SELECT ST_Crosses(ST_GeomFromText('MULTIPOINT(1 3, 2 2, 3 2)'),
ST_GeomFromText('LINESTRING(0 3, 1 1, 2 2, 2 0)')) a;
a
1
SELECT ST_Crosses(ST_GeomFromText('MULTIPOINT(1 1, 1 3, 2 3)'),
ST_GeomFromText('POLYGON((0 0, 0 3, 2 0, 0 0))')) a;
a
1
SELECT ST_Crosses(ST_GeomFromText('LINESTRING(0 1, 3 2, 4 1)'),
ST_GeomFromText('POLYGON((1 0, 1 2, 2 3, 2 1, 1 0))')) a;
a
1
# line x line, crossing (dims 1,1) -> 1
SELECT ST_Crosses(ST_GeomFromText('LINESTRING(0 0, 2 2)'),
ST_GeomFromText('LINESTRING(0 2, 2 0)')) a;
a
1
# line x line, not crossing (dims 1,1) -> 0
SELECT ST_Crosses(ST_GeomFromText('LINESTRING(0 0, 2 0)'),
ST_GeomFromText('LINESTRING(0 1, 2 1)')) a;
a
0
# point x line, disjoint (dims 0,1) -> 0
SELECT ST_Crosses(ST_GeomFromText('MULTIPOINT(10 10)'),
ST_GeomFromText('LINESTRING(0 0, 1 1)')) a;
a
0
# point x polygon, disjoint (dims 0,2) -> 0
SELECT ST_Crosses(ST_GeomFromText('MULTIPOINT(100 100)'),
ST_GeomFromText('POLYGON((0 0, 0 3, 2 0, 0 0))')) a;
a
0
# line x point (g2 is a point) -> NULL
SELECT ST_Crosses(ST_GeomFromText('LINESTRING(0 0, 1 1)'),
ST_GeomFromText('POINT(5 5)')) a;
a
NULL
# line x multipoint (g2 is a multipoint) -> NULL
SELECT ST_Crosses(ST_GeomFromText('LINESTRING(0 0, 5 5)'),
ST_GeomFromText('MULTIPOINT(1 1, 2 2)')) a;
a
NULL
# multipolygon x line (g1 is a multipolygon) -> NULL
SELECT ST_Crosses(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 3, 3 3, 3 0, 0 0)))'),
ST_GeomFromText('LINESTRING(1 1, 2 2)')) a;
a
NULL
# polygon x line, reversed order of a valid crossing case -> NULL
SELECT ST_Crosses(ST_GeomFromText('POLYGON((1 0, 1 2, 2 3, 2 1, 1 0))'),
ST_GeomFromText('LINESTRING(0 1, 3 2, 4 1)')) a;
a
NULL
# line x same line, equal (not lower-dim intersection) -> 0
SELECT ST_Crosses(ST_GeomFromText('LINESTRING(0 0, 2 2)'),
ST_GeomFromText('LINESTRING(0 0, 2 2)')) a;
a
0
#
# MDEV-39449: Memory corruption (heap-buffer-overflow) in uint4korr and
# Gcalc_function::count_internal, apparent partial stack looping in
# Gcalc_function::count_internal and Assertion `(0)' failed in

View File

@@ -494,6 +494,45 @@ SELECT ST_CROSSES( ST_GEOMFROMTEXT('point(1 1)'), st_geomfromtext('point(1 1)')
SELECT ST_CROSSES( ST_GEOMFROMTEXT('POLYGON ((59 18,67 18,67 13,59 13,59 18)) '), st_geomfromtext('polygon((2 2,2 4, 4 2,2 2))') ) a;
SELECT ST_CROSSES( ST_GEOMFROMTEXT('POLYGON ((59 18,67 18,67 13,59 13,59 18)) '), st_geomfromtext('point(1 1)') ) a;
--echo #
--echo # MDEV-40584 ST_CROSSES always returns 0 for geometries of different dimensions
--echo #
SELECT ST_Crosses(ST_GeomFromText('MULTIPOINT(1 3, 2 2, 3 2)'),
ST_GeomFromText('LINESTRING(0 3, 1 1, 2 2, 2 0)')) a;
SELECT ST_Crosses(ST_GeomFromText('MULTIPOINT(1 1, 1 3, 2 3)'),
ST_GeomFromText('POLYGON((0 0, 0 3, 2 0, 0 0))')) a;
SELECT ST_Crosses(ST_GeomFromText('LINESTRING(0 1, 3 2, 4 1)'),
ST_GeomFromText('POLYGON((1 0, 1 2, 2 3, 2 1, 1 0))')) a;
--echo # line x line, crossing (dims 1,1) -> 1
SELECT ST_Crosses(ST_GeomFromText('LINESTRING(0 0, 2 2)'),
ST_GeomFromText('LINESTRING(0 2, 2 0)')) a;
--echo # line x line, not crossing (dims 1,1) -> 0
SELECT ST_Crosses(ST_GeomFromText('LINESTRING(0 0, 2 0)'),
ST_GeomFromText('LINESTRING(0 1, 2 1)')) a;
--echo # point x line, disjoint (dims 0,1) -> 0
SELECT ST_Crosses(ST_GeomFromText('MULTIPOINT(10 10)'),
ST_GeomFromText('LINESTRING(0 0, 1 1)')) a;
--echo # point x polygon, disjoint (dims 0,2) -> 0
SELECT ST_Crosses(ST_GeomFromText('MULTIPOINT(100 100)'),
ST_GeomFromText('POLYGON((0 0, 0 3, 2 0, 0 0))')) a;
--echo # line x point (g2 is a point) -> NULL
SELECT ST_Crosses(ST_GeomFromText('LINESTRING(0 0, 1 1)'),
ST_GeomFromText('POINT(5 5)')) a;
--echo # line x multipoint (g2 is a multipoint) -> NULL
SELECT ST_Crosses(ST_GeomFromText('LINESTRING(0 0, 5 5)'),
ST_GeomFromText('MULTIPOINT(1 1, 2 2)')) a;
--echo # multipolygon x line (g1 is a multipolygon) -> NULL
SELECT ST_Crosses(ST_GeomFromText('MULTIPOLYGON(((0 0, 0 3, 3 3, 3 0, 0 0)))'),
ST_GeomFromText('LINESTRING(1 1, 2 2)')) a;
--echo # polygon x line, reversed order of a valid crossing case -> NULL
SELECT ST_Crosses(ST_GeomFromText('POLYGON((1 0, 1 2, 2 3, 2 1, 1 0))'),
ST_GeomFromText('LINESTRING(0 1, 3 2, 4 1)')) a;
--echo # line x same line, equal (not lower-dim intersection) -> 0
SELECT ST_Crosses(ST_GeomFromText('LINESTRING(0 0, 2 2)'),
ST_GeomFromText('LINESTRING(0 0, 2 2)')) a;
--echo #
--echo # MDEV-39449: Memory corruption (heap-buffer-overflow) in uint4korr and
--echo # Gcalc_function::count_internal, apparent partial stack looping in

View File

@@ -5641,6 +5641,15 @@ NULL
SELECT ST_GEOMFROMWKB (0x01050000000100000082040000000100000000000000000000000000000000000000) as g;
g
NULL
#
# MDEV-40552 UBSAN : load of value X, which is not a valid value for type 'wkbByteOrder' Gis_multi_point::init_from_wkb
#
SELECT ST_GEOMFROMWKB (0x0104000000010000000201000000000000000000000000000000000000000000000000) as multipoint_bad_inner_bo;
multipoint_bad_inner_bo
NULL
SELECT ST_GEOMFROMWKB (0x0104000000010000008201000000000000000000000000000000000000000000000000) as multipoint_bad_inner_bo;
multipoint_bad_inner_bo
NULL
# End of 10.11 tests
#
# Start of 11.5 tests

View File

@@ -3601,6 +3601,13 @@ SELECT ST_GEOMFROMWKB (0x01070000000100000082010000000000000000000000) as g;
SELECT ST_GEOMFROMWKB (0x01050000000100000002040000000100000000000000000000000000000000000000) as g;
SELECT ST_GEOMFROMWKB (0x01050000000100000082040000000100000000000000000000000000000000000000) as g;
--echo #
--echo # MDEV-40552 UBSAN : load of value X, which is not a valid value for type 'wkbByteOrder' Gis_multi_point::init_from_wkb
--echo #
SELECT ST_GEOMFROMWKB (0x0104000000010000000201000000000000000000000000000000000000000000000000) as multipoint_bad_inner_bo;
SELECT ST_GEOMFROMWKB (0x0104000000010000008201000000000000000000000000000000000000000000000000) as multipoint_bad_inner_bo;
--echo # End of 10.11 tests
--echo #

View File

@@ -500,6 +500,36 @@ drop user u1@localhost;
Warnings:
Note 4227 Dropped users 'u1'@'localhost' have active connections. Use KILL CONNECTION if they should not be used anymore.
drop user u2@localhost;
#
# MDEV-40541 role vs user@localhost acl_cache key confusion
#
create database db;
create table db.t1(a varchar(40));
insert into db.t1 values ('role-cache-collision-row');
create role r1;
create user r1@localhost identified by 'r1pass';
create user u1@'127.0.0.1' identified by 'u1pass';
grant select on db.* to r1@localhost;
grant r1 to u1@'127.0.0.1';
connect r1,localhost,r1,r1pass;
select a as precache from db.t1;
precache
role-cache-collision-row
connect u1,127.0.0.1,u1,u1pass;
set role r1;
show grants;
Grants for u1@127.0.0.1
GRANT `r1` TO `u1`@`127.0.0.1`
GRANT USAGE ON *.* TO `u1`@`127.0.0.1` IDENTIFIED BY PASSWORD '*4C5C0A2C80D7567C7CFBDFC09409901AADC4B390'
GRANT USAGE ON *.* TO `r1`
select a from db.t1;
ERROR 42000: SELECT command denied to user 'u1'@'localhost' for table `db`.`t1`
connection default;
disconnect r1;
disconnect u1;
drop database db;
drop role r1;
drop user r1@localhost, u1@'127.0.0.1';
# End of 10.6 tests
#
# MDEV-37256: The permission check of LOAD INDEX INTO CACHE and CACHE INDEX is broken
@@ -522,4 +552,50 @@ disconnect foo;
connection default;
drop table t1;
drop user foo@localhost;
#
# MDEV-23086 Error codes/messages reveal information about table structure
#
create database db;
create table db.t1 (a int, b int, c int);
create user foo@localhost;
grant select (a,b) on db.t1 to foo@localhost;
alter table db.t1 drop column b;
create table db.t2 (x int, y int);
grant select on db.t2 to foo@localhost;
create table t1 (k int, l int, m int);
grant select on test.t1 to foo@localhost;
connect con1,localhost,foo,,db;
select a from t1;
a
select b from t1;
ERROR 42S22: Unknown column 'b' in 'SELECT'
select c from t1;
ERROR 42000: SELECT command denied to user 'foo'@'localhost' for column 'c' in table 't1'
select d from t1;
ERROR 42000: SELECT command denied to user 'foo'@'localhost' for column 'd' in table 't1'
select a from t0;
ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table `db`.`t0`
use db2;
ERROR 42000: Access denied for user 'foo'@'localhost' to database 'db2'
select a from t2;
ERROR 42S22: Unknown column 'a' in 'SELECT'
select c from t2, t1;
ERROR 42000: SELECT command denied to user 'foo'@'localhost' for column 'c' in table 't1'
select c from t1, t2;
ERROR 42000: SELECT command denied to user 'foo'@'localhost' for column 'c' in table 't1'
select d from t2, t1;
ERROR 42000: SELECT command denied to user 'foo'@'localhost' for column 'd' in table 't1'
select d from t1, t2;
ERROR 42000: SELECT command denied to user 'foo'@'localhost' for column 'd' in table 't1'
select t2.c from t2,t1;
ERROR 42S22: Unknown column 't2.c' in 'SELECT'
select * from test.t1;
k l m
select test.t1.c from t1,test.t1;
ERROR 42S22: Unknown column 'test.t1.c' in 'SELECT'
connection default;
disconnect con1;
drop user foo@localhost;
drop database db;
drop table t1;
# End of 10.11 tests

View File

@@ -457,6 +457,37 @@ show create user u2@localhost;
drop user u1@localhost;
drop user u2@localhost;
--echo #
--echo # MDEV-40541 role vs user@localhost acl_cache key confusion
--echo #
create database db;
create table db.t1(a varchar(40));
insert into db.t1 values ('role-cache-collision-row');
create role r1;
create user r1@localhost identified by 'r1pass';
create user u1@'127.0.0.1' identified by 'u1pass';
grant select on db.* to r1@localhost;
grant r1 to u1@'127.0.0.1';
#flush privileges;
connect r1,localhost,r1,r1pass;
select a as precache from db.t1;
connect u1,127.0.0.1,u1,u1pass;
set role r1;
show grants;
--error ER_TABLEACCESS_DENIED_ERROR
select a from db.t1;
connection default;
disconnect r1;
disconnect u1;
drop database db;
drop role r1;
drop user r1@localhost, u1@'127.0.0.1';
--echo # End of 10.6 tests
--echo #
@@ -483,4 +514,45 @@ load index into cache test.t2 key (i2);
drop table t1;
drop user foo@localhost;
--echo #
--echo # MDEV-23086 Error codes/messages reveal information about table structure
--echo #
create database db;
create table db.t1 (a int, b int, c int);
create user foo@localhost;
grant select (a,b) on db.t1 to foo@localhost;
alter table db.t1 drop column b;
create table db.t2 (x int, y int);
grant select on db.t2 to foo@localhost;
create table t1 (k int, l int, m int);
grant select on test.t1 to foo@localhost;
connect con1,localhost,foo,,db;
disable_abort_on_error;
select a from t1; # can access, column exist
select b from t1; # can access, column doesn't exist
select c from t1; # no access, column exists
select d from t1; # no access, column doesn't exists
select a from t0; # no access, table doesn't exists
use db2; # no access, db doesn't exists
select a from t2; # table level grant, column doesn't exists
select c from t2, t1; # mix tbl/col grant, no access, column exist
select c from t1, t2; # mix tbl/col grant, no access, column exist
select d from t2, t1; # mix tbl/col grant, no access, column doesn't exists
select d from t1, t2; # mix tbl/col grant, no access, column doesn't exist
select t2.c from t2,t1; # mix tbl/col grant, explicit tbl, column doesn't exist
select * from test.t1; # this should work
select test.t1.c from t1,test.t1; # mix, explicit db name, column doesn't exist
enable_abort_on_error;
connection default;
disconnect con1;
drop user foo@localhost;
drop database db;
drop table t1;
--echo # End of 10.11 tests

View File

@@ -86,7 +86,7 @@ GRANT FEDERATED ADMIN ON *.* TO user1@localhost;
connect con1,localhost,user1,,;
SHOW CREATE SERVER srv;
Server Create Server
srv CREATE SERVER `srv` FOREIGN DATA WRAPPER `mysql` OPTIONS (USER 'remote_user', HOST 'localhost', PASSWORD 'secret', DATABASE 'test2');
srv CREATE SERVER `srv` FOREIGN DATA WRAPPER `mysql` OPTIONS (`USER` 'remote_user', `HOST` 'localhost', `PASSWORD` 'secret', `DATABASE` 'test2');
disconnect con1;
connection default;
DROP SERVER srv;

View File

@@ -478,3 +478,57 @@ drop table t1;
set global innodb_stats_persistent= @innodb_stats_persistent_save;
set global innodb_stats_persistent_sample_pages=
@innodb_stats_persistent_sample_pages_save;
#
# Begin 10.11 tests
#
CREATE TABLE t1 (pk INT, a INT, b INT, PRIMARY KEY (pk), KEY (a,b)) ENGINE=InnoDB;
INSERT INTO t1 (pk,a) VALUES (1,11),(2,12),(3,13),(4,14);
connect con1,localhost,root,,;
DELETE FROM t1 WHERE pk <= 3;
connection default;
INSERT INTO t1 (pk) VALUES (5);
connection con1;
START TRANSACTION;
INSERT INTO t1 (pk) VALUES (6);
connection default;
SET @save_innodb_lock_wait_timeout= @@innodb_lock_wait_timeout;
SET innodb_lock_wait_timeout= 1;
EXPLAIN SELECT MIN(b), MAX(b), a FROM t1 GROUP BY a FOR UPDATE;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range NULL a 10 NULL # Using index for group-by
SELECT MIN(b), MAX(b), a FROM t1 GROUP BY a FOR UPDATE;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
SET innodb_lock_wait_timeout= @save_innodb_lock_wait_timeout;
connection con1;
COMMIT;
DROP TABLE t1;
disconnect con1;
connection default;
CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, a INT, b INT, c INT,
KEY (a,b,c)) ENGINE=InnoDB;
INSERT INTO t1 (a,b,c) VALUES
(1,1,10),(1,1,11),(1,2,20),(1,2,21),
(2,1,10),(2,1,11),(2,2,20),(2,2,21);
INSERT INTO t1 (a,b,c) SELECT a,b,c FROM t1;
INSERT INTO t1 (a,b,c) SELECT a,b,c FROM t1;
INSERT INTO t1 (a,b,c) SELECT a,b,c FROM t1;
connect con1,localhost,root,,;
START TRANSACTION;
INSERT INTO t1 (a,b,c) VALUES (1,2,0);
connection default;
SET @save_innodb_lock_wait_timeout= @@innodb_lock_wait_timeout;
SET innodb_lock_wait_timeout= 1;
EXPLAIN SELECT MIN(c) FROM t1 WHERE b = 2 GROUP BY a FOR UPDATE;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range NULL a 15 NULL # Using where; Using index for group-by
SELECT MIN(c) FROM t1 WHERE b = 2 GROUP BY a FOR UPDATE;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
SET innodb_lock_wait_timeout= @save_innodb_lock_wait_timeout;
connection con1;
COMMIT;
DROP TABLE t1;
disconnect con1;
connection default;
#
# End 10.11 tests
#

View File

@@ -360,3 +360,93 @@ drop table t1;
set global innodb_stats_persistent= @innodb_stats_persistent_save;
set global innodb_stats_persistent_sample_pages=
@innodb_stats_persistent_sample_pages_save;
--echo #
--echo # Begin 10.11 tests
--echo #
# Default client connection to the database.
CREATE TABLE t1 (pk INT, a INT, b INT, PRIMARY KEY (pk), KEY (a,b)) ENGINE=InnoDB;
INSERT INTO t1 (pk,a) VALUES (1,11),(2,12),(3,13),(4,14);
# Start a new, separate client connection to the database called 'con1'.
--connect (con1,localhost,root,,)
--send
DELETE FROM t1 WHERE pk <= 3;
# On the default connection, insert a value into the table.
--connection default
INSERT INTO t1 (pk) VALUES (5);
# On 'con1', insert a value within a transaction and hold the transaction while
# on the default connection try to compute an aggregate.
--connection con1
--reap
START TRANSACTION;
INSERT INTO t1 (pk) VALUES (6);
--connection default
SET @save_innodb_lock_wait_timeout= @@innodb_lock_wait_timeout;
SET innodb_lock_wait_timeout= 1;
# SELECT ... FOR UPDATE locks the rows for write operations and prevents other transactions
# from modifying or reading the selected rows until the transaction ends.
# This should lead to the error, not a crash.
--replace_column 9 #
EXPLAIN SELECT MIN(b), MAX(b), a FROM t1 GROUP BY a FOR UPDATE;
--error ER_LOCK_WAIT_TIMEOUT
SELECT MIN(b), MAX(b), a FROM t1 GROUP BY a FOR UPDATE;
SET innodb_lock_wait_timeout= @save_innodb_lock_wait_timeout;
# Cleanup, commit the 'con1' transaction.
--connection con1
COMMIT;
DROP TABLE t1;
--disconnect con1
# This scenario passes with or without the patch. The query requests only a
# MIN, so the max branch never runs. The scenario is kept for coverage, to
# execute the early return, which the patch adds in the min branch for symmetry
# with the max branch and to honor the convention that no further reads follow
# a fatal handler error.
--connection default
CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, a INT, b INT, c INT,
KEY (a,b,c)) ENGINE=InnoDB;
# Two groups over key part a. Each group has rows with b=1 and rows with
# b=2, with enough rows overall that the optimizer chooses the loose
# index scan ("Using index for group-by") over a full index scan.
INSERT INTO t1 (a,b,c) VALUES
(1,1,10),(1,1,11),(1,2,20),(1,2,21),
(2,1,10),(2,1,11),(2,2,20),(2,2,21);
INSERT INTO t1 (a,b,c) SELECT a,b,c FROM t1;
INSERT INTO t1 (a,b,c) SELECT a,b,c FROM t1;
INSERT INTO t1 (a,b,c) SELECT a,b,c FROM t1;
--connect (con1,localhost,root,,)
START TRANSACTION;
# This uncommitted row becomes the first row of the a=1, b=2 prefix because its
# c is smaller than every committed c in that subgroup. The MIN read seeks
# exactly this position, so it waits for con1.
INSERT INTO t1 (a,b,c) VALUES (1,2,0);
--connection default
SET @save_innodb_lock_wait_timeout= @@innodb_lock_wait_timeout;
SET innodb_lock_wait_timeout= 1;
# The MIN read inside the loose index scan lands on the row locked by con1.
--replace_column 9 #
EXPLAIN SELECT MIN(c) FROM t1 WHERE b = 2 GROUP BY a FOR UPDATE;
--error ER_LOCK_WAIT_TIMEOUT
SELECT MIN(c) FROM t1 WHERE b = 2 GROUP BY a FOR UPDATE;
SET innodb_lock_wait_timeout= @save_innodb_lock_wait_timeout;
# Cleanup, commit the 'con1' transaction.
--connection con1
COMMIT;
DROP TABLE t1;
--disconnect con1
--connection default
--echo #
--echo # End 10.11 tests
--echo #

View File

@@ -1427,3 +1427,94 @@ a b
1 2
drop tables t1, t2, t3;
set sql_mode= default;
#
# MDEV-38722 server crash hp_rec_key_cmp
#
# original reproducer (used to crash), returns a single row
SELECT 1 INTERSECT SELECT 1 UNION ALL SELECT 1 EXCEPT ALL SELECT 1;
1
1
CREATE TABLE t1 (i INT);
INSERT INTO t1 VALUES (1),(1),(2),(3);
CREATE TABLE t2 (i INT);
INSERT INTO t2 VALUES (1),(2),(2);
CREATE TABLE t3 (i INT);
INSERT INTO t3 VALUES (1),(3);
SELECT i FROM t1 INTERSECT SELECT i FROM t3
UNION ALL SELECT i FROM t2 EXCEPT ALL SELECT i FROM t3 ORDER BY i;
i
1
2
2
(((SELECT i FROM t1) INTERSECT (SELECT i FROM t3)) UNION ALL (SELECT i FROM t2))
EXCEPT ALL (SELECT i FROM t3) ORDER BY i;
i
1
2
2
# trailing UNION ALL after the EXCEPT ALL
SELECT i FROM t1 INTERSECT SELECT i FROM t2 UNION ALL SELECT i FROM t2
EXCEPT ALL SELECT i FROM t3 UNION ALL SELECT i FROM t1 ORDER BY i;
i
1
1
1
2
2
2
2
3
((((SELECT i FROM t1) INTERSECT (SELECT i FROM t2)) UNION ALL (SELECT i FROM t2))
EXCEPT ALL (SELECT i FROM t3)) UNION ALL (SELECT i FROM t1) ORDER BY i;
i
1
1
1
2
2
2
2
3
# a leading INTERSECT ALL keeps the operation extended while the last
# INTERSECT DISTINCT node is the index-release point
SELECT i FROM t1 INTERSECT ALL SELECT i FROM t2 INTERSECT SELECT i FROM t3
UNION ALL SELECT i FROM t2 ORDER BY i;
i
1
1
2
2
(((SELECT i FROM t1) INTERSECT ALL (SELECT i FROM t2)) INTERSECT (SELECT i FROM t3))
UNION ALL (SELECT i FROM t2) ORDER BY i;
i
1
1
2
2
DROP TABLE t1,t2,t3;
# End of 10.6 tests
#
# MDEV-38722 fix merge problem with view/derived
#
CREATE TABLE t1 (i INT);
INSERT INTO t1 VALUES (1),(1),(2),(3);
CREATE TABLE t2 (i INT);
INSERT INTO t2 VALUES (1),(2),(2);
CREATE TABLE t3 (i INT);
INSERT INTO t3 VALUES (1),(3);
SELECT * FROM (SELECT i FROM t1 INTERSECT SELECT i FROM t3
UNION ALL SELECT i FROM t2 EXCEPT ALL SELECT i FROM t3) d ORDER BY i;
i
1
2
2
CREATE VIEW v1 AS SELECT i FROM t1 INTERSECT SELECT i FROM t3
UNION ALL SELECT i FROM t2 EXCEPT ALL SELECT i FROM t3;
SELECT * FROM v1 ORDER BY i;
i
1
2
2
DROP VIEW v1;
DROP TABLE t1,t2,t3;
# End of 11.4 tests

View File

@@ -499,3 +499,53 @@ select * from t1 except all select * from t2 intersect all select * from t1 unio
select * from t1 except all select * from t2 intersect all select * from t1 union all select * from t2 order by a desc limit 3;
drop tables t1, t2, t3;
set sql_mode= default;
--echo #
--echo # MDEV-38722 server crash hp_rec_key_cmp
--echo #
--echo # original reproducer (used to crash), returns a single row
SELECT 1 INTERSECT SELECT 1 UNION ALL SELECT 1 EXCEPT ALL SELECT 1;
CREATE TABLE t1 (i INT);
INSERT INTO t1 VALUES (1),(1),(2),(3);
CREATE TABLE t2 (i INT);
INSERT INTO t2 VALUES (1),(2),(2);
CREATE TABLE t3 (i INT);
INSERT INTO t3 VALUES (1),(3);
SELECT i FROM t1 INTERSECT SELECT i FROM t3
UNION ALL SELECT i FROM t2 EXCEPT ALL SELECT i FROM t3 ORDER BY i;
(((SELECT i FROM t1) INTERSECT (SELECT i FROM t3)) UNION ALL (SELECT i FROM t2))
EXCEPT ALL (SELECT i FROM t3) ORDER BY i;
--echo # trailing UNION ALL after the EXCEPT ALL
SELECT i FROM t1 INTERSECT SELECT i FROM t2 UNION ALL SELECT i FROM t2
EXCEPT ALL SELECT i FROM t3 UNION ALL SELECT i FROM t1 ORDER BY i;
((((SELECT i FROM t1) INTERSECT (SELECT i FROM t2)) UNION ALL (SELECT i FROM t2))
EXCEPT ALL (SELECT i FROM t3)) UNION ALL (SELECT i FROM t1) ORDER BY i;
--echo # a leading INTERSECT ALL keeps the operation extended while the last
--echo # INTERSECT DISTINCT node is the index-release point
SELECT i FROM t1 INTERSECT ALL SELECT i FROM t2 INTERSECT SELECT i FROM t3
UNION ALL SELECT i FROM t2 ORDER BY i;
(((SELECT i FROM t1) INTERSECT ALL (SELECT i FROM t2)) INTERSECT (SELECT i FROM t3))
UNION ALL (SELECT i FROM t2) ORDER BY i;
DROP TABLE t1,t2,t3;
--echo # End of 10.6 tests
--echo #
--echo # MDEV-38722 fix merge problem with view/derived
--echo #
CREATE TABLE t1 (i INT);
INSERT INTO t1 VALUES (1),(1),(2),(3);
CREATE TABLE t2 (i INT);
INSERT INTO t2 VALUES (1),(2),(2);
CREATE TABLE t3 (i INT);
INSERT INTO t3 VALUES (1),(3);
SELECT * FROM (SELECT i FROM t1 INTERSECT SELECT i FROM t3
UNION ALL SELECT i FROM t2 EXCEPT ALL SELECT i FROM t3) d ORDER BY i;
CREATE VIEW v1 AS SELECT i FROM t1 INTERSECT SELECT i FROM t3
UNION ALL SELECT i FROM t2 EXCEPT ALL SELECT i FROM t3;
SELECT * FROM v1 ORDER BY i;
DROP VIEW v1;
DROP TABLE t1,t2,t3;
--echo # End of 11.4 tests

View File

@@ -39,7 +39,7 @@ a
2
3
select invisible,a from t1;
ERROR 42S22: Unknown column 'invisible' in 'SELECT'
ERROR 42000: SELECT command denied to user 'user_1'@'localhost' for column 'invisible' in table 't1'
delete from t1 where a =1;
update t1 set a=1 where a=3;
select * from t1;

View File

@@ -29,7 +29,7 @@ insert into t1 values(2);
select * from t1;
insert into t1(a) values(3);
select * from t1;
--error ER_BAD_FIELD_ERROR
--error ER_COLUMNACCESS_DENIED_ERROR
select invisible,a from t1;
delete from t1 where a =1;
update t1 set a=1 where a=3;

View File

@@ -1 +1 @@
--skip-name-resolve
--skip-name-resolve --bind-address=::1,127.0.0.1

View File

@@ -39,6 +39,83 @@ disconnect a;
disconnect b;
drop user a@'127.0.0.1';
drop user b@'127.0.0.1';
#
# End of 10.3 tests
#
# MDEV-40554 KILL checks user (not priv_user) and doesn't verify hostname
#
create user u1@'::1' identified by 'pw1';
create user ''@'127.0.0.1';
connect u1_ipv6,::1,u1,pw1;
select current_user();
current_user()
u1@::1
# the reported case: same login name, but an anonymous account
connect u1_anon,127.0.0.1,u1,;
select user(), current_user();
user() current_user()
u1@127.0.0.1 @127.0.0.1
# anonymous users don't see the process list at all
show processlist;
ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
select count(*) as `threads visible` from information_schema.processlist;
threads visible
1
select count(*) as `u1@'::1' visible`
from information_schema.processlist where id=$cid_sock;
u1@'::1' visible
0
kill $cid_sock;
ERROR HY000: You are not owner of thread CID
show explain for $cid_sock;
ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
kill user u1@'::1';
connection u1_ipv6;
select user(), current_user();
user() current_user()
u1@::1 u1@::1
connection u1_anon;
connection default;
disconnect u1_anon;
drop user ''@'127.0.0.1';
# same login name, a real account, but a different host
create user u1@'127.0.0.1' identified by 'pw2';
connect u1_ipv4,127.0.0.1,u1,pw2;
select current_user();
current_user()
u1@127.0.0.1
# u1@127.0.0.1 must not see u1@'::1' - same user name, other account
show processlist;
Id User Host db Command Time State Info Progress
# u1 # # Query # # # #
select count(*) as `u1@'::1' visible`
from information_schema.processlist where id=$cid_sock;
u1@'::1' visible
0
kill $cid_sock;
ERROR HY000: You are not owner of thread CID
show explain for $cid_sock;
ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
kill user u1@'::1';
connection u1_ipv6;
select user(), current_user();
user() current_user()
u1@::1 u1@::1
connection u1_ipv4;
# but another u1@127.0.0.1 connection is the same account, so it may
connect u1_tcp2,127.0.0.1,u1,pw2;
select count(*) as `u1@127.0.0.1 visible`
from information_schema.processlist where id=$cid_tcp;
u1@127.0.0.1 visible
1
kill $cid_tcp;
# u1@'::1' was not killed
connection u1_ipv6;
select 1;
1
1
connection default;
disconnect u1_ipv6;
disconnect u1_tcp2;
drop user u1@'::1';
drop user u1@'127.0.0.1';
# End of 10.11 tests

View File

@@ -6,7 +6,9 @@
# connection does not read() from a socket, but returns control to the
# application. 'mysqltest' does not handle the kill request.
#
-- source include/not_embedded.inc
--source include/not_embedded.inc
--source include/count_sessions.inc
--source include/check_ipv6.inc
--echo #
--echo # MDEV-6896 kill user command cause MariaDB crash!
@@ -55,6 +57,87 @@ kill user b;
drop user a@'127.0.0.1';
drop user b@'127.0.0.1';
--echo #
--echo # End of 10.3 tests
--echo #
--echo # MDEV-40554 KILL checks user (not priv_user) and doesn't verify hostname
--echo #
create user u1@'::1' identified by 'pw1';
create user ''@'127.0.0.1';
connect u1_ipv6,::1,u1,pw1;
select current_user();
let $cid_sock=`select connection_id()`;
--echo # the reported case: same login name, but an anonymous account
connect u1_anon,127.0.0.1,u1,;
select user(), current_user();
--echo # anonymous users don't see the process list at all
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
show processlist;
select count(*) as `threads visible` from information_schema.processlist;
evalp select count(*) as `u1@'::1' visible`
from information_schema.processlist where id=$cid_sock;
--replace_regex /thread [0-9]+/thread CID/
--error ER_KILL_DENIED_ERROR
evalp kill $cid_sock;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
evalp show explain for $cid_sock;
# killing a non-matching user doesn't report an error to not disclose
# that the user exists. but doesn't kill either
kill user u1@'::1';
connection u1_ipv6;
select user(), current_user();
connection u1_anon;
connection default;
disconnect u1_anon;
drop user ''@'127.0.0.1';
--echo # same login name, a real account, but a different host
create user u1@'127.0.0.1' identified by 'pw2';
connect u1_ipv4,127.0.0.1,u1,pw2;
select current_user();
let $cid_tcp=`select connection_id()`;
--echo # u1@127.0.0.1 must not see u1@'::1' - same user name, other account
--replace_result Execute Query
--replace_column 1 # 3 # 4 # 6 # 7 # 8 # 9 #
show processlist;
evalp select count(*) as `u1@'::1' visible`
from information_schema.processlist where id=$cid_sock;
--replace_regex /thread [0-9]+/thread CID/
--error ER_KILL_DENIED_ERROR
evalp kill $cid_sock;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
evalp show explain for $cid_sock;
# doesn't report an error, doesn't kill
kill user u1@'::1';
connection u1_ipv6;
select user(), current_user();
connection u1_ipv4;
--echo # but another u1@127.0.0.1 connection is the same account, so it may
connect u1_tcp2,127.0.0.1,u1,pw2;
evalp select count(*) as `u1@127.0.0.1 visible`
from information_schema.processlist where id=$cid_tcp;
evalp kill $cid_tcp;
--echo # u1@'::1' was not killed
connection u1_ipv6;
select 1;
connection default;
disconnect u1_ipv6;
#u1_ipv4 was killed, must not be disconnected
disconnect u1_tcp2;
--source include/wait_until_count_sessions.inc
drop user u1@'::1';
drop user u1@'127.0.0.1';
--echo # End of 10.11 tests

View File

@@ -172,4 +172,15 @@ id f
1 foo
2 foo
drop table t1;
#
# MDEV-39846 UNIQUE BLOB contains duplicate records after ALTER IGNORE with READ COMMITTED
#
create table t1 (pk int primary key, b blob) engine=innodb;
insert into t1 values (1,'foo'),(2,'foo');
set transaction isolation level read committed;
alter ignore table t1 add unique (b);
select * from t1;
pk b
1 foo
drop table t1;
# End of 10.6 tests

View File

@@ -177,4 +177,14 @@ update ignore t1 set id = 2;
select * from t1;
drop table t1;
--echo #
--echo # MDEV-39846 UNIQUE BLOB contains duplicate records after ALTER IGNORE with READ COMMITTED
--echo #
create table t1 (pk int primary key, b blob) engine=innodb;
insert into t1 values (1,'foo'),(2,'foo');
set transaction isolation level read committed;
alter ignore table t1 add unique (b);
select * from t1;
drop table t1;
--echo # End of 10.6 tests

View File

@@ -103,6 +103,18 @@ drop table t3|
# MDEV-40409 ST_GeomFromText stack overrun on deeply nested GeometryCollection
#
SELECT ST_GeomFromText(CONCAT(REPEAT('GEOMETRYCOLLECTION(',5000),'POINT(1 1)',REPEAT(')',5000)));
#
# MDEV-40540 ST_GeomFromWKB stack overrun on deeply nested GeometryCollection
#
set @a=concat(0x0107000000, repeat(0x010000000107000000, 120000), 0x00000000);
SELECT ST_GeomFromWKB(@a);
#
# MDEV-39750 ExtractValue does not control recursion depth.
#
SELECT ExtractValue('<a/>', REPEAT('(', 100000));
ERROR HY000: Thread stack overrun: 'used bytes' used of a 'available' byte stack, and 'X' bytes needed. Consider increasing the thread_stack system variable.
SELECT ExtractValue('<a/>', REPEAT('/n', 100000));
ERROR HY000: Thread stack overrun: 'used bytes' used of a 'available' byte stack, and 'X' bytes needed. Consider increasing the thread_stack system variable.
# End of 10.6 tests
#
# MDEV-39813 ST_GeomFromGeoJSON does not control recursion depth

View File

@@ -147,6 +147,26 @@ delimiter ;|
SELECT ST_GeomFromText(CONCAT(REPEAT('GEOMETRYCOLLECTION(',5000),'POINT(1 1)',REPEAT(')',5000)));
--enable_result_log
--echo #
--echo # MDEV-40540 ST_GeomFromWKB stack overrun on deeply nested GeometryCollection
--echo #
set @a=concat(0x0107000000, repeat(0x010000000107000000, 120000), 0x00000000);
--disable_result_log
--error ER_STACK_OVERRUN_NEED_MORE
SELECT ST_GeomFromWKB(@a);
--enable_result_log
--echo #
--echo # MDEV-39750 ExtractValue does not control recursion depth.
--echo #
--replace_regex /overrun: [0-9]* bytes used of a [0-9]* byte stack, and [0-9]* bytes needed/overrun: 'used bytes' used of a 'available' byte stack, and 'X' bytes needed/
--error ER_STACK_OVERRUN_NEED_MORE
SELECT ExtractValue('<a/>', REPEAT('(', 100000));
--replace_regex /overrun: [0-9]* bytes used of a [0-9]* byte stack, and [0-9]* bytes needed/overrun: 'used bytes' used of a 'available' byte stack, and 'X' bytes needed/
--error ER_STACK_OVERRUN_NEED_MORE
SELECT ExtractValue('<a/>', REPEAT('/n', 100000));
--echo # End of 10.6 tests

View File

@@ -0,0 +1,8 @@
#
# MDEV-37000 Deleting a row from Aria table results to 'Index is corrupt'
#
CREATE OR REPLACE TABLE t (a INT, b CHAR(8) NOT NULL, KEY(b)) ENGINE=Aria DEFAULT CHARSET=utf8;
INSERT INTO t VALUES (1,'20070101'), (2,'20070101');
DELETE FROM t LIMIT 2;
DROP TABLE t;
# End of 10.6 tests

View File

@@ -0,0 +1,9 @@
--echo #
--echo # MDEV-37000 Deleting a row from Aria table results to 'Index is corrupt'
--echo #
CREATE OR REPLACE TABLE t (a INT, b CHAR(8) NOT NULL, KEY(b)) ENGINE=Aria DEFAULT CHARSET=utf8;
INSERT INTO t VALUES (1,'20070101'), (2,'20070101');
DELETE FROM t LIMIT 2;
DROP TABLE t;
--echo # End of 10.6 tests

View File

@@ -245,6 +245,14 @@ DECLARE a mysql_json;
END;
$$
ERROR HY000: 'MYSQL_JSON' is not allowed in this context
#
# End of 10.5 tests
#
# MDEV-40678 mysql_json plugin OOB reads
#
alter table t1 force;
ERROR HY000: Error parsing MySQL JSON format, please dump this table from MySQL and then restore it to be able to use it in MariaDB.
flush tables;
alter table t1 force;
ERROR HY000: Error parsing MySQL JSON format, please dump this table from MySQL and then restore it to be able to use it in MariaDB.
drop table t1;
# End of 10.6 tests

View File

@@ -17,7 +17,7 @@ call mtr.add_suppression("Table rebuild required");
call mtr.add_suppression("is marked as crashed");
call mtr.add_suppression("Checking");
let $MYSQLD_DATADIR= `select @@datadir`;
let MYSQLD_DATADIR= `select @@datadir`;
SET NAMES utf8;
@@ -161,6 +161,40 @@ END;
$$
DELIMITER ;$$
--echo #
--echo # End of 10.5 tests
--echo #
--echo # MDEV-40678 mysql_json plugin OOB reads
--echo #
--copy_file std_data/mysql_json/mysql_json_test.frm $MYSQLD_DATADIR/test/t1.frm
--copy_file std_data/mysql_json/mysql_json_test.MYI $MYSQLD_DATADIR/test/t1.MYI
--copy_file std_data/mysql_json/mysql_json_test.MYD $MYSQLD_DATADIR/test/t1.MYD
perl;
my $f="$ENV{MYSQLD_DATADIR}/test/t1.MYD";
open F, '+<', $f or die "open($f): $!";
sysseek F, 0x3c5, 0 or die "sysseek: $!";
syswrite F, '(' or die "syswrite: $!";
EOF
--error ER_UNKNOWN_ERROR
alter table t1 force;
flush tables;
--remove_file $MYSQLD_DATADIR/test/t1.MYD
--copy_file std_data/mysql_json/mysql_json_test.MYD $MYSQLD_DATADIR/test/t1.MYD
perl;
my $f="$ENV{MYSQLD_DATADIR}/test/t1.MYD";
open F, '+<', $f or die "open($f): $!";
sysseek F, 0x3bc, 0 or die "sysseek: $!";
syswrite F, '(' or die "syswrite: $!";
EOF
--error ER_UNKNOWN_ERROR
alter table t1 force;
drop table t1;
--echo # End of 10.6 tests

View File

@@ -16,7 +16,17 @@
--net-buffer-length=#
Buffer length for TCP/IP and socket communication
--net-read-timeout=#
@@ -1568,6 +1570,10 @@
@@ -1399,8 +1401,7 @@
(Defaults to on; use --skip-secure-auth to disable.)
--secure-file-priv=name
Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to
- files within specified directory. Empty value means no
- limits except /proc
+ files within specified directory
--secure-timestamp=name
Restricts direct setting of a session timestamp. Possible
levels are: YES - timestamp cannot deviate from the
@@ -1569,6 +1570,10 @@
Alias for log_slow_query_file. Log slow queries to given
log file. Defaults logging to 'hostname'-slow.log. Must
be enabled to activate other slow log options
@@ -27,7 +37,7 @@
--socket=name Socket file to use for connection
--sort-buffer-size=#
Each thread that needs to do a sort allocates a buffer of
@@ -1587,6 +1593,7 @@
@@ -1588,6 +1593,7 @@
aborted. Prevents the common mistake of accidentally
deleting or updating every row in a table
--stack-trace Print a symbolic stack trace on failure
@@ -35,7 +45,7 @@
--standard-compliant-cte
Allow only CTEs compliant to SQL standard
(Defaults to on; use --skip-standard-compliant-cte to disable.)
@@ -1666,6 +1673,12 @@
@@ -1667,6 +1673,12 @@
--thread-pool-max-threads=#
Maximum allowed number of worker threads in the thread
pool
@@ -48,7 +58,7 @@
--thread-pool-oversubscribe=#
How many additional active worker threads in a group are
allowed
@@ -1707,8 +1720,8 @@
@@ -1708,8 +1720,8 @@
background for binlogging by user threads are placed in a
separate location (see `binlog_large_commit_threshold`
option). Several paths may be specified, separated by a
@@ -59,7 +69,7 @@
--transaction-alloc-block-size=#
Allocation block size for transactions to be stored in
binary log
@@ -1958,6 +1971,7 @@
@@ -1959,6 +1971,7 @@
myisam-stats-method NULLS_UNEQUAL
myisam-use-mmap FALSE
mysql56-temporal-format TRUE
@@ -67,7 +77,7 @@
net-buffer-length 16384
net-read-timeout 30
net-retry-count 10
@@ -2137,6 +2151,7 @@
@@ -2138,6 +2151,7 @@
slave-type-conversions
slow-launch-time 2
slow-query-log FALSE
@@ -75,7 +85,7 @@
sort-buffer-size 2097152
sql-mode STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
sql-safe-updates FALSE
@@ -2163,6 +2178,8 @@
@@ -2164,6 +2178,8 @@
thread-pool-exact-stats FALSE
thread-pool-idle-timeout 60
thread-pool-max-threads 65536

View File

@@ -1399,7 +1399,8 @@ The following specify which files/extra groups are read (specified before remain
(Defaults to on; use --skip-secure-auth to disable.)
--secure-file-priv=name
Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to
files within specified directory
files within specified directory. Empty value means no
limits except /proc
--secure-timestamp=name
Restricts direct setting of a session timestamp. Possible
levels are: YES - timestamp cannot deviate from the

View File

@@ -6,7 +6,7 @@
mysql.time_zone_transition 3719776009
-mysql.plugin 1587119305
+mysql.plugin 2184891911
mysql.servers 1109359608
mysql.servers 3351805004
-mysql.func 2140302938
+mysql.func 2154697260
mysql.innodb_table_stats 1972297402
@@ -18,7 +18,7 @@
mysql.time_zone_transition 3719776009
-mysql.plugin 1587119305
+mysql.plugin 2184891911
mysql.servers 1109359608
mysql.servers 3351805004
-mysql.func 2140302938
+mysql.func 2154697260
mysql.innodb_table_stats 1972297402

View File

@@ -40,6 +40,7 @@ CREATE SERVER s1 FOREIGN DATA WRAPPER mysql
OPTIONS (HOST 'localhost', DATABASE 'd''b', USER 'o''brien', PASSWORD 'pw''d');
CREATE SERVER `s'2` FOREIGN DATA WRAPPER 'my''sql'
OPTIONS (HOST 'h2', DATABASE 'db2', USER 'u2');
create server `s``3` foreign data wrapper mysql options (host 'value');
CREATE FUNCTION metaphon RETURNS STRING SONAME "UDF_EXAMPLE_LIB";
CREATE AGGREGATE FUNCTION avgcost RETURNS REAL SONAME "UDF_EXAMPLE_LIB";
#
@@ -95,8 +96,9 @@ DROP ROLE mariadb_dump_import_role;
/*M!100203 EXECUTE IMMEDIATE CONCAT('SET ROLE ', @current_role) */;
CREATE FUNCTION `metaphon` RETURNS STRING SONAME 'UDF_EXAMPLE_LIB';
CREATE AGGREGATE FUNCTION `avgcost` RETURNS REAL SONAME 'UDF_EXAMPLE_LIB';
CREATE SERVER `s'2` FOREIGN DATA WRAPPER `my'sql` OPTIONS (HOST 'h2', DATABASE 'db2', USER 'u2');
CREATE SERVER `s1` FOREIGN DATA WRAPPER `mysql` OPTIONS (HOST 'localhost', DATABASE 'd''b', USER 'o''brien', PASSWORD 'pw''d');
CREATE SERVER `s'2` FOREIGN DATA WRAPPER `my'sql` OPTIONS (`HOST` 'h2', `DATABASE` 'db2', `USER` 'u2');
CREATE SERVER `s1` FOREIGN DATA WRAPPER `mysql` OPTIONS (`HOST` 'localhost', `DATABASE` 'd''b', `USER` 'o''brien', `PASSWORD` 'pw''d');
CREATE SERVER `s``3` FOREIGN DATA WRAPPER `mysql` OPTIONS (`host` 'value');
USE mysql;
@@ -718,8 +720,9 @@ DROP ROLE mariadb_dump_import_role;
CREATE /*M!100103 OR REPLACE */ FUNCTION `metaphon` RETURNS STRING SONAME 'UDF_EXAMPLE_LIB';
/*!50701 DROP FUNCTION IF EXISTS `avgcost` */;
CREATE /*M!100103 OR REPLACE */ AGGREGATE FUNCTION `avgcost` RETURNS REAL SONAME 'UDF_EXAMPLE_LIB';
CREATE /*M!100103 OR REPLACE */ SERVER `s'2` FOREIGN DATA WRAPPER `my'sql` OPTIONS (HOST 'h2', DATABASE 'db2', USER 'u2');
CREATE /*M!100103 OR REPLACE */ SERVER `s1` FOREIGN DATA WRAPPER `mysql` OPTIONS (HOST 'localhost', DATABASE 'd''b', USER 'o''brien', PASSWORD 'pw''d');
CREATE /*M!100103 OR REPLACE */ SERVER `s'2` FOREIGN DATA WRAPPER `my'sql` OPTIONS (`HOST` 'h2', `DATABASE` 'db2', `USER` 'u2');
CREATE /*M!100103 OR REPLACE */ SERVER `s1` FOREIGN DATA WRAPPER `mysql` OPTIONS (`HOST` 'localhost', `DATABASE` 'd''b', `USER` 'o''brien', `PASSWORD` 'pw''d');
CREATE /*M!100103 OR REPLACE */ SERVER `s``3` FOREIGN DATA WRAPPER `mysql` OPTIONS (`host` 'value');
USE mysql;
@@ -1317,8 +1320,9 @@ DROP ROLE mariadb_dump_import_role;
/*M!100203 EXECUTE IMMEDIATE CONCAT('SET ROLE ', @current_role) */;
CREATE FUNCTION IF NOT EXISTS `metaphon` RETURNS STRING SONAME 'UDF_EXAMPLE_LIB';
CREATE AGGREGATE FUNCTION IF NOT EXISTS `avgcost` RETURNS REAL SONAME 'UDF_EXAMPLE_LIB';
CREATE SERVER /*M!100103 IF NOT EXISTS */ `s'2` FOREIGN DATA WRAPPER `my'sql` OPTIONS (HOST 'h2', DATABASE 'db2', USER 'u2');
CREATE SERVER /*M!100103 IF NOT EXISTS */ `s1` FOREIGN DATA WRAPPER `mysql` OPTIONS (HOST 'localhost', DATABASE 'd''b', USER 'o''brien', PASSWORD 'pw''d');
CREATE SERVER /*M!100103 IF NOT EXISTS */ `s'2` FOREIGN DATA WRAPPER `my'sql` OPTIONS (`HOST` 'h2', `DATABASE` 'db2', `USER` 'u2');
CREATE SERVER /*M!100103 IF NOT EXISTS */ `s1` FOREIGN DATA WRAPPER `mysql` OPTIONS (`HOST` 'localhost', `DATABASE` 'd''b', `USER` 'o''brien', `PASSWORD` 'pw''d');
CREATE SERVER /*M!100103 IF NOT EXISTS */ `s``3` FOREIGN DATA WRAPPER `mysql` OPTIONS (`host` 'value');
USE mysql;
@@ -1876,7 +1880,7 @@ Table Checksum
mysql.roles_mapping 2510045525
mysql.time_zone_transition 3719776009
mysql.plugin 1587119305
mysql.servers 1109359608
mysql.servers 3351805004
mysql.func 2140302938
mysql.innodb_table_stats 1972297402
mysql.table_stats 1911089388
@@ -1897,6 +1901,7 @@ DROP FUNCTION IF EXISTS metaphon;
DROP FUNCTION IF EXISTS avgcost;
DROP SERVER s1;
DROP SERVER `s'2`;
DROP SERVER `s``3`;
set time_zone= @@global.time_zone;
# Restore from mysqldump
DROP USER mariadb_test_restore;
@@ -1913,7 +1918,7 @@ Table Checksum
mysql.roles_mapping 2510045525
mysql.time_zone_transition 3719776009
mysql.plugin 1587119305
mysql.servers 1109359608
mysql.servers 3351805004
mysql.func 2140302938
mysql.innodb_table_stats 1972297402
mysql.table_stats 1911089388
@@ -1921,6 +1926,7 @@ DROP FUNCTION IF EXISTS metaphon;
DROP FUNCTION IF EXISTS avgcost;
DROP SERVER s1;
DROP SERVER `s'2`;
DROP SERVER `s``3`;
DELETE FROM mysql.column_stats WHERE db_name='mysql';
DELETE FROM mysql.index_stats WHERE db_name='mysql';
DELETE FROM mysql.table_stats WHERE db_name='mysql';

View File

@@ -62,6 +62,7 @@ CREATE SERVER s1 FOREIGN DATA WRAPPER mysql
OPTIONS (HOST 'localhost', DATABASE 'd''b', USER 'o''brien', PASSWORD 'pw''d');
CREATE SERVER `s'2` FOREIGN DATA WRAPPER 'my''sql'
OPTIONS (HOST 'h2', DATABASE 'db2', USER 'u2');
create server `s``3` foreign data wrapper mysql options (host 'value');
--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB
eval CREATE FUNCTION metaphon RETURNS STRING SONAME "$UDF_EXAMPLE_SO";
@@ -131,6 +132,7 @@ DROP FUNCTION IF EXISTS metaphon;
DROP FUNCTION IF EXISTS avgcost;
DROP SERVER s1;
DROP SERVER `s'2`;
DROP SERVER `s``3`;
set time_zone= @@global.time_zone;
--echo # Restore from mysqldump
@@ -157,6 +159,7 @@ DROP FUNCTION IF EXISTS avgcost;
DROP SERVER s1;
DROP SERVER `s'2`;
DROP SERVER `s``3`;
# EITS && innodb stats
DELETE FROM mysql.column_stats WHERE db_name='mysql';

View File

@@ -6974,25 +6974,25 @@ mariadb-dump: Couldn't execute 'SHOW CREATE FUNCTION `f1`': Undeclared variable:
COMMIT;
SET AUTOCOMMIT=@OLD_AUTOCOMMIT;
/*!50106 SET @save_time_zone= @@TIME_ZONE */ ;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
/*!50003 SET character_set_client = utf8mb3 */ ;
/*!50003 SET character_set_results = utf8mb3 */ ;
/*!50003 SET collation_connection = utf8mb3_uca1400_ai_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = '' */ ;
/*!50003 SET @saved_time_zone = @@time_zone */ ;
/*!50003 SET time_zone = 'SYSTEM' */ ;
DELIMITER ;;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;;
/*!50003 SET character_set_client = utf8mb3 */ ;;
/*!50003 SET character_set_results = utf8mb3 */ ;;
/*!50003 SET collation_connection = utf8mb3_uca1400_ai_ci */ ;;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;;
/*!50003 SET sql_mode = '' */ ;;
/*!50003 SET @saved_time_zone = @@time_zone */ ;;
/*!50003 SET time_zone = 'SYSTEM' */ ;;
/*!50106 CREATE*/ /*!50117 DEFINER=`root`@`localhost`*/ /*!50106 EVENT `e1` ON SCHEDULE EVERY 1 YEAR STARTS '2030-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO select not_a_value
*/ ;;
/*!50003 SET time_zone = @saved_time_zone */ ;;
/*!50003 SET sql_mode = @saved_sql_mode */ ;;
/*!50003 SET character_set_client = @saved_cs_client */ ;;
/*!50003 SET character_set_results = @saved_cs_results */ ;;
/*!50003 SET collation_connection = @saved_col_connection */ ;;
DELIMITER ;
/*!50003 SET time_zone = @saved_time_zone */ ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
/*!50106 SET TIME_ZONE= @save_time_zone */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = '' */ ;

View File

@@ -3221,7 +3221,7 @@ drop table db2.t1;
--exec $MYSQL db1 < $MYSQLTEST_VARDIR/tmp/dump/db1/t1.sql
--exec $MYSQL db2 < $MYSQLTEST_VARDIR/tmp/dump/db2/t1.sql
--exec $MYSQL_IMPORT --silent db1 $MYSQLTEST_VARDIR/tmp/dump/db1/t1.txt
--exec $MYSQL_IMPORT --silent db2 $MYSQLTEST_VARDIR/tmp/dump/db2/t1.txt
--exec $MYSQL_IMPORT --lock-tables --silent db2 $MYSQLTEST_VARDIR/tmp/dump/db2/t1.txt
select * from db1.t1;
select * from db2.t1;
drop database db1;

View File

@@ -1031,6 +1031,12 @@ the false block has written nothing
mysqltest: At line 1: End of file encountered before 'eval' delimiter was found
# Only 'eval' is allowed as the third argument
mysqltest: At line 1: Invalid argument 'junk' to 'write_file', only 'eval' is allowed
#
# \0 in a query
#
select hex("12");
hex("1\x002")
310032
# End of 10.6 tests
#
# MDEV-29344: engines/iuds.insert_time cannot run with PS protocol (syntax error)

View File

@@ -3057,6 +3057,11 @@ EOF
--error 1
--exec echo "--write_file $file EOF junk" | $MYSQL_TEST 2>&1
--echo #
--echo # \0 in a query
--echo #
select hex("12");
--echo # End of 10.6 tests
--echo #
@@ -3080,12 +3085,11 @@ SELECT 1 /* doesn't throw error */;
--rmdir $srcdir
--echo # End of 10.11 tests
# Wait till we reached the initial number of concurrent sessions
--source include/wait_until_count_sessions.inc
--disable_query_log
--eval SET GLOBAL max_connections = $saved_max_connections
--enable_query_log
--echo # End of 10.11 tests

View File

@@ -505,4 +505,11 @@ mysqltest: At line 1: Evaluation error: Modulo by zero
# Test case: Overflow
mysqltest: At line 1: Range error: 18446744073709551616 value out of range for Integer type
mysqltest: At line 1: Range error: 18446744073709551616 value out of range for Integer type
#
# MDEV-37865: IF() function is returning incorrect error
#
# Test case: unknown function name that is a prefix of a known one
mysqltest: At line 1: Syntax error: Unknown function 'if'
mysqltest: At line 1: Syntax error: Unknown function 'l'
# Expression evaluation tests completed successfully
# End of 10.6 tests

View File

@@ -894,4 +894,17 @@ let $large_xor = $(0x7FFFFFFFFFFFFFFF ^ 0x7FFFFFFFFFFFFFFE);
--error 1
--exec echo "let \$a = \$(-18446744073709551616);" | $MYSQL_TEST 2>&1
--echo #
--echo # MDEV-37865: IF() function is returning incorrect error
--echo #
--echo # Test case: unknown function name that is a prefix of a known one
--error 1
--exec echo "let \$a = \$(if(null, 'fallback', 'actual'));" | $MYSQL_TEST 2>&1
--error 1
--exec echo "let \$a = \$(l('AB'));" | $MYSQL_TEST 2>&1
--echo # Expression evaluation tests completed successfully
--echo # End of 10.6 tests

View File

@@ -1116,4 +1116,11 @@ insert(upper('hello world'), 7, 5, lower('MARIADB')) -> HELLO mariadb
concat_ws(' ', upper('hello'), lower('WORLD')) -> HELLO world
ifnull(nullif('same', 'same'), 'default') -> default
coalesce(nullif('test', 'test'), 'backup') -> backup
#
# MDEV-37859: Mysqltest hex() not working for string values
#
hex("abc") -> 616263
hex("255") -> 323535
hex('') ->
# Expression evaluation string functions tests completed successfully
# End of 10.6 tests

View File

@@ -2128,4 +2128,19 @@ let $result5 = $(ifnull(nullif('same', 'same'), 'default'));
let $result6 = $(coalesce(nullif('test', 'test'), 'backup'));
--echo coalesce(nullif('test', 'test'), 'backup') -> $result6
--echo #
--echo # MDEV-37859: Mysqltest hex() not working for string values
--echo #
let $hex_str1 = $(hex("abc"));
--echo hex("abc") -> $hex_str1
let $hex_str2 = $(hex("255"));
--echo hex("255") -> $hex_str2
let $hex_str3 = $(hex(''));
--echo hex('') -> $hex_str3
--echo # Expression evaluation string functions tests completed successfully
--echo # End of 10.6 tests

View File

@@ -480,3 +480,48 @@ drop procedure if exists p1;
drop function if exists f1;
drop view if exists t1;
drop schema if exists mysqltest;
#
# MDEV-38472 Assertion `! is_set() || m_can_overwrite_status'
# failed in Diagnostics_area::set_error_status
#
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1),(2),(3);
PREPARE stmt FROM "UPDATE t1 SET a = ? LIMIT ?";
ALTER TABLE t1 FORCE;
EXECUTE stmt USING 1, DEFAULT;
ERROR HY000: Default/ignore value is not supported for such parameter usage
DEALLOCATE PREPARE stmt;
DROP TABLE t1;
CREATE TABLE t1 (a INT, b INT);
CREATE TABLE t2 (a INT, c INT);
INSERT INTO t1 VALUES (1,1),(2,2);
INSERT INTO t2 VALUES (1,1),(2,2);
CREATE VIEW v1 AS SELECT t1.a, t1.b, t2.c FROM t1 JOIN t2 ON t1.a = t2.a;
PREPARE stmt FROM "UPDATE v1 SET b = ? LIMIT ?";
ALTER TABLE t1 FORCE;
EXECUTE stmt USING 1, DEFAULT;
ERROR HY000: Default/ignore value is not supported for such parameter usage
DEALLOCATE PREPARE stmt;
DROP VIEW v1;
DROP TABLE t1, t2;
CREATE TABLE t1 (a INT);
CREATE TABLE t3 (a INT);
INSERT INTO t3 VALUES (1),(2),(3);
PREPARE stmt FROM "INSERT INTO t1 SELECT a FROM t3 LIMIT ?";
ALTER TABLE t1 FORCE;
EXECUTE stmt USING DEFAULT;
ERROR HY000: Default/ignore value is not supported for such parameter usage
DEALLOCATE PREPARE stmt;
DROP TABLE t1, t3;
CREATE TABLE t1 (a INT PRIMARY KEY);
CREATE TABLE t3 (a INT);
INSERT INTO t3 VALUES (1),(2),(3);
PREPARE stmt FROM "REPLACE INTO t1 SELECT a FROM t3 LIMIT ?";
ALTER TABLE t1 FORCE;
EXECUTE stmt USING DEFAULT;
ERROR HY000: Default/ignore value is not supported for such parameter usage
DEALLOCATE PREPARE stmt;
DROP TABLE t1, t3;
#
# End of 10.11 tests
#

View File

@@ -398,3 +398,54 @@ drop function if exists f1;
drop view if exists t1;
drop schema if exists mysqltest;
--enable_warnings
--echo #
--echo # MDEV-38472 Assertion `! is_set() || m_can_overwrite_status'
--echo # failed in Diagnostics_area::set_error_status
--echo #
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1),(2),(3);
PREPARE stmt FROM "UPDATE t1 SET a = ? LIMIT ?";
ALTER TABLE t1 FORCE;
--error ER_INVALID_DEFAULT_PARAM
EXECUTE stmt USING 1, DEFAULT;
DEALLOCATE PREPARE stmt;
DROP TABLE t1;
CREATE TABLE t1 (a INT, b INT);
CREATE TABLE t2 (a INT, c INT);
INSERT INTO t1 VALUES (1,1),(2,2);
INSERT INTO t2 VALUES (1,1),(2,2);
CREATE VIEW v1 AS SELECT t1.a, t1.b, t2.c FROM t1 JOIN t2 ON t1.a = t2.a;
PREPARE stmt FROM "UPDATE v1 SET b = ? LIMIT ?";
ALTER TABLE t1 FORCE;
--error ER_INVALID_DEFAULT_PARAM
EXECUTE stmt USING 1, DEFAULT;
DEALLOCATE PREPARE stmt;
DROP VIEW v1;
DROP TABLE t1, t2;
CREATE TABLE t1 (a INT);
CREATE TABLE t3 (a INT);
INSERT INTO t3 VALUES (1),(2),(3);
PREPARE stmt FROM "INSERT INTO t1 SELECT a FROM t3 LIMIT ?";
ALTER TABLE t1 FORCE;
--error ER_INVALID_DEFAULT_PARAM
EXECUTE stmt USING DEFAULT;
DEALLOCATE PREPARE stmt;
DROP TABLE t1, t3;
CREATE TABLE t1 (a INT PRIMARY KEY);
CREATE TABLE t3 (a INT);
INSERT INTO t3 VALUES (1),(2),(3);
PREPARE stmt FROM "REPLACE INTO t1 SELECT a FROM t3 LIMIT ?";
ALTER TABLE t1 FORCE;
--error ER_INVALID_DEFAULT_PARAM
EXECUTE stmt USING DEFAULT;
DEALLOCATE PREPARE stmt;
DROP TABLE t1, t3;
--echo #
--echo # End of 10.11 tests
--echo #

View File

@@ -0,0 +1,18 @@
CHANGE MASTER TO master_host='127.0.0.1', master_user='root';
START SLAVE SQL_THREAD;
include/wait_for_slave_sql_to_start.inc
SET @@SESSION.debug_sync=
'hold_sss_with_run_lock SIGNAL sss_got_run_lock WAIT_FOR sss_continue';
SHOW SLAVE STATUS;
connect stopper, 127.0.0.1, root, , , $SERVER_MYPORT_1;
SET @@SESSION.debug_sync= 'now WAIT_FOR sss_got_run_lock';
STOP SLAVE SQL_THREAD;
connect continuer, 127.0.0.1, root, , , $SERVER_MYPORT_1;
SET @@SESSION.debug_sync= 'now SIGNAL sss_continue';
connection stopper;
disconnect continuer;
connection default;
disconnect stopper;
SET @@SESSION.debug_sync= RESET;
include/wait_for_slave_sql_to_stop.inc
RESET SLAVE ALL;

View File

@@ -0,0 +1,43 @@
# MDEV-40298
# Use-After-Free when SQL Thread stops in the middle of SHOW SLAVE STATUS
#
# Test that the correct synchronization is performed
--source include/have_debug_sync.inc
--source include/have_binlog_format_mixed.inc # No actual replication required
CHANGE MASTER TO master_host='127.0.0.1', master_user='root'; # basic setup
START SLAVE SQL_THREAD;
--source include/wait_for_slave_sql_to_start.inc
SET @@SESSION.debug_sync=
'hold_sss_with_run_lock SIGNAL sss_got_run_lock WAIT_FOR sss_continue';
--send SHOW SLAVE STATUS
--connect (stopper, 127.0.0.1, root, , , $SERVER_MYPORT_1)
SET @@SESSION.debug_sync= 'now WAIT_FOR sss_got_run_lock';
--send STOP SLAVE SQL_THREAD
# Wait a bit for the thread to "shut down"
# (It should not shut down, but block waiting for the ongoing SSS;
# the tested bug instead pulled this carpet under the SSS's feet.)
--sleep 1
--connect (continuer, 127.0.0.1, root, , , $SERVER_MYPORT_1)
SET @@SESSION.debug_sync= 'now SIGNAL sss_continue';
--connection stopper
--disconnect continuer
--reap
--connection default
--disconnect stopper
--disable_result_log
--reap
--enable_result_log
# Clean-up
SET @@SESSION.debug_sync= RESET;
--source include/wait_for_slave_sql_to_stop.inc
RESET SLAVE ALL;

View File

@@ -59,28 +59,28 @@ create server srv foreign data wrapper mysql options
(host "localhost", port 12345, wait_what "it's all good");
show create server srv;
Server Create Server
srv CREATE SERVER `srv` FOREIGN DATA WRAPPER `mysql` OPTIONS (host 'localhost', port '12345', wait_what 'it''s all good');
srv CREATE SERVER `srv` FOREIGN DATA WRAPPER `mysql` OPTIONS (`host` 'localhost', `port` '12345', `wait_what` 'it''s all good');
create or replace server srv foreign data wrapper Foo options
(host "somewhere.else", port 54321, wait_what "it's all good", foo 'bar');
show create server srv;
Server Create Server
srv CREATE SERVER `srv` FOREIGN DATA WRAPPER `Foo` OPTIONS (host 'somewhere.else', port '54321', wait_what 'it''s all good', foo 'bar');
srv CREATE SERVER `srv` FOREIGN DATA WRAPPER `Foo` OPTIONS (`host` 'somewhere.else', `port` '54321', `wait_what` 'it''s all good', `foo` 'bar');
alter server srv options (socket "sock", port 123, foo "", bar ')"{');
show create server srv;
Server Create Server
srv CREATE SERVER `srv` FOREIGN DATA WRAPPER `Foo` OPTIONS (host 'somewhere.else', wait_what 'it''s all good', socket 'sock', port '123', foo '', bar ')"{');
srv CREATE SERVER `srv` FOREIGN DATA WRAPPER `Foo` OPTIONS (`host` 'somewhere.else', `wait_what` 'it''s all good', `socket` 'sock', `port` '123', `foo` '', `bar` ')"{');
alter server srv options (socket "sock", port 123, bar "quux");
show create server srv;
Server Create Server
srv CREATE SERVER `srv` FOREIGN DATA WRAPPER `Foo` OPTIONS (host 'somewhere.else', wait_what 'it''s all good', foo '', socket 'sock', port '123', bar 'quux');
srv CREATE SERVER `srv` FOREIGN DATA WRAPPER `Foo` OPTIONS (`host` 'somewhere.else', `wait_what` 'it''s all good', `foo` '', `socket` 'sock', `port` '123', `bar` 'quux');
create or replace server srv foreign data wrapper foo options
(host "localhost", port "12345");
create or replace server srv foreign data wrapper mysql options
(host "localhost", port "bar321");
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '"bar321")' at line 2
ERROR HY000: Incorrect value 'bar321' for option 'PORT'
create or replace server srv foreign data wrapper mysql options
(host "localhost", port "123bar");
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '"123bar")' at line 2
ERROR HY000: Incorrect value '123bar' for option 'PORT'
create or replace server srv foreign data wrapper mysql options
(host "localhost", port "0");
show create server nonexist;
@@ -153,21 +153,51 @@ rename table mysql.plugin_save to mysql.plugin;
#
## Error code depends on length of long
CREATE SERVER s FOREIGN DATA WRAPPER mysql OPTIONS (HOST'',PORT 4294967295);
ERROR 22003: port value is out of range in 'INT'
ERROR HY000: Incorrect value '4294967295' for option 'PORT'
show warnings;
Level Code Message
Error 1912 Incorrect value '4294967295' for option 'PORT'
CREATE SERVER s FOREIGN DATA WRAPPER mysql OPTIONS (HOST'',PORT 2147483647);
select * from mysql.servers;
Server_name Host Db Username Password Port Socket Wrapper Owner Options
s 2147483647 mysql {"HOST": "", "PORT": "2147483647"}
ALTER SERVER s OPTIONS (PORT 4294967295);
ERROR 22003: port value is out of range in 'INT'
ALTER SERVER s OPTIONS (PORT '4294967295');
ERROR HY000: Incorrect value '4294967295' for option 'PORT'
select * from mysql.servers;
Server_name Host Db Username Password Port Socket Wrapper Owner Options
s 2147483647 mysql {"HOST": "", "PORT": "2147483647"}
drop server s;
CREATE OR REPLACE SERVER s FOREIGN DATA WRAPPER mysql OPTIONS (HOST'',PORT '4294967295');
ERROR HY000: Incorrect value '4294967295' for option 'PORT'
select * from mysql.servers;
Server_name Host Db Username Password Port Socket Wrapper Owner Options
s 2147483647 mysql {"HOST": "", "PORT": "2147483647"}
DROP SERVER s;
CREATE SERVER s FOREIGN DATA WRAPPER mysql OPTIONS (HOST'',PORT 2147483648);
ERROR 22003: port value is out of range in 'INT'
CREATE SERVER s FOREIGN DATA WRAPPER mysql OPTIONS (HOST'',PORT 18446744073709551615);
ERROR 22003: port value is out of range in 'INT'
ERROR HY000: Incorrect value '2147483648' for option 'PORT'
CREATE SERVER s FOREIGN DATA WRAPPER mysql OPTIONS (HOST'',PORT -5);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '-5)' at line 1
CREATE SERVER s FOREIGN DATA WRAPPER mysqL OPTIONS (HOST '',PORT '1', PORT '2');
SHOW CREATE SERVER s;
Server Create Server
s CREATE SERVER `s` FOREIGN DATA WRAPPER `mysqL` OPTIONS (`HOST` '', `PORT` '2');
select * from mysql.servers;
Server_name Host Db Username Password Port Socket Wrapper Owner Options
s 2 mysqL {"HOST": "", "PORT": "2"}
ALTER SERVER s options (PORT '7', PORT '8');
SHOW CREATE SERVER s;
Server Create Server
s CREATE SERVER `s` FOREIGN DATA WRAPPER `mysqL` OPTIONS (`HOST` '', `PORT` '8');
select * from mysql.servers;
Server_name Host Db Username Password Port Socket Wrapper Owner Options
s 8 mysqL {"HOST": "", "PORT": "8"}
DROP SERVER s;
# End of 10.11 tests
#
# MDEV-40312 SHOW CREATE SERVER incorrect quoting
#
create server s1 foreign data wrapper 'my''sql' options (`ho``st` 'va''lue');
show create server s1;
Server Create Server
s1 CREATE SERVER `s1` FOREIGN DATA WRAPPER `my'sql` OPTIONS (`ho``st` 'va''lue');
drop server s1;
# End of 11.8 tests

View File

@@ -71,11 +71,11 @@ show create server srv;
create or replace server srv foreign data wrapper foo options
(host "localhost", port "12345");
--error ER_PARSE_ERROR
--error ER_BAD_OPTION_VALUE
create or replace server srv foreign data wrapper mysql options
(host "localhost", port "bar321");
--error ER_PARSE_ERROR
--error ER_BAD_OPTION_VALUE
create or replace server srv foreign data wrapper mysql options
(host "localhost", port "123bar");
@@ -166,19 +166,38 @@ rename table mysql.plugin_save to mysql.plugin;
--echo # MDEV-36230 SIGSEGV in store_server_fields on CREATE SERVER
--echo #
--echo ## Error code depends on length of long
--error ER_DATA_OUT_OF_RANGE
--error ER_BAD_OPTION_VALUE
CREATE SERVER s FOREIGN DATA WRAPPER mysql OPTIONS (HOST'',PORT 4294967295);
show warnings;
CREATE SERVER s FOREIGN DATA WRAPPER mysql OPTIONS (HOST'',PORT 2147483647);
select * from mysql.servers;
--error ER_DATA_OUT_OF_RANGE
ALTER SERVER s OPTIONS (PORT 4294967295);
--error ER_BAD_OPTION_VALUE
ALTER SERVER s OPTIONS (PORT '4294967295');
select * from mysql.servers;
drop server s;
--error ER_DATA_OUT_OF_RANGE
--error ER_BAD_OPTION_VALUE
CREATE OR REPLACE SERVER s FOREIGN DATA WRAPPER mysql OPTIONS (HOST'',PORT '4294967295');
select * from mysql.servers;
DROP SERVER s;
--error ER_BAD_OPTION_VALUE
CREATE SERVER s FOREIGN DATA WRAPPER mysql OPTIONS (HOST'',PORT 2147483648);
--error ER_DATA_OUT_OF_RANGE
CREATE SERVER s FOREIGN DATA WRAPPER mysql OPTIONS (HOST'',PORT 18446744073709551615);
--error ER_PARSE_ERROR
CREATE SERVER s FOREIGN DATA WRAPPER mysql OPTIONS (HOST'',PORT -5);
CREATE SERVER s FOREIGN DATA WRAPPER mysqL OPTIONS (HOST '',PORT '1', PORT '2');
SHOW CREATE SERVER s;
select * from mysql.servers;
ALTER SERVER s options (PORT '7', PORT '8');
SHOW CREATE SERVER s;
select * from mysql.servers;
DROP SERVER s;
--echo # End of 10.11 tests
--echo #
--echo # MDEV-40312 SHOW CREATE SERVER incorrect quoting
--echo #
create server s1 foreign data wrapper 'my''sql' options (`ho``st` 'va''lue');
show create server s1;
drop server s1;
--echo # End of 11.8 tests

View File

@@ -5,11 +5,11 @@ call mtr.add_suppression('$SEARCH_PATTERN');
create server s foreign data wrapper mysql options (host "127.0.0.1", database "test", user "root", port 3306);
show create server s;
Server Create Server
s CREATE SERVER `s` FOREIGN DATA WRAPPER `mysql` OPTIONS (host '127.0.0.1', database 'test', user 'root', port '3306');
s CREATE SERVER `s` FOREIGN DATA WRAPPER `mysql` OPTIONS (`host` '127.0.0.1', `database` 'test', `user` 'root', `port` '3306');
alter table mysql.servers drop column Options;
show create server s;
Server Create Server
s CREATE SERVER `s` FOREIGN DATA WRAPPER `mysql` OPTIONS (host '127.0.0.1', database 'test', user 'root', port '3306');
s CREATE SERVER `s` FOREIGN DATA WRAPPER `mysql` OPTIONS (`host` '127.0.0.1', `database` 'test', `user` 'root', `port` '3306');
# restart
show create server s;
Server Create Server

View File

@@ -1110,5 +1110,81 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2
DROP TABLE t1, t2;
#
# MDEV-36610: Subquery wrongly marked as eliminated by table elimination
# when equality propagation shares a WHERE-clause subquery
# into an eliminated outer join's ON expression
#
CREATE TABLE t0 (k INT);
INSERT INTO t0 VALUES (20),(9);
CREATE TABLE t1 (a BIGINT);
INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2 (b INT PRIMARY KEY);
INSERT INTO t2 VALUES (3),(4);
INSERT INTO t2 VALUES (5),(6);
CREATE TABLE t3 (c INT);
INSERT INTO t3 VALUES (2);
CREATE TABLE t4 (a BIGINT, x INT);
INSERT INTO t4 VALUES (2,20),(3,30);
# t2 is eliminated, but the subquery must still be shown and executed:
explain SELECT t1.* FROM t1 LEFT JOIN t2 ON (t2.b = t1.a)
WHERE t1.a = (SELECT c FROM t3);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
2 SUBQUERY t3 system NULL NULL NULL NULL 1
SELECT t1.* FROM t1 LEFT JOIN t2 ON (t2.b = t1.a)
WHERE t1.a = (SELECT c FROM t3);
a
2
# t2 is eliminated; the subquery must still be shown and executed:
explain SELECT t0.k, t4.x FROM t0
LEFT JOIN (t4 LEFT JOIN t2 ON t2.b = t4.a)
ON (t0.k = t4.x AND t4.a = (SELECT c FROM t3));
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t0 ALL NULL NULL NULL NULL 2
1 PRIMARY t4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
2 SUBQUERY t3 system NULL NULL NULL NULL 1
SELECT t0.k, t4.x FROM t0
LEFT JOIN (t4 LEFT JOIN t2 ON t2.b = t4.a)
ON (t0.k = t4.x AND t4.a = (SELECT c FROM t3));
k x
20 20
9 NULL
truncate t2;
DROP TABLE t4;
CREATE TABLE t4 (d INT);
INSERT INTO t4 VALUES (1),(2),(7);
# The subquery is shared with the WHERE clause, so it must still be
# shown and executed:
explain SELECT t1.* FROM t1
LEFT JOIN t2 ON (t2.b = t1.a)
LEFT JOIN t4 ON (t4.d = t1.a)
WHERE t1.a = (SELECT c FROM t3);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 system PRIMARY NULL NULL NULL 0 Const row not found
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
1 PRIMARY t4 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
2 SUBQUERY t3 system NULL NULL NULL NULL 1
SELECT t1.* FROM t1
LEFT JOIN t2 ON (t2.b = t1.a)
LEFT JOIN t4 ON (t4.d = t1.a)
WHERE t1.a = (SELECT c FROM t3);
a
2
explain SELECT t1.a FROM t1
LEFT JOIN t2 ON (t2.b = t1.a AND t1.a <> (SELECT c FROM t3))
LEFT JOIN t4 ON (t4.d = t1.a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 system PRIMARY NULL NULL NULL 0 Const row not found
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
1 PRIMARY t4 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
2 SUBQUERY t3 system NULL NULL NULL NULL 1
SELECT t1.a FROM t1
LEFT JOIN t2 ON (t2.b = t1.a AND t1.a <> (SELECT c FROM t3))
LEFT JOIN t4 ON (t4.d = t1.a);
a
1
2
DROP TABLE t0, t1, t2, t3, t4;
#
# End of 10.11 tests
#

View File

@@ -841,6 +841,63 @@ select t1.null_col from t1 left join t2 on (t2.unique_col<=>t1.notnull_col);
DROP TABLE t1, t2;
--echo #
--echo # MDEV-36610: Subquery wrongly marked as eliminated by table elimination
--echo # when equality propagation shares a WHERE-clause subquery
--echo # into an eliminated outer join's ON expression
--echo #
CREATE TABLE t0 (k INT);
INSERT INTO t0 VALUES (20),(9);
CREATE TABLE t1 (a BIGINT);
INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2 (b INT PRIMARY KEY);
INSERT INTO t2 VALUES (3),(4);
INSERT INTO t2 VALUES (5),(6);
CREATE TABLE t3 (c INT);
INSERT INTO t3 VALUES (2);
CREATE TABLE t4 (a BIGINT, x INT);
INSERT INTO t4 VALUES (2,20),(3,30);
--echo # t2 is eliminated, but the subquery must still be shown and executed:
let $q=
SELECT t1.* FROM t1 LEFT JOIN t2 ON (t2.b = t1.a)
WHERE t1.a = (SELECT c FROM t3);
eval explain $q;
eval $q;
--echo # t2 is eliminated; the subquery must still be shown and executed:
let $q=
SELECT t0.k, t4.x FROM t0
LEFT JOIN (t4 LEFT JOIN t2 ON t2.b = t4.a)
ON (t0.k = t4.x AND t4.a = (SELECT c FROM t3));
eval explain $q;
eval $q;
truncate t2;
DROP TABLE t4;
CREATE TABLE t4 (d INT);
INSERT INTO t4 VALUES (1),(2),(7);
--echo # The subquery is shared with the WHERE clause, so it must still be
--echo # shown and executed:
let $q=
SELECT t1.* FROM t1
LEFT JOIN t2 ON (t2.b = t1.a)
LEFT JOIN t4 ON (t4.d = t1.a)
WHERE t1.a = (SELECT c FROM t3);
eval explain $q;
eval $q;
let $q=
SELECT t1.a FROM t1
LEFT JOIN t2 ON (t2.b = t1.a AND t1.a <> (SELECT c FROM t3))
LEFT JOIN t4 ON (t4.d = t1.a);
eval explain $q;
eval $q;
DROP TABLE t0, t1, t2, t3, t4;
--echo #
--echo # End of 10.11 tests
--echo #

View File

@@ -2624,4 +2624,33 @@ select * from t1;
select * from t1;
a
drop table t1;
set sql_mode=default;
#
# MDEV-28498 Incorrect information in file: './test/t0.frm' on CREATE TABLE
#
CREATE TABLE t1 (a ENUM ('',0x0000),b ENUM ('')) CHARACTER SET latin1;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` enum('','\0\0') DEFAULT NULL,
`b` enum('') DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
INSERT INTO t1 VALUES (0x0000,'');
INSERT INTO t1 VALUES ('\0\0','');
SELECT HEX(a) FROM t1;
HEX(a)
0000
0000
DROP TABLE t1;
CREATE TABLE t1 (a ENUM ('',0x0000) AS (0x0000) VIRTUAL,b ENUM ('') DEFAULT '') CHARACTER SET latin1;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` enum('','\0\0') GENERATED ALWAYS AS (0x0000) VIRTUAL,
`b` enum('') DEFAULT ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
INSERT INTO t1 VALUES ();
SELECT HEX(a) FROM t1;
HEX(a)
0000
DROP TABLE t1;

View File

@@ -630,4 +630,21 @@ select * from t1;
select * from t1;
drop table t1;
set sql_mode=default;
--echo #
--echo # MDEV-28498 Incorrect information in file: './test/t0.frm' on CREATE TABLE
--echo #
CREATE TABLE t1 (a ENUM ('',0x0000),b ENUM ('')) CHARACTER SET latin1;
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES (0x0000,'');
INSERT INTO t1 VALUES ('\0\0','');
SELECT HEX(a) FROM t1;
DROP TABLE t1;
CREATE TABLE t1 (a ENUM ('',0x0000) AS (0x0000) VIRTUAL,b ENUM ('') DEFAULT '') CHARACTER SET latin1;
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES ();
SELECT HEX(a) FROM t1;
DROP TABLE t1;

View File

@@ -699,4 +699,35 @@ Catalog Database Table Table_alias Column Column_alias Type Length Max length Is
def COALESCE(c_int, c_set) 253 33 0 Y 0 39 192
COALESCE(c_int, c_set)
DROP TABLE t1;
#
# MDEV-28498 Incorrect information in file: './test/t0.frm' on CREATE TABLE
#
CREATE TABLE t1 (a SET ('',0x0000),b SET ('')) CHARACTER SET latin1;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` set('','\0\0') DEFAULT NULL,
`b` set('') DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
INSERT INTO t1 VALUES (0x0000,'');
INSERT INTO t1 VALUES ('\0\0','');
INSERT INTO t1 VALUES ('','');
SELECT a+0, HEX(a) FROM t1;
a+0 HEX(a)
2 0000
2 0000
0
DROP TABLE t1;
CREATE TABLE t1 (a SET ('',0x0000) AS (0x0000) VIRTUAL,b SET ('') DEFAULT '') CHARACTER SET latin1;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` set('','\0\0') GENERATED ALWAYS AS (0x0000) VIRTUAL,
`b` set('') DEFAULT ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
INSERT INTO t1 VALUES ();
SELECT a+0, HEX(a) FROM t1;
a+0 HEX(a)
2 0000
DROP TABLE t1;
# End of 10.11 tests

View File

@@ -334,4 +334,22 @@ SELECT COALESCE(c_int, c_set) FROM t1;
DROP TABLE t1;
--echo #
--echo # MDEV-28498 Incorrect information in file: './test/t0.frm' on CREATE TABLE
--echo #
CREATE TABLE t1 (a SET ('',0x0000),b SET ('')) CHARACTER SET latin1;
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES (0x0000,'');
INSERT INTO t1 VALUES ('\0\0','');
INSERT INTO t1 VALUES ('','');
SELECT a+0, HEX(a) FROM t1;
DROP TABLE t1;
CREATE TABLE t1 (a SET ('',0x0000) AS (0x0000) VIRTUAL,b SET ('') DEFAULT '') CHARACTER SET latin1;
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES ();
SELECT a+0, HEX(a) FROM t1;
DROP TABLE t1;
--echo # End of 10.11 tests

View File

@@ -565,4 +565,154 @@ tmp CREATE TABLE `tmp` (
c
drop table tmp, t1, t2;
set sql_mode=@old_sql_mode;
#
# MDEV-40486 ER_TOO_BIG_FIELDLENGTH or assertion failure upon creating vector from blob
#
## Original testcase
CREATE TABLE t (a TEXT) AS SELECT '[1]' AS a;
CREATE TABLE tt AS SELECT VEC_FROMTEXT(a) AS f FROM t;
ERROR 22007: Incorrect vector value: '\x00\x00\x80?' for column `test`.`tt`.`f` at row 1
DROP TABLE t;
CREATE TABLE t (a LONGBLOB) AS SELECT '[1]' AS a;
CREATE TABLE tt AS SELECT VEC_FROMTEXT(a) AS f FROM t;
ERROR 22007: Incorrect vector value: '\x00\x00\x80?' for column `test`.`tt`.`f` at row 1
DROP TABLE t;
## Another case, which would have failed with ERROR 1292
## without the fix
CREATE TABLE t SELECT VEC_FROMTEXT('[1]');
DROP TABLE t;
## Conversion from max varchar length
CREATE TABLE t (a VARCHAR(16383)) AS
SELECT concat('[1', repeat(',1', 8190), ']') AS a;
CREATE TABLE tt AS SELECT VEC_FROMTEXT(a) AS f FROM t;
DROP TABLE t,tt;
## Conversion to max vector dimension
CREATE TABLE tt AS
SELECT VEC_FROMTEXT(concat('[1', repeat(',1', 16382), ']')) AS f;
DROP TABLE tt;
CREATE TABLE tt AS
SELECT VEC_FROMTEXT(concat('[1', repeat(',1', 16383), ']')) AS f;
ERROR 22007: Truncated incorrect vector value: '[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,...'
CREATE TABLE t1 (v VECTOR(2));
INSERT INTO t1 VALUES (VEC_FROMTEXT(CONCAT('[1.', REPEAT('0',70000), ',2]')));
DROP TABLE t1;
SELECT VEC_FROMTEXT('😀😀😀');
VEC_FROMTEXT('😀😀😀')
NULL
Warnings:
Warning 4038 Syntax error in JSON text in argument 1 to function 'VEC_FromText' at position 1
## "Zero-dimensional" argument, no change in behaviour after fix
SELECT VEC_FROMTEXT('[]') as f;
f
CREATE TABLE t1 SELECT VEC_FROMTEXT('[]');
ERROR 22007: Incorrect vector value: '' for column `test`.`t1`.`VEC_FROMTEXT('[]')` at row 1
## Zero length: no underflow
SELECT VEC_FROMTEXT('') AS f;
f
NULL
Warnings:
Warning 4037 Unexpected end of JSON text in argument 1 to function 'VEC_FromText'
CREATE TABLE tt AS SELECT VEC_FROMTEXT('') AS f;
ERROR HY000: Unexpected end of JSON text in argument 1 to function 'VEC_FromText'
CREATE TABLE t1 (a CHAR(1));
CREATE TABLE t2 AS SELECT VEC_FROMTEXT(a) AS f FROM t1;
show create table t2;
Table Create Table
t2 CREATE TABLE `t2` (
`f` vector(1) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
DROP TABLE t1, t2;
CREATE TABLE t1 (a CHAR(2));
CREATE TABLE t2 AS SELECT VEC_FROMTEXT(a) AS f FROM t1;
show create table t2;
Table Create Table
t2 CREATE TABLE `t2` (
`f` vector(1) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
DROP TABLE t1, t2;
CREATE TABLE t3 (f VECTOR(0));
ERROR 42000: Incorrect column specifier for column 'f'
create view v1 as select vec_fromtext(concat('[',group_concat(1),']')) from seq_1_to_64;
DROP view v1;
create table t1 as select vec_fromtext(concat('[',group_concat(1),']')) from seq_1_to_64;
ERROR 22007: Incorrect vector value: '\x00\x00\x80?\x00\x00\x80?\x00\x00\x80?\x00\x00\x80?\x00\x00\x80?\x00\x00\x80?\x00\x00\x80?\x00\x00\x80?\x00\x00\x80?\x00\x00...' for column `test`.`t1`.`vec_fromtext(concat('[',group_concat(1),']'))` at row 65
## NULLs
select vec_fromtext(NULL);
vec_fromtext(NULL)
NULL
select vec_fromtext(NULL + NULL);
vec_fromtext(NULL + NULL)
NULL
create table t1 select vec_fromtext(NULL) as c;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c` vector(1) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
DROP TABLE t1;
create table t1 select vec_fromtext(NULL + NULL) as c;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c` vector(8) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
drop table t1;
create table t1 select vec_fromtext(c) from (select '[1,2]' as c) d;
DROP TABLE t1;
create table t1 select vec_fromtext(c) from (select '' as c) d;
ERROR HY000: Unexpected end of JSON text in argument 1 to function 'VEC_FromText'
create table t1 select vec_fromtext(c) from (select NULL as c) d;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`vec_fromtext(c)` vector(1) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
DROP TABLE t1;
create table t2 (c varchar(5));
insert into t2 values (NULL);
create table t1 select vec_fromtext(c) from t2;
drop table t1, t2;
## Prepared statements with placeholders
prepare p1 from 'select vec_fromtext(?)';
execute p1 using '[1,2]';
execute p1 using NULL;
vec_fromtext(?)
NULL
execute p1 using '[]';
vec_fromtext(?)
deallocate prepare p1;
prepare p1 from 'create table t1 select vec_fromtext(?)';
execute p1 using '[1,2]';
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`vec_fromtext(?)` vector(2) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
DROP TABLE t1;
execute p1 using NULL;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`vec_fromtext(?)` vector(1) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
DROP TABLE t1;
execute p1 using '[]';
ERROR 22007: Incorrect vector value: '' for column `test`.`t1`.`vec_fromtext(?)` at row 1
execute p1 using '';
ERROR HY000: Unexpected end of JSON text in argument 1 to function 'VEC_FromText'
deallocate prepare p1;
#
# MDEV-40751 CREATE ... SELECT VEC_FROMTEXT(...) may create VECTOR columns that reject every value
#
CREATE TABLE t1 (a CHAR(4));
create table t2 select vec_fromtext(a) from t1;
show create table t2;
Table Create Table
t2 CREATE TABLE `t2` (
`vec_fromtext(a)` vector(1) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
insert into t2 values (vec_fromtext('[1]'));
DROP TABLE t1, t2;
# End of 11.8 tests

View File

@@ -447,4 +447,127 @@ drop table tmp, t1, t2;
set sql_mode=@old_sql_mode;
--echo #
--echo # MDEV-40486 ER_TOO_BIG_FIELDLENGTH or assertion failure upon creating vector from blob
--echo #
--echo ## Original testcase
CREATE TABLE t (a TEXT) AS SELECT '[1]' AS a;
--error ER_TRUNCATED_WRONG_VALUE
CREATE TABLE tt AS SELECT VEC_FROMTEXT(a) AS f FROM t;
DROP TABLE t;
CREATE TABLE t (a LONGBLOB) AS SELECT '[1]' AS a;
--error ER_TRUNCATED_WRONG_VALUE
CREATE TABLE tt AS SELECT VEC_FROMTEXT(a) AS f FROM t;
DROP TABLE t;
--echo ## Another case, which would have failed with ERROR 1292
--echo ## without the fix
CREATE TABLE t SELECT VEC_FROMTEXT('[1]');
DROP TABLE t;
--echo ## Conversion from max varchar length
CREATE TABLE t (a VARCHAR(16383)) AS
SELECT concat('[1', repeat(',1', 8190), ']') AS a;
CREATE TABLE tt AS SELECT VEC_FROMTEXT(a) AS f FROM t;
DROP TABLE t,tt;
--echo ## Conversion to max vector dimension
CREATE TABLE tt AS
SELECT VEC_FROMTEXT(concat('[1', repeat(',1', 16382), ']')) AS f;
DROP TABLE tt;
--error ER_TRUNCATED_WRONG_VALUE
CREATE TABLE tt AS
SELECT VEC_FROMTEXT(concat('[1', repeat(',1', 16383), ']')) AS f;
CREATE TABLE t1 (v VECTOR(2));
INSERT INTO t1 VALUES (VEC_FROMTEXT(CONCAT('[1.', REPEAT('0',70000), ',2]')));
DROP TABLE t1;
SELECT VEC_FROMTEXT('😀😀😀');
--echo ## "Zero-dimensional" argument, no change in behaviour after fix
SELECT VEC_FROMTEXT('[]') as f;
--error ER_TRUNCATED_WRONG_VALUE
CREATE TABLE t1 SELECT VEC_FROMTEXT('[]');
--echo ## Zero length: no underflow
SELECT VEC_FROMTEXT('') AS f;
--error ER_JSON_EOS
CREATE TABLE tt AS SELECT VEC_FROMTEXT('') AS f;
CREATE TABLE t1 (a CHAR(1));
CREATE TABLE t2 AS SELECT VEC_FROMTEXT(a) AS f FROM t1;
show create table t2;
DROP TABLE t1, t2;
CREATE TABLE t1 (a CHAR(2));
CREATE TABLE t2 AS SELECT VEC_FROMTEXT(a) AS f FROM t1;
show create table t2;
DROP TABLE t1, t2;
--error ER_WRONG_FIELD_SPEC
CREATE TABLE t3 (f VECTOR(0));
create view v1 as select vec_fromtext(concat('[',group_concat(1),']')) from seq_1_to_64;
DROP view v1;
--error ER_TRUNCATED_WRONG_VALUE
create table t1 as select vec_fromtext(concat('[',group_concat(1),']')) from seq_1_to_64;
--echo ## NULLs
select vec_fromtext(NULL);
select vec_fromtext(NULL + NULL);
create table t1 select vec_fromtext(NULL) as c;
show create table t1;
DROP TABLE t1;
create table t1 select vec_fromtext(NULL + NULL) as c;
show create table t1;
drop table t1;
create table t1 select vec_fromtext(c) from (select '[1,2]' as c) d;
DROP TABLE t1;
--error ER_JSON_EOS
create table t1 select vec_fromtext(c) from (select '' as c) d;
create table t1 select vec_fromtext(c) from (select NULL as c) d;
show create table t1;
DROP TABLE t1;
create table t2 (c varchar(5));
insert into t2 values (NULL);
create table t1 select vec_fromtext(c) from t2;
drop table t1, t2;
--echo ## Prepared statements with placeholders
prepare p1 from 'select vec_fromtext(?)';
--disable_result_log
execute p1 using '[1,2]';
--enable_result_log
execute p1 using NULL;
execute p1 using '[]';
deallocate prepare p1;
prepare p1 from 'create table t1 select vec_fromtext(?)';
execute p1 using '[1,2]';
show create table t1;
DROP TABLE t1;
execute p1 using NULL;
show create table t1;
DROP TABLE t1;
--error ER_TRUNCATED_WRONG_VALUE
execute p1 using '[]';
--error ER_JSON_EOS
execute p1 using '';
deallocate prepare p1;
--echo #
--echo # MDEV-40751 CREATE ... SELECT VEC_FROMTEXT(...) may create VECTOR columns that reject every value
--echo #
CREATE TABLE t1 (a CHAR(4));
create table t2 select vec_fromtext(a) from t1;
show create table t2;
insert into t2 values (vec_fromtext('[1]'));
DROP TABLE t1, t2;
--echo # End of 11.8 tests

View File

@@ -1914,8 +1914,6 @@ test.v5 check error Corrupt
test.v6 check status OK
drop view v1, v2, v3, v4, v5, v6;
drop table t2;
drop function if exists f1;
drop function if exists f2;
CREATE TABLE t1 (col1 time);
CREATE TABLE t2 (col1 time);
CREATE TABLE t3 (col1 time);
@@ -2152,8 +2150,6 @@ CREATE VIEW v1 AS SELECT f1();
ERROR HY000: View's SELECT refers to a temporary table 't1'
DROP FUNCTION f1;
DROP TABLE t1;
DROP TABLE IF EXISTS t1;
DROP VIEW IF EXISTS v1;
CREATE TABLE t1 (f4 CHAR(5));
CREATE VIEW v1 AS SELECT * FROM t1;
DESCRIBE v1;
@@ -2443,7 +2439,6 @@ f1 sum(f2)
NULL 12
drop view v1;
drop table t1;
drop procedure if exists p1;
create procedure p1 () deterministic
begin
create view v1 as select 1;
@@ -2456,7 +2451,6 @@ v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VI
drop view v1;
drop procedure p1;
CREATE VIEW v1 AS SELECT 42 AS Meaning;
DROP FUNCTION IF EXISTS f1;
CREATE FUNCTION f1() RETURNS INTEGER
BEGIN
DECLARE retn INTEGER;
@@ -2874,7 +2868,6 @@ SHOW TABLES;
Tables_in_test
t1
DROP TABLE t1;
DROP VIEW IF EXISTS v1;
set GLOBAL sql_mode="";
set LOCAL sql_mode="";
CREATE DATABASE bug21261DB;
@@ -2915,9 +2908,6 @@ View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1` where `t1`.`f1` between current_timestamp() and current_timestamp() + interval 1 minute latin1 latin1_swedish_ci
drop view v1;
drop table t1;
DROP TABLE IF EXISTS t1;
DROP VIEW IF EXISTS v1;
DROP VIEW IF EXISTS v2;
CREATE TABLE t1(a INT, b INT);
CREATE DEFINER=longer_than_80_456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789@localhost
VIEW v1 AS SELECT a FROM t1;
@@ -2926,10 +2916,6 @@ CREATE DEFINER=some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890
VIEW v2 AS SELECT b FROM t1;
ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTYa...' is too long for host name (should be no longer than 255)
DROP TABLE t1;
DROP FUNCTION IF EXISTS f1;
DROP FUNCTION IF EXISTS f2;
DROP VIEW IF EXISTS v1, v2;
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (i INT);
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE FUNCTION f1() RETURNS INT
@@ -2992,9 +2978,6 @@ View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=MERGE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`pk` AS `pk` from (`t1` join `t2` on(`t2`.`fk` = `t1`.`pk` and `t2`.`ver` = (select max(`t`.`ver`) from `t2` `t` where `t`.`org` = `t2`.`org`))) latin1 latin1_swedish_ci
DROP VIEW v1;
DROP TABLE t1, t2;
DROP FUNCTION IF EXISTS f1;
DROP VIEW IF EXISTS v1;
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (i INT);
INSERT INTO t1 VALUES (1);
CREATE VIEW v1 AS SELECT MAX(i) FROM t1;
@@ -3016,8 +2999,6 @@ UPDATE v1 SET val=6 WHERE id=2;
ERROR 44000: CHECK OPTION failed `test`.`v1`
DROP VIEW v1;
DROP TABLE t1;
DROP VIEW IF EXISTS v1, v2;
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (i INT AUTO_INCREMENT PRIMARY KEY, j INT);
CREATE VIEW v1 AS SELECT j FROM t1;
CREATE VIEW v2 AS SELECT * FROM t1;
@@ -3061,7 +3042,6 @@ SELECT * FROM v;
x
5
DROP VIEW v;
DROP VIEW IF EXISTS v1;
CREATE VIEW v1 AS SELECT 'The\ZEnd';
SELECT * FROM v1;
TheEnd
@@ -3172,15 +3152,11 @@ code COUNT(DISTINCT country)
100 2
DROP VIEW v1;
DROP TABLE t1;
DROP VIEW IF EXISTS v1;
SELECT * FROM (SELECT 1) AS t into @w;
CREATE VIEW v1 AS SELECT * FROM (SELECT 1) AS t into @w;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'into @w' at line 1
# Previously the following would fail.
SELECT * FROM (SELECT 1) AS t into @w;
drop view if exists view_24532_a;
drop view if exists view_24532_b;
drop table if exists table_24532;
create table table_24532 (
a int,
b bigint,
@@ -3644,38 +3620,24 @@ DROP TABLE t1;
# -----------------------------------------------------------------
# -- Bug#34337 Server crash when Altering a view using a table name.
# -----------------------------------------------------------------
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(c1 INT);
SELECT * FROM t1;
c1
ALTER ALGORITHM=TEMPTABLE SQL SECURITY INVOKER VIEW t1 (c2) AS SELECT (1);
ERROR HY000: 'test.t1' is not of type 'VIEW'
DROP TABLE t1;
# -- End of test case for Bug#34337.
# -----------------------------------------------------------------
# -- Bug#35193 VIEW query is rewritten without "FROM DUAL",
# -- causing syntax error
# -----------------------------------------------------------------
CREATE VIEW v1 AS SELECT 1 FROM DUAL WHERE 1;
SELECT * FROM v1;
1
1
SHOW CREATE TABLE v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 1 AS `1` from DUAL where 1 latin1 latin1_swedish_ci
DROP VIEW v1;
# -- End of test case for Bug#35193.
CREATE VIEW v1 AS SELECT 1;
DROP VIEW v1;
CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 INT, INDEX (c2));
@@ -3836,7 +3798,6 @@ DROP TABLE t1;
# -----------------------------------------------------------------
# -- End of 5.0 tests.
# -----------------------------------------------------------------
DROP DATABASE IF EXISTS `d-1`;
CREATE DATABASE `d-1`;
USE `d-1`;
CREATE TABLE `t-1` (c1 INT);
@@ -3855,93 +3816,61 @@ DROP TABLE `t-2`;
DROP VIEW `v-2`;
DROP DATABASE `d-1`;
USE test;
#
# Bug#26676 VIEW using old table schema in a session.
#
DROP VIEW IF EXISTS v1;
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(c1 INT, c2 INT);
INSERT INTO t1 VALUES (1, 2), (3, 4);
SELECT * FROM t1;
c1 c2
1 2
3 4
CREATE VIEW v1 AS SELECT * FROM t1;
SELECT * FROM v1;
c1 c2
1 2
3 4
ALTER TABLE t1 ADD COLUMN c3 INT AFTER c2;
SELECT * FROM t1;
c1 c2 c3
1 2 NULL
3 4 NULL
SELECT * FROM v1;
c1 c2
1 2
3 4
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`c1` AS `c1`,`t1`.`c2` AS `c2` from `t1` latin1 latin1_swedish_ci
DROP VIEW v1;
DROP TABLE t1;
# End of test case for Bug#26676.
# -----------------------------------------------------------------
# -- Bug#32538 View definition picks up character set, but not collation
# -----------------------------------------------------------------
DROP VIEW IF EXISTS v1;
SET collation_connection = latin1_general_ci;
CREATE VIEW v1 AS SELECT _latin1 'text1' AS c1, 'text2' AS c2;
SELECT COLLATION(c1), COLLATION(c2) FROM v1;
COLLATION(c1) COLLATION(c2)
latin1_swedish_ci latin1_general_ci
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select _latin1'text1' AS `c1`,'text2' AS `c2` latin1 latin1_general_ci
SELECT * FROM v1 WHERE c1 = 'text1';
ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin1_general_ci,COERCIBLE) for operation '='
SELECT * FROM v1 WHERE c2 = 'text2';
c1 c2
text1 text2
use test;
SET names latin1;
SELECT COLLATION(c1), COLLATION(c2) FROM v1;
COLLATION(c1) COLLATION(c2)
latin1_swedish_ci latin1_general_ci
SELECT * FROM v1 WHERE c1 = 'text1';
c1 c2
text1 text2
SELECT * FROM v1 WHERE c2 = 'text2';
ERROR HY000: Illegal mix of collations (latin1_general_ci,COERCIBLE) and (latin1_swedish_ci,COERCIBLE) for operation '='
DROP VIEW v1;
# -- End of test case for Bug#32538.
drop view if exists a;
drop procedure if exists p;
create procedure p()
begin
declare continue handler for sqlexception begin end;
@@ -3964,9 +3893,6 @@ DROP TABLE t1;
# Bug#48449: hang on show create view after upgrading when
# view contains function of view
#
DROP VIEW IF EXISTS v1,v2;
DROP TABLE IF EXISTS t1,t2;
DROP FUNCTION IF EXISTS f1;
CREATE TABLE t1 (a INT);
CREATE TABLE t2 (a INT);
CREATE FUNCTION f1() RETURNS INT
@@ -4730,8 +4656,6 @@ c a b c
0 93 1 0
DROP VIEW v4;
DROP TABLE t1,t2,t3,t4;
drop table if exists t_9801;
drop view if exists v_9801;
create table t_9801 (s1 int);
create view v_9801 as
select sum(s1) from t_9801 with check option;
@@ -4746,8 +4670,6 @@ drop table t_9801;
#
# Bug #47335 assert in get_table_share
#
DROP TABLE IF EXISTS t1;
DROP VIEW IF EXISTS v1;
CREATE TEMPORARY TABLE t1 (id INT);
ALTER VIEW t1 AS SELECT 1 AS f1;
ERROR 42S02: Table 'test.t1' doesn't exist
@@ -4764,8 +4686,6 @@ DROP VIEW v1;
# Bug #47635 assert in start_waiting_global_read_lock
# during CREATE VIEW
#
DROP TABLE IF EXISTS t1, t2;
DROP VIEW IF EXISTS t2;
CREATE TABLE t1 (f1 integer);
CREATE TEMPORARY TABLE IF NOT EXISTS t1 (f1 integer);
CREATE TEMPORARY TABLE t2 (f1 integer);
@@ -4779,8 +4699,6 @@ DROP TABLE t1, t2;
# Bug#48315 Metadata lock is not taken for merged views that
# use an INFORMATION_SCHEMA table
#
DROP VIEW IF EXISTS v1;
DROP PROCEDURE IF EXISTS p1;
connect con2, localhost, root;
connect con3, localhost, root;
connection default;
@@ -4823,7 +4741,6 @@ disconnect con3;
# Bug#12626844: WRONG ERROR MESSAGE WHILE CREATING A VIEW ON A
# NON EXISTING DATABASE
#
DROP DATABASE IF EXISTS nodb;
CREATE VIEW nodb.a AS SELECT 1;
ERROR 42000: Unknown database 'nodb'
#
@@ -6948,10 +6865,8 @@ SELECT * FROM v1;
b''
DROP VIEW v1;
#
# End of 10.3 tests
#
#
# MDEV-25206: view specification contains unknown column reference
#
CREATE TABLE t1 (a int);

File diff suppressed because it is too large Load Diff

View File

@@ -1414,13 +1414,6 @@ ExtractValue(@xml, '/employee/dt3')
NULL
Warnings:
Warning 1525 Incorrect XML value: 'parse error at line 10 pos 27: unexpected END-OF-INPUT'
#
# MDEV-39750 ExtractValue does not control recursion depth.
#
SELECT ExtractValue('<a/>', REPEAT('(', 100000));
ERROR HY000: Thread stack overrun: 'used bytes' used of a 'available' byte stack, and 'X' bytes needed. Consider increasing the thread_stack system variable.
SELECT ExtractValue('<a/>', REPEAT('/n', 100000));
ERROR HY000: Thread stack overrun: 'used bytes' used of a 'available' byte stack, and 'X' bytes needed. Consider increasing the thread_stack system variable.
# End of 10.6 tests
# Start of 11.4 tests
#

View File

@@ -903,18 +903,6 @@ set @xml= '<?xml version="1.0"?>
SELECT ExtractValue(@xml, '/employee/dt3');
--echo #
--echo # MDEV-39750 ExtractValue does not control recursion depth.
--echo #
--replace_regex /overrun: [0-9]* bytes used of a [0-9]* byte stack, and [0-9]* bytes needed/overrun: 'used bytes' used of a 'available' byte stack, and 'X' bytes needed/
--error ER_STACK_OVERRUN_NEED_MORE
SELECT ExtractValue('<a/>', REPEAT('(', 100000));
--replace_regex /overrun: [0-9]* bytes used of a [0-9]* byte stack, and [0-9]* bytes needed/overrun: 'used bytes' used of a 'available' byte stack, and 'X' bytes needed/
--error ER_STACK_OVERRUN_NEED_MORE
SELECT ExtractValue('<a/>', REPEAT('/n', 100000));
--echo # End of 10.6 tests
--echo # Start of 11.4 tests

Binary file not shown.

View File

@@ -0,0 +1,12 @@
CREATE TABLE t1(
t TEXT NULL DEFAULT NULL
) COLLATE='utf8_general_ci' ENGINE=archive;
INSERT INTO t1(t) VALUES ('Testtext');
REPAIR TABLE t1;
Table Op Msg_type Msg_text
test.t1 repair status OK
SELECT t = 'Testtext' as Expect_1 from t1;
Expect_1
1
DROP TABLE t1;
# End of 10.6 tests

View File

@@ -0,0 +1,10 @@
--source include/have_archive.inc
CREATE TABLE t1(
t TEXT NULL DEFAULT NULL
) COLLATE='utf8_general_ci' ENGINE=archive;
INSERT INTO t1(t) VALUES ('Testtext');
REPAIR TABLE t1;
SELECT t = 'Testtext' as Expect_1 from t1;
DROP TABLE t1;
--echo # End of 10.6 tests

View File

@@ -0,0 +1,10 @@
SET @saved_dbug= @@GLOBAL.debug_dbug;
SET @@GLOBAL.debug_dbug=
'+d,truncate_fde_post_header_len,truncate_fde_used_checksum_alg';
FLUSH BINARY LOGS;
ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Wrong offset or I/O error
SET @@GLOBAL.debug_dbug= '+d,truncate_fde_common_header_len';
FLUSH BINARY LOGS;
ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Wrong offset or I/O error
SET @@GLOBAL.debug_dbug= @saved_dbug;
RESET MASTER;

View File

@@ -0,0 +1,8 @@
CREATE TABLE t (a INT);
INSERT INTO t VALUES (0);
DROP TABLE t;
FLUSH BINARY LOGS;
#mariadb_binlog --debug=d,corrupt_table_map_colcnt_read --start-position=#binlog_start --stop-position=#binlog_stop #binlog_file 2>&1
FOUND 1 /CRC32 0x[[:xdigit:]]{8}.*\n# [Uu]nknown [Ee]vent/ in unknown_log_event.sql
#mariadb_binlog --debug=d,simulate_checksum_test_failure --stop-position=5 #binlog_file 2>&1
FOUND 1 /CRC32 0x[[:xdigit:]]{8}.*\n# [Uu]nknown [Ee]vent/ in unknown_log_event.sql

View File

@@ -0,0 +1,38 @@
--source include/have_debug.inc
--source include/have_binlog_format_mixed.inc # format-agnostic
# OOB read on malformed `Format_description_log_event`
#
# Verify that Format Description Events with truncated contents fails gracefully
# rather than underflow the post-header count and lead to buffer over-read.
SET @saved_dbug= @@GLOBAL.debug_dbug;
# MDEV-40366: `used_checksum_alg`
SET @@GLOBAL.debug_dbug=
'+d,truncate_fde_post_header_len,truncate_fde_used_checksum_alg';
FLUSH BINARY LOGS;
--let $binlog_file= query_get_value(SHOW BINLOG STATUS, File, 1)
--disable_query_log
--error ER_ERROR_WHEN_EXECUTING_COMMAND
--eval SHOW BINLOG EVENTS IN '$binlog_file'
--enable_query_log
# MDEV-40365: `common_header_len` & `post_header_len`
SET @@GLOBAL.debug_dbug= '+d,truncate_fde_common_header_len';
FLUSH BINARY LOGS;
--let $binlog_file= query_get_value(SHOW BINLOG STATUS, File, 1)
--disable_query_log
--error ER_ERROR_WHEN_EXECUTING_COMMAND
--eval SHOW BINLOG EVENTS IN '$binlog_file'
--enable_query_log
# Clean-up
SET @@GLOBAL.debug_dbug= @saved_dbug;
RESET MASTER;

View File

@@ -0,0 +1,37 @@
# MDEV-40674: Test `mariadb-binlog --force`'s Unknown event output
#
# Also: MDEV-40542
# MSAN use-of-uninitialized-value on Unknown_log_event::read_checksum_alg
--source include/have_debug.inc
--source include/have_binlog_format_row.inc # Testing with Table Map event
# Setup
CREATE TABLE t (a INT);
--let $binlog_file= query_get_value(SHOW BINLOG STATUS, File, 1)
--let $binlog_start= query_get_value(SHOW BINLOG STATUS, Position, 1)
# Generate an invalid Table Map event followed by an otherwise-valid Rows Event
INSERT INTO t VALUES (0);
--let $binlog_stop= query_get_value(SHOW BINLOG STATUS, Position, 1)
DROP TABLE t;
FLUSH BINARY LOGS;
--let SEARCH_FILE= $MYSQLTEST_VARDIR/tmp/unknown_log_event.sql
--let SEARCH_PATTERN= CRC32 0x[[:xdigit:]]{8}.*\\n# [Uu]nknown [Ee]vent
--let $mariadb_binlog= $MYSQL_BINLOG --result-file=$SEARCH_FILE --verify-binlog-checksum --force-read
--let $binlog_file= `SELECT CONCAT(@@datadir, '/$binlog_file')`
--echo #mariadb_binlog --debug=d,corrupt_table_map_colcnt_read --start-position=#binlog_start --stop-position=#binlog_stop #binlog_file 2>&1
--exec $mariadb_binlog --debug=d,corrupt_table_map_colcnt_read --start-position=$binlog_start --stop-position=$binlog_stop $binlog_file 2>&1
--source include/search_pattern_in_file.inc
# Test checksum failure
#
# Only test the first event since the rest of the binlog is unreadable
# without a valid Format Description, which is typically the first event.
--echo #mariadb_binlog --debug=d,simulate_checksum_test_failure --stop-position=5 #binlog_file 2>&1
--exec $mariadb_binlog --debug=d,simulate_checksum_test_failure --stop-position=5 $binlog_file 2>&1
--source include/search_pattern_in_file.inc

View File

@@ -11,6 +11,7 @@ call mtr.add_suppression('event read from binlog did not pass crc check');
call mtr.add_suppression('Replication event checksum verification failed');
call mtr.add_suppression('Event crc check failed! Most likely there is event corruption');
call mtr.add_suppression('Slave SQL: Error initializing relay log position: I/O error reading event at position .*, error.* 1593');
call mtr.add_suppression('Slave I/O: Fatal error: Event from master declares a length that does not match the packet the event arrived in;');
SET @old_master_verify_checksum = @@master_verify_checksum;
# 1. Creating test table/data and set corruption position for testing
connection master;

Some files were not shown because too many files have changed in this diff Show More