mariadb/mysql-test/suite/vcol/r/not_supported.result
Aleksey Midenkov 16069eb4de MDEV-29155 CREATE OR REPLACE with self-referencing CHECK hangs
forever, cannot be killed

Virtual_column_info::fix_and_check_expr() first does fix_expr() which
finds all fields in query tables and then check_vcol_func_processor()
which prohibits SELECT expression. So before we get the error
prohibiting SELECT in vcol expression we must satisfy fix_expr() with
all the opened tables. The patch achieves this by iterating
query_tables from parsed vcol expression and by assigning opened
tables from the main parser context (as they are already preopened if
the parser sees some SELECT expressions).

But the problem is, we cannot use these TABLE objects fully for vcol
expression, at least the comment about MERGE tables states so:

  /* MERGE tables need to access parent and child TABLE_LISTs. */
  DBUG_ASSERT(tables->table->pos_in_table_list == tables);

Therefore after we have done vcol check we should revert back
TABLE_LISTs to the original TABLE-less state.

As CREATE OR REPLACE first drops the original table (at least prior to
MDEV-25292) we can use the above hack from the currently opening
table. And that is possible only after bitmaps initialized, so we move
their execution to a little earlier stage, before vcol parsing. But
partitioning depends on uninitialized bitmaps, so we temporarily
revert some to make partitioning initialization happy.

Note that plain CREATE TABLE just fails this case in parser with
NO_SUCH_TABLE, CREATE OR REPLACE doesn't fail in parser as the old
table still exists.

Now to the hang, mysql_rm_table_no_locks() does TDC_RT_REMOVE_ALL
which waits while share is closed. The table normally is open only as
OPEN_STUB, this is what parser does for CREATE TABLE. But for SELECT
the table is opened not as a stub. If it is the same table name we
anyway have two TABLE_LIST objects: stub and not stub. So for "not
stub" TDC_RT_REMOVE_ALL sees open count and decides to wait until it
is closed. And of course it hangs, because that was opened in the same
thread. Now we force close such TABLE objects before
mysql_rm_table_no_locks().

And the third, condition for sequences was wrong: we have to check
TABLE_LIST::sequence property to make sure we processing sequence.
2025-04-21 13:47:47 +03:00

82 lines
3.6 KiB
Text

connect con1, localhost, root;
set lc_time_names = 'es_MX';
set time_zone='+10:00';
set div_precision_increment=20;
create table t1 (a int, b int, v decimal(20,19) as (a/3));
create table t2 (a int, b int, v int as (a+@a));
drop table t2;
create table t2 (a int, b int, v int as (a+@a) PERSISTENT);
ERROR HY000: Function or expression '@a' cannot be used in the GENERATED ALWAYS AS clause of `v`
create table t3_ok (a int, b int, v int as (a+@@error_count));
create table t3 (a int, b int, v int as (a+@@error_count) PERSISTENT);
ERROR HY000: Function or expression '@@error_count' cannot be used in the GENERATED ALWAYS AS clause of `v`
create table t4 (a int, b int, v int as (@a:=a));
drop table t4;
create table t4 (a int, b int, v int as (@a:=a) PERSISTENT);
ERROR HY000: Function or expression '@a' cannot be used in the GENERATED ALWAYS AS clause of `v`
create table t8 (a int, b int, v varchar(100) as (from_unixtime(a)));
insert t1 (a,b) values (1,2);
insert t8 (a,b) values (1234567890,2);
select * from t1;
a b v
1 2 0.3333333333333333333
select * from t8;
a b v
1234567890 2 2009-02-14 09:31:30
disconnect con1;
connection default;
set time_zone='+1:00';
flush tables;
select * from t1;
a b v
1 2 0.3333333330000000000
select * from t8;
a b v
1234567890 2 2009-02-14 00:31:30
drop table t1, t3_ok, t8;
#
# Bug#33141966 - INCONSISTENT BEHAVIOR IF A COLUMN OF TYPE SERIAL IS SET AS GENERATED
#
create table t1 (a int, b serial as (a+1));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'as (a+1))' at line 1
#
# End of 10.2 tests
#
create table t1 (a int, b real as (rand()), c real as (b) stored);
ERROR HY000: Function or expression 'b' cannot be used in the GENERATED ALWAYS AS clause of `c`
create table t1 (a int, b real as (rand()), c real as (b) unique);
ERROR HY000: Function or expression 'b' cannot be used in the GENERATED ALWAYS AS clause of `c`
create table t1 (a int auto_increment primary key,
b int as (a+1), c int as (b+1) stored);
ERROR HY000: Function or expression 'b' cannot be used in the GENERATED ALWAYS AS clause of `c`
create table t1 (a int auto_increment primary key,
b int as (a+1), c int as (b+1) unique);
ERROR HY000: Function or expression 'b' cannot be used in the GENERATED ALWAYS AS clause of `c`
#
# End of 10.3 tests
#
#
# MDEV-29155 CREATE OR REPLACE with self-referencing CHECK hangs forever, cannot be killed
#
create table t1 (a int);
create table t2 (b int)
# create or replace table t (b int);
create table t3 (c int, check(exists(select a from t1) or exists(select b from t2)));
ERROR HY000: Function or expression 'select ...' cannot be used in the CHECK clause of `CONSTRAINT_1`
create table t3 (c int, check(exists(select c from t3)));
ERROR 42S02: Table 'test.t3' doesn't exist
create table t3 (d int);
create or replace table t3 (c int, check(exists(select a from t1) or exists(select b from t2)));
ERROR HY000: Function or expression 'select ...' cannot be used in the CHECK clause of `CONSTRAINT_1`
create table t3 (d int);
create or replace table t3 (c int, check(exists(select c from t3)));
ERROR HY000: Function or expression 'select ...' cannot be used in the CHECK clause of `CONSTRAINT_1`
create table t3 (c int);
alter table t3 add check(exists(select a from t1) or exists(select b from t2));
ERROR HY000: Function or expression 'select ...' cannot be used in the CHECK clause of `CONSTRAINT_1`
alter table t3 add check(exists(select c from t3));
ERROR HY000: Function or expression 'select ...' cannot be used in the CHECK clause of `CONSTRAINT_1`
drop tables t1, t2, t3;
#
# End of 10.4 tests
#