Merge branch '2.2' into develop
This commit is contained in:
commit
75ddfe4c14
@ -922,7 +922,7 @@ static uint32_t resolve_query_type(parsing_info_t *pi, THD* thd)
|
||||
break;
|
||||
|
||||
case SQLCOM_DEALLOCATE_PREPARE:
|
||||
type |= QUERY_TYPE_WRITE;
|
||||
type |= QUERY_TYPE_DEALLOC_PREPARE;
|
||||
break;
|
||||
|
||||
case SQLCOM_SELECT:
|
||||
|
@ -781,36 +781,6 @@ public:
|
||||
return type_mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns some string from an expression.
|
||||
*
|
||||
* @param pExpr An expression.
|
||||
*
|
||||
* @return Some string referred to in pExpr.
|
||||
*/
|
||||
static const char* find_one_string(Expr* pExpr)
|
||||
{
|
||||
const char* z = NULL;
|
||||
|
||||
if (pExpr->op == TK_STRING)
|
||||
{
|
||||
ss_dassert(pExpr->u.zToken);
|
||||
z = pExpr->u.zToken;
|
||||
}
|
||||
|
||||
if (!z && pExpr->pLeft)
|
||||
{
|
||||
z = find_one_string(pExpr->pLeft);
|
||||
}
|
||||
|
||||
if (!z && pExpr->pRight)
|
||||
{
|
||||
z = find_one_string(pExpr->pRight);
|
||||
}
|
||||
|
||||
return z;
|
||||
}
|
||||
|
||||
static int string_to_truth(const char* s)
|
||||
{
|
||||
int truth = -1;
|
||||
@ -2660,33 +2630,16 @@ public:
|
||||
{
|
||||
ss_dassert(this_thread.initialized);
|
||||
|
||||
// If the mode is MODE_ORACLE then if expression contains simply a string
|
||||
// we can conclude that the statement has been fully parsed, because it will
|
||||
// be sensible to parse the preparable statement. Otherwise we mark the
|
||||
// statement as having been partially parsed, since the preparable statement
|
||||
// will not contain the full statement.
|
||||
if (m_sql_mode == QC_SQL_MODE_ORACLE)
|
||||
switch (pStmt->op)
|
||||
{
|
||||
if (pStmt->op == TK_STRING)
|
||||
{
|
||||
m_status = QC_QUERY_PARSED;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_status = QC_QUERY_PARTIALLY_PARSED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the mode is not MODE_ORACLE, then only a string is acceptable.
|
||||
if (pStmt->op == TK_STRING)
|
||||
{
|
||||
m_status = QC_QUERY_PARSED;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_status = QC_QUERY_INVALID;
|
||||
}
|
||||
case TK_STRING:
|
||||
case TK_VARIABLE:
|
||||
m_status = QC_QUERY_PARSED;
|
||||
break;
|
||||
|
||||
default:
|
||||
m_status = QC_QUERY_PARTIALLY_PARSED;
|
||||
break;
|
||||
}
|
||||
|
||||
m_type_mask = QUERY_TYPE_PREPARE_NAMED_STMT;
|
||||
@ -2702,14 +2655,11 @@ public:
|
||||
m_zPrepare_name[pName->n] = 0;
|
||||
}
|
||||
|
||||
// If the expression just contains a string, then zStmt will
|
||||
// be that string. Otherwise it will be _some_ string from the
|
||||
// expression. In the latter case we've already marked the result
|
||||
// to have been partially parsed.
|
||||
const char* zStmt = find_one_string(pStmt);
|
||||
|
||||
if (zStmt)
|
||||
if (pStmt->op == TK_STRING)
|
||||
{
|
||||
const char* zStmt = pStmt->u.zToken;
|
||||
ss_dassert(zStmt);
|
||||
|
||||
size_t preparable_stmt_len = zStmt ? strlen(zStmt) : 0;
|
||||
size_t payload_len = 1 + preparable_stmt_len;
|
||||
size_t packet_len = MYSQL_HEADER_LEN + payload_len;
|
||||
@ -2731,10 +2681,6 @@ public:
|
||||
memcpy(ptr, zStmt, preparable_stmt_len);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_status = QC_QUERY_INVALID;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -140,6 +140,10 @@ char* get_types_as_string(uint32_t types)
|
||||
{
|
||||
s = append(s, "QUERY_TYPE_SHOW_TABLES", &len);
|
||||
}
|
||||
if (types & QUERY_TYPE_DEALLOC_PREPARE)
|
||||
{
|
||||
s = append(s, "QUERY_TYPE_DEALLOC_PREPARE", &len);
|
||||
}
|
||||
|
||||
if (!s)
|
||||
{
|
||||
|
@ -1302,19 +1302,20 @@ bool compare(QUERY_CLASSIFIER* pClassifier1, GWBUF* pBuf1,
|
||||
{
|
||||
GWBUF* pPreparable1;
|
||||
pClassifier1->qc_get_preparable_stmt(pBuf1, &pPreparable1);
|
||||
ss_dassert(pPreparable1);
|
||||
|
||||
GWBUF* pPreparable2;
|
||||
pClassifier2->qc_get_preparable_stmt(pBuf2, &pPreparable2);
|
||||
ss_dassert(pPreparable2);
|
||||
|
||||
string indent = global.indent;
|
||||
global.indent += string(4, ' ');
|
||||
if (pPreparable1 && pPreparable2)
|
||||
{
|
||||
string indent = global.indent;
|
||||
global.indent += string(4, ' ');
|
||||
|
||||
success = compare(pClassifier1, pPreparable1,
|
||||
pClassifier2, pPreparable2);
|
||||
success = compare(pClassifier1, pPreparable1,
|
||||
pClassifier2, pPreparable2);
|
||||
|
||||
global.indent = indent;
|
||||
global.indent = indent;
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
|
@ -108,4 +108,7 @@ CALL p1((SELECT f1()), ?);
|
||||
SELECT PREVIOUS VALUE FOR SEQ;
|
||||
|
||||
# MXS-1874
|
||||
SET STATEMENT max_statement_time=30 FOR SELECT seq FROM seq_0_to_100000;
|
||||
SET STATEMENT max_statement_time=30 FOR SELECT seq FROM seq_0_to_100000;
|
||||
|
||||
# MXS-1935
|
||||
PREPARE a FROM @sql;
|
||||
|
@ -604,6 +604,14 @@ struct type_name_info type_to_type_name_info(qc_query_type_t type)
|
||||
}
|
||||
break;
|
||||
|
||||
case QUERY_TYPE_DEALLOC_PREPARE:
|
||||
{
|
||||
static const char name[] = "QUERY_TYPE_DEALLOC_PREPARE";
|
||||
info.name = name;
|
||||
info.name_len = sizeof(name) - 1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
static const char name[] = "UNKNOWN_QUERY_TYPE";
|
||||
@ -650,6 +658,7 @@ static const qc_query_type_t QUERY_TYPES[] =
|
||||
QUERY_TYPE_READ_TMP_TABLE,
|
||||
QUERY_TYPE_SHOW_DATABASES,
|
||||
QUERY_TYPE_SHOW_TABLES,
|
||||
QUERY_TYPE_DEALLOC_PREPARE,
|
||||
};
|
||||
|
||||
static const int N_QUERY_TYPES = sizeof(QUERY_TYPES) / sizeof(QUERY_TYPES[0]);
|
||||
|
@ -802,17 +802,18 @@ static bool roles_are_available(MYSQL* conn, SERVICE* service, SERVER* server)
|
||||
{
|
||||
static bool log_missing_privs = true;
|
||||
|
||||
if (mxs_mysql_query(conn, "SELECT 1 FROM mysql.roles_mapping LIMIT 1") == 0)
|
||||
if (mxs_mysql_query(conn, "SET @roles_are_available=(SELECT 1 FROM mysql.roles_mapping LIMIT 1)") == 0 &&
|
||||
mxs_mysql_query(conn, "SET @roles_are_available=(SELECT default_role FROM mysql.user LIMIT 1)") == 0)
|
||||
{
|
||||
mysql_free_result(mysql_store_result(conn));
|
||||
rval = true;
|
||||
}
|
||||
else if (log_missing_privs)
|
||||
{
|
||||
log_missing_privs = false;
|
||||
MXS_WARNING("The user for service '%s' is missing the SELECT grant on "
|
||||
"`mysql.roles_mapping`. Use of default roles is disabled "
|
||||
"until the missing privileges are added.", service->name);
|
||||
MXS_WARNING("The user for service '%s' might be missing the SELECT grant on "
|
||||
"`mysql.roles_mapping` or `mysql.user`. Use of default roles is disabled "
|
||||
"until the missing privileges are added. Error was: %s",
|
||||
service->name, mysql_error(conn));
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user