MXS-1339 QC: Report each table just once
If a particular table appears in a statement multiple times, qc_get_table_names will report it as many times as it appears. Each name should be reported just once. Same applies for database names.
This commit is contained in:
@ -1552,16 +1552,31 @@ int32_t qc_mysql_get_table_names(GWBUF* querybuf, int32_t fullnames, char*** tab
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!catnm)
|
||||||
|
{
|
||||||
|
// Sometimes the tablename is "*"; we exclude that.
|
||||||
|
if (strcmp(tbl->table_name, "*") != 0)
|
||||||
|
{
|
||||||
|
catnm = strdup(tbl->table_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (catnm)
|
if (catnm)
|
||||||
|
{
|
||||||
|
int j = 0;
|
||||||
|
|
||||||
|
while ((j < i) && (strcmp(catnm, tables[j]) != 0))
|
||||||
|
{
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j == i) // Not found
|
||||||
{
|
{
|
||||||
tables[i++] = catnm;
|
tables[i++] = catnm;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Sometimes the tablename is "*"; we exclude that.
|
free(catnm);
|
||||||
if (strcmp(tbl->table_name, "*") != 0)
|
|
||||||
{
|
|
||||||
tables[i++] = strdup(tbl->table_name);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1854,8 +1869,18 @@ int32_t qc_mysql_get_database_names(GWBUF* querybuf, char*** databasesp, int* si
|
|||||||
currsz = currsz * 2 + 1;
|
currsz = currsz * 2 + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int j = 0;
|
||||||
|
|
||||||
|
while ((j < i) && (strcmp(tbl->db, databases[j]) != 0))
|
||||||
|
{
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j == i) // Not found
|
||||||
|
{
|
||||||
databases[i++] = strdup(tbl->db);
|
databases[i++] = strdup(tbl->db);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tbl = tbl->next_local;
|
tbl = tbl->next_local;
|
||||||
}
|
}
|
||||||
|
@ -444,58 +444,53 @@ public:
|
|||||||
{
|
{
|
||||||
if (strcasecmp(zTable, "DUAL") != 0)
|
if (strcasecmp(zTable, "DUAL") != 0)
|
||||||
{
|
{
|
||||||
char* zCopy = MXS_STRDUP(zTable);
|
size_t table_len = strlen(zTable);
|
||||||
MXS_ABORT_IF_NULL(zCopy);
|
char table[table_len + 1];
|
||||||
|
|
||||||
|
strcpy(table, zTable);
|
||||||
// TODO: Is this call really needed. Check also sqlite3Dequote.
|
// TODO: Is this call really needed. Check also sqlite3Dequote.
|
||||||
exposed_sqlite3Dequote(zCopy);
|
exposed_sqlite3Dequote(table);
|
||||||
|
|
||||||
|
if (!table_name_collected(table))
|
||||||
|
{
|
||||||
|
char* zCopy = MXS_STRDUP_A(table);
|
||||||
|
|
||||||
enlarge_string_array(1, table_names_len, &table_names, &table_names_capacity);
|
enlarge_string_array(1, table_names_len, &table_names, &table_names_capacity);
|
||||||
table_names[table_names_len++] = zCopy;
|
table_names[table_names_len++] = zCopy;
|
||||||
table_names[table_names_len] = NULL;
|
table_names[table_names_len] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t database_len = zDatabase ? strlen(zDatabase) : 0;
|
||||||
|
char fullname[database_len + 1 + table_len + 1];
|
||||||
|
|
||||||
if (zDatabase)
|
if (zDatabase)
|
||||||
{
|
{
|
||||||
zCopy = (char*)MXS_MALLOC(strlen(zDatabase) + 1 + strlen(zTable) + 1);
|
strcpy(fullname, zDatabase);
|
||||||
MXS_ABORT_IF_NULL(zCopy);
|
// TODO: Is this call really needed. Check also sqlite3Dequote.
|
||||||
|
exposed_sqlite3Dequote(fullname);
|
||||||
strcpy(zCopy, zDatabase);
|
strcat(fullname, ".");
|
||||||
strcat(zCopy, ".");
|
|
||||||
strcat(zCopy, zTable);
|
|
||||||
exposed_sqlite3Dequote(zCopy);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
zCopy = MXS_STRDUP(zCopy);
|
fullname[0] = 0;
|
||||||
MXS_ABORT_IF_NULL(zCopy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
strcat(fullname, table);
|
||||||
|
|
||||||
|
if (!table_fullname_collected(fullname))
|
||||||
|
{
|
||||||
|
char* zCopy = MXS_STRDUP_A(fullname);
|
||||||
|
|
||||||
enlarge_string_array(1, table_fullnames_len,
|
enlarge_string_array(1, table_fullnames_len,
|
||||||
&table_fullnames, &table_fullnames_capacity);
|
&table_fullnames, &table_fullnames_capacity);
|
||||||
table_fullnames[table_fullnames_len++] = zCopy;
|
table_fullnames[table_fullnames_len++] = zCopy;
|
||||||
table_fullnames[table_fullnames_len] = NULL;
|
table_fullnames[table_fullnames_len] = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((collect & QC_COLLECT_DATABASES) && !(collected & QC_COLLECT_DATABASES))
|
|
||||||
{
|
|
||||||
if (zDatabase)
|
|
||||||
{
|
|
||||||
update_database_names(zDatabase);
|
update_database_names(zDatabase);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void update_database_names(const char* zDatabase)
|
|
||||||
{
|
|
||||||
char* zCopy = MXS_STRDUP(zDatabase);
|
|
||||||
MXS_ABORT_IF_NULL(zCopy);
|
|
||||||
exposed_sqlite3Dequote(zCopy);
|
|
||||||
|
|
||||||
enlarge_string_array(1, database_names_len,
|
|
||||||
&database_names, &database_names_capacity);
|
|
||||||
database_names[database_names_len++] = zCopy;
|
|
||||||
database_names[database_names_len] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QcSqliteInfo(uint32_t cllct)
|
QcSqliteInfo(uint32_t cllct)
|
||||||
@ -606,6 +601,65 @@ private:
|
|||||||
return pz;
|
return pz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool table_name_collected(const char* zTable)
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
while ((i < table_names_len) && (strcmp(table_names[i], zTable) != 0))
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return i != table_names_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool table_fullname_collected(const char* zTable)
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
while ((i < table_fullnames_len) && (strcmp(table_fullnames[i], zTable) != 0))
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return i != table_fullnames_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool database_name_collected(const char* zDatabase)
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
while ((i < database_names_len) && (strcmp(database_names[i], zDatabase) != 0))
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return i != database_names_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_database_names(const char* zDatabase)
|
||||||
|
{
|
||||||
|
if ((collect & QC_COLLECT_DATABASES) && !(collected & QC_COLLECT_DATABASES))
|
||||||
|
{
|
||||||
|
if (zDatabase)
|
||||||
|
{
|
||||||
|
char database[strlen(zDatabase) + 1];
|
||||||
|
strcpy(database, zDatabase);
|
||||||
|
exposed_sqlite3Dequote(database);
|
||||||
|
|
||||||
|
if (!database_name_collected(database))
|
||||||
|
{
|
||||||
|
char* zCopy = MXS_STRDUP_A(database);
|
||||||
|
|
||||||
|
enlarge_string_array(1, database_names_len,
|
||||||
|
&database_names, &database_names_capacity);
|
||||||
|
database_names[database_names_len++] = zCopy;
|
||||||
|
database_names[database_names_len] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// TODO: Make these private once everything's been updated.
|
// TODO: Make these private once everything's been updated.
|
||||||
qc_parse_result_t status; // The validity of the information in this structure.
|
qc_parse_result_t status; // The validity of the information in this structure.
|
||||||
|
Reference in New Issue
Block a user