Commit fa115a0f authored by unknown's avatar unknown
Browse files

bug #22372 (LOAD DATA crashes the table with the geometry field)

The problem is that the GEOMETRY NOT NULL can't automatically set
any value as a default one. We always tried to complete LOAD DATA
command even if there's not enough data in file. That doesn't work
for GEOMETRY NOT NULL. Now Field_*::reset() returns an error sign
and it's checked in mysql_load()


mysql-test/r/gis.result:
  test result
mysql-test/t/gis.test:
  testcase
sql/field.cc:
  reset() now returns error sign
sql/field.h:
  Field_*::reset() now returns error sign if the field can't be reset
sql/sql_load.cc:
  check if field can't be reset and return error if it's so
parent 0184996b
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -671,3 +671,9 @@ Catalog Database Table Table_alias Column Column_alias Type Length Max length Is
def					asbinary(g)	252	8192	0	Y	128	0	63
asbinary(g)
drop table t1;
create table t1 (a TEXT, b GEOMETRY NOT NULL, SPATIAL KEY(b));
alter table t1 disable keys;
load data infile '../../std_data/bad_gis_data.dat' into table t1;
ERROR 01000: Data truncated; NULL supplied to NOT NULL column 'b' at row 1
alter table t1 enable keys;
drop table t1;
+9 −2
Original line number Diff line number Diff line
@@ -363,11 +363,18 @@ drop table t1;
select (asWKT(geomfromwkb((0x000000000140240000000000004024000000000000))));
select (asWKT(geomfromwkb((0x010100000000000000000024400000000000002440))));

# End of 4.1 tests

--enable_metadata
create table t1 (g GEOMETRY);
select * from t1;
select asbinary(g) from t1;
--disable_metadata
drop table t1;

create table t1 (a TEXT, b GEOMETRY NOT NULL, SPATIAL KEY(b));
alter table t1 disable keys;
--error 1263
load data infile '../../std_data/bad_gis_data.dat' into table t1;
alter table t1 enable keys;
drop table t1;

# End of 4.1 tests
+2 −1
Original line number Diff line number Diff line
@@ -1137,10 +1137,11 @@ void Field_null::sql_type(String &res) const
  This is an number stored as a pre-space (or pre-zero) string
****************************************************************************/

void
int
Field_decimal::reset(void)
{
  Field_decimal::store("0",1,&my_charset_bin);
  return 0;
}

