Skip to content

Commit

Permalink
MDEV-12668 SRID is not preserved in UNION, VIEW, MIN, MAX
Browse files Browse the repository at this point in the history
Fixing the problem that an operation involving a mix of
two or more GEOMETRY operands did not preserve their SRIDs.
Now SRIDs are preserved by hybrid functions, subqueries, TVCs, UNIONs, VIEWs.

Incompatible change:
  An attempt to mix two different SRIDs now raises an error.

Details:

- Adding a new class Type_extra_attributes. It's a generic
  container which can store very specific data type attributes.
  For now it can store one uint32 and one const pointer attribute
  (for GEOMETRY's SRID and for ENUM/SET TYPELIB respectively).
  In the future it can grow as needed.

  Type_extra_attributes will also be reused soon to store "const Type_zone*"
  pointers for the TIMESTAMP's "WITH TIME ZONE 'tz'" attribute
  (a timestamp data type with a fixed time zone independent from @@time_zone).
  The time zone attribute will be stored in exactly the same way like
  a TYPELIB pointer is stored by ENUM/SET.

- Removing Column_definition_attributes members "interval" and "srid".
  Deriving Column_definition_attributes from the generic attribute container
  Type_extra_attributes instead.

- Adding a new class Type_typelib_attributes, to store
  the TYPELIB of the ENUM and SET data types. Deriving Field_enum from it.
  Removing the member Field_enum::typelib.

- Adding a new class Type_geom_attributes, to store
  the GEOMETRY related attributes. Deriving Field_geom from it.
  Removing the member Field_geom::srid.

- Removing virtual methods:
    Field::get_typelib()
    Type_all_attributes::get_typelib() and
    Type_all_attributes::set_typelib()
  They were very specific to TYPELIB.
  Adding more generic virtual methods instead:
  * Field::type_extra_attributes() - to get extra attributes
  * Type_all_attributes::type_extra_attributes() - to get extra attributes
  * Type_all_attributes::type_extra_attributes_addr() - to set extra attributes

- Removing Item_type_holder::enum_set_typelib. Deriving Item_type_holder
  from the generic attribute container Type_extra_attributes instead.
  This makes it possible for UNION to preserve SRID
  (in addition to preserving TYPELIB).

- Deriving Item_hybrid_func from Type_extra_attributes.
  This makes it possible for hybrid functions (e.g. CASE, COALESCE,
  LEAST, GREATEST etc) to preserve SRID.

- Deriving Item_singlerow_subselect from Type_extra_attributes and
  overriding methods:
  * Item_cache::type_extra_attributes()
  * subselect_single_select_engine::fix_length_and_dec()
  * Item_singlerow_subselect::type_extra_attributes()
  * Item_singlerow_subselect::type_extra_attributes_addr()
  This is needed to preserve SRID in subqueries and TVCs

- Cleanup: fixing the data type of members
  * Binlog_type_info::m_enum_typelib
  * Binlog_type_info::m_set_typelib
  from "TYPELIB *" to "const TYPELIB *"
  • Loading branch information
abarkov committed Apr 27, 2024
1 parent 486d42d commit 001f93d
Show file tree
Hide file tree
Showing 21 changed files with 502 additions and 153 deletions.
66 changes: 66 additions & 0 deletions mysql-test/main/gis.result
Expand Up @@ -5437,3 +5437,69 @@ DROP TABLE t1;
#
# End of 10.5 tests
#
#
# Start of 11.5 tests
#
#
# MDEV-12668 SRID is not preserved in UNION, VIEW, MIN, MAX
#
CREATE TABLE t1 (a POINT REF_SYSTEM_ID=0, b POINT REF_SYSTEM_ID=102);
SELECT a FROM t1 UNION SELECT b FROM t1;
ERROR HY000: Illegal parameter data types `point ref_system_id=0` and `point ref_system_id=102` for operation 'UNION'
DROP TABLE t1;
CREATE TABLE t1 (a POINT REF_SYSTEM_ID=101, b POINT REF_SYSTEM_ID=102);
SELECT a FROM t1 UNION SELECT b FROM t1;
ERROR HY000: Illegal parameter data types `point ref_system_id=101` and `point ref_system_id=102` for operation 'UNION'
DROP TABLE t1;
CREATE TABLE t1 (a POINT REF_SYSTEM_ID=101, b POINT REF_SYSTEM_ID=101);
CREATE TABLE t2 AS SELECT a, b FROM t1;
CREATE VIEW v2 AS SELECT a, b FROM t1;
CREATE TABLE t3 AS SELECT a FROM t1 UNION SELECT b FROM t1;
CREATE VIEW v3 AS SELECT a FROM t1 UNION SELECT b FROM t1;
CREATE TABLE t4 AS SELECT COALESCE(a,b) AS a FROM t1;
CREATE VIEW v4 AS SELECT COALESCE(a,b) AS a FROM t1;
CREATE TABLE t5 AS SELECT LEAST(a,b) AS a FROM t1;
CREATE VIEW v5 AS SELECT LEAST(a,b) AS a FROM t1;
CREATE TABLE t6 AS SELECT MIN(a) AS a FROM t1;
CREATE VIEW v6 AS SELECT MIN(a) AS a FROM t1;
CREATE TABLE t7 AS SELECT MIN(a) AS a FROM t1 UNION SELECT b FROM v2;
CREATE VIEW v7 AS SELECT MIN(a) AS a FROM t1 UNION SELECT b FROM v2;
CREATE TABLE t8 AS SELECT (SELECT a FROM t1) AS a;
CREATE VIEW v8 AS SELECT (SELECT a FROM t1) AS a;
CREATE TABLE t9 AS VALUES ((SELECT MAX(a) FROM t1)),(((SELECT MIN(b) FROM t1)));
CREATE VIEW v9 AS VALUES ((SELECT MAX(a) FROM t1)),(((SELECT MIN(b) FROM t1)));
SELECT
G_TABLE_NAME, G_GEOMETRY_COLUMN, SRID
FROM
INFORMATION_SCHEMA.GEOMETRY_COLUMNS
WHERE
F_TABLE_SCHEMA='test'
ORDER
BY G_TABLE_NAME, G_GEOMETRY_COLUMN;
G_TABLE_NAME G_GEOMETRY_COLUMN SRID
t1 a 101
t1 b 101
t2 a 101
t2 b 101
t3 a 101
t4 a 101
t5 a 101
t6 a 101
t7 a 101
t8 a 101
t9 (SELECT MAX(a) FROM t1) 101
v2 a 101
v2 b 101
v3 a 101
v4 a 101
v5 a 101
v6 a 101
v7 a 101
v8 a 101
v9 (select max(`test`.`t1`.`a`) from `test`.`t1`) 101
DROP TABLE t2,t3,t4,t5,t6,t7,t8,t9;
DROP VIEW v2,v3,v4,v5,v6,v7,v8,v9;
DROP TABLE t1;
#
# End of 11.5 tests
#
61 changes: 61 additions & 0 deletions mysql-test/main/gis.test
Expand Up @@ -3441,3 +3441,64 @@ DROP TABLE t1;
--echo #
--echo # End of 10.5 tests
--echo #

--echo #
--echo # Start of 11.5 tests
--echo #

--echo #
--echo # MDEV-12668 SRID is not preserved in UNION, VIEW, MIN, MAX
--echo #

CREATE TABLE t1 (a POINT REF_SYSTEM_ID=0, b POINT REF_SYSTEM_ID=102);
--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT a FROM t1 UNION SELECT b FROM t1;
DROP TABLE t1;

CREATE TABLE t1 (a POINT REF_SYSTEM_ID=101, b POINT REF_SYSTEM_ID=102);
--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT a FROM t1 UNION SELECT b FROM t1;
DROP TABLE t1;

CREATE TABLE t1 (a POINT REF_SYSTEM_ID=101, b POINT REF_SYSTEM_ID=101);

CREATE TABLE t2 AS SELECT a, b FROM t1;
CREATE VIEW v2 AS SELECT a, b FROM t1;

CREATE TABLE t3 AS SELECT a FROM t1 UNION SELECT b FROM t1;
CREATE VIEW v3 AS SELECT a FROM t1 UNION SELECT b FROM t1;

CREATE TABLE t4 AS SELECT COALESCE(a,b) AS a FROM t1;
CREATE VIEW v4 AS SELECT COALESCE(a,b) AS a FROM t1;

CREATE TABLE t5 AS SELECT LEAST(a,b) AS a FROM t1;
CREATE VIEW v5 AS SELECT LEAST(a,b) AS a FROM t1;

CREATE TABLE t6 AS SELECT MIN(a) AS a FROM t1;
CREATE VIEW v6 AS SELECT MIN(a) AS a FROM t1;

CREATE TABLE t7 AS SELECT MIN(a) AS a FROM t1 UNION SELECT b FROM v2;
CREATE VIEW v7 AS SELECT MIN(a) AS a FROM t1 UNION SELECT b FROM v2;

CREATE TABLE t8 AS SELECT (SELECT a FROM t1) AS a;
CREATE VIEW v8 AS SELECT (SELECT a FROM t1) AS a;

CREATE TABLE t9 AS VALUES ((SELECT MAX(a) FROM t1)),(((SELECT MIN(b) FROM t1)));
CREATE VIEW v9 AS VALUES ((SELECT MAX(a) FROM t1)),(((SELECT MIN(b) FROM t1)));

SELECT
G_TABLE_NAME, G_GEOMETRY_COLUMN, SRID
FROM
INFORMATION_SCHEMA.GEOMETRY_COLUMNS
WHERE
F_TABLE_SCHEMA='test'
ORDER
BY G_TABLE_NAME, G_GEOMETRY_COLUMN;

DROP TABLE t2,t3,t4,t5,t6,t7,t8,t9;
DROP VIEW v2,v3,v4,v5,v6,v7,v8,v9;
DROP TABLE t1;

--echo #
--echo # End of 11.5 tests
--echo #

0 comments on commit 001f93d

Please sign in to comment.