char *mysql_query_digest_and_first_comment(char *s, int _len, char **first_comment){ int i = 0; char cur_comment[FIRST_COMMENT_MAX_LENGTH]; cur_comment[0]=0; int ccl=0; int cmd=0; int len = _len; if (_len > QUERY_DIGEST_MAX_LENGTH) { len = QUERY_DIGEST_MAX_LENGTH; } char *r = (char *) malloc(len + SIZECHAR); char *p_r = r; char *p_r_t = r; char prev_char = 0; char qutr_char = 0; char flag = 0; char fc=0; int fc_len=0; char fns=0; bool lowercase=0; lowercase=mysql_thread___query_digests_lowercase; while(i < len) { // ================================================= // START - read token char and set flag what's going on. // ================================================= if(flag == 0) { // store current position p_r_t = p_r; // comment type 1 - start with '/*' if(prev_char == '/' && *s == '*') { ccl=0; flag = 1; if (*(s+1)=='!') cmd=1; } // comment type 2 - start with '#' else if(*s == '#') { flag = 2; } // string - start with ' else if(*s == '\'' || *s == '"') { flag = 3; qutr_char = *s; } // may be digit - start with digit else if(is_token_char(prev_char) && is_digit_char(*s)) { flag = 4; if(len == i+1) continue; } // not above case - remove duplicated space char else { flag = 0; if (fns==0 && is_space_char(*s)) { s++; i++; continue; } if (fns==0) fns=1; if(is_space_char(prev_char) && is_space_char(*s)){ prev_char = ' '; *p_r = ' '; s++; i++; continue; } } } // ================================================= // PROCESS and FINISH - do something on each case // ================================================= else { // -------- // comment // -------- if (flag == 1) { if (cmd) { if (ccl<FIRST_COMMENT_MAX_LENGTH-1) { cur_comment[ccl]=*s; ccl++; } } if (fc==0) { fc=1; } if (fc==1) { if (fc_len<FIRST_COMMENT_MAX_LENGTH-1) { if (*first_comment==NULL) { *first_comment=(char *)malloc(FIRST_COMMENT_MAX_LENGTH); } char *c=*first_comment+fc_len; *c = !is_space_char(*s) ? *s : ' '; fc_len++; } if (prev_char == '*' && *s == '/') { if (fc_len>=2) fc_len-=2; char *c=*first_comment+fc_len; *c=0; //*first_comment[fc_len]=0; fc=2; } } } if( // comment type 1 - /* .. */ (flag == 1 && prev_char == '*' && *s == '/') || // comment type 2 - # ... \n (flag == 2 && (*s == '\n' || *s == '\r')) ) { p_r = flag == 1 ? p_r_t - SIZECHAR : p_r_t; if (cmd) { cur_comment[ccl]=0; if (ccl>=2) { ccl-=2; cur_comment[ccl]=0; char el=0; int fcc=0; while (el==0 && fcc<ccl ) { switch (cur_comment[fcc]) { case '/': case '*': case '!': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case ' ': fcc++; break; default: el=1; break; } } if (el) { memcpy(p_r,cur_comment+fcc,ccl-fcc); p_r+=(ccl-fcc); *p_r++=' '; } } cmd=0; } prev_char = ' '; flag = 0; s++; i++; continue; } // -------- // string // -------- else if(flag == 3) { // Last char process if(len == i + 1) { p_r = p_r_t; *p_r++ = '?'; flag = 0; break; } // need to be ignored case if(p_r > p_r_t + SIZECHAR) { if( (prev_char == '\\' && *s == '\\') || // to process '\\\\', '\\' (prev_char == '\\' && *s == qutr_char) || // to process '\'' (prev_char == qutr_char && *s == qutr_char) // to process '''' ) { prev_char = 'X'; s++; i++; continue; } } // satisfied closing string - swap string to ? if(*s == qutr_char && (len == i+1 || *(s + SIZECHAR) != qutr_char)) { p_r = p_r_t; *p_r++ = '?'; flag = 0; if(i < len) s++; i++; continue; } } // -------- // digit // -------- else if(flag == 4) { // last single char if(p_r_t == p_r) { *p_r++ = '?'; i++; continue; } // token char or last char if(is_token_char(*s) || len == i+1) { if(is_digit_string(p_r_t, p_r)) { p_r = p_r_t; *p_r++ = '?'; if(len == i+1) { if(is_token_char(*s)) *p_r++ = *s; i++; continue; } } flag = 0; } } } // ================================================= // COPY CHAR // ================================================= // convert every space char to ' ' if (lowercase==0) { *p_r++ = !is_space_char(*s) ? *s : ' '; } else { *p_r++ = !is_space_char(*s) ? (tolower(*s)) : ' '; } prev_char = *s++; i++; } // remove a trailing space if (p_r>r) { char *e=p_r; e--; if (*e==' ') { *e=0; } } *p_r = 0; // process query stats return r; }
char *mysql_query_digest_and_first_comment(char *s, int len, char *first_comment){ int i = 0; char *r = (char *) malloc(len + SIZECHAR); char *p_r = r; char *p_r_t = r; char prev_char = 0; char qutr_char = 0; char flag = 0; char fc=0; int fc_len=0; char fns=0; while(i < len) { // ================================================= // START - read token char and set flag what's going on. // ================================================= if(flag == 0) { // store current position p_r_t = p_r; // comment type 1 - start with '/*' if(prev_char == '/' && *s == '*') { flag = 1; } // comment type 2 - start with '#' else if(*s == '#') { flag = 2; } // string - start with ' else if(*s == '\'' || *s == '"') { flag = 3; qutr_char = *s; } // may be digit - start with digit else if(is_token_char(prev_char) && is_digit_char(*s)) { flag = 4; if(len == i+1) continue; } // not above case - remove duplicated space char else { flag = 0; if (fns==0 && is_space_char(*s)) { s++; i++; continue; } if (fns==0) fns=1; if(is_space_char(prev_char) && is_space_char(*s)){ prev_char = ' '; *p_r = ' '; s++; i++; continue; } } } // ================================================= // PROCESS and FINISH - do something on each case // ================================================= else { // -------- // comment // -------- if (flag == 1) { if (fc==0) { fc=1; } if (fc==1) { if (fc_len<FIRST_COMMENT_MAX_LENGTH-1) { first_comment[fc_len]= !is_space_char(*s) ? *s : ' '; fc_len++; } if (prev_char == '*' && *s == '/') { if (fc_len>=2) fc_len-=2; first_comment[fc_len]=0; fc=2; } } } if( // comment type 1 - /* .. */ (flag == 1 && prev_char == '*' && *s == '/') || // comment type 2 - # ... \n (flag == 2 && (*s == '\n' || *s == '\r')) ) { p_r = flag == 1 ? p_r_t - SIZECHAR : p_r_t; prev_char = ' '; flag = 0; s++; i++; continue; } // -------- // string // -------- else if(flag == 3) { // Last char process if(len == i + 1) { p_r = p_r_t; *p_r++ = '?'; flag = 0; break; } // need to be ignored case if(p_r > p_r_t + SIZECHAR) { if( (prev_char == '\\' && *s == '\\') || // to process '\\\\', '\\' (prev_char == '\\' && *s == qutr_char) || // to process '\'' (prev_char == qutr_char && *s == qutr_char) // to process '''' ) { prev_char = 'X'; s++; i++; continue; } } // satisfied closing string - swap string to ? if(*s == qutr_char && (len == i+1 || *(s + SIZECHAR) != qutr_char)) { p_r = p_r_t; *p_r++ = '?'; flag = 0; if(i < len) s++; i++; continue; } } // -------- // digit // -------- else if(flag == 4) { // last single char if(p_r_t == p_r) { *p_r++ = '?'; i++; continue; } // token char or last char if(is_token_char(*s) || len == i+1) { if(is_digit_string(p_r_t, p_r)) { p_r = p_r_t; *p_r++ = '?'; if(len == i+1) { if(is_token_char(*s)) *p_r++ = *s; i++; continue; } } flag = 0; } } } // ================================================= // COPY CHAR // ================================================= // convert every space char to ' ' *p_r++ = !is_space_char(*s) ? *s : ' '; prev_char = *s++; i++; } // remove a trailing space if (p_r>r) { char *e=p_r; e--; if (*e==' ') { *e=0; } } *p_r = 0; // process query stats return r; }