res_config_mysql: Fix several issues related to recent table changes
authorGeorge Joseph <gjoseph@digium.com>
Wed, 12 Oct 2016 21:30:40 +0000 (15:30 -0600)
committerGeorge Joseph <gjoseph@digium.com>
Wed, 12 Oct 2016 21:49:01 +0000 (16:49 -0500)
Unlike any of the other database drivers, res_config_mysql checks that
the table definition matches the requirements for every insert and
update statement.  Since all requirements are forced to 'char', any
column that isn't a char, like ps_contacts' expiration_time,
qualify_timeout, etc., will throw a warning.  It's kinda harmless but
very misleading.  Since no other driver does those checks on insert
or update, they've been removed from res_config_mysql.  Also, all
the logic that actually attempted to ALTER the table to fix the issue
has been removed.  With the move to alembic, the auto-alter
functionality is not only unnecessary, it's also dangerous.

The other issue is that res_config_mysql calls the mysql_insert_id
function inside store_mysql.  Presumably the intention was to return
the number of rows inserted DESPITE A NOTE IN THE CODE THAT THE VALUE
IS NON_PORTABLE AND MAY CHANGE.  That value is then returned to
config realtime as the number of rows inserted.  Guess what?  The value
changed.  It now only returns the number of rows inserted if there's an
auto increment column on the table, which ps_contacts doesn't have.
Otherwise it returns 0.  So now, the insert worked but we tell config
realtime and sorcery that no rows were inserted.  That call to
mysql_insert_id was removed and we now always return 1 if the insert
succeeded.  We're only inserting 1 row at a time anyway.  If the insert
fails, we still return -1.

ASTERISK-26362 #close
Reported-by: Carlos Chavez

Change-Id: I83ce633efdb477b03c8399946994ee16fefceaf4

addons/res_config_mysql.c

