|
GIS data types are declared as (non-reserved) keywords in lex.h:
{ "GEOMETRY", SYM(GEOMETRY_SYM)},
|
{ "GEOMETRYCOLLECTION",SYM(GEOMETRYCOLLECTION)},
|
{ "LINESTRING", SYM(LINESTRING)},
|
{ "MULTILINESTRING", SYM(MULTILINESTRING)},
|
{ "MULTIPOINT", SYM(MULTIPOINT)},
|
{ "MULTIPOLYGON", SYM(MULTIPOLYGON)},
|
{ "POINT", SYM(POINT_SYM)},
|
{ "POLYGON", SYM(POLYGON)},
|
There is an sql_yacc.yy rule to parse GIS data types:
spatial_type:
|
GEOMETRY_SYM { $$= GEOM_TYPE(&type_handler_geometry); }
|
| GEOMETRYCOLLECTION { $$= GEOM_TYPE(&type_handler_geometrycollection);
|
| POINT_SYM { $$= GEOM_TYPE(&type_handler_point); }
|
| MULTIPOINT { $$= GEOM_TYPE(&type_handler_multipoint); }
|
| LINESTRING { $$= GEOM_TYPE(&type_handler_linestring); }
|
| MULTILINESTRING { $$= GEOM_TYPE(&type_handler_multilinestring); }
|
| POLYGON { $$= GEOM_TYPE(&type_handler_polygon); }
|
| MULTIPOLYGON { $$= GEOM_TYPE(&type_handler_multipolygon); }
|
;
|
There is also another sql_yacc.yy rule to create GIS contructor functions:
| GEOMETRYCOLLECTION '(' expr_list ')'
|
{
|
$$= GEOM_NEW(thd, Item_func_geometrycollection(thd, *$3));
|
}
|
| LINESTRING '(' expr_list ')'
|
{
|
$$= GEOM_NEW(thd, Item_func_linestring(thd, *$3));
|
}
|
| MULTILINESTRING '(' expr_list ')'
|
{
|
$$= GEOM_NEW(thd, Item_func_multilinestring(thd, *$3));
|
}
|
| MULTIPOINT '(' expr_list ')'
|
{
|
$$= GEOM_NEW(thd, Item_func_multipoint(thd, *$3));
|
}
|
| MULTIPOLYGON '(' expr_list ')'
|
{
|
$$= GEOM_NEW(thd, Item_func_multipolygon(thd, *$3));
|
}
|
| POINT_SYM '(' expr ',' expr ')'
|
{
|
$$= GEOM_NEW(thd, Item_func_point(thd, $3, $5));
|
}
|
| POLYGON '(' expr_list ')'
|
{
|
$$= GEOM_NEW(thd, Item_func_polygon(thd, *$3));
|
}
|
Under terms of this task we'll make GIS data types more plugable:
- remove the above keyword definitions and grammar rules
- add a new method in Type_handler:
static handler_by_name(const LEX_CSTRING &name);
|
- add a new method in Type_handler:
virtual Item *make_constructor_item(THD *thd, List<Item> *args) const
|
{
|
return NULL;
|
}
|
- The grammar to parse a GIS data type will turn into:
| IDENT_sys float_options srid_option
|
{
|
const Type_handler *h;
|
if (!(h= Type_handler::handler_by_name_or_error($1)))
|
MYSQL_YYABORT;
|
$$.set(h, $2);
|
Lex->charset= &my_charset_bin;
|
}
|
;
|
- The grammar to parse GIS contructor functions will be removed, and a new code path will be added into the rule function_call_generic instead, with approximately this diff:
- builder= find_native_function_builder(thd, &$1);
|
- if (builder)
|
+ if ((h= Type_handler::handler_by_name($1)) &&
|
+ (item= h->make_constructor_item(thd, $4)))
|
+ {
|
+ // Found a constructor with a proper argument count
|
+ }
|
+ else if ((builder= find_native_function_builder(thd, &$1))
|
These changes will help to add pluggable data types and new built-in data types in a simple way, without changes in sql_yacc.yy.
|