Remove qc_get_prepare_operation

Since the whole preparable statement will be available, it is
superfluous to provide a function using which the operation of
the preparable statement can be obtained.
This commit is contained in:
Johan Wikman 2017-01-16 19:58:19 +02:00
parent e349319400
commit 8a95a0f045
5 changed files with 2 additions and 175 deletions

View File

@ -307,18 +307,6 @@ typedef struct query_classifier
*/
int32_t (*qc_get_prepare_name)(GWBUF* stmt, char** name);
/**
* Reports the prepare operation.
*
* @param stmt A statement.
* @param name On return, the operation (one of @c qc_query_op_t) of a prepare
* statement, if @c QC_RESULT_OK is returned.
*
* @return QC_RESULT_OK, if the parsing was not aborted due to resource
* exhaustion or equivalent.
*/
int32_t (*qc_get_prepare_operation)(GWBUF* stmt, int32_t* op);
/**
* Reports field information.
*
@ -584,17 +572,6 @@ qc_query_op_t qc_get_operation(GWBUF* stmt);
*/
char* qc_get_prepare_name(GWBUF* stmt);
/**
* Returns the operator of the prepared statement, if the statement
* is a PREPARE statement.
*
* @param stmt A buffer containing a COM_QUERY packet.
*
* @return The operator of the prepared statement, if the statement
* is a PREPARE statement; otherwise QUERY_OP_UNDEFINED.
*/
qc_query_op_t qc_get_prepare_operation(GWBUF* stmt);
/**
* Returns the preparable statement of a PREPARE statment. Other query classifier
* functions can then be used on the returned statement to find out information

View File

@ -71,12 +71,6 @@ int32_t qc_dummy_get_prepare_name(GWBUF* query, char** pzName)
return QC_RESULT_OK;
}
int32_t qc_dummy_get_prepare_operation(GWBUF* query, int32_t* pOp)
{
*pOp = QUERY_OP_UNDEFINED;
return QC_RESULT_OK;
}
int32_t qc_dummy_get_field_info(GWBUF* query, const QC_FIELD_INFO** ppInfos, uint32_t* nInfos)
{
*ppInfos = NULL;
@ -141,7 +135,6 @@ extern "C"
qc_dummy_query_has_clause,
qc_dummy_get_database_names,
qc_dummy_get_prepare_name,
qc_dummy_get_prepare_operation,
qc_dummy_get_field_info,
qc_dummy_get_function_info,
qc_dummy_get_preparable_stmt,

View File

@ -1773,84 +1773,6 @@ int32_t qc_mysql_get_prepare_name(GWBUF* stmt, char** namep)
return QC_RESULT_OK;
}
int32_t qc_mysql_get_prepare_operation(GWBUF* stmt, int32_t* operation)
{
*operation = QUERY_OP_UNDEFINED;
if (stmt)
{
if (ensure_query_is_parsed(stmt))
{
LEX* lex = get_lex(stmt);
if (lex->sql_command == SQLCOM_PREPARE)
{
// This is terriby inefficient, but as qc_mysqlembedded is not used
// for anything else but comparisons it is ok.
const char* prepare_str = lex->prepared_stmt_code.str;
size_t prepare_str_len = lex->prepared_stmt_code.length;
// MySQL does not parse e.g. "select * from x where ?=5". To work
// around that we'll replace all "?":s with "@a":s. We might replace
// something unnecessarily, but that won't hurt the classification.
size_t n_questions = 0;
const char* p = prepare_str;
while (p < prepare_str + prepare_str_len)
{
if (*p == '?')
{
++n_questions;
}
++p;
}
size_t payload_len = prepare_str_len + n_questions * 2 + 1;
size_t prepare_stmt_len = MYSQL_HEADER_LEN + payload_len;
GWBUF* prepare_stmt = gwbuf_alloc(prepare_stmt_len);
if (prepare_stmt)
{
// Encode the length of the payload in the 3 first bytes.
*((unsigned char*)GWBUF_DATA(prepare_stmt) + 0) = payload_len;
*((unsigned char*)GWBUF_DATA(prepare_stmt) + 1) = (payload_len >> 8);
*((unsigned char*)GWBUF_DATA(prepare_stmt) + 2) = (payload_len >> 16);
// Sequence id
*((unsigned char*)GWBUF_DATA(prepare_stmt) + 3) = 0x00;
// Payload, starts with command.
*((unsigned char*)GWBUF_DATA(prepare_stmt) + 4) = COM_QUERY;
// Is followed by the statement.
char *s = (char*)GWBUF_DATA(prepare_stmt) + 5;
p = prepare_str;
while (p < prepare_str + prepare_str_len)
{
switch (*p)
{
case '?':
*s++ = '@';
*s = 'a';
break;
default:
*s = *p;
}
++p;
++s;
}
qc_mysql_get_operation(prepare_stmt, operation);
gwbuf_free(prepare_stmt);
}
}
}
}
return QC_RESULT_OK;
}
int32_t qc_mysql_get_preparable_stmt(GWBUF* stmt, GWBUF** preparable_stmt)
{
*preparable_stmt = NULL;
@ -2757,9 +2679,9 @@ MXS_MODULE* MXS_CREATE_MODULE()
qc_mysql_query_has_clause,
qc_mysql_get_database_names,
qc_mysql_get_prepare_name,
qc_mysql_get_prepare_operation,
qc_mysql_get_field_info,
qc_mysql_get_function_info
qc_mysql_get_function_info,
qc_mysql_get_preparable_stmt,
};
static MXS_MODULE info =

View File

@ -3313,37 +3313,6 @@ static int32_t qc_sqlite_get_prepare_name(GWBUF* query, char** prepare_name)
return rv;
}
static int32_t qc_sqlite_get_prepare_operation(GWBUF* query, int32_t* op)
{
QC_TRACE();
int32_t rv = QC_RESULT_ERROR;
ss_dassert(this_unit.initialized);
ss_dassert(this_thread.initialized);
*op = QUERY_OP_UNDEFINED;
QC_SQLITE_INFO* info = get_query_info(query);
if (info)
{
if (qc_info_is_valid(info->status))
{
*op = info->prepare_operation;
}
else if (MXS_LOG_PRIORITY_IS_ENABLED(LOG_INFO))
{
log_invalid_data(query, "cannot report the operation of a prepared statement");
}
rv = QC_RESULT_OK;
}
else
{
MXS_ERROR("The query could not be parsed. Response not valid.");
}
return rv;
}
int32_t qc_sqlite_get_field_info(GWBUF* query, const QC_FIELD_INFO** infos, uint32_t* n_infos)
{
QC_TRACE();
@ -3467,7 +3436,6 @@ MXS_MODULE* MXS_CREATE_MODULE()
qc_sqlite_query_has_clause,
qc_sqlite_get_database_names,
qc_sqlite_get_prepare_name,
qc_sqlite_get_prepare_operation,
qc_sqlite_get_field_info,
qc_sqlite_get_function_info,
qc_sqlite_get_preparable_stmt,

View File

@ -781,38 +781,6 @@ bool compare_get_prepare_name(QUERY_CLASSIFIER* pClassifier1, GWBUF* pCopy1,
return success;
}
bool compare_get_prepare_operation(QUERY_CLASSIFIER* pClassifier1, GWBUF* pCopy1,
QUERY_CLASSIFIER* pClassifier2, GWBUF* pCopy2)
{
bool success = false;
const char HEADING[] = "qc_get_prepare_operation : ";
int32_t rv1;
pClassifier1->qc_get_prepare_operation(pCopy1, &rv1);
int32_t rv2;
pClassifier2->qc_get_prepare_operation(pCopy2, &rv2);
stringstream ss;
ss << HEADING;
if (rv1 == rv2)
{
ss << "Ok : " << qc_op_to_string(static_cast<qc_query_op_t>(rv1));
success = true;
}
else
{
ss << "ERR: "
<< qc_op_to_string(static_cast<qc_query_op_t>(rv1))
<< " != "
<< qc_op_to_string(static_cast<qc_query_op_t>(rv2));
}
report(success, ss.str());
return success;
}
bool operator == (const QC_FIELD_INFO& lhs, const QC_FIELD_INFO& rhs)
{
bool rv = false;
@ -1206,7 +1174,6 @@ bool compare(QUERY_CLASSIFIER* pClassifier1, QUERY_CLASSIFIER* pClassifier2, con
errors += !compare_query_has_clause(pClassifier1, pCopy1, pClassifier2, pCopy2);
errors += !compare_get_database_names(pClassifier1, pCopy1, pClassifier2, pCopy2);
errors += !compare_get_prepare_name(pClassifier1, pCopy1, pClassifier2, pCopy2);
errors += !compare_get_prepare_operation(pClassifier1, pCopy1, pClassifier2, pCopy2);
errors += !compare_get_field_info(pClassifier1, pCopy1, pClassifier2, pCopy2);
errors += !compare_get_function_info(pClassifier1, pCopy1, pClassifier2, pCopy2);