Merge branch '2.2' into develop
This commit is contained in:
@ -922,7 +922,7 @@ static uint32_t resolve_query_type(parsing_info_t *pi, THD* thd)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SQLCOM_DEALLOCATE_PREPARE:
|
case SQLCOM_DEALLOCATE_PREPARE:
|
||||||
type |= QUERY_TYPE_WRITE;
|
type |= QUERY_TYPE_DEALLOC_PREPARE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SQLCOM_SELECT:
|
case SQLCOM_SELECT:
|
||||||
|
|||||||
@ -781,36 +781,6 @@ public:
|
|||||||
return type_mask;
|
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)
|
static int string_to_truth(const char* s)
|
||||||
{
|
{
|
||||||
int truth = -1;
|
int truth = -1;
|
||||||
@ -2660,33 +2630,16 @@ public:
|
|||||||
{
|
{
|
||||||
ss_dassert(this_thread.initialized);
|
ss_dassert(this_thread.initialized);
|
||||||
|
|
||||||
// If the mode is MODE_ORACLE then if expression contains simply a string
|
switch (pStmt->op)
|
||||||
// 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)
|
|
||||||
{
|
{
|
||||||
if (pStmt->op == TK_STRING)
|
case TK_STRING:
|
||||||
{
|
case TK_VARIABLE:
|
||||||
m_status = QC_QUERY_PARSED;
|
m_status = QC_QUERY_PARSED;
|
||||||
}
|
break;
|
||||||
else
|
|
||||||
{
|
default:
|
||||||
m_status = QC_QUERY_PARTIALLY_PARSED;
|
m_status = QC_QUERY_PARTIALLY_PARSED;
|
||||||
}
|
break;
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_type_mask = QUERY_TYPE_PREPARE_NAMED_STMT;
|
m_type_mask = QUERY_TYPE_PREPARE_NAMED_STMT;
|
||||||
@ -2702,14 +2655,11 @@ public:
|
|||||||
m_zPrepare_name[pName->n] = 0;
|
m_zPrepare_name[pName->n] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the expression just contains a string, then zStmt will
|
if (pStmt->op == TK_STRING)
|
||||||
// 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)
|
|
||||||
{
|
{
|
||||||
|
const char* zStmt = pStmt->u.zToken;
|
||||||
|
ss_dassert(zStmt);
|
||||||
|
|
||||||
size_t preparable_stmt_len = zStmt ? strlen(zStmt) : 0;
|
size_t preparable_stmt_len = zStmt ? strlen(zStmt) : 0;
|
||||||
size_t payload_len = 1 + preparable_stmt_len;
|
size_t payload_len = 1 + preparable_stmt_len;
|
||||||
size_t packet_len = MYSQL_HEADER_LEN + payload_len;
|
size_t packet_len = MYSQL_HEADER_LEN + payload_len;
|
||||||
@ -2731,10 +2681,6 @@ public:
|
|||||||
memcpy(ptr, zStmt, preparable_stmt_len);
|
memcpy(ptr, zStmt, preparable_stmt_len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
m_status = QC_QUERY_INVALID;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@ -140,6 +140,10 @@ char* get_types_as_string(uint32_t types)
|
|||||||
{
|
{
|
||||||
s = append(s, "QUERY_TYPE_SHOW_TABLES", &len);
|
s = append(s, "QUERY_TYPE_SHOW_TABLES", &len);
|
||||||
}
|
}
|
||||||
|
if (types & QUERY_TYPE_DEALLOC_PREPARE)
|
||||||
|
{
|
||||||
|
s = append(s, "QUERY_TYPE_DEALLOC_PREPARE", &len);
|
||||||
|
}
|
||||||
|
|
||||||
if (!s)
|
if (!s)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1302,19 +1302,20 @@ bool compare(QUERY_CLASSIFIER* pClassifier1, GWBUF* pBuf1,
|
|||||||
{
|
{
|
||||||
GWBUF* pPreparable1;
|
GWBUF* pPreparable1;
|
||||||
pClassifier1->qc_get_preparable_stmt(pBuf1, &pPreparable1);
|
pClassifier1->qc_get_preparable_stmt(pBuf1, &pPreparable1);
|
||||||
ss_dassert(pPreparable1);
|
|
||||||
|
|
||||||
GWBUF* pPreparable2;
|
GWBUF* pPreparable2;
|
||||||
pClassifier2->qc_get_preparable_stmt(pBuf2, &pPreparable2);
|
pClassifier2->qc_get_preparable_stmt(pBuf2, &pPreparable2);
|
||||||
ss_dassert(pPreparable2);
|
|
||||||
|
|
||||||
string indent = global.indent;
|
if (pPreparable1 && pPreparable2)
|
||||||
global.indent += string(4, ' ');
|
{
|
||||||
|
string indent = global.indent;
|
||||||
|
global.indent += string(4, ' ');
|
||||||
|
|
||||||
success = compare(pClassifier1, pPreparable1,
|
success = compare(pClassifier1, pPreparable1,
|
||||||
pClassifier2, pPreparable2);
|
pClassifier2, pPreparable2);
|
||||||
|
|
||||||
global.indent = indent;
|
global.indent = indent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
|
|||||||
@ -108,4 +108,7 @@ CALL p1((SELECT f1()), ?);
|
|||||||
SELECT PREVIOUS VALUE FOR SEQ;
|
SELECT PREVIOUS VALUE FOR SEQ;
|
||||||
|
|
||||||
# MXS-1874
|
# 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;
|
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:
|
default:
|
||||||
{
|
{
|
||||||
static const char name[] = "UNKNOWN_QUERY_TYPE";
|
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_READ_TMP_TABLE,
|
||||||
QUERY_TYPE_SHOW_DATABASES,
|
QUERY_TYPE_SHOW_DATABASES,
|
||||||
QUERY_TYPE_SHOW_TABLES,
|
QUERY_TYPE_SHOW_TABLES,
|
||||||
|
QUERY_TYPE_DEALLOC_PREPARE,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int N_QUERY_TYPES = sizeof(QUERY_TYPES) / sizeof(QUERY_TYPES[0]);
|
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;
|
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;
|
rval = true;
|
||||||
}
|
}
|
||||||
else if (log_missing_privs)
|
else if (log_missing_privs)
|
||||||
{
|
{
|
||||||
log_missing_privs = false;
|
log_missing_privs = false;
|
||||||
MXS_WARNING("The user for service '%s' is missing the SELECT grant on "
|
MXS_WARNING("The user for service '%s' might be missing the SELECT grant on "
|
||||||
"`mysql.roles_mapping`. Use of default roles is disabled "
|
"`mysql.roles_mapping` or `mysql.user`. Use of default roles is disabled "
|
||||||
"until the missing privileges are added.", service->name);
|
"until the missing privileges are added. Error was: %s",
|
||||||
|
service->name, mysql_error(conn));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user