MXS-1621: Skip unneeded ALTER TABLE operations
Some ALTER TABLE operations (e.g. ADD INDEX) are not useful to the avrorouter. These need to be detected and skipped.
This commit is contained in:
parent
e14710ab2b
commit
93923acafb
@ -1021,6 +1021,40 @@ void unify_whitespace(char *sql, int len)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A very simple function for stripping auto-generated executable comments
|
||||
*
|
||||
* Note that the string will not strip the trailing part of the comment, making
|
||||
* the SQL invalid.
|
||||
*
|
||||
* @param sql String to modify
|
||||
* @param len Pointer to current length of string, updated to new length if
|
||||
* @c sql is modified
|
||||
*/
|
||||
static void strip_executable_comments(char *sql, int* len)
|
||||
{
|
||||
if (strncmp(sql, "/*!", 3) == 0 || strncmp(sql, "/*M!", 4) == 0)
|
||||
{
|
||||
// Executable comment, remove it
|
||||
char* p = sql + 3;
|
||||
if (*p == '!')
|
||||
{
|
||||
p++;
|
||||
}
|
||||
|
||||
// Skip the versioning part
|
||||
while (*p && isdigit(*p))
|
||||
{
|
||||
p++;
|
||||
}
|
||||
|
||||
int n_extra = p - sql;
|
||||
int new_len = *len - n_extra;
|
||||
memmove(sql, sql + n_extra, new_len);
|
||||
*len = new_len;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handling of query events
|
||||
*
|
||||
@ -1046,6 +1080,7 @@ void handle_query_event(AVRO_INSTANCE *router, REP_HEADER *hdr, int *pending_tra
|
||||
sql = tmp;
|
||||
len = tmpsz;
|
||||
unify_whitespace(sql, len);
|
||||
strip_executable_comments(sql, &len);
|
||||
sql[len] = '\0';
|
||||
|
||||
static bool warn_not_row_format = true;
|
||||
@ -1107,7 +1142,7 @@ void handle_query_event(AVRO_INSTANCE *router, REP_HEADER *hdr, int *pending_tra
|
||||
}
|
||||
else
|
||||
{
|
||||
MXS_ERROR("Alter statement to a table with no create statement.");
|
||||
MXS_ERROR("Alter statement to table '%s' has no preceding create statement.", ident);
|
||||
}
|
||||
}
|
||||
/* A transaction starts with this event */
|
||||
|
@ -337,9 +337,9 @@ bool handle_row_event(AVRO_INSTANCE *router, REP_HEADER *hdr, uint8_t *ptr)
|
||||
}
|
||||
else if (ncolumns == map->columns && create->columns != map->columns)
|
||||
{
|
||||
MXS_ERROR("Table map event has a different column "
|
||||
"count for table %s.%s than the CREATE TABLE statement.",
|
||||
map->database, map->table);
|
||||
MXS_ERROR("Table map event has a different column count for table "
|
||||
"%s.%s than the CREATE TABLE statement. Possible "
|
||||
"unsupported DDL detected.", map->database, map->table);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1392,6 +1392,14 @@ int get_column_index(TABLE_CREATE *create, const char *tok, int len)
|
||||
char safe_tok[len + 2];
|
||||
memcpy(safe_tok, tok, len);
|
||||
safe_tok[len] = '\0';
|
||||
|
||||
if (*safe_tok == '`')
|
||||
{
|
||||
int toklen = strlen(safe_tok) - 2; // Token length without backticks
|
||||
memmove(safe_tok, safe_tok + 1, toklen); // Overwrite first backtick
|
||||
safe_tok[toklen] = '\0'; // Null-terminate the string before the second backtick
|
||||
}
|
||||
|
||||
fix_reserved_word(safe_tok);
|
||||
|
||||
for (int x = 0; x < create->columns; x++)
|
||||
@ -1406,6 +1414,35 @@ int get_column_index(TABLE_CREATE *create, const char *tok, int len)
|
||||
return idx;
|
||||
}
|
||||
|
||||
static bool not_column_operation(const char* tok, int len)
|
||||
{
|
||||
const char* keywords[] =
|
||||
{
|
||||
"PRIMARY",
|
||||
"UNIQUE",
|
||||
"FULLTEXT",
|
||||
"SPATIAL",
|
||||
"PERIOD",
|
||||
"PRIMARY",
|
||||
"KEY",
|
||||
"KEYS",
|
||||
"INDEX",
|
||||
"FOREIGN",
|
||||
"CONSTRAINT",
|
||||
NULL
|
||||
};
|
||||
|
||||
for (int i = 0; keywords[i]; i++)
|
||||
{
|
||||
if (tok_eq(tok, keywords[i], strlen(keywords[i])))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool table_create_alter(TABLE_CREATE *create, const char *sql, const char *end)
|
||||
{
|
||||
const char *tbl = strcasestr(sql, "table"), *def;
|
||||
@ -1431,7 +1468,12 @@ bool table_create_alter(TABLE_CREATE *create, const char *sql, const char *end)
|
||||
|
||||
if (tok)
|
||||
{
|
||||
if (tok_eq(tok, "column", len))
|
||||
if (not_column_operation(tok, len))
|
||||
{
|
||||
MXS_INFO("Statement doesn't affect columns, not processing: %s", sql);
|
||||
return true;
|
||||
}
|
||||
else if (tok_eq(tok, "column", len))
|
||||
{
|
||||
// Skip the optional COLUMN keyword
|
||||
tok = get_tok(tok + len, &len, end);
|
||||
|
Loading…
x
Reference in New Issue
Block a user