index c9fa7c7..e6b0e53 100644 (file)
@@ -126,7 +126,6 @@ static char *handle_cli_realtime_mysql_status(struct ast_cli_entry *e, int cmd,
 static char *handle_cli_realtime_mysql_cache(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
 static int load_mysql_config(struct ast_config *config, const char *category, struct mysql_conn *conn);
 static int require_mysql(const char *database, const char *tablename, va_list ap);
 static char *handle_cli_realtime_mysql_cache(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
 static int load_mysql_config(struct ast_config *config, const char *category, struct mysql_conn *conn);
 static int require_mysql(const char *database, const char *tablename, va_list ap);
-static int internal_require(const char *database, const char *table, ...) attribute_sentinel;
 
 static struct ast_cli_entry cli_realtime_mysql_status[] = {
        AST_CLI_DEFINE(handle_cli_realtime_mysql_status, "Shows connection information for the MySQL RealTime driver"),
 
 static struct ast_cli_entry cli_realtime_mysql_status[] = {
        AST_CLI_DEFINE(handle_cli_realtime_mysql_status, "Shows connection information for the MySQL RealTime driver"),
@@ -165,16 +164,6 @@ static struct mysql_conn *find_database(const char *database, int for_write)
 
 #define release_database(a)    ast_mutex_unlock(&(a)->lock)
 
 
 #define release_database(a)    ast_mutex_unlock(&(a)->lock)
 
-static int internal_require(const char *database, const char *table, ...)
-{
-       va_list ap;
-       int res;
-       va_start(ap, table);
-       res = require_mysql(database, table, ap);
-       va_end(ap);
-       return res;
-}
-
 static void destroy_table(struct tables *table)
 {
        struct columns *column;
 static void destroy_table(struct tables *table)
 {
        struct columns *column;
@@ -600,11 +589,6 @@ static int update_mysql(const char *database, const char *tablename, const char
        ESCAPE_STRING(buf, field->value);
        ast_str_set(&sql, 0, "UPDATE %s SET `%s` = '%s'", tablename, field->name, ast_str_buffer(buf));
 
        ESCAPE_STRING(buf, field->value);
        ast_str_set(&sql, 0, "UPDATE %s SET `%s` = '%s'", tablename, field->name, ast_str_buffer(buf));
 
-       /* If the column length isn't long enough, give a chance to lengthen it. */
-       if (strncmp(column->type, "char", 4) == 0 || strncmp(column->type, "varchar", 7) == 0) {
-               internal_require(database, tablename, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
-       }
-
        while ((field = field->next)) {
                /* If the column is not within the table, then skip it */
                if (!(column = find_column(table, field->name))) {
        while ((field = field->next)) {
                /* If the column is not within the table, then skip it */
                if (!(column = find_column(table, field->name))) {
@@ -614,11 +598,6 @@ static int update_mysql(const char *database, const char *tablename, const char
 
                ESCAPE_STRING(buf, field->value);
                ast_str_append(&sql, 0, ", `%s` = '%s'", field->name, ast_str_buffer(buf));
 
                ESCAPE_STRING(buf, field->value);
                ast_str_append(&sql, 0, ", `%s` = '%s'", field->name, ast_str_buffer(buf));
-
-               /* If the column length isn't long enough, give a chance to lengthen it. */
-               if (strncmp(column->type, "char", 4) == 0 || strncmp(column->type, "varchar", 7) == 0) {
-                       internal_require(database, tablename, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
-               }
        }
 
        ESCAPE_STRING(buf, lookup);
        }
 
        ESCAPE_STRING(buf, lookup);
@@ -703,11 +682,6 @@ static int update2_mysql(const char *database, const char *tablename, const stru
                ESCAPE_STRING(buf, field->value);
                ast_str_append(&where, 0, "%s `%s` = '%s'", first ? "" : " AND", field->name, ast_str_buffer(buf));
                first = 0;
                ESCAPE_STRING(buf, field->value);
                ast_str_append(&where, 0, "%s `%s` = '%s'", first ? "" : " AND", field->name, ast_str_buffer(buf));
                first = 0;
-
-               /* If the column length isn't long enough, give a chance to lengthen it. */
-               if (strncmp(column->type, "char", 4) == 0 || strncmp(column->type, "varchar", 7) == 0) {
-                       internal_require(database, tablename, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
-               }
        }
 
        first = 1;
        }
 
        first = 1;
@@ -721,11 +695,6 @@ static int update2_mysql(const char *database, const char *tablename, const stru
                ESCAPE_STRING(buf, field->value);
                ast_str_append(&sql, 0, "%s `%s` = '%s'", first ? "" : ",", field->name, ast_str_buffer(buf));
                first = 0;
                ESCAPE_STRING(buf, field->value);
                ast_str_append(&sql, 0, "%s `%s` = '%s'", first ? "" : ",", field->name, ast_str_buffer(buf));
                first = 0;
-
-               /* If the column length isn't long enough, give a chance to lengthen it. */
-               if (strncmp(column->type, "char", 4) == 0 || strncmp(column->type, "varchar", 7) == 0) {
-                       internal_require(database, tablename, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
-               }
        }
 
        release_table(table);
        }
 
        release_table(table);
@@ -759,7 +728,6 @@ static int update2_mysql(const char *database, const char *tablename, const stru
 static int store_mysql(const char *database, const char *table, const struct ast_variable *rt_fields)
 {
        struct mysql_conn *dbh;
 static int store_mysql(const char *database, const char *table, const struct ast_variable *rt_fields)
 {
        struct mysql_conn *dbh;
-       my_ulonglong insertid;
        struct ast_str *sql = ast_str_thread_get(&sql_buf, 16);
        struct ast_str *sql2 = ast_str_thread_get(&sql2_buf, 16);
        struct ast_str *buf = ast_str_thread_get(&scratch_buf, 16);
        struct ast_str *sql = ast_str_thread_get(&sql_buf, 16);
        struct ast_str *sql2 = ast_str_thread_get(&sql2_buf, 16);
        struct ast_str *buf = ast_str_thread_get(&scratch_buf, 16);
@@ -792,15 +760,11 @@ static int store_mysql(const char *database, const char *table, const struct ast
        ast_str_set(&sql, 0, "INSERT INTO %s (`%s`", table, field->name);
        ast_str_set(&sql2, 0, ") VALUES ('%s'", ast_str_buffer(buf));
 
        ast_str_set(&sql, 0, "INSERT INTO %s (`%s`", table, field->name);
        ast_str_set(&sql2, 0, ") VALUES ('%s'", ast_str_buffer(buf));
 
-       internal_require(database, table, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
-
        while ((field = field->next)) {
                ESCAPE_STRING(buf, field->value);
 
        while ((field = field->next)) {
                ESCAPE_STRING(buf, field->value);
 
-               if (internal_require(database, table, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL) == 0) {
-                       ast_str_append(&sql, 0, ", `%s`", field->name);
-                       ast_str_append(&sql2, 0, ", '%s'", ast_str_buffer(buf));
-               }
+               ast_str_append(&sql, 0, ", `%s`", field->name);
+               ast_str_append(&sql2, 0, ", '%s'", ast_str_buffer(buf));
        }
        ast_str_append(&sql, 0, "%s)", ast_str_buffer(sql2));
        ast_debug(1,"MySQL RealTime: Insert SQL: %s\n", ast_str_buffer(sql));
        }
        ast_str_append(&sql, 0, "%s)", ast_str_buffer(sql2));
        ast_debug(1,"MySQL RealTime: Insert SQL: %s\n", ast_str_buffer(sql));
@@ -812,18 +776,11 @@ static int store_mysql(const char *database, const char *table, const struct ast
                return -1;
        }
 
                return -1;
        }
 
-       /*!\note The return value is non-portable and may change in future versions. */
-       insertid = mysql_insert_id(&dbh->handle);
        release_database(dbh);
 
        release_database(dbh);
 
-       ast_debug(1, "MySQL RealTime: row inserted on table: %s, id: %llu\n", table, insertid);
+       ast_debug(1, "MySQL RealTime: row inserted on table: %s\n", table);
 
 
-       /* From http://dev.mysql.com/doc/mysql/en/mysql-affected-rows.html
-        * An integer greater than zero indicates the number of rows affected
-        * Zero indicates that no records were updated
-        * -1 indicates that the query returned an error (although, if the query failed, it should have been caught above.)
-       */
-       return (int)insertid;
+       return 1;
 }
 
 static int destroy_mysql(const char *database, const char *table, const char *keyfield, const char *lookup, const struct ast_variable *rt_fields)
 }
 
 static int destroy_mysql(const char *database, const char *table, const char *keyfield, const char *lookup, const struct ast_variable *rt_fields)
@@ -989,105 +946,14 @@ static int unload_mysql(const char *database, const char *tablename)
        return cur ? 0 : -1;
 }
 
        return cur ? 0 : -1;
 }
 
-static int modify_mysql(const char *database, const char *tablename, struct columns *column, require_type type, int len)
-{
-       /*!\note Cannot use ANY of the same scratch space as is used in other functions, as this one is interspersed. */
-       struct ast_str *sql = ast_str_thread_get(&modify_buf, 100), *escbuf = ast_str_thread_get(&modify2_buf, 100);
-       struct ast_str *typestr = ast_str_thread_get(&modify3_buf, 30);
-       int waschar = strncasecmp(column->type, "char", 4) == 0 ? 1 : 0;
-       int wasvarchar = strncasecmp(column->type, "varchar", 7) == 0 ? 1 : 0;
-       int res = 0;
-       struct mysql_conn *dbh;
-
-       if (!(dbh = find_database(database, 1))) {
-               return -1;
-       }
-
-       do {
-               if (type == RQ_CHAR || waschar || wasvarchar) {
-                       if (wasvarchar) {
-                               ast_str_set(&typestr, 0, "VARCHAR(%d)", len);
-                       } else {
-                               ast_str_set(&typestr, 0, "CHAR(%d)", len);
-                       }
-               } else if (type == RQ_UINTEGER1) {
-                       ast_str_set(&typestr, 0, "tinyint(3) unsigned");
-               } else if (type == RQ_INTEGER1) {
-                       ast_str_set(&typestr, 0, "tinyint(4)");
-               } else if (type == RQ_UINTEGER2) {
-                       ast_str_set(&typestr, 0, "smallint(5) unsigned");
-               } else if (type == RQ_INTEGER2) {
-                       ast_str_set(&typestr, 0, "smallint(6)");
-               } else if (type == RQ_UINTEGER3) {
-                       ast_str_set(&typestr, 0, "mediumint(8) unsigned");
-               } else if (type == RQ_INTEGER3) {
-                       ast_str_set(&typestr, 0, "mediumint(8)");
-               } else if (type == RQ_UINTEGER4) {
-                       ast_str_set(&typestr, 0, "int(10) unsigned");
-               } else if (type == RQ_INTEGER4) {
-                       ast_str_set(&typestr, 0, "int(11)");
-               } else if (type == RQ_UINTEGER8) {
-                       ast_str_set(&typestr, 0, "bigint(19) unsigned");
-               } else if (type == RQ_INTEGER8) {
-                       ast_str_set(&typestr, 0, "bigint(20)");
-               } else if (type == RQ_DATETIME) {
-                       ast_str_set(&typestr, 0, "datetime");
-               } else if (type == RQ_DATE) {
-                       ast_str_set(&typestr, 0, "date");
-               } else if (type == RQ_FLOAT) {
-                       ast_str_set(&typestr, 0, "FLOAT(%d,2)", len);
-               } else {
-                       ast_log(LOG_ERROR, "Unknown type (should NEVER happen)\n");
-                       res = -1;
-                       break;
-               }
-               ast_str_set(&sql, 0, "ALTER TABLE %s MODIFY `%s` %s", tablename, column->name, ast_str_buffer(typestr));
-               if (!column->null) {
-                       ast_str_append(&sql, 0, " NOT NULL");
-               }
-               if (!ast_strlen_zero(column->dflt)) {
-                       ESCAPE_STRING(escbuf, column->dflt);
-                       ast_str_append(&sql, 0, " DEFAULT '%s'", ast_str_buffer(escbuf));
-               }
-
-               if (!mysql_reconnect(dbh)) {
-                       ast_log(LOG_ERROR, "Unable to add column: %s\n", ast_str_buffer(sql));
-                       res = -1;
-                       break;
-               }
-
-               /* Execution. */
-               if (mysql_real_query(&dbh->handle, ast_str_buffer(sql), ast_str_strlen(sql))) {
-                       ast_log(LOG_WARNING, "MySQL RealTime: Failed to modify database: %s\n", mysql_error(&dbh->handle));
-                       ast_debug(1, "MySQL RealTime: Query: %s\n", ast_str_buffer(sql));
-                       res = -1;
-               }
-       } while (0);
-
-       release_database(dbh);
-       return res;
-}
-
-#define PICK_WHICH_ALTER_ACTION(stringtype) \
-       if (table->database->requirements == RQ_WARN) {                                                                       \
-               ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for "            \
-                       "the required data length: %d (detected stringtype)\n",                                      \
-                       tablename, database, column->name, size);                                                    \
-               res = -1;                                                                                        \
-       } else if (table->database->requirements == RQ_CREATECLOSE && modify_mysql(database, tablename, column, type, size) == 0) {     \
-               table_altered = 1;                                                                               \
-       } else if (table->database->requirements == RQ_CREATECHAR && modify_mysql(database, tablename, column, RQ_CHAR, size) == 0) {   \
-               table_altered = 1;                                                                               \
-       } else {                                                                                             \
-               res = -1;                                                                                        \
-       }
-
 static int require_mysql(const char *database, const char *tablename, va_list ap)
 {
        struct columns *column;
        struct tables *table = find_table(database, tablename);
        char *elm;
 static int require_mysql(const char *database, const char *tablename, va_list ap)
 {
        struct columns *column;
        struct tables *table = find_table(database, tablename);
        char *elm;
-       int type, size, res = 0, table_altered = 0;
+       int type;
+       int size;
+       int res = 0;
 
        if (!table) {
                ast_log(LOG_WARNING, "Table %s not found in database.  This table should exist if you're using realtime.\n", tablename);
 
        if (!table) {
                ast_log(LOG_WARNING, "Table %s not found in database.  This table should exist if you're using realtime.\n", tablename);
@@ -1097,55 +963,54 @@ static int require_mysql(const char *database, const char *tablename, va_list ap
        while ((elm = va_arg(ap, char *))) {
                type = va_arg(ap, require_type);
                size = va_arg(ap, int);
        while ((elm = va_arg(ap, char *))) {
                type = va_arg(ap, require_type);
                size = va_arg(ap, int);
+
                AST_LIST_TRAVERSE(&table->columns, column, list) {
                        if (strcmp(column->name, elm) == 0) {
                                /* Char can hold anything, as long as it is large enough */
                                if (strncmp(column->type, "char", 4) == 0 || strncmp(column->type, "varchar", 7) == 0) {
                                        if ((size > column->len) && column->len != -1) {
                AST_LIST_TRAVERSE(&table->columns, column, list) {
                        if (strcmp(column->name, elm) == 0) {
                                /* Char can hold anything, as long as it is large enough */
                                if (strncmp(column->type, "char", 4) == 0 || strncmp(column->type, "varchar", 7) == 0) {
                                        if ((size > column->len) && column->len != -1) {
-                                               if (table->database->requirements == RQ_WARN) {
-                                                       ast_log(LOG_WARNING, "Realtime table %s@%s: Column '%s' should be at least %d long, but is only %d long.\n", database, tablename, column->name, size, column->len);
-                                                       res = -1;
-                                               } else if (modify_mysql(database, tablename, column, type, size) == 0) {
-                                                       table_altered = 1;
-                                               } else {
-                                                       res = -1;
-                                               }
+                                               ast_log(LOG_WARNING, "Realtime table %s@%s: Column '%s' should be at least %d long, but is only %d long.\n", database, tablename, column->name, size, column->len);
+                                               res = -1;
                                        }
                                } else if (strcasestr(column->type, "unsigned")) {
                                        if (!ast_rq_is_int(type)) {
                                        }
                                } else if (strcasestr(column->type, "unsigned")) {
                                        if (!ast_rq_is_int(type)) {
-                                               if (table->database->requirements == RQ_WARN) {
-                                                       ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' cannot be type '%s' (need %s)\n",
-                                                               database, tablename, column->name, column->type,
-                                                               type == RQ_CHAR ? "char" : type == RQ_FLOAT ? "float" :
-                                                               type == RQ_DATETIME ? "datetime" : type == RQ_DATE ? "date" : "a rather stiff drink");
-                                                       res = -1;
-                                               } else if (table->database->requirements == RQ_CREATECLOSE && modify_mysql(database, tablename, column, type, size) == 0) {
-                                                       table_altered = 1;
-                                               } else if (table->database->requirements == RQ_CREATECHAR && modify_mysql(database, tablename, column, RQ_CHAR, size) == 0) {
-                                                       table_altered = 1;
-                                               } else {
-                                                       res = -1;
-                                               }
+                                               ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' cannot be type '%s' (need %s)\n",
+                                                       database, tablename, column->name, column->type,
+                                                       type == RQ_CHAR ? "char" : type == RQ_FLOAT ? "float" :
+                                                       type == RQ_DATETIME ? "datetime" : type == RQ_DATE ? "date" : "a rather stiff drink");
+                                               res = -1;
                                        } else if (strncasecmp(column->type, "tinyint", 1) == 0) {
                                                if (type != RQ_UINTEGER1) {
                                        } else if (strncasecmp(column->type, "tinyint", 1) == 0) {
                                                if (type != RQ_UINTEGER1) {
-                                                       PICK_WHICH_ALTER_ACTION(unsigned tinyint)
+                                                       ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for "            \
+                                                               "the required data length: %d (detected stringtype)\n",                                      \
+                                                               tablename, database, column->name, size);                                                    \
+                                                       res = -1;                                                                                        \
                                                }
                                        } else if (strncasecmp(column->type, "smallint", 1) == 0) {
                                                if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 && type != RQ_UINTEGER2) {
                                                }
                                        } else if (strncasecmp(column->type, "smallint", 1) == 0) {
                                                if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 && type != RQ_UINTEGER2) {
-                                                       PICK_WHICH_ALTER_ACTION(unsigned smallint)
+                                                       ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for "            \
+                                                               "the required data length: %d (detected stringtype)\n",                                      \
+                                                               tablename, database, column->name, size);                                                    \
+                                                       res = -1;                                                                                        \
                                                }
                                        } else if (strncasecmp(column->type, "mediumint", 1) == 0) {
                                                if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 &&
                                                        type != RQ_UINTEGER2 && type != RQ_INTEGER2 &&
                                                        type != RQ_UINTEGER3) {
                                                }
                                        } else if (strncasecmp(column->type, "mediumint", 1) == 0) {
                                                if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 &&
                                                        type != RQ_UINTEGER2 && type != RQ_INTEGER2 &&
                                                        type != RQ_UINTEGER3) {
-                                                       PICK_WHICH_ALTER_ACTION(unsigned mediumint)
+                                                       ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for "            \
+                                                               "the required data length: %d (detected stringtype)\n",                                      \
+                                                               tablename, database, column->name, size);                                                    \
+                                                       res = -1;                                                                                        \
                                                }
                                        } else if (strncasecmp(column->type, "int", 1) == 0) {
                                                if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 &&
                                                        type != RQ_UINTEGER2 && type != RQ_INTEGER2 &&
                                                        type != RQ_UINTEGER3 && type != RQ_INTEGER3 &&
                                                        type != RQ_UINTEGER4) {
                                                }
                                        } else if (strncasecmp(column->type, "int", 1) == 0) {
                                                if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 &&
                                                        type != RQ_UINTEGER2 && type != RQ_INTEGER2 &&
                                                        type != RQ_UINTEGER3 && type != RQ_INTEGER3 &&
                                                        type != RQ_UINTEGER4) {
-                                                       PICK_WHICH_ALTER_ACTION(unsigned int)
+                                                       ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for "            \
+                                                               "the required data length: %d (detected stringtype)\n",                                      \
+                                                               tablename, database, column->name, size);                                                    \
+                                                       res = -1;                                                                                        \
                                                }
                                        } else if (strncasecmp(column->type, "bigint", 1) == 0) {
                                                if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 &&
                                                }
                                        } else if (strncasecmp(column->type, "bigint", 1) == 0) {
                                                if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 &&
@@ -1153,45 +1018,52 @@ static int require_mysql(const char *database, const char *tablename, va_list ap
                                                        type != RQ_UINTEGER3 && type != RQ_INTEGER3 &&
                                                        type != RQ_UINTEGER4 && type != RQ_INTEGER4 &&
                                                        type != RQ_UINTEGER8) {
                                                        type != RQ_UINTEGER3 && type != RQ_INTEGER3 &&
                                                        type != RQ_UINTEGER4 && type != RQ_INTEGER4 &&
                                                        type != RQ_UINTEGER8) {
-                                                       PICK_WHICH_ALTER_ACTION(unsigned bigint)
+                                                       ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for "            \
+                                                               "the required data length: %d (detected stringtype)\n",                                      \
+                                                               tablename, database, column->name, size);                                                    \
+                                                       res = -1;                                                                                        \
                                                }
                                        }
                                } else if (strcasestr(column->type, "int")) {
                                        if (!ast_rq_is_int(type)) {
                                                }
                                        }
                                } else if (strcasestr(column->type, "int")) {
                                        if (!ast_rq_is_int(type)) {
-                                               if (table->database->requirements == RQ_WARN) {
-                                                       ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' cannot be type '%s' (need %s)\n",
-                                                               database, tablename, column->name, column->type,
-                                                               type == RQ_CHAR ? "char" : type == RQ_FLOAT ? "float" :
-                                                               type == RQ_DATETIME ? "datetime" : type == RQ_DATE ? "date" :
-                                                               "to get a life, rather than writing silly error messages");
-                                                       res = -1;
-                                               } else if (table->database->requirements == RQ_CREATECLOSE && modify_mysql(database, tablename, column, type, size) == 0) {
-                                                       table_altered = 1;
-                                               } else if (table->database->requirements == RQ_CREATECHAR && modify_mysql(database, tablename, column, RQ_CHAR, size) == 0) {
-                                                       table_altered = 1;
-                                               } else {
-                                                       res = -1;
-                                               }
+                                               ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' cannot be type '%s' (need %s)\n",
+                                                       database, tablename, column->name, column->type,
+                                                       type == RQ_CHAR ? "char" : type == RQ_FLOAT ? "float" :
+                                                       type == RQ_DATETIME ? "datetime" : type == RQ_DATE ? "date" :
+                                                       "to get a life, rather than writing silly error messages");
+                                               res = -1;
                                        } else if (strncasecmp(column->type, "tinyint", 1) == 0) {
                                                if (type != RQ_INTEGER1) {
                                        } else if (strncasecmp(column->type, "tinyint", 1) == 0) {
                                                if (type != RQ_INTEGER1) {
-                                                       PICK_WHICH_ALTER_ACTION(tinyint)
+                                                       ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for "            \
+                                                               "the required data length: %d (detected stringtype)\n",                                      \
+                                                               tablename, database, column->name, size);                                                    \
+                                                       res = -1;                                                                                        \
                                                }
                                        } else if (strncasecmp(column->type, "smallint", 1) == 0) {
                                                if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 && type != RQ_INTEGER2) {
                                                }
                                        } else if (strncasecmp(column->type, "smallint", 1) == 0) {
                                                if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 && type != RQ_INTEGER2) {
-                                                       PICK_WHICH_ALTER_ACTION(smallint)
+                                                       ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for "            \
+                                                               "the required data length: %d (detected stringtype)\n",                                      \
+                                                               tablename, database, column->name, size);                                                    \
+                                                       res = -1;                                                                                        \
                                                }
                                        } else if (strncasecmp(column->type, "mediumint", 1) == 0) {
                                                if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 &&
                                                        type != RQ_UINTEGER2 && type != RQ_INTEGER2 &&
                                                        type != RQ_INTEGER3) {
                                                }
                                        } else if (strncasecmp(column->type, "mediumint", 1) == 0) {
                                                if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 &&
                                                        type != RQ_UINTEGER2 && type != RQ_INTEGER2 &&
                                                        type != RQ_INTEGER3) {
-                                                       PICK_WHICH_ALTER_ACTION(mediumint)
+                                                       ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for "            \
+                                                               "the required data length: %d (detected stringtype)\n",                                      \
+                                                               tablename, database, column->name, size);                                                    \
+                                                       res = -1;                                                                                        \
                                                }
                                        } else if (strncasecmp(column->type, "int", 1) == 0) {
                                                if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 &&
                                                        type != RQ_UINTEGER2 && type != RQ_INTEGER2 &&
                                                        type != RQ_UINTEGER3 && type != RQ_INTEGER3 &&
                                                        type != RQ_INTEGER4) {
                                                }
                                        } else if (strncasecmp(column->type, "int", 1) == 0) {
                                                if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 &&
                                                        type != RQ_UINTEGER2 && type != RQ_INTEGER2 &&
                                                        type != RQ_UINTEGER3 && type != RQ_INTEGER3 &&
                                                        type != RQ_INTEGER4) {
-                                                       PICK_WHICH_ALTER_ACTION(int)
+                                                       ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for "            \
+                                                               "the required data length: %d (detected stringtype)\n",                                      \
+                                                               tablename, database, column->name, size);                                                    \
+                                                       res = -1;                                                                                        \
                                                }
                                        } else if (strncasecmp(column->type, "bigint", 1) == 0) {
                                                if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 &&
                                                }
                                        } else if (strncasecmp(column->type, "bigint", 1) == 0) {
                                                if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 &&
@@ -1199,137 +1071,41 @@ static int require_mysql(const char *database, const char *tablename, va_list ap
                                                        type != RQ_UINTEGER3 && type != RQ_INTEGER3 &&
                                                        type != RQ_UINTEGER4 && type != RQ_INTEGER4 &&
                                                        type != RQ_INTEGER8) {
                                                        type != RQ_UINTEGER3 && type != RQ_INTEGER3 &&
                                                        type != RQ_UINTEGER4 && type != RQ_INTEGER4 &&
                                                        type != RQ_INTEGER8) {
-                                                       PICK_WHICH_ALTER_ACTION(bigint)
+                                                       ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for "            \
+                                                               "the required data length: %d (detected stringtype)\n",                                      \
+                                                               tablename, database, column->name, size);                                                    \
+                                                       res = -1;                                                                                        \
                                                }
                                        }
                                } else if (strncmp(column->type, "float", 5) == 0) {
                                        if (!ast_rq_is_int(type) && type != RQ_FLOAT) {
                                                }
                                        }
                                } else if (strncmp(column->type, "float", 5) == 0) {
                                        if (!ast_rq_is_int(type) && type != RQ_FLOAT) {
-                                               if (table->database->requirements == RQ_WARN) {
-                                                       ast_log(LOG_WARNING, "Realtime table %s@%s: Column %s cannot be a %s\n", tablename, database, column->name, column->type);
-                                                       res = -1;
-                                               } else if (table->database->requirements == RQ_CREATECLOSE && modify_mysql(database, tablename, column, type, size) == 0) {
-                                                       table_altered = 1;
-                                               } else if (table->database->requirements == RQ_CREATECHAR && modify_mysql(database, tablename, column, RQ_CHAR, size) == 0) {
-                                                       table_altered = 1;
-                                               } else {
-                                                       res = -1;
-                                               }
+                                               ast_log(LOG_WARNING, "Realtime table %s@%s: Column %s cannot be a %s\n", tablename, database, column->name, column->type);
+                                               res = -1;
                                        }
                                } else if (strncmp(column->type, "datetime", 8) == 0 || strncmp(column->type, "timestamp", 9) == 0) {
                                        if (type != RQ_DATETIME) {
                                        }
                                } else if (strncmp(column->type, "datetime", 8) == 0 || strncmp(column->type, "timestamp", 9) == 0) {
                                        if (type != RQ_DATETIME) {
-                                               if (table->database->requirements == RQ_WARN) {
-                                                       ast_log(LOG_WARNING, "Realtime table %s@%s: Column %s cannot be a %s\n", tablename, database, column->name, column->type);
-                                                       res = -1;
-                                               } else if (table->database->requirements == RQ_CREATECLOSE && modify_mysql(database, tablename, column, type, size) == 0) {
-                                                       table_altered = 1;
-                                               } else if (table->database->requirements == RQ_CREATECHAR && modify_mysql(database, tablename, column, RQ_CHAR, size) == 0) {
-                                                       table_altered = 1;
-                                               } else {
-                                                       res = -1;
-                                               }
+                                               ast_log(LOG_WARNING, "Realtime table %s@%s: Column %s cannot be a %s\n", tablename, database, column->name, column->type);
+                                               res = -1;
                                        }
                                } else if (strncmp(column->type, "date", 4) == 0) {
                                        if (type != RQ_DATE) {
                                        }
                                } else if (strncmp(column->type, "date", 4) == 0) {
                                        if (type != RQ_DATE) {
-                                               if (table->database->requirements == RQ_WARN) {
-                                                       ast_log(LOG_WARNING, "Realtime table %s@%s: Column %s cannot be a %s\n", tablename, database, column->name, column->type);
-                                                       res = -1;
-                                               } else if (table->database->requirements == RQ_CREATECLOSE && modify_mysql(database, tablename, column, type, size) == 0) {
-                                                       table_altered = 1;
-                                               } else if (table->database->requirements == RQ_CREATECHAR && modify_mysql(database, tablename, column, RQ_CHAR, size) == 0) {
-                                                       table_altered = 1;
-                                               } else {
-                                                       res = -1;
-                                               }
-                                       }
-                               } else { /* Other, possibly unsupported types? */
-                                       if (table->database->requirements == RQ_WARN) {
-                                               ast_log(LOG_WARNING, "Possibly unsupported column type '%s' on column '%s'\n", column->type, column->name);
+                                               ast_log(LOG_WARNING, "Realtime table %s@%s: Column %s cannot be a %s\n", tablename, database, column->name, column->type);
                                                res = -1;
                                                res = -1;
-                                       } else if (table->database->requirements == RQ_CREATECLOSE && modify_mysql(database, tablename, column, type, size) == 0) {
-                                               table_altered = 1;
-                                       } else if (table->database->requirements == RQ_CREATECHAR && modify_mysql(database, tablename, column, RQ_CHAR, size) == 0) {
-                                               table_altered = 1;
-                                       } else {
                                        }
                                        }
+                               } else { /* Other, possibly unsupported types? */
+                                       ast_log(LOG_WARNING, "Possibly unsupported column type '%s' on column '%s'\n", column->type, column->name);
+                                       res = -1;
                                }
                                break;
                        }
                }
 
                if (!column) {
                                }
                                break;
                        }
                }
 
                if (!column) {
-                       if (table->database->requirements == RQ_WARN) {
-                               ast_log(LOG_WARNING, "Table %s requires a column '%s' of size '%d', but no such column exists.\n", tablename, elm, size);
-                       } else {
-                               struct ast_str *sql = ast_str_thread_get(&modify_buf, 100), *fieldtype = ast_str_thread_get(&modify3_buf, 16);
-
-                               if (table->database->requirements == RQ_CREATECHAR || type == RQ_CHAR) {
-                                       ast_str_set(&fieldtype, 0, "CHAR(%d)", size);
-                               } else if (type == RQ_UINTEGER1 || type == RQ_UINTEGER2 || type == RQ_UINTEGER3 || type == RQ_UINTEGER4 || type == RQ_UINTEGER8) {
-                                       if (type == RQ_UINTEGER1) {
-                                               ast_str_set(&fieldtype, 0, "TINYINT(3) UNSIGNED");
-                                       } else if (type == RQ_UINTEGER2) {
-                                               ast_str_set(&fieldtype, 0, "SMALLINT(5) UNSIGNED");
-                                       } else if (type == RQ_UINTEGER3) {
-                                               ast_str_set(&fieldtype, 0, "MEDIUMINT(8) UNSIGNED");
-                                       } else if (type == RQ_UINTEGER4) {
-                                               ast_str_set(&fieldtype, 0, "INT(10) UNSIGNED");
-                                       } else if (type == RQ_UINTEGER8) {
-                                               ast_str_set(&fieldtype, 0, "BIGINT(20) UNSIGNED");
-                                       } else {
-                                               ast_log(LOG_WARNING, "Somebody should check this code for a rather large bug... it's about to squash Tokyo.\n");
-                                               continue;
-                                       }
-                               } else if (ast_rq_is_int(type)) {
-                                       if (type == RQ_INTEGER1) {
-                                               ast_str_set(&fieldtype, 0, "TINYINT(3)");
-                                       } else if (type == RQ_INTEGER2) {
-                                               ast_str_set(&fieldtype, 0, "SMALLINT(5)");
-                                       } else if (type == RQ_INTEGER3) {
-                                               ast_str_set(&fieldtype, 0, "MEDIUMINT(8)");
-                                       } else if (type == RQ_INTEGER4) {
-                                               ast_str_set(&fieldtype, 0, "INT(10)");
-                                       } else if (type == RQ_INTEGER8) {
-                                               ast_str_set(&fieldtype, 0, "BIGINT(20)");
-                                       } else {
-                                               ast_log(LOG_WARNING, "Somebody should check this code for a rather large bug... it's about to eat Cincinnati.\n");
-                                               continue;
-                                       }
-                               } else if (type == RQ_FLOAT) {
-                                       ast_str_set(&fieldtype, 0, "FLOAT");
-                               } else if (type == RQ_DATE) {
-                                       ast_str_set(&fieldtype, 0, "DATE");
-                               } else if (type == RQ_DATETIME) {
-                                       ast_str_set(&fieldtype, 0, "DATETIME");
-                               } else {
-                                       continue;
-                               }
-                               ast_str_set(&sql, 0, "ALTER TABLE %s ADD COLUMN %s %s", tablename, elm, ast_str_buffer(fieldtype));
-
-                               ast_mutex_lock(&table->database->lock);
-                               if (!mysql_reconnect(table->database)) {
-                                       ast_mutex_unlock(&table->database->lock);
-                                       ast_log(LOG_ERROR, "Unable to add column: %s\n", ast_str_buffer(sql));
-                                       continue;
-                               }
-
-                               /* Execution. */
-                               if (mysql_real_query(&table->database->handle, ast_str_buffer(sql), ast_str_strlen(sql))) {
-                                       ast_log(LOG_WARNING, "MySQL RealTime: Failed to query database. Check debug for more info.\n");
-                                       ast_debug(1, "MySQL RealTime: Query: %s\n", ast_str_buffer(sql));
-                                       ast_debug(1, "MySQL RealTime: Query Failed because: %s\n", mysql_error(&table->database->handle));
-                               } else {
-                                       table_altered = 1;
-                               }
-                       }
+                       ast_log(LOG_WARNING, "Table %s requires a column '%s' of size '%d', but no such column exists.\n", tablename, elm, size);
                }
        }
        release_table(table);
 
                }
        }
        release_table(table);
 
-       /* If we altered the table, we must refresh the cache */
-       if (table_altered) {
-               unload_mysql(database, tablename);
-               release_table(find_table(database, tablename));
-       }
        return res;
 }
 
        return res;
 }