← Back to team overview

maria-developers team mailing list archive

Re: [Commits] MDEV-60 Support for Spatial Reference systems for the GIS data.

 

Hi, Alexey!

First, please, please, *do not* send patches from Thunderbird.

It took me a lot of time to fix it, the patch was badly garbled.
May be broken formatting everywhere in the patch was also caused by
this.

Then, I didn't see any tests in the patch, not even syntax tests, but
also not create field, store, read tests.

Please add them.

Now, the review:

> diff --git a/sql/field.cc b/sql/field.cc
> --- a/sql/field.cc
> +++ b/sql/field.cc
> @@ -7808,6 +7808,35 @@ uint Field_blob::is_equal(Create_field *new_field)
>  
>   #ifdef HAVE_SPATIAL
>  
> +uint gis_field_options_image(uchar *buff, List<Create_field> &create_fields)
> +{
> +  uint image_size= 0;
> +  uint n_field= 0;
> +  List_iterator<Create_field> it(create_fields);
> +  Create_field *field;
> +  while ((field= it++))
> +  {
> +    if (field->sql_type != MYSQL_TYPE_GEOMETRY)
> +      continue;
> +    if (buff)
> +      int2store(buff + image_size, ((uint16) n_field));
> +    image_size+= 2;
> +   if (buff)
> +      int2store(buff + image_size, ((uint16) field->length));
> +    image_size+= 2;
> +    if (buff)
> +      int2store(buff + image_size, ((uint16) field->decimals));
> +    image_size+= 2;
> +    if (buff)
> +      int4store(buff + image_size, ((uint32) field->srid));
> +    image_size+= 4;
> +    n_field++;
> +  }
> +
> +  return image_size;
> +}

Hmm... So, you basically, put an array of properties in frm, under EXTRA2_GIS
Two comments:
1. Why n_field, length and decimals? I thought you only add srid,
   other properties are already stored elsewhere, aren't they?

2. Really think about upgrades downgrades. The "extra" section in the frm
   doesn't handle them well, I know how these problems happen.
   Think, what happens when you add more properties here?
   What if you remove some? How new server will parse old frms, how
   old server will read new frms?

> +
> +
>   void Field_geom::sql_type(String &res) const
>   {
>     CHARSET_INFO *cs= &my_charset_latin1;
> @@ -9181,7 +9210,7 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
>                           Item *fld_on_update_value, LEX_STRING *fld_comment,
>                           char *fld_change, List<String> *fld_interval_list,
>                           CHARSET_INFO *fld_charset, uint fld_geom_type,
> -            Virtual_column_info *fld_vcol_info,
> +            char *fld_srid, Virtual_column_info *fld_vcol_info,

fix the formatting, please

>                           engine_option_value *create_opt, bool check_exists)
>   {
>     uint sign_len, allowed_type_modifier= 0;
> @@ -9232,6 +9261,7 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
>     pack_length= key_length= 0;
>     charset= fld_charset;
>     geom_type= (Field::geometry_type) fld_geom_type;
> +  srid= fld_srid ? (uint)atoi(fld_srid) : 0;

and here

>     interval_list.empty();
>  
>     comment= *fld_comment;
> @@ -9635,7 +9665,7 @@ Field *make_field(TABLE_SHARE *share, uchar *ptr, uint32 field_length,
>             uint pack_flag,
>             enum_field_types field_type,
>             CHARSET_INFO *field_charset,
> -          Field::geometry_type geom_type,
> +          Field::geometry_type geom_type, uint srid,

and here, and everywhere, I won't comment on that anymore

>             Field::utype unireg_check,
>             TYPELIB *interval,
>             const char *field_name)
> diff --git a/sql/sql_lex.h b/sql/sql_lex.h
> --- a/sql/sql_lex.h
> +++ b/sql/sql_lex.h
> @@ -2358,6 +2358,7 @@ struct LEX: public Query_tables_list
>     char *backup_dir;                /* For RESTORE/BACKUP */
>     char* to_log;                                 /* For PURGE MASTER LOGS TO */
>     char* x509_subject,*x509_issuer,*ssl_cipher;
> +  char *srid;

really? it can only be used for field declarations, I don't think there's
a need to put it in LEX
see below.

>     String *wild; /* Wildcard in SHOW {something} LIKE 'wild'*/
>     sql_exchange *exchange;
>     select_result *result;
> diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
> --- a/sql/sql_yacc.yy
> +++ b/sql/sql_yacc.yy
> @@ -6359,6 +6360,16 @@ precision:
>             }
>           ;
>  
> +srid_option:
> +          /* empty */
> +          { Lex->srid= (char *)0; }
> +        |
> +          SRID_SYM EQ NUM
> +          {
> +            Lex->srid=$3.str;
> +          }

return the value of srid here, don't store it in lex. Like

    $$ = $3.str;

or even

    $$ = atoi($3.str);

> +        ;
> +
>   field_options:
>             /* empty */ {}
>           | field_opt_list {}
> diff --git a/sql/table.cc b/sql/table.cc
> --- a/sql/table.cc
> +++ b/sql/table.cc
> @@ -1451,6 +1464,20 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
>   #ifdef HAVE_SPATIAL
>       geom_type= (Field::geometry_type) strpos[14];
>       charset= &my_charset_bin;
> +        if (gis_options && gis_options_len >= 10)
> +        {
> +          gis_length= uint2korr(gis_options+2);
> +          gis_decimals= uint2korr(gis_options+4);
> +          srid= uint4korr(gis_options+6);
> +          gis_options_len-= 10;
> +          gis_options+= 10;

If you have the function to generate this data in field.cc,
I'd put a small function to read it in field.cc too. Just to have
all reading/writing code in the same place.

> +        }
> +        else
> +        {
> +          srid= 0;
> +          gis_length= 0;
> +          gis_decimals= 0;
> +        }
>   #else
>       goto err;
>   #endif
> diff --git a/sql/unireg.h b/sql/unireg.h
> --- a/sql/unireg.h
> +++ b/sql/unireg.h
> @@ -190,6 +190,7 @@ enum extra2_frm_value_type {
>   #define EXTRA2_ENGINE_IMPORTANT 128
>  
>     EXTRA2_ENGINE_TABLEOPTS=128,
> +  EXTRA2_GIS=129,

better make it 2, not 129 (below EXTRA2_ENGINE_IMPORTANT threshold),
because you de facto ignore it anyway when HAVE_SPATIAL is not defined.

>   };
>  
>   int rea_create_table(THD *thd, LEX_CUSTRING *frm,
> diff --git a/unittest/mysys/CMakeLists.txt b/unittest/mysys/CMakeLists.txt
> --- a/unittest/mysys/CMakeLists.txt
> +++ b/unittest/mysys/CMakeLists.txt
> @@ -17,7 +17,7 @@ MY_ADD_TESTS(bitmap base64 my_vsnprintf my_atomic my_rdtsc lf my_malloc
>                LINK_LIBRARIES mysys)
>  
>   MY_ADD_TESTS(ma_dyncol
> -         LINK_LIBRARIES mysqlclient)
> +         LINK_LIBRARIES mysqlclient stdc++)

Why?

>  
>   IF(WIN32)
>     MY_ADD_TESTS(my_delete LINK_LIBRARIES mysys)
>  

Regards,
Sergei


Follow ups