void Field_decimal::overflow(bool negative)
+63 −50
Original line number Diff line number Diff line
@@ -126,7 +126,7 @@ class Field
  bool eq(Field *field) { return ptr == field->ptr && null_ptr == field->null_ptr; }
  virtual bool eq_def(Field *field);
  virtual uint32 pack_length() const { return (uint32) field_length; }
  virtual void reset(void) { bzero(ptr,pack_length()); }
  virtual int reset(void) { bzero(ptr,pack_length()); return 0; }
  virtual void reset_fields() {}
  virtual void set_default()
  {
@@ -387,7 +387,7 @@ class Field_decimal :public Field_num {
  enum_field_types type() const { return FIELD_TYPE_DECIMAL;}
  enum ha_base_keytype key_type() const
  { return zerofill ? HA_KEYTYPE_BINARY : HA_KEYTYPE_NUM; }
  void reset(void);
  int reset(void);
  int store(const char *to,uint length,CHARSET_INFO *charset);
  int store(double nr);
  int store(longlong nr);
@@ -421,7 +421,7 @@ class Field_tiny :public Field_num {
  int store(const char *to,uint length,CHARSET_INFO *charset);
  int store(double nr);
  int store(longlong nr);
  void reset(void) { ptr[0]=0; }
  int reset(void) { ptr[0]=0; return 0; }
  double val_real(void);
  longlong val_int(void);
  String *val_str(String*,String *);
@@ -457,7 +457,7 @@ class Field_short :public Field_num {
  int store(const char *to,uint length,CHARSET_INFO *charset);
  int store(double nr);
  int store(longlong nr);
  void reset(void) { ptr[0]=ptr[1]=0; }
  int reset(void) { ptr[0]=ptr[1]=0; return 0; }
  double val_real(void);
  longlong val_int(void);
  String *val_str(String*,String *);
@@ -488,7 +488,7 @@ class Field_medium :public Field_num {
  int  store(const char *to,uint length,CHARSET_INFO *charset);
  int  store(double nr);
  int store(longlong nr);
  void reset(void) { ptr[0]=ptr[1]=ptr[2]=0; }
  int reset(void) { ptr[0]=ptr[1]=ptr[2]=0; return 0; }
  double val_real(void);
  longlong val_int(void);
  String *val_str(String*,String *);
@@ -524,7 +524,7 @@ class Field_long :public Field_num {
  int store(const char *to,uint length,CHARSET_INFO *charset);
  int store(double nr);
  int store(longlong nr);
  void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; }
  int reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; return 0; }
  double val_real(void);
  longlong val_int(void);
  bool send_binary(Protocol *protocol);
@@ -562,7 +562,11 @@ class Field_longlong :public Field_num {
  int store(const char *to,uint length,CHARSET_INFO *charset);
  int store(double nr);
  int store(longlong nr);
  void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=ptr[4]=ptr[5]=ptr[6]=ptr[7]=0; }
  int reset(void)
  {
    ptr[0]=ptr[1]=ptr[2]=ptr[3]=ptr[4]=ptr[5]=ptr[6]=ptr[7]=0;
    return 0;
  }
  double val_real(void);
  longlong val_int(void);
  String *val_str(String*,String *);
@@ -597,7 +601,7 @@ class Field_float :public Field_num {
  int store(const char *to,uint length,CHARSET_INFO *charset);
  int store(double nr);
  int store(longlong nr);
  void reset(void) { bzero(ptr,sizeof(float)); }
  int reset(void) { bzero(ptr,sizeof(float)); return 0; }
  double val_real(void);
  longlong val_int(void);
  String *val_str(String*,String *);
@@ -631,7 +635,7 @@ class Field_double :public Field_num {
  int store(const char *to,uint length,CHARSET_INFO *charset);
  int store(double nr);
  int store(longlong nr);
  void reset(void) { bzero(ptr,sizeof(double)); }
  int reset(void) { bzero(ptr,sizeof(double)); return 0; }
  double val_real(void);
  longlong val_int(void);
  String *val_str(String*,String *);
@@ -660,7 +664,7 @@ class Field_null :public Field_str {
  { null[0]=1; return 0; }
  int store(double nr)   { null[0]=1; return 0; }
  int store(longlong nr) { null[0]=1; return 0; }
  void reset(void)	  {}
  int reset(void)	  { return 0; }
  double val_real(void)		{ return 0.0;}
  longlong val_int(void)	{ return 0;}
  String *val_str(String *value,String *value2)
@@ -687,7 +691,7 @@ class Field_timestamp :public Field_str {
  int  store(const char *to,uint length,CHARSET_INFO *charset);
  int  store(double nr);
  int  store(longlong nr);
  void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; }
  int  reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; return 0; }
  double val_real(void);
  longlong val_int(void);
  String *val_str(String*,String *);
@@ -766,7 +770,7 @@ class Field_date :public Field_str {
  int store(const char *to,uint length,CHARSET_INFO *charset);
  int store(double nr);
  int store(longlong nr);
  void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; }
  int reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; return 0; }
  double val_real(void);
  longlong val_int(void);
  String *val_str(String*,String *);
@@ -795,7 +799,7 @@ class Field_newdate :public Field_str {
  int  store(double nr);
  int  store(longlong nr);
  void store_time(TIME *ltime,timestamp_type type);
  void reset(void) { ptr[0]=ptr[1]=ptr[2]=0; }
  int reset(void) { ptr[0]=ptr[1]=ptr[2]=0; return 0; }
  double val_real(void);
  longlong val_int(void);
  String *val_str(String*,String *);
@@ -829,7 +833,7 @@ class Field_time :public Field_str {
  int store(const char *to,uint length,CHARSET_INFO *charset);
  int store(double nr);
  int store(longlong nr);
  void reset(void) { ptr[0]=ptr[1]=ptr[2]=0; }
  int reset(void) { ptr[0]=ptr[1]=ptr[2]=0; return 0; }
  double val_real(void);
  longlong val_int(void);
  String *val_str(String*,String *);
@@ -867,7 +871,11 @@ class Field_datetime :public Field_str {
  int  store(double nr);
  int  store(longlong nr);
  void store_time(TIME *ltime,timestamp_type type);
  void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=ptr[4]=ptr[5]=ptr[6]=ptr[7]=0; }
  int reset(void)
  {
    ptr[0]=ptr[1]=ptr[2]=ptr[3]=ptr[4]=ptr[5]=ptr[6]=ptr[7]=0;
    return 0;
  }
  double val_real(void);
  longlong val_int(void);
  String *val_str(String*,String *);
@@ -905,7 +913,11 @@ class Field_string :public Field_str {
  enum ha_base_keytype key_type() const
    { return binary() ? HA_KEYTYPE_BINARY : HA_KEYTYPE_TEXT; }
  bool zero_pack() const { return 0; }
  void reset(void) { charset()->cset->fill(charset(),ptr,field_length,' '); }
  int reset(void)
  {
    charset()->cset->fill(charset(),ptr,field_length,' ');
    return 0;
  }
  int store(const char *to,uint length,CHARSET_INFO *charset);
  int store(longlong nr);
  int store(double nr) { return Field_str::store(nr); } /* QQ: To be deleted */
@@ -948,7 +960,7 @@ class Field_varstring :public Field_str {
  enum ha_base_keytype key_type() const
    { return binary() ? HA_KEYTYPE_VARBINARY : HA_KEYTYPE_VARTEXT; }
  bool zero_pack() const { return 0; }
  void reset(void) { bzero(ptr,field_length+2); }
  int reset(void) { bzero(ptr,field_length+2); return 0; }
  uint32 pack_length() const { return (uint32) field_length+2; }
  uint32 key_length() const { return (uint32) field_length; }
  int  store(const char *to,uint length,CHARSET_INFO *charset);
@@ -1017,7 +1029,7 @@ class Field_blob :public Field_str {
  {
    return (uint32) (((ulonglong) 1 << (packlength*8)) -1);
  }
  void reset(void) { bzero(ptr, packlength+sizeof(char*)); }
  int reset(void) { bzero(ptr, packlength+sizeof(char*)); return 0; }
  void reset_fields() { bzero((char*) &value,sizeof(value)); }
  void store_length(uint32 number);
  inline uint32 get_length(uint row_offset=0)
@@ -1093,6 +1105,7 @@ class Field_geom :public Field_blob {
  int  store(const char *to, uint length, CHARSET_INFO *charset);
  int  store(double nr) { return 1; }
  int  store(longlong nr) { return 1; }
  int  reset(void) { return !maybe_null(); }

  void get_key_image(char *buff,uint length, CHARSET_INFO *cs,imagetype type);
  void set_key_image(char *buff,uint length, CHARSET_INFO *cs);
@@ -1123,7 +1136,7 @@ class Field_enum :public Field_str {
  int  store(const char *to,uint length,CHARSET_INFO *charset);
  int  store(double nr);
  int  store(longlong nr);
  void reset() { bzero(ptr,packlength); }
  int reset() { bzero(ptr,packlength); return 0; }
  double val_real(void);
  longlong val_int(void);
  String *val_str(String*,String *);
+12 −2
Original line number Diff line number Diff line
@@ -527,7 +527,12 @@ read_sep_field(THD *thd,COPY_INFO &info,TABLE *table,
	  (enclosed_length && length == 4 && !memcmp(pos,"NULL",4)) ||
	  (length == 1 && read_info.found_null))
      {
	field->reset();
        if (field->reset())
        {
          my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0), field->field_name,
              thd->row_count);
          DBUG_RETURN(1);
        }
	field->set_null();
	if (!field->maybe_null())
	{
@@ -560,7 +565,12 @@ read_sep_field(THD *thd,COPY_INFO &info,TABLE *table,
      for (; sql_field ; sql_field=(Item_field*) it++)
      {
	sql_field->field->set_null();
	sql_field->field->reset();
        if (sql_field->field->reset())
        {
          my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0),sql_field->field->field_name,
              thd->row_count);
          DBUG_RETURN(1);
        }
	thd->cuted_fields++;
 	push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 
                	    ER_WARN_TOO_FEW_RECORDS,