query_classifier: implemented skygw_get_canonical which returns a copy of original string with given substrings being replaced with questionmarks.

skygw_utils.cc: added string replacement function for use of skygw_get_canonical
This commit is contained in:
VilhoRaatikka 2014-08-18 14:19:46 +03:00
parent 087c4720bb
commit 544e64a301
4 changed files with 114 additions and 2 deletions

View File

@ -412,7 +412,7 @@ static skygw_query_type_t resolve_query_type(
ss_info_dassert(thd != NULL, ("thd is NULL\n"));
force_data_modify_op_replication = FALSE;
force_data_modify_op_replication = FALSE;
lex = thd->lex;
/** SELECT ..INTO variable|OUTFILE|DUMPFILE */
@ -816,3 +816,45 @@ char* skygw_query_classifier_get_stmtname(
return ((THD *)(mysql->thd))->lex->prepared_stmt_name.str;
}
char* skygw_get_canonical(
MYSQL* mysql,
char* querystr)
{
THD* thd;
LEX* lex;
bool found = false;
char* newstr;
thd = (THD *)mysql->thd;
lex = thd->lex;
Item* item;
for (item=thd->free_list; item != NULL; item=item->next)
{
Item::Type itype;
itype = item->type();
if (itype == Item::STRING_ITEM || itype == Item::INT_ITEM)
{
if (!found)
{
newstr = replace_str(querystr,
item->name,
"?");
found = true;
}
else
{
char* prevstr = newstr;
newstr = replace_str(prevstr,
item->name,
"?");
free(prevstr);
}
}
} /*< for */
return newstr;
}

View File

@ -60,6 +60,8 @@ skygw_query_type_t skygw_query_classifier_get_type(
/** Free THD context and close MYSQL */
void skygw_query_classifier_free(MYSQL* mysql);
char* skygw_query_classifier_get_stmtname(MYSQL* mysql);
char* skygw_get_canonical(MYSQL* mysql, char* querystr);
EXTERN_C_BLOCK_END

View File

@ -23,7 +23,7 @@
#include <errno.h>
#include <string.h>
#include <time.h>
#include <stddef.h>
#include "skygw_debug.h"
#include "skygw_types.h"
#include "skygw_utils.h"
@ -1863,3 +1863,69 @@ void skygw_file_done(
free(file);
}
}
/**
* Replaces in the string str all the occurrences of the source string old with
* the destination string new. The lengths of the strings old and new may differ.
* The string new may be of any length, but the string "old" must be of non-zero
* length - the penalty for providing an empty string for the "old" parameter is
* an infinite loop. In addition, none of the three parameters may be NULL.
*
* @param str String to be modified
* @param old Substring to be replaced
* @param new Replacement
* @return String with replacements in new memory area or NULL if memory
* allocation failed.
* Dependencies: For this function to compile, you will need to also #include
* the following files: <string.h>, <stdlib.h> and <stddef.h>.
*
* Thanks, to Laird Shaw who implemented most of this function.
*/
char* replace_str (
const char *str,
const char *old,
const char *replacement)
{
char* ret;
char* r;
const char* p;
const char* q;
size_t oldlen;
size_t count;
size_t retlen;
size_t newlen;
oldlen = strlen(old);
newlen = strlen(replacement);
if (oldlen != newlen)
{
for (count = 0, p = str; (q = strstr(p, old)) != NULL; p = q + oldlen)
{
count++;
}
/* this is undefined if p - str > PTRDIFF_MAX */
retlen = p - str + strlen(p) + count * (newlen - oldlen);
}
else
{
retlen = strlen(str);
}
if ((ret = (char *)malloc(retlen + 1)) == NULL)
{
return NULL;
}
for (r = ret, p = str; (q = strstr(p, old)) != NULL; p = q + oldlen)
{
/* this is undefined if q - p > PTRDIFF_MAX */
ptrdiff_t l = q - p;
memcpy(r, p, l);
r += l;
memcpy(r, replacement, newlen);
r += newlen;
}
strcpy(r, p);
return ret;
}

View File

@ -191,5 +191,7 @@ int skygw_rwlock_unlock(skygw_rwlock_t* rwlock);
int skygw_rwlock_init(skygw_rwlock_t** rwlock);
int atomic_add(int *variable, int value);
char* replace_str(const char* str, const char* old, const char* replacement);
#endif /* SKYGW_UTILS_H */