/** * Replace the contents of a GWBUF with the new SQL statement passed as a text string. * The routine takes care of the modification needed to the MySQL packet, * returning a GWBUF chain that can be used to send the data to a MySQL server * * @param orig The original request in a GWBUF * @param sql The SQL text to replace in the packet * @return A newly formed GWBUF containing the MySQL packet. */ GWBUF * modutil_replace_SQL(GWBUF *orig, char *sql) { unsigned char *ptr; int length, newlength; GWBUF *addition; if (!modutil_is_SQL(orig)) return NULL; ptr = GWBUF_DATA(orig); length = *ptr++; length += (*ptr++ << 8); length += (*ptr++ << 16); ptr += 2; // Skip sequence id and COM_QUERY byte newlength = strlen(sql); if (length - 1 == newlength) { /* New SQL is the same length as old */ memcpy(ptr, sql, newlength); } else if (length - 1 > newlength) { /* New SQL is shorter */ memcpy(ptr, sql, newlength); GWBUF_RTRIM(orig, (length - 1) - newlength); ptr = GWBUF_DATA(orig); *ptr++ = (newlength + 1) & 0xff; *ptr++ = ((newlength + 1) >> 8) & 0xff; *ptr++ = ((newlength + 1) >> 16) & 0xff; }
/** * Trim bytes from the end of a GWBUF structure that may be the first * in a list. If the buffer has n_bytes or less then it will be freed and * the next buffer in the list will be returned, or if none, NULL. * * @param head The buffer to trim * @param n_bytes The number of bytes to trim off * @return The buffer chain or NULL if buffer chain now empty */ GWBUF * gwbuf_rtrim(GWBUF *head, unsigned int n_bytes) { GWBUF *rval = head; CHK_GWBUF(head); GWBUF_RTRIM(head, n_bytes); CHK_GWBUF(head); if (GWBUF_EMPTY(head)) { rval = head->next; gwbuf_free(head); } return rval; }
/** * * @param my_instance * @param my_session * @param buffer * @return */ GWBUF* clone_query(TEE_INSTANCE* my_instance, TEE_SESSION* my_session, GWBUF* buffer) { GWBUF* clone = NULL; int length, residual = 0; char* ptr; if (my_session->branch_session && my_session->branch_session->state == SESSION_STATE_ROUTER_READY) { if (my_session->residual) { clone = gwbuf_clone_all(buffer); if (my_session->residual < GWBUF_LENGTH(clone)) { GWBUF_RTRIM(clone, GWBUF_LENGTH(clone) - residual); } my_session->residual -= GWBUF_LENGTH(clone); if (my_session->residual < 0) { my_session->residual = 0; } } else if (my_session->active && (ptr = modutil_get_SQL(buffer)) != NULL) { if ((my_instance->match == NULL || regexec(&my_instance->re, ptr, 0, NULL, 0) == 0) && (my_instance->nomatch == NULL || regexec(&my_instance->nore,ptr,0,NULL, 0) != 0)) { length = modutil_MySQL_query_len(buffer, &residual); clone = gwbuf_clone_all(buffer); my_session->residual = residual; } free(ptr); } else if (packet_is_required(buffer)) { clone = gwbuf_clone_all(buffer); } } return clone; }