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:
@ -816,3 +816,45 @@ char* skygw_query_classifier_get_stmtname(
|
|||||||
return ((THD *)(mysql->thd))->lex->prepared_stmt_name.str;
|
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;
|
||||||
|
}
|
@ -60,6 +60,8 @@ skygw_query_type_t skygw_query_classifier_get_type(
|
|||||||
/** Free THD context and close MYSQL */
|
/** Free THD context and close MYSQL */
|
||||||
void skygw_query_classifier_free(MYSQL* mysql);
|
void skygw_query_classifier_free(MYSQL* mysql);
|
||||||
char* skygw_query_classifier_get_stmtname(MYSQL* mysql);
|
char* skygw_query_classifier_get_stmtname(MYSQL* mysql);
|
||||||
|
char* skygw_get_canonical(MYSQL* mysql, char* querystr);
|
||||||
|
|
||||||
|
|
||||||
EXTERN_C_BLOCK_END
|
EXTERN_C_BLOCK_END
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include "skygw_debug.h"
|
#include "skygw_debug.h"
|
||||||
#include "skygw_types.h"
|
#include "skygw_types.h"
|
||||||
#include "skygw_utils.h"
|
#include "skygw_utils.h"
|
||||||
@ -1863,3 +1863,69 @@ void skygw_file_done(
|
|||||||
free(file);
|
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;
|
||||||
|
}
|
@ -191,5 +191,7 @@ int skygw_rwlock_unlock(skygw_rwlock_t* rwlock);
|
|||||||
int skygw_rwlock_init(skygw_rwlock_t** rwlock);
|
int skygw_rwlock_init(skygw_rwlock_t** rwlock);
|
||||||
|
|
||||||
int atomic_add(int *variable, int value);
|
int atomic_add(int *variable, int value);
|
||||||
|
char* replace_str(const char* str, const char* old, const char* replacement);
|
||||||
|
|
||||||
|
|
||||||
#endif /* SKYGW_UTILS_H */
|
#endif /* SKYGW_UTILS_H */
|
||||||
|
Reference in New Issue
Block a user