Merge branch '2.2' into develop

This commit is contained in:
Markus Mäkelä 2018-06-21 14:02:00 +03:00
commit 75ddfe4c14
No known key found for this signature in database
GPG Key ID: 72D48FCE664F7B19
7 changed files with 45 additions and 81 deletions

View File

@ -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:

View File

@ -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
{

View File

@ -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)
{

View File

@ -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;

View File

@ -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;

View File

@ -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]);

View File

@ -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));
}
}