1
0
mirror of https://github.com/MariaDB/server.git synced 2026-01-06 05:22:24 +03:00

MDEV-20004 Move Field_geom from field.cc to sql_type_geom.cc

This commit is contained in:
Alexander Barkov
2019-07-09 19:47:57 +04:00
parent 4dc85973b4
commit feb2695ed3
13 changed files with 376 additions and 368 deletions

View File

@@ -21,6 +21,7 @@
#include <mysql/plugin.h>
#include "sql_show.h" // get_all_tables()
#include "sql_error.h" // convert_error_to_warning()
#include "sql_type_geom.h"
/*********** INFORMATION_SCHEMA.SPATIEL_REF_SYS *******************/

View File

@@ -8781,242 +8781,6 @@ longlong Field_blob_compressed::val_int(void)
}
#ifdef HAVE_SPATIAL
/* Values 1-40 reserved for 1-byte options,
41-80 for 2-byte options,
81-120 for 4-byte options,
121-160 for 8-byte options,
other - varied length in next 1-3 bytes.
*/
enum extra2_gis_field_options {
FIELDGEOM_END=0,
FIELDGEOM_STORAGE_MODEL=1,
FIELDGEOM_PRECISION=2,
FIELDGEOM_SCALE=3,
FIELDGEOM_SRID=81,
};
uint gis_field_options_image(uchar *buff, List<Create_field> &create_fields)
{
uint image_size= 0;
List_iterator<Create_field> it(create_fields);
Create_field *field;
while ((field= it++))
{
if (field->real_field_type() != MYSQL_TYPE_GEOMETRY)
continue;
if (buff)
{
uchar *cbuf= buff + image_size;
cbuf[0]= FIELDGEOM_STORAGE_MODEL;
cbuf[1]= (uchar) Field_geom::GEOM_STORAGE_WKB;
cbuf[2]= FIELDGEOM_PRECISION;
cbuf[3]= (uchar) field->length;
cbuf[4]= FIELDGEOM_SCALE;
cbuf[5]= (uchar) field->decimals;
cbuf[6]= FIELDGEOM_SRID;
int4store(cbuf + 7, ((uint32) field->srid));
cbuf[11]= FIELDGEOM_END;
}
image_size+= 12;
}
return image_size;
}
uint gis_field_options_read(const uchar *buf, size_t buf_len,
Field_geom::storage_type *st_type,uint *precision, uint *scale, uint *srid)
{
const uchar *buf_end= buf + buf_len;
const uchar *cbuf= buf;
int option_id;
*precision= *scale= *srid= 0;
*st_type= Field_geom::GEOM_STORAGE_WKB;
if (!buf) /* can only happen with the old FRM file */
goto end_of_record;
while (cbuf < buf_end)
{
switch ((option_id= *(cbuf++)))
{
case FIELDGEOM_STORAGE_MODEL:
*st_type= (Field_geom::storage_type) cbuf[0];
break;
case FIELDGEOM_PRECISION:
*precision= cbuf[0];
break;
case FIELDGEOM_SCALE:
*scale= cbuf[0];
break;
case FIELDGEOM_SRID:
*srid= uint4korr(cbuf);
break;
case FIELDGEOM_END:
goto end_of_record;
}
if (option_id > 0 && option_id <= 40)
cbuf+= 1;
else if (option_id > 40 && option_id <= 80)
cbuf+= 2;
else if (option_id > 80 && option_id <= 120)
cbuf+= 4;
else if (option_id > 120 && option_id <= 160)
cbuf+= 8;
else /* > 160 and <=255 */
cbuf+= cbuf[0] ? 1 + cbuf[0] : 3 + uint2korr(cbuf+1);
}
end_of_record:
return (uint)(cbuf - buf);
}
void Field_geom::sql_type(String &res) const
{
CHARSET_INFO *cs= &my_charset_latin1;
const Name tmp= m_type_handler->name();
res.set(tmp.ptr(), tmp.length(), cs);
}
int Field_geom::store(double nr)
{
my_message(ER_CANT_CREATE_GEOMETRY_OBJECT,
ER_THD(get_thd(), ER_CANT_CREATE_GEOMETRY_OBJECT), MYF(0));
return -1;
}
int Field_geom::store(longlong nr, bool unsigned_val)
{
my_message(ER_CANT_CREATE_GEOMETRY_OBJECT,
ER_THD(get_thd(), ER_CANT_CREATE_GEOMETRY_OBJECT), MYF(0));
return -1;
}
int Field_geom::store_decimal(const my_decimal *)
{
my_message(ER_CANT_CREATE_GEOMETRY_OBJECT,
ER_THD(get_thd(), ER_CANT_CREATE_GEOMETRY_OBJECT), MYF(0));
return -1;
}
int Field_geom::store(const char *from, size_t length, CHARSET_INFO *cs)
{
if (!length)
bzero(ptr, Field_blob::pack_length());
else
{
if (from == Geometry::bad_geometry_data.ptr())
goto err;
// Check given WKB
uint32 wkb_type;
if (length < SRID_SIZE + WKB_HEADER_SIZE + 4)
goto err;
wkb_type= uint4korr(from + SRID_SIZE + 1);
if (wkb_type < (uint32) Geometry::wkb_point ||
wkb_type > (uint32) Geometry::wkb_last)
goto err;
if (m_type_handler->geometry_type() != Type_handler_geometry::GEOM_GEOMETRY &&
m_type_handler->geometry_type() != Type_handler_geometry::GEOM_GEOMETRYCOLLECTION &&
(uint32) m_type_handler->geometry_type() != wkb_type)
{
const char *db= table->s->db.str;
const char *tab_name= table->s->table_name.str;
if (!db)
db= "";
if (!tab_name)
tab_name= "";
my_error(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, MYF(0),
Geometry::ci_collection[m_type_handler->geometry_type()]->m_name.str,
Geometry::ci_collection[wkb_type]->m_name.str,
db, tab_name, field_name.str,
(ulong) table->in_use->get_stmt_da()->
current_row_for_warning());
goto err_exit;
}
Field_blob::store_length(length);
if ((table->copy_blobs || length <= MAX_FIELD_WIDTH) &&
from != value.ptr())
{ // Must make a copy
value.copy(from, length, cs);
from= value.ptr();
}
bmove(ptr + packlength, &from, sizeof(char*));
}
return 0;
err:
my_message(ER_CANT_CREATE_GEOMETRY_OBJECT,
ER_THD(get_thd(), ER_CANT_CREATE_GEOMETRY_OBJECT), MYF(0));
err_exit:
bzero(ptr, Field_blob::pack_length());
return -1;
}
bool Field_geom::is_equal(const Column_definition &new_field) const
{
/*
- Allow ALTER..INPLACE to supertype (GEOMETRY),
e.g. POINT to GEOMETRY or POLYGON to GEOMETRY.
- Allow ALTER..INPLACE to the same geometry type: POINT -> POINT
*/
if (new_field.type_handler() == m_type_handler)
return true;
const Type_handler_geometry *gth=
dynamic_cast<const Type_handler_geometry*>(new_field.type_handler());
return gth && gth->is_binary_compatible_geom_super_type_for(m_type_handler);
}
bool Field_geom::can_optimize_range(const Item_bool_func *cond,
const Item *item,
bool is_eq_func) const
{
return item->cmp_type() == STRING_RESULT;
}
bool Field_geom::load_data_set_no_data(THD *thd, bool fixed_format)
{
return Field_geom::load_data_set_null(thd);
}
bool Field_geom::load_data_set_null(THD *thd)
{
Field_blob::reset();
if (!maybe_null())
{
my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0), field_name.str,
thd->get_stmt_da()->current_row_for_warning());
return true;
}
set_null();
set_has_explicit_value(); // Do not auto-update this field
return false;
}
#endif /*HAVE_SPATIAL*/
/****************************************************************************
** enum type.
** This is a string which only can have a selection of different values.

View File

@@ -32,7 +32,6 @@
#include "sql_error.h" /* Sql_condition */
#include "compat56.h"
#include "sql_type.h" /* Type_std_attributes */
#include "sql_type_geom.h"
#include "field_comp.h"
class Send_field;
@@ -4226,120 +4225,6 @@ private:
};
#ifdef HAVE_SPATIAL
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 &param) const;
enum ha_base_keytype key_type() const { return HA_KEYTYPE_VARBINARY2; }
const Type_handler *type_handler() const
{
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
{
return MYSQL_TYPE_GEOMETRY;
}
enum_field_types real_type() const
{
return MYSQL_TYPE_GEOMETRY;
}
Information_schema_character_attributes
information_schema_character_attributes() const
{
return Information_schema_character_attributes();
}
void make_send_field(Send_field *to)
{
Field_longstr::make_send_field(to);
}
bool can_optimize_range(const Item_bool_func *cond,
const Item *item,
bool is_eq_func) const;
void sql_type(String &str) const;
Copy_func *get_copy_func(const Field *from) const
{
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
{
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;
bool can_be_converted_by_engine(const Column_definition &new_type) const
{
return table->file->can_convert_geom(this, new_type);
}
int store(const char *to, size_t length, CHARSET_INFO *charset);
int store(double nr);
int store(longlong nr, bool unsigned_val);
int store_decimal(const my_decimal *);
uint size_of() const { 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 { return packlength; }
/**
Non-nullable GEOMETRY types cannot have defaults,
but the underlying blob must still be reset.
*/
int reset(void) { return Field_blob::reset() || !maybe_null(); }
bool load_data_set_null(THD *thd);
bool load_data_set_no_data(THD *thd, bool fixed_format);
uint get_srid() const { return srid; }
void print_key_value(String *out, uint32 length)
{
out->append(STRING_WITH_LEN("unprintable_geometry_value"));
}
};
uint gis_field_options_image(uchar *buff, List<Create_field> &create_fields);
uint gis_field_options_read(const uchar *buf, size_t buf_len,
Field_geom::storage_type *st_type,uint *precision, uint *scale, uint *srid);
#endif /*HAVE_SPATIAL*/
class Field_enum :public Field_str {
static void do_field_enum(Copy_field *copy_field);
protected:

View File

@@ -52,7 +52,6 @@ class Rowid_filter;
class Field_string;
class Field_varstring;
class Field_blob;
class Field_geom;
class Column_definition;
// the following is for checking tables
@@ -4818,11 +4817,6 @@ public:
{
return false;
}
virtual bool can_convert_geom(const Field_geom *field,
const Column_definition &new_type) const
{
return false;
}
protected:
Handler_share *get_ha_share_ptr();

View File

@@ -5792,7 +5792,6 @@ public:
#include "item_row.h"
#include "item_cmpfunc.h"
#include "item_strfunc.h"
#include "item_geofunc.h"
#include "item_timefunc.h"
#include "item_subselect.h"
#include "item_xmlfunc.h"

View File

@@ -35,6 +35,7 @@
#include "sp.h"
#include "item_inetfunc.h"
#include "sql_time.h"
#include "sql_type_geom.h"
/*
=============================================================================

View File

@@ -38,6 +38,7 @@
#ifdef HAVE_SPATIAL
#include <m_ctype.h>
#include "opt_range.h"
#include "item_geofunc.h"
bool Item_geometry_func::fix_length_and_dec()

View File

@@ -26,6 +26,8 @@
#pragma interface /* gcc class implementation */
#endif
#include "sql_type_geom.h"
#include "item.h"
#include "gcalc_slicescan.h"
#include "gcalc_tools.h"

View File

@@ -3484,6 +3484,12 @@ public:
{
return false;
}
virtual uint Column_definition_gis_options_image(uchar *buff,
const Column_definition &def)
const
{
return 0;
}
// Check if the implicit default value is Ok in the current sql_mode
virtual bool validate_implicit_default_value(THD *thd,
const Column_definition &def)

View File

@@ -15,12 +15,14 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
#include "sql_type_geom.h"
#include "sql_class.h"
#include "item.h"
#include "mariadb.h"
#ifdef HAVE_SPATIAL
#include "sql_class.h"
#include "sql_type_geom.h"
#include "item_geofunc.h"
const Name
Type_handler_geometry::
m_name_geometry(STRING_WITH_LEN("geometry")),
@@ -619,6 +621,97 @@ void Type_handler_geometry::
}
/* Values 1-40 reserved for 1-byte options,
41-80 for 2-byte options,
81-120 for 4-byte options,
121-160 for 8-byte options,
other - varied length in next 1-3 bytes.
*/
enum extra2_gis_field_options {
FIELDGEOM_END=0,
FIELDGEOM_STORAGE_MODEL=1,
FIELDGEOM_PRECISION=2,
FIELDGEOM_SCALE=3,
FIELDGEOM_SRID=81,
};
uint
Type_handler_geometry::
Column_definition_gis_options_image(uchar *cbuf,
const Column_definition &def) const
{
if (cbuf)
{
cbuf[0]= FIELDGEOM_STORAGE_MODEL;
cbuf[1]= (uchar) Field_geom::GEOM_STORAGE_WKB;
cbuf[2]= FIELDGEOM_PRECISION;
cbuf[3]= (uchar) def.length;
cbuf[4]= FIELDGEOM_SCALE;
cbuf[5]= (uchar) def.decimals;
cbuf[6]= FIELDGEOM_SRID;
int4store(cbuf + 7, ((uint32) def.srid));
cbuf[11]= FIELDGEOM_END;
}
return 12;
}
static uint gis_field_options_read(const uchar *buf, size_t buf_len,
Field_geom::storage_type *st_type,
uint *precision, uint *scale, uint *srid)
{
const uchar *buf_end= buf + buf_len;
const uchar *cbuf= buf;
int option_id;
*precision= *scale= *srid= 0;
*st_type= Field_geom::GEOM_STORAGE_WKB;
if (!buf) /* can only happen with the old FRM file */
goto end_of_record;
while (cbuf < buf_end)
{
switch ((option_id= *(cbuf++)))
{
case FIELDGEOM_STORAGE_MODEL:
*st_type= (Field_geom::storage_type) cbuf[0];
break;
case FIELDGEOM_PRECISION:
*precision= cbuf[0];
break;
case FIELDGEOM_SCALE:
*scale= cbuf[0];
break;
case FIELDGEOM_SRID:
*srid= uint4korr(cbuf);
break;
case FIELDGEOM_END:
goto end_of_record;
}
if (option_id > 0 && option_id <= 40)
cbuf+= 1;
else if (option_id > 40 && option_id <= 80)
cbuf+= 2;
else if (option_id > 80 && option_id <= 120)
cbuf+= 4;
else if (option_id > 120 && option_id <= 160)
cbuf+= 8;
else /* > 160 and <=255 */
cbuf+= cbuf[0] ? 1 + cbuf[0] : 3 + uint2korr(cbuf+1);
}
end_of_record:
return (uint)(cbuf - buf);
}
bool Type_handler_geometry::
Column_definition_attributes_frm_unpack(Column_definition_attributes *attr,
TABLE_SHARE *share,
@@ -658,4 +751,139 @@ Field_geom::rpl_conv_type_from(const Conv_source &source,
}
/*****************************************************************/
void Field_geom::sql_type(String &res) const
{
CHARSET_INFO *cs= &my_charset_latin1;
const Name tmp= m_type_handler->name();
res.set(tmp.ptr(), tmp.length(), cs);
}
int Field_geom::store(double nr)
{
my_message(ER_CANT_CREATE_GEOMETRY_OBJECT,
ER_THD(get_thd(), ER_CANT_CREATE_GEOMETRY_OBJECT), MYF(0));
return -1;
}
int Field_geom::store(longlong nr, bool unsigned_val)
{
my_message(ER_CANT_CREATE_GEOMETRY_OBJECT,
ER_THD(get_thd(), ER_CANT_CREATE_GEOMETRY_OBJECT), MYF(0));
return -1;
}
int Field_geom::store_decimal(const my_decimal *)
{
my_message(ER_CANT_CREATE_GEOMETRY_OBJECT,
ER_THD(get_thd(), ER_CANT_CREATE_GEOMETRY_OBJECT), MYF(0));
return -1;
}
int Field_geom::store(const char *from, size_t length, CHARSET_INFO *cs)
{
if (!length)
bzero(ptr, Field_blob::pack_length());
else
{
if (from == Geometry::bad_geometry_data.ptr())
goto err;
// Check given WKB
uint32 wkb_type;
if (length < SRID_SIZE + WKB_HEADER_SIZE + 4)
goto err;
wkb_type= uint4korr(from + SRID_SIZE + 1);
if (wkb_type < (uint32) Geometry::wkb_point ||
wkb_type > (uint32) Geometry::wkb_last)
goto err;
if (m_type_handler->geometry_type() != Type_handler_geometry::GEOM_GEOMETRY &&
m_type_handler->geometry_type() != Type_handler_geometry::GEOM_GEOMETRYCOLLECTION &&
(uint32) m_type_handler->geometry_type() != wkb_type)
{
const char *db= table->s->db.str;
const char *tab_name= table->s->table_name.str;
if (!db)
db= "";
if (!tab_name)
tab_name= "";
my_error(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, MYF(0),
Geometry::ci_collection[m_type_handler->geometry_type()]->m_name.str,
Geometry::ci_collection[wkb_type]->m_name.str,
db, tab_name, field_name.str,
(ulong) table->in_use->get_stmt_da()->
current_row_for_warning());
goto err_exit;
}
Field_blob::store_length(length);
if ((table->copy_blobs || length <= MAX_FIELD_WIDTH) &&
from != value.ptr())
{ // Must make a copy
value.copy(from, length, cs);
from= value.ptr();
}
bmove(ptr + packlength, &from, sizeof(char*));
}
return 0;
err:
my_message(ER_CANT_CREATE_GEOMETRY_OBJECT,
ER_THD(get_thd(), ER_CANT_CREATE_GEOMETRY_OBJECT), MYF(0));
err_exit:
bzero(ptr, Field_blob::pack_length());
return -1;
}
bool Field_geom::is_equal(const Column_definition &new_field) const
{
/*
- Allow ALTER..INPLACE to supertype (GEOMETRY),
e.g. POINT to GEOMETRY or POLYGON to GEOMETRY.
- Allow ALTER..INPLACE to the same geometry type: POINT -> POINT
*/
if (new_field.type_handler() == m_type_handler)
return true;
const Type_handler_geometry *gth=
dynamic_cast<const Type_handler_geometry*>(new_field.type_handler());
return gth && gth->is_binary_compatible_geom_super_type_for(m_type_handler);
}
bool Field_geom::can_optimize_range(const Item_bool_func *cond,
const Item *item,
bool is_eq_func) const
{
return item->cmp_type() == STRING_RESULT;
}
bool Field_geom::load_data_set_no_data(THD *thd, bool fixed_format)
{
return Field_geom::load_data_set_null(thd);
}
bool Field_geom::load_data_set_null(THD *thd)
{
Field_blob::reset();
if (!maybe_null())
{
my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0), field_name.str,
thd->get_stmt_da()->current_row_for_warning());
return true;
}
set_null();
set_has_explicit_value(); // Do not auto-update this field
return false;
}
#endif // HAVE_SPATIAL

View File

@@ -72,6 +72,9 @@ public:
const st_value *value) const override;
Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const override;
uint Column_definition_gis_options_image(uchar *buff,
const Column_definition &def)
const override;
void
Column_definition_attributes_frm_pack(const Column_definition_attributes *at,
uchar *buff) const override;
@@ -316,6 +319,115 @@ extern MYSQL_PLUGIN_IMPORT
extern MYSQL_PLUGIN_IMPORT 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 &param) const;
enum ha_base_keytype key_type() const { return HA_KEYTYPE_VARBINARY2; }
const Type_handler *type_handler() const
{
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
{
return MYSQL_TYPE_GEOMETRY;
}
enum_field_types real_type() const
{
return MYSQL_TYPE_GEOMETRY;
}
Information_schema_character_attributes
information_schema_character_attributes() const
{
return Information_schema_character_attributes();
}
void make_send_field(Send_field *to)
{
Field_longstr::make_send_field(to);
}
bool can_optimize_range(const Item_bool_func *cond,
const Item *item,
bool is_eq_func) const;
void sql_type(String &str) const;
Copy_func *get_copy_func(const Field *from) const
{
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
{
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;
bool can_be_converted_by_engine(const Column_definition &new_type) const
{
return false; // Override the Field_blob behavior
}
int store(const char *to, size_t length, CHARSET_INFO *charset);
int store(double nr);
int store(longlong nr, bool unsigned_val);
int store_decimal(const my_decimal *);
uint size_of() const { 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 { return packlength; }
/**
Non-nullable GEOMETRY types cannot have defaults,
but the underlying blob must still be reset.
*/
int reset(void) { return Field_blob::reset() || !maybe_null(); }
bool load_data_set_null(THD *thd);
bool load_data_set_no_data(THD *thd, bool fixed_format);
uint get_srid() const { return srid; }
void print_key_value(String *out, uint32 length)
{
out->append(STRING_WITH_LEN("unprintable_geometry_value"));
}
};
#endif // HAVE_SPATIAL
#endif // SQL_TYPE_GEOM_H_INCLUDED

View File

@@ -152,6 +152,25 @@ static size_t extra2_str_size(size_t len)
return (len > 255 ? 3 : 1) + len;
}
static uint gis_field_options_image(uchar *buff,
List<Create_field> &create_fields)
{
uint image_size= 0;
List_iterator<Create_field> it(create_fields);
Create_field *field;
while ((field= it++))
{
if (field->real_field_type() != MYSQL_TYPE_GEOMETRY)
continue;
uchar *cbuf= buff ? buff + image_size : NULL;
image_size+= field->type_handler()->
Column_definition_gis_options_image(cbuf, *field);
}
return image_size;
}
/**
Create a frm (table definition) file
@@ -241,9 +260,7 @@ LEX_CUSTRING build_frm_image(THD *thd, const LEX_CSTRING &table,
options_len= engine_table_options_frm_length(create_info->option_list,
create_fields,
keys, key_info);
#ifdef HAVE_SPATIAL
gis_extra2_len= gis_field_options_image(NULL, create_fields);
#endif /*HAVE_SPATIAL*/
DBUG_PRINT("info", ("Options length: %u", options_len));
if (validate_comment_length(thd, &create_info->comment, TABLE_COMMENT_MAXLEN,
@@ -356,14 +373,12 @@ LEX_CUSTRING build_frm_image(THD *thd, const LEX_CSTRING &table,
create_fields, keys, key_info);
}
#ifdef HAVE_SPATIAL
if (gis_extra2_len)
{
*pos= EXTRA2_GIS;
pos= extra2_write_len(pos+1, gis_extra2_len);
pos+= gis_field_options_image(pos, create_fields);
}
#endif /*HAVE_SPATIAL*/
// PERIOD
if (create_info->period_info.is_set())

View File

@@ -6089,7 +6089,7 @@ int ha_mroonga::storage_write_row(uchar *buf)
#ifdef MRN_HAVE_SPATIAL
bool is_null_geometry_value =
field->real_type() == MYSQL_TYPE_GEOMETRY &&
static_cast<Field_geom *>(field)->get_length() == 0;
static_cast<Field_blob *>(field)->get_length() == 0;
if (is_null_geometry_value) {
continue;
}
@@ -10729,7 +10729,7 @@ int ha_mroonga::generic_store_bulk_geometry(Field *field, grn_obj *buf)
int error = 0;
#ifdef MRN_HAVE_SPATIAL
String buffer;
Field_geom *geometry = (Field_geom *)field;
Field_blob *geometry = (Field_blob *)field;
String *value = geometry->val_str(0, &buffer);
const char *wkb = value->ptr();
int len = value->length();
@@ -11199,7 +11199,7 @@ void ha_mroonga::storage_store_field_geometry(Field *field,
String *geometry_buffer = &blob_buffers[field->field_index];
geometry_buffer->length(0);
uint wkb_length = sizeof(wkb) / sizeof(*wkb);
Field_geom *geometry = (Field_geom *)field;
Field_blob *geometry= (Field_blob *)field;
geometry_buffer->reserve(wkb_length);
geometry_buffer->q_append((const char *) wkb, wkb_length);
geometry->set_ptr((uint32) wkb_length, (uchar *) geometry_buffer->ptr());