mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-12668 SRID is not preserved in UNION, VIEW, MIN, MAX
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 *"
This commit is contained in:
@ -3402,6 +3402,98 @@ public:
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
A container for very specific data type attributes.
|
||||
For now it prodives space for:
|
||||
- one const pointer attributes
|
||||
- one unt32 attribute
|
||||
*/
|
||||
class Type_extra_attributes
|
||||
{
|
||||
const void *m_attr_const_void_ptr[1];
|
||||
uint32 m_attr_uint32[1];
|
||||
public:
|
||||
Type_extra_attributes()
|
||||
:m_attr_const_void_ptr{0},
|
||||
m_attr_uint32{0}
|
||||
{ }
|
||||
Type_extra_attributes(const void *const_void_ptr)
|
||||
:m_attr_const_void_ptr{const_void_ptr},
|
||||
m_attr_uint32{0}
|
||||
{ }
|
||||
/*
|
||||
Generic const pointer attributes.
|
||||
The ENUM and SET data types store TYPELIB information here.
|
||||
*/
|
||||
Type_extra_attributes & set_attr_const_void_ptr(uint i, const void *value)
|
||||
{
|
||||
m_attr_const_void_ptr[i]= value;
|
||||
return *this;
|
||||
}
|
||||
const void *get_attr_const_void_ptr(uint i) const
|
||||
{
|
||||
return m_attr_const_void_ptr[i];
|
||||
}
|
||||
/*
|
||||
Generic uint32 attributes.
|
||||
The GEOMETRY data type stores SRID here.
|
||||
*/
|
||||
Type_extra_attributes & set_attr_uint32(uint i, uint32 value)
|
||||
{
|
||||
m_attr_uint32[i]= value;
|
||||
return *this;
|
||||
}
|
||||
uint32 get_attr_uint32(uint i) const
|
||||
{
|
||||
return m_attr_uint32[i];
|
||||
}
|
||||
/*
|
||||
Helper methods for TYPELIB attributes.
|
||||
They are mostly needed to simplify the code
|
||||
in Column_definition_attributes and Column_definition methods.
|
||||
Eventually we should move this code into Type_typelib_attributes
|
||||
and remove these methods.
|
||||
*/
|
||||
Type_extra_attributes & set_typelib(const TYPELIB *typelib)
|
||||
{
|
||||
return set_attr_const_void_ptr(0, typelib);
|
||||
}
|
||||
const TYPELIB *typelib() const
|
||||
{
|
||||
return (const TYPELIB*) get_attr_const_void_ptr(0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class Type_typelib_attributes
|
||||
{
|
||||
protected:
|
||||
const TYPELIB *m_typelib;
|
||||
public:
|
||||
Type_typelib_attributes()
|
||||
:m_typelib(nullptr)
|
||||
{ }
|
||||
Type_typelib_attributes(const TYPELIB *typelib)
|
||||
:m_typelib(typelib)
|
||||
{ }
|
||||
Type_typelib_attributes(const Type_extra_attributes &eattr)
|
||||
:m_typelib((const TYPELIB *) eattr.get_attr_const_void_ptr(0))
|
||||
{ }
|
||||
void store(Type_extra_attributes *to) const
|
||||
{
|
||||
to->set_attr_const_void_ptr(0, m_typelib);
|
||||
}
|
||||
const TYPELIB *typelib() const
|
||||
{
|
||||
return m_typelib;
|
||||
}
|
||||
void set_typelib(const TYPELIB *typelib)
|
||||
{
|
||||
m_typelib= typelib;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class Type_all_attributes: public Type_std_attributes
|
||||
{
|
||||
public:
|
||||
@ -3411,8 +3503,8 @@ public:
|
||||
virtual void set_type_maybe_null(bool maybe_null_arg)= 0;
|
||||
// Returns total number of decimal digits
|
||||
virtual decimal_digits_t decimal_precision() const= 0;
|
||||
virtual const TYPELIB *get_typelib() const= 0;
|
||||
virtual void set_typelib(const TYPELIB *typelib)= 0;
|
||||
virtual Type_extra_attributes *type_extra_attributes_addr() = 0;
|
||||
virtual const Type_extra_attributes type_extra_attributes() const= 0;
|
||||
};
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user