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:
parent
e349319400
commit
8a95a0f045
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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 =
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user