[MDEV-19362] New STRICT flags for sql_mode Created: 2019-04-30  Updated: 2023-12-22

Status: Open
Project: MariaDB Server
Component/s: OTHER
Fix Version/s: 11.5

Type: Task Priority: Major
Reporter: Alexander Barkov Assignee: Sergei Golubchik
Resolution: Unresolved Votes: 0
Labels: None

Issue Links:
Blocks
blocks MDEV-11875 Inconsistent behavior of CREATE TABLE... Open
blocks MDEV-28140 Unexpected error when UPDATE a NULL Confirmed
Duplicate
is duplicated by MDEV-31810 Sec feature request: New strict SQL m... Closed
Relates
relates to MDEV-8300 CAST('' AS DECIMAL) is too strict on ... Stalled
relates to MDEV-11876 CONVERT produces a warning and result... Open
relates to MDEV-11888 SELECT produces more warnings in non-... Open
relates to MDEV-28069 A misleading warning message from the... Open
relates to MDEV-28142 Unexpected UPDATE behavior under stri... Open

 Description   

Currently we have two flags:

  • STRICT_TRANS_TABLES
  • STRICT_ALL_TABLES

These flags were originally added to control how to treat warnings that happen on updating table fields for transactional and non-transactional tables.

Gradually these flags spread all around the code to change the server behavior in contexts not directly related to tables, such as:

  • SP variables, SP routine parameters, function return values
  • Built-in SQL functions (e.g. badly formed strings)
  • Too long comments
  • Too long messages in SIGNAL
  • Duplicate values in ENUM/SET
  • Automatic VARCHAR -> BLOB conversion

During recent discussions we agreed (bar, elenst, serg) that STRICT_XXX_TABLES should not affect anything when no tables are involved.

To address that we restore the original meaning of these flags:

  • STRICT_TRANS_TABLES applies to all cases where a statement can be cleanly aborted, restoring the data as it was before the statement started executing
  • STRICT_ALL_TABLES applies to all cases, even when it'll leave tables partially updated

We might rename flags to better match the intended semantics.

original proposal:

To address this, we'll introduce a new STRICT_XXX flag that will control server behavior when no tables are involved.

The exact flags name is a subject to discussion.



 Comments   
Comment by Sergei Golubchik [ 2019-04-30 ]

may be we should not introduce a new mode, but rename one of the existing STRICT_*_TABLES?

It's a very strange concept, a mode that only applies when storing into a table, may be it'd be better to get rid of it.

STRICT_*_TABLES modes were introduced for cases like INSERT ... SELECT. If an error happens in the middle of INSERT, transactional tables can undo all changes done by the statement, but non-transactional tables generally will keep already inserted data. So, it was argued, one might want to be "strict" for transactional tables but "non-strict" for non-transactional tables.

This logic does not really apply to changes that don't modify tables, they can be safely strict anytime the user wants the strict behavior. In that sense STRICT_TRANS_TABLES should also enable strict behavior when no tables are modified.

Comment by Elena Stepanova [ 2019-04-30 ]

I agree that instead of introducing a new mode, old modes should be re-thought, but I believe it should go deeper than just renaming. The concept behind current STRICT_TRANS_TABLES is insane and incomprehensible from any point of view, apart from probalby implementation (I can't think of any other justification why such thing was invented). Yes, one might want to be "strict for transactional tables but non-strict for non-transactional tables", but I don't think anyone might ever want to be strict "except that for non-transactional storage engines and statements affecting multiple rows where the invalid or missing data is not the first row" (our current documented definition of STRICT_TRANS_TABLES).
Such differentiation can only come to mind of those who implements it, because yes, I understand that it's a different path altogether. For any reasonable user however, and we encountered this opinion many times, "STRICT_ALL_TABLES" means strict mode for tables of all engines, in any situation, and "STRICT_TRANS_TABLES" means strict mode only for tables of engines which declare support of transactions, in any situation.

Comment by Sergei Golubchik [ 2020-08-14 ]

OK, what about this:

  • STRICT_ALL_TABLES means strict (= abort the statement on certain "warnings") always in any situation, no matter whether tables are involved or not.
  • STRICT_TRANS_TABLES means strict (= abort the statement on certain "warnings") always in any situation, no matter whether tables are involved or not if the statement can be completely rolled back.

practically, the latter means checking thd->transaction->stmt.modified_non_trans_table

Comment by Elena Stepanova [ 2020-08-14 ]

And also rename them, right?

Comment by Sergei Golubchik [ 2020-08-14 ]

No, not necessarily

Comment by Elena Stepanova [ 2020-08-14 ]

Then it would be a move in an opposite direction to what the description says, and in orthogonal direction to a sanity vector: we now have STRICT_xx_TABLES flags which are sometimes not about tables and not quite about "xx", after the change we'll have the flags which are indeed about "xx", but not about tables at all.

Comment by Alexander Barkov [ 2020-08-15 ]

Perhaps rename and keep the old names for backward compatibility?

Comment by Sergei Golubchik [ 2020-08-16 ]

elenst, I think it'll be mostly about tables. STRICT_TRANS_TABLES will make statements "strict" if only transactional tables but none of the non-transactional tables were modified. STRICT_ALL_TABLES will make statements "strict" even if non-transactional tables were modified.

This goes back to the original intention of those sql modes, STRICT_TRANS_TABLES aborts on warnings only when the statement can be completely rolled back, and STRICT_ALL_TABLES aborts on warnings even if the statement cannot be completely rolled back.

Comment by Elena Stepanova [ 2020-08-16 ]

serg, still, the whole point of the item, according to the description, is "STRICT_XXX_TABLES should not affect anything when no tables are involved". And your suggestion for both flags is "always in any situation, no matter whether tables are involved or not <...>". I don't see any correlation between the two. Semantically nothing will improve.

Comment by Sergei Golubchik [ 2020-08-30 ]

Yes, we'll have to clarify the documentation to go back to the original intention of those sql modes. It seems now the semantics became too literal and, perhaps, rather meaningless.

Generated at Thu Feb 08 08:51:06 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.