diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 18:07:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 18:07:14 +0000 |
commit | a175314c3e5827eb193872241446f2f8f5c9d33c (patch) | |
tree | cd3d60ca99ae00829c52a6ca79150a5b6e62528b /sql/sql_type_geom.h | |
parent | Initial commit. (diff) | |
download | mariadb-10.5-upstream/1%10.5.12.tar.xz mariadb-10.5-upstream/1%10.5.12.zip |
Adding upstream version 1:10.5.12.upstream/1%10.5.12upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | sql/sql_type_geom.h | 439 |
1 files changed, 439 insertions, 0 deletions
diff --git a/sql/sql_type_geom.h b/sql/sql_type_geom.h new file mode 100644 index 00000000..fed988c3 --- /dev/null +++ b/sql/sql_type_geom.h @@ -0,0 +1,439 @@ +#ifndef SQL_TYPE_GEOM_H_INCLUDED +#define SQL_TYPE_GEOM_H_INCLUDED +/* + Copyright (c) 2015 MariaDB Foundation + Copyright (c) 2019 MariaDB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + +#ifdef USE_PRAGMA_IMPLEMENTATION +#pragma implementation // gcc: Class implementation +#endif + +#include "mariadb.h" +#include "sql_type.h" + +#ifdef HAVE_SPATIAL +class Type_handler_geometry: public Type_handler_string_result +{ +public: + enum geometry_types + { + GEOM_GEOMETRY = 0, GEOM_POINT = 1, GEOM_LINESTRING = 2, GEOM_POLYGON = 3, + GEOM_MULTIPOINT = 4, GEOM_MULTILINESTRING = 5, GEOM_MULTIPOLYGON = 6, + GEOM_GEOMETRYCOLLECTION = 7 + }; + static bool check_type_geom_or_binary(const char *opname, const Item *item); + static bool check_types_geom_or_binary(const char *opname, + Item * const *args, + uint start, uint end); + static const Type_handler_geometry *type_handler_geom_by_type(uint type); + LEX_CSTRING extended_metadata_data_type_name() const; +public: + virtual ~Type_handler_geometry() {} + enum_field_types field_type() const override { return MYSQL_TYPE_GEOMETRY; } + bool Item_append_extended_type_info(Send_field_extended_metadata *to, + const Item *item) const override + { + LEX_CSTRING tmp= extended_metadata_data_type_name(); + return tmp.length ? to->set_data_type_name(tmp) : false; + } + bool is_param_long_data_type() const override { return true; } + uint32 max_display_length_for_field(const Conv_source &src) const override; + uint32 calc_pack_length(uint32 length) const override; + const Type_collection *type_collection() const override; + const Type_handler *type_handler_for_comparison() const override; + virtual geometry_types geometry_type() const { return GEOM_GEOMETRY; } + virtual Item *create_typecast_item(THD *thd, Item *item, + const Type_cast_attributes &attr) + const override; + const Type_handler *type_handler_frm_unpack(const uchar *buffer) + const override; + bool is_binary_compatible_geom_super_type_for(const Type_handler_geometry *th) + const + { + return geometry_type() == GEOM_GEOMETRY || + geometry_type() == th->geometry_type(); + } + bool type_can_have_key_part() const override { return true; } + bool subquery_type_allows_materialization(const Item *, const Item *, bool) + const override + { + return false; // Materialization does not work with GEOMETRY columns + } + void Item_param_set_param_func(Item_param *param, + uchar **pos, ulong len) const override; + bool Item_param_set_from_value(THD *thd, + Item_param *param, + const Type_all_attributes *attr, + const st_value *value) const override; + Field *make_conversion_table_field(MEM_ROOT *root, + TABLE *table, uint metadata, + const Field *target) const override; + uint Column_definition_gis_options_image(uchar *buff, + const Column_definition &def) + const override; + bool Column_definition_data_type_info_image(Binary_string *to, + const Column_definition &def) + const override + { + return false; + } + void + Column_definition_attributes_frm_pack(const Column_definition_attributes *at, + uchar *buff) const override; + bool + Column_definition_attributes_frm_unpack(Column_definition_attributes *attr, + TABLE_SHARE *share, + const uchar *buffer, + LEX_CUSTRING *gis_options) const + override; + bool Column_definition_fix_attributes(Column_definition *c) const override; + void Column_definition_reuse_fix_attributes(THD *thd, + Column_definition *c, + const Field *field) const + override; + bool Column_definition_prepare_stage1(THD *thd, + MEM_ROOT *mem_root, + Column_definition *c, + handler *file, + ulonglong table_flags, + const Column_derived_attributes + *derived_attr) + const override; + bool Column_definition_prepare_stage2(Column_definition *c, + handler *file, + ulonglong table_flags) const override; + bool Key_part_spec_init_primary(Key_part_spec *part, + const Column_definition &def, + const handler *file) const override; + bool Key_part_spec_init_unique(Key_part_spec *part, + const Column_definition &def, + const handler *file, + bool *has_key_needed) const override; + bool Key_part_spec_init_multiple(Key_part_spec *part, + const Column_definition &def, + const handler *file) const override; + bool Key_part_spec_init_foreign(Key_part_spec *part, + const Column_definition &def, + const handler *file) const override; + bool Key_part_spec_init_spatial(Key_part_spec *part, + const Column_definition &def) const override; + Field *make_table_field(MEM_ROOT *root, + const LEX_CSTRING *name, + const Record_addr &addr, + const Type_all_attributes &attr, + TABLE_SHARE *share) const override; + + Field *make_table_field_from_def(TABLE_SHARE *share, + MEM_ROOT *mem_root, + const LEX_CSTRING *name, + const Record_addr &addr, + const Bit_addr &bit, + const Column_definition_attributes *attr, + uint32 flags) const override; + + bool can_return_int() const override { return false; } + bool can_return_decimal() const override { return false; } + bool can_return_real() const override { return false; } + bool can_return_text() const override { return false; } + bool can_return_date() const override { return false; } + bool can_return_time() const override { return false; } + bool Item_func_round_fix_length_and_dec(Item_func_round *) const override; + bool Item_func_int_val_fix_length_and_dec(Item_func_int_val *) const override; + bool Item_func_abs_fix_length_and_dec(Item_func_abs *) const override; + bool Item_func_neg_fix_length_and_dec(Item_func_neg *) const override; + bool Item_hybrid_func_fix_attributes(THD *thd, + const char *name, + Type_handler_hybrid_field_type *h, + Type_all_attributes *attr, + Item **items, uint nitems) const + override; + bool Item_sum_sum_fix_length_and_dec(Item_sum_sum *) const override; + bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *) const override; + bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *) const override; + + bool Item_func_signed_fix_length_and_dec(Item_func_signed *) const override; + bool Item_func_unsigned_fix_length_and_dec(Item_func_unsigned *) const + override; + bool Item_double_typecast_fix_length_and_dec(Item_double_typecast *) const + override; + bool Item_float_typecast_fix_length_and_dec(Item_float_typecast *) const + override; + bool Item_decimal_typecast_fix_length_and_dec(Item_decimal_typecast *) const + override; + bool Item_char_typecast_fix_length_and_dec(Item_char_typecast *) const + override; + bool Item_time_typecast_fix_length_and_dec(Item_time_typecast *) const + override; + bool Item_date_typecast_fix_length_and_dec(Item_date_typecast *) const + override; + bool Item_datetime_typecast_fix_length_and_dec(Item_datetime_typecast *) const + override; +}; + + +class Type_handler_point: public Type_handler_geometry +{ + // Binary length of a POINT value: 4 byte SRID + 21 byte WKB POINT + static uint octet_length() { return 25; } +public: + geometry_types geometry_type() const override { return GEOM_POINT; } + Item *make_constructor_item(THD *thd, List<Item> *args) const override; + bool Key_part_spec_init_primary(Key_part_spec *part, + const Column_definition &def, + const handler *file) const override; + bool Key_part_spec_init_unique(Key_part_spec *part, + const Column_definition &def, + const handler *file, + bool *has_key_needed) const override; + bool Key_part_spec_init_multiple(Key_part_spec *part, + const Column_definition &def, + const handler *file) const override; + bool Key_part_spec_init_foreign(Key_part_spec *part, + const Column_definition &def, + const handler *file) const override; +}; + + +class Type_handler_linestring: public Type_handler_geometry +{ +public: + geometry_types geometry_type() const override { return GEOM_LINESTRING; } + Item *make_constructor_item(THD *thd, List<Item> *args) const override; +}; + + +class Type_handler_polygon: public Type_handler_geometry +{ +public: + geometry_types geometry_type() const override { return GEOM_POLYGON; } + Item *make_constructor_item(THD *thd, List<Item> *args) const override; +}; + + +class Type_handler_multipoint: public Type_handler_geometry +{ +public: + geometry_types geometry_type() const override { return GEOM_MULTIPOINT; } + Item *make_constructor_item(THD *thd, List<Item> *args) const override; +}; + + +class Type_handler_multilinestring: public Type_handler_geometry +{ +public: + geometry_types geometry_type() const override { return GEOM_MULTILINESTRING; } + Item *make_constructor_item(THD *thd, List<Item> *args) const override; +}; + + +class Type_handler_multipolygon: public Type_handler_geometry +{ +public: + geometry_types geometry_type() const override { return GEOM_MULTIPOLYGON; } + Item *make_constructor_item(THD *thd, List<Item> *args) const override; +}; + + +class Type_handler_geometrycollection: public Type_handler_geometry +{ +public: + geometry_types geometry_type() const override { return GEOM_GEOMETRYCOLLECTION; } + Item *make_constructor_item(THD *thd, List<Item> *args) const override; +}; + +extern Named_type_handler<Type_handler_geometry> type_handler_geometry; +extern Named_type_handler<Type_handler_point> type_handler_point; +extern Named_type_handler<Type_handler_linestring> type_handler_linestring; +extern Named_type_handler<Type_handler_polygon> type_handler_polygon; +extern Named_type_handler<Type_handler_multipoint> type_handler_multipoint; +extern Named_type_handler<Type_handler_multilinestring> type_handler_multilinestring; +extern Named_type_handler<Type_handler_multipolygon> type_handler_multipolygon; +extern Named_type_handler<Type_handler_geometrycollection> type_handler_geometrycollection; + +class Type_collection_geometry: public Type_collection +{ + const Type_handler *aggregate_common(const Type_handler *a, + const Type_handler *b) const + { + if (a == b) + return a; + if (dynamic_cast<const Type_handler_geometry*>(a) && + dynamic_cast<const Type_handler_geometry*>(b)) + return &type_handler_geometry; + return NULL; + } + const Type_handler *aggregate_if_null(const Type_handler *a, + const Type_handler *b) const + { + return a == &type_handler_null ? b : + b == &type_handler_null ? a : + NULL; + } + const Type_handler *aggregate_if_long_blob(const Type_handler *a, + const Type_handler *b) const + { + return a == &type_handler_long_blob ? &type_handler_long_blob : + b == &type_handler_long_blob ? &type_handler_long_blob : + NULL; + } + const Type_handler *aggregate_if_string(const Type_handler *a, + const Type_handler *b) const; +#ifndef DBUG_OFF + bool init_aggregators(Type_handler_data *data, const Type_handler *geom) const; +#endif +public: + bool init(Type_handler_data *data) override; + const Type_handler *handler_by_name(const LEX_CSTRING &name) const override; + const Type_handler *aggregate_for_result(const Type_handler *a, + const Type_handler *b) + const override; + const Type_handler *aggregate_for_comparison(const Type_handler *a, + const Type_handler *b) + const override; + const Type_handler *aggregate_for_min_max(const Type_handler *a, + const Type_handler *b) + const override; + const Type_handler *aggregate_for_num_op(const Type_handler *a, + const Type_handler *b) + const override + { + return NULL; + } +}; + +extern Type_collection_geometry type_collection_geometry; + +#include "field.h" + +class Field_geom :public Field_blob +{ + const Type_handler_geometry *m_type_handler; +public: + uint srid; + uint precision; + enum storage_type { GEOM_STORAGE_WKB= 0, GEOM_STORAGE_BINARY= 1}; + enum storage_type storage; + + Field_geom(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, + enum utype unireg_check_arg, const LEX_CSTRING *field_name_arg, + TABLE_SHARE *share, uint blob_pack_length, + const Type_handler_geometry *gth, + uint field_srid) + :Field_blob(ptr_arg, null_ptr_arg, null_bit_arg, unireg_check_arg, + field_name_arg, share, blob_pack_length, &my_charset_bin), + m_type_handler(gth) + { srid= field_srid; } + enum_conv_type rpl_conv_type_from(const Conv_source &source, + const Relay_log_info *rli, + const Conv_param ¶m) const override; + enum ha_base_keytype key_type() const override + { + return HA_KEYTYPE_VARBINARY2; + } + const Type_handler *type_handler() const override + { + return m_type_handler; + } + const Type_handler_geometry *type_handler_geom() const + { + return m_type_handler; + } + void set_type_handler(const Type_handler_geometry *th) + { + m_type_handler= th; + } + enum_field_types type() const override + { + return MYSQL_TYPE_GEOMETRY; + } + enum_field_types real_type() const override + { + return MYSQL_TYPE_GEOMETRY; + } + Information_schema_character_attributes + information_schema_character_attributes() const override + { + return Information_schema_character_attributes(); + } + void make_send_field(Send_field *to) override + { + Field_longstr::make_send_field(to); + LEX_CSTRING tmp= m_type_handler->extended_metadata_data_type_name(); + if (tmp.length) + to->set_data_type_name(tmp); + } + bool can_optimize_range(const Item_bool_func *cond, + const Item *item, + bool is_eq_func) const override; + void sql_type(String &str) const override; + Copy_func *get_copy_func(const Field *from) const override + { + const Type_handler_geometry *fth= + dynamic_cast<const Type_handler_geometry*>(from->type_handler()); + if (fth && m_type_handler->is_binary_compatible_geom_super_type_for(fth)) + return get_identical_copy_func(); + return do_conv_blob; + } + bool memcpy_field_possible(const Field *from) const override + { + const Type_handler_geometry *fth= + dynamic_cast<const Type_handler_geometry*>(from->type_handler()); + return fth && + m_type_handler->is_binary_compatible_geom_super_type_for(fth) && + !table->copy_blobs; + } + bool is_equal(const Column_definition &new_field) const override; + bool can_be_converted_by_engine(const Column_definition &new_type) + const override + { + return false; // Override the Field_blob behavior + } + + int store(const char *to, size_t length, CHARSET_INFO *charset) override; + int store(double nr) override; + int store(longlong nr, bool unsigned_val) override; + int store_decimal(const my_decimal *) override; + uint size_of() const override{ return sizeof(*this); } + /** + Key length is provided only to support hash joins. (compared byte for byte) + Ex: SELECT .. FROM t1,t2 WHERE t1.field_geom1=t2.field_geom2. + + The comparison is not very relevant, as identical geometry might be + represented differently, but we need to support it either way. + */ + uint32 key_length() const override{ return packlength; } + uint get_key_image(uchar *buff,uint length, + const uchar *ptr_arg, imagetype type_arg) const override; + + /** + Non-nullable GEOMETRY types cannot have defaults, + but the underlying blob must still be reset. + */ + int reset(void) override{ return Field_blob::reset() || !maybe_null(); } + bool load_data_set_null(THD *thd) override; + bool load_data_set_no_data(THD *thd, bool fixed_format) override; + + uint get_srid() const { return srid; } + void print_key_value(String *out, uint32 length) override + { + out->append(STRING_WITH_LEN("unprintable_geometry_value")); + } + Binlog_type_info binlog_type_info() const override; +}; + +#endif // HAVE_SPATIAL + +#endif // SQL_TYPE_GEOM_H_INCLUDED |