MXS-1475 Attempt to set unknown MXS user variable causes error
By causing an error if an unknown MaxScale user variable is set, the user will become aware of typos etc.
This commit is contained in:
@ -137,11 +137,14 @@ typedef struct mxs_upstream
|
||||
* @param value_begin The beginning of the value as specified in the
|
||||
* "set @maxscale.x.y = VALUE" statement.
|
||||
* @param value_end One past the end of the VALUE.
|
||||
*
|
||||
* @return NULL if successful, otherwise a dynamically allocated string
|
||||
* containing an end-user friendly error message.
|
||||
*/
|
||||
typedef void (*session_variable_handler_t)(void* context,
|
||||
const char* name,
|
||||
const char* value_begin,
|
||||
const char* value_end);
|
||||
typedef char* (*session_variable_handler_t)(void* context,
|
||||
const char* name,
|
||||
const char* value_begin,
|
||||
const char* value_end);
|
||||
|
||||
#ifdef __cplusplus
|
||||
typedef struct session_variable
|
||||
@ -572,13 +575,16 @@ bool session_remove_variable(MXS_SESSION* session,
|
||||
* @param value_begin Should point to the beginning of the value.
|
||||
* @param value_end Should point one past the end of the value.
|
||||
*
|
||||
* @return NULL if successful, otherwise a dynamically allocated string
|
||||
* containing an end-user friendly error message.
|
||||
*
|
||||
* @note Should only be called from the protocol module that scans
|
||||
* incoming statements.
|
||||
*/
|
||||
void session_set_variable_value(MXS_SESSION* session,
|
||||
const char* name_begin,
|
||||
const char* name_end,
|
||||
const char* value_begin,
|
||||
const char* value_end);
|
||||
char* session_set_variable_value(MXS_SESSION* session,
|
||||
const char* name_begin,
|
||||
const char* name_end,
|
||||
const char* value_begin,
|
||||
const char* value_end);
|
||||
|
||||
MXS_END_DECLS
|
||||
|
@ -108,9 +108,8 @@ MXS_SESSION* session_alloc_with_id(SERVICE *service, DCB *client_dcb, uint64_t i
|
||||
return NULL;
|
||||
}
|
||||
|
||||
session->variables = session_variables;
|
||||
|
||||
session_initialize(session);
|
||||
session->variables = session_variables;
|
||||
session->ses_id = id;
|
||||
return session_alloc_body(service, client_dcb, session);
|
||||
}
|
||||
@ -1144,12 +1143,14 @@ bool session_add_variable(MXS_SESSION* session,
|
||||
return added;
|
||||
}
|
||||
|
||||
void session_set_variable_value(MXS_SESSION* session,
|
||||
const char* name_begin,
|
||||
const char* name_end,
|
||||
const char* value_begin,
|
||||
const char* value_end)
|
||||
char* session_set_variable_value(MXS_SESSION* session,
|
||||
const char* name_begin,
|
||||
const char* name_end,
|
||||
const char* value_begin,
|
||||
const char* value_end)
|
||||
{
|
||||
char* rv = NULL;
|
||||
|
||||
string key(name_begin, name_end - name_begin);
|
||||
|
||||
transform(key.begin(), key.end(), key.begin(), toupper);
|
||||
@ -1158,8 +1159,26 @@ void session_set_variable_value(MXS_SESSION* session,
|
||||
|
||||
if (i != session->variables->end())
|
||||
{
|
||||
i->second.handler(i->second.context, key.c_str(), value_begin, value_end);
|
||||
rv = i->second.handler(i->second.context, key.c_str(), value_begin, value_end);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char FORMAT[] = "Attempt to set unknown MaxScale user variable %.*s";
|
||||
|
||||
int name_length = name_end - name_begin;
|
||||
int len = snprintf(NULL, 0, FORMAT, name_length, name_begin);
|
||||
|
||||
rv = static_cast<char*>(MXS_MALLOC(len + 1));
|
||||
|
||||
if (rv)
|
||||
{
|
||||
sprintf(rv, FORMAT, name_length, name_begin);
|
||||
}
|
||||
|
||||
MXS_WARNING(FORMAT, name_length, name_begin);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool session_remove_variable(MXS_SESSION* session,
|
||||
|
@ -879,9 +879,13 @@ static bool process_client_commands(DCB* dcb, int bytes_available, GWBUF** buffe
|
||||
* @param session The session for which the query classifier mode is adjusted.
|
||||
* @param read_buffer Pointer to a buffer, assumed to contain a statement.
|
||||
* May be reallocated if not contiguous.
|
||||
*
|
||||
* @return NULL if successful, otherwise dynamically allocated error message.
|
||||
*/
|
||||
void handle_variables(MXS_SESSION* session, GWBUF** read_buffer)
|
||||
char* handle_variables(MXS_SESSION* session, GWBUF** read_buffer)
|
||||
{
|
||||
char* message = NULL;
|
||||
|
||||
SetParser set_parser;
|
||||
SetParser::Result result;
|
||||
|
||||
@ -917,9 +921,9 @@ void handle_variables(MXS_SESSION* session, GWBUF** read_buffer)
|
||||
break;
|
||||
|
||||
case SetParser::IS_SET_MAXSCALE:
|
||||
session_set_variable_value(session,
|
||||
result.variable_begin(), result.variable_end(),
|
||||
result.value_begin(), result.value_end());
|
||||
message = session_set_variable_value(session,
|
||||
result.variable_begin(), result.variable_end(),
|
||||
result.value_begin(), result.value_end());
|
||||
break;
|
||||
|
||||
case SetParser::NOT_RELEVANT:
|
||||
@ -928,6 +932,8 @@ void handle_variables(MXS_SESSION* session, GWBUF** read_buffer)
|
||||
default:
|
||||
ss_dassert(!true);
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -985,10 +991,20 @@ gw_read_normal_data(DCB *dcb, GWBUF *read_buffer, int nbytes_read)
|
||||
return 0;
|
||||
}
|
||||
|
||||
handle_variables(session, &read_buffer);
|
||||
// Must be done whether or not there were any changes, as the query classifier
|
||||
// is thread and not session specific.
|
||||
qc_set_sql_mode(static_cast<qc_sql_mode_t>(session->client_protocol_data));
|
||||
char* message = handle_variables(session, &read_buffer);
|
||||
|
||||
if (message)
|
||||
{
|
||||
int rv = dcb->func.write(dcb, modutil_create_mysql_err_msg(1, 0, 1193, "HY000", message));
|
||||
MXS_FREE(message);
|
||||
return rv;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Must be done whether or not there were any changes, as the query classifier
|
||||
// is thread and not session specific.
|
||||
qc_set_sql_mode(static_cast<qc_sql_mode_t>(session->client_protocol_data));
|
||||
}
|
||||
}
|
||||
/** Update the current protocol command being executed */
|
||||
else if (!process_client_commands(dcb, nbytes_read, &read_buffer))
|
||||
|
Reference in New Issue
Block a user