Intended to be used from fatal signal handlers. As the statement will
be returned only while classification is in process, if a statement
is returned, it is an indication that the crash was caused by the
classification.
According to bug-report it seems that a SrcList can be NULL. This
fixes the immediate problem, but it would be good to know in what
contexts the SrcList can be NULL so that the check could be made
before calling the function instead of checking (possibly
unnecessarily at times) in the function.
With this change, both 'SET @my_id = (SELECT LAST_INSERT_ID())' and
'SET @my_id = (SELECT @@LAST_INSERT_ID)' are classified as
QUERY_TYPE_MASTER_READ|QUERY_TYPE_SESSION_WRITE|QUERY_TYPE_USERVAR_WRITE
Earlier @@last_insert_id had the QUERY_TYPE_READ bit set as well, which
indirectly caused the problems of MXS-2898.
DIV and MOD are now also accepted instead of / and % respectively.
MOD is a keyword but (in principle incorrectly) decays into an id
when used in some other context. That is so that it will be
parser by the general function rule ("id ( ... )"). If used
incorrectly, the server will later reject.
With these changes
SET @saved_cs_client= @@character_set_client;
will be classified as QUERY_TYPE_USERVAR_WRITE and
SELECT 1 AS c1 FROM t1 ORDER BY ( SELECT 1 AS c2 FROM
t1 GROUP BY GREATEST(LAST_INSERT_ID(), t1.a) ORDER BY
GREATEST(LAST_INSERT_ID(), t1.a) LIMIT 1);
will be classified as QUERY_TYPE_READ|QUERY_TYPE_MASTER_READ
On RHEL8 the former may give rise to incorrect
error: 'char* strncpy(char*, const char*, size_t)' destination
unchanged after copying no bytes [-Werror=stringop-truncation]
When a statement like 'DESCRIBE tbl' is classified, the table
name will now be available so that a router can check whether the
table is a temporary one. In that case, the statement must be sent
to the master.
Before this change, if the firewall was configured to block the use
of certain columns, it could be be bypassed simply by
> set @@sql_mode='ANSI_QUOTES';
> select "ssn" from person;
The reason is that as the query classifier is not aware of whether
'ANSI_QUOTES' is on or not, it will not know that what above appears
to be the string "ssn", actually is the field name `ssn`. Consequently,
the select will not be blocked and the result returned in cleartext.
It's now possible to instruct the query classifier to report all strings
as fields, which will prevent the above. However, it will also mean that
there may be false positives.
Before this change, the masking could be bypassed simply by
> set @@sql_mode='ANSI_QUOTES';
> select concat("ssn") from person;
The reason is that as the query classifier is not aware of whether
'ANSI_QUOTES' is on or not, it will not know that what above appears
to be the string "ssn", actually is the field name `ssn`. Consequently,
the select will not be blocked and the result returned in cleartext.
It's now possible to instruct the query classifier to report all string
arguments of functions as fields, which will prevent the above. However,
it will also mean that there may be false positives.
The type mask of CREATE, ALTER, etc. that cause an implicit commit
will no longer contain the bit QUERY_TYPE_COMMIT.
As an implicit commit does not change the transaction state as seen
by MaxScale, it does not make sense to claim that the statement is
a commit.