1 /*
2    Copyright (c) 2000, 2015, Oracle and/or its affiliates.
3    Copyright (c) 2009, 2019, MariaDB
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; version 2 of the License.
8 
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
17 
18 #include <my_global.h>
19 #include <sql_class.h>          // THD
20 #include <sql_i_s.h>            // ST_SCHEMA_TABLE
21 #include <mysql/plugin.h>
22 #include "sql_show.h"           // get_all_tables()
23 #include "sql_error.h"          // convert_error_to_warning()
24 #include "sql_type_geom.h"
25 
26 
27 /*********** INFORMATION_SCHEMA.SPATIEL_REF_SYS *******************/
28 
29 namespace Show {
30 
31 static ST_FIELD_INFO spatial_ref_sys_fields_info[]=
32 {
33   Column("SRID",      SShort(5),          NOT_NULL),
34   Column("AUTH_NAME", Varchar(FN_REFLEN), NOT_NULL),
35   Column("AUTH_SRID", SLong(5),           NOT_NULL),
36   Column("SRTEXT",    Varchar(2048),      NOT_NULL),
37   CEnd()
38 };
39 
40 
spatial_ref_sys_fill(THD * thd,TABLE_LIST * tables,COND * cond)41 static int spatial_ref_sys_fill(THD *thd, TABLE_LIST *tables, COND *cond)
42 {
43   DBUG_ENTER("fill_spatial_ref_sys");
44   TABLE *table= tables->table;
45   CHARSET_INFO *cs= system_charset_info;
46   int result= 1;
47 
48   restore_record(table, s->default_values);
49 
50   table->field[0]->store(-1, FALSE); /*SRID*/
51   table->field[1]->store(STRING_WITH_LEN("Not defined"), cs); /*AUTH_NAME*/
52   table->field[2]->store(-1, FALSE); /*AUTH_SRID*/
53   table->field[3]->store(STRING_WITH_LEN(
54         "LOCAL_CS[\"Spatial reference wasn't specified\","
55         "LOCAL_DATUM[\"Unknown\",0]," "UNIT[\"m\",1.0]," "AXIS[\"x\",EAST],"
56         "AXIS[\"y\",NORTH]]"), cs);/*SRTEXT*/
57   if (schema_table_store_record(thd, table))
58     goto exit;
59 
60   table->field[0]->store(0, TRUE); /*SRID*/
61   table->field[1]->store(STRING_WITH_LEN("EPSG"), cs); /*AUTH_NAME*/
62   table->field[2]->store(404000, TRUE); /*AUTH_SRID*/
63   table->field[3]->store(STRING_WITH_LEN(
64         "LOCAL_CS[\"Wildcard 2D cartesian plane in metric unit\","
65         "LOCAL_DATUM[\"Unknown\",0]," "UNIT[\"m\",1.0],"
66         "AXIS[\"x\",EAST]," "AXIS[\"y\",NORTH],"
67         "AUTHORITY[\"EPSG\",\"404000\"]]"), cs);/*SRTEXT*/
68   if (schema_table_store_record(thd, table))
69     goto exit;
70 
71   result= 0;
72 
73 exit:
74   DBUG_RETURN(result);
75 }
76 
77 
plugin_init_spatial_ref_sys(void * p)78 static int plugin_init_spatial_ref_sys(void *p)
79 {
80   ST_SCHEMA_TABLE *schema= (ST_SCHEMA_TABLE *)p;
81   schema->fields_info= spatial_ref_sys_fields_info;
82   schema->fill_table= spatial_ref_sys_fill;
83   return 0;
84 }
85 
86 
87 static struct st_mysql_information_schema spatial_ref_sys_plugin=
88 { MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION };
89 
90 
91 } // namespace Show
92 
93 /*********** INFORMATION_SCHEMA.GEOMETRY_COLUMNS *******************/
94 
95 
96 namespace Show {
97 
98 static ST_FIELD_INFO geometry_columns_fields_info[]=
99 {
100   Column("F_TABLE_CATALOG",    Catalog(), NOT_NULL,  OPEN_FRM_ONLY),
101   Column("F_TABLE_SCHEMA",     Name(),    NOT_NULL,  OPEN_FRM_ONLY),
102   Column("F_TABLE_NAME",       Name(),    NOT_NULL,  OPEN_FRM_ONLY),
103   Column("F_GEOMETRY_COLUMN",  Name(),    NOT_NULL,  OPEN_FRM_ONLY),
104   Column("G_TABLE_CATALOG",    Catalog(), NOT_NULL,  OPEN_FRM_ONLY),
105   Column("G_TABLE_SCHEMA",     Name(),    NOT_NULL,  OPEN_FRM_ONLY),
106   Column("G_TABLE_NAME",       Name(),    NOT_NULL,  OPEN_FRM_ONLY),
107   Column("G_GEOMETRY_COLUMN",  Name(),    NOT_NULL,  OPEN_FRM_ONLY),
108   Column("STORAGE_TYPE",       STiny(2),  NOT_NULL,  OPEN_FRM_ONLY),
109   Column("GEOMETRY_TYPE",      SLong(7),  NOT_NULL,  OPEN_FRM_ONLY),
110   Column("COORD_DIMENSION",    STiny(2),  NOT_NULL,  OPEN_FRM_ONLY),
111   Column("MAX_PPR",            STiny(2),  NOT_NULL,  OPEN_FRM_ONLY),
112   Column("SRID",               SShort(5), NOT_NULL,  OPEN_FRM_ONLY),
113   CEnd()
114 };
115 
116 
geometry_columns_fill_record(TABLE * table,const LEX_CSTRING * db_name,const LEX_CSTRING * table_name,const Field_geom * field)117 static void geometry_columns_fill_record(TABLE *table,
118                                          const LEX_CSTRING *db_name,
119                                          const LEX_CSTRING *table_name,
120                                          const Field_geom *field)
121 {
122   static const LEX_CSTRING catalog= {STRING_WITH_LEN("def")};
123   const CHARSET_INFO *cs= system_charset_info;
124   const Type_handler_geometry *gth= field->type_handler_geom();
125   /*F_TABLE_CATALOG*/
126   table->field[0]->store(catalog, cs);
127   /*F_TABLE_SCHEMA*/
128   table->field[1]->store(db_name, cs);
129   /*F_TABLE_NAME*/
130   table->field[2]->store(table_name, cs);
131   /*G_TABLE_CATALOG*/
132   table->field[4]->store(catalog, cs);
133   /*G_TABLE_SCHEMA*/
134   table->field[5]->store(db_name, cs);
135   /*G_TABLE_NAME*/
136   table->field[6]->store(table_name, cs);
137   /*G_GEOMETRY_COLUMN*/
138   table->field[7]->store(field->field_name, cs);
139   /*STORAGE_TYPE*/
140   table->field[8]->store(1LL, true); /*Always 1 (binary implementation)*/
141   /*GEOMETRY_TYPE*/
142   table->field[9]->store((longlong) (gth->geometry_type()), true);
143   /*COORD_DIMENSION*/
144   table->field[10]->store(2LL, true);
145   /*MAX_PPR*/
146   table->field[11]->set_null();
147   /*SRID*/
148   table->field[12]->store((longlong) (field->get_srid()), true);
149 }
150 
151 
get_geometry_column_record(THD * thd,TABLE_LIST * tables,TABLE * table,bool res,const LEX_CSTRING * db_name,const LEX_CSTRING * table_name)152 static int get_geometry_column_record(THD *thd, TABLE_LIST *tables,
153                                       TABLE *table, bool res,
154                                       const LEX_CSTRING *db_name,
155                                       const LEX_CSTRING *table_name)
156 {
157   TABLE *show_table;
158   Field **ptr, *field;
159   DBUG_ENTER("get_geometry_column_record");
160 
161   if (res)
162   {
163     /*
164       open_table() failed with an error.
165       Convert the error to a warning and let the caller
166       continue with the next table.
167     */
168     convert_error_to_warning(thd);
169     DBUG_RETURN(0);
170   }
171 
172   // Skip INFORMATION_SCHEMA tables. They don't have geometry columns.
173   if (tables->schema_table)
174     DBUG_RETURN(0);
175 
176   show_table= tables->table;
177   ptr= show_table->field;
178   show_table->use_all_columns();               // Required for default
179   restore_record(show_table, s->default_values);
180 
181   for (; (field= *ptr) ; ptr++)
182   {
183     const Field_geom *fg;
184     if (field->type() == MYSQL_TYPE_GEOMETRY &&
185         (fg= dynamic_cast<const Field_geom*>(field)))
186     {
187       DEBUG_SYNC(thd, "get_schema_column");
188       /* Get default row, with all NULL fields set to NULL */
189       restore_record(table, s->default_values);
190       geometry_columns_fill_record(table, db_name, table_name, fg);
191       if (schema_table_store_record(thd, table))
192         DBUG_RETURN(1);
193     }
194   }
195 
196   DBUG_RETURN(0);
197 }
198 
199 
plugin_init_geometry_columns(void * p)200 static int plugin_init_geometry_columns(void *p)
201 {
202   ST_SCHEMA_TABLE *schema= (ST_SCHEMA_TABLE *)p;
203   schema->fields_info= geometry_columns_fields_info;
204   schema->fill_table= get_all_tables;
205   schema->process_table= get_geometry_column_record;
206   schema->idx_field1= 1;
207   schema->idx_field2= 2;
208   schema->i_s_requested_object= OPTIMIZE_I_S_TABLE | OPEN_VIEW_FULL;
209   return 0;
210 }
211 
212 
213 static struct st_mysql_information_schema geometry_columns_plugin=
214 { MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION };
215 
216 
217 } // namespace Show
218 
219 
220 /********************* Plugin library descriptors ************************/
221 
222 
maria_declare_plugin(type_geom)223 maria_declare_plugin(type_geom)
224 {
225   MYSQL_INFORMATION_SCHEMA_PLUGIN,   // the plugin type (see include/mysql/plugin.h)
226   &Show::spatial_ref_sys_plugin,     // pointer to type-specific plugin descriptor
227   "SPATIAL_REF_SYS",                 // plugin name
228   "MariaDB",                         // plugin author
229   "Lists all geometry columns",      // the plugin description
230   PLUGIN_LICENSE_GPL,                // the plugin license (see include/mysql/plugin.h)
231   Show::plugin_init_spatial_ref_sys, // Pointer to plugin initialization function
232   0,                                 // Pointer to plugin deinitialization function
233   0x0100,                            // Numeric version 0xAABB means AA.BB version
234   NULL,                              // Status variables
235   NULL,                              // System variables
236   "1.0",                             // String version representation
237   MariaDB_PLUGIN_MATURITY_STABLE     // Maturity (see include/mysql/plugin.h)*/
238 },
239 {
240   MYSQL_INFORMATION_SCHEMA_PLUGIN,   // the plugin type (see include/mysql/plugin.h)
241   &Show::geometry_columns_plugin,    // pointer to type-specific plugin descriptor
242   "GEOMETRY_COLUMNS",                // plugin name
243   "MariaDB",                         // plugin author
244   "Lists all geometry columns",      // the plugin description
245   PLUGIN_LICENSE_GPL,                // the plugin license (see include/mysql/plugin.h)
246   Show::plugin_init_geometry_columns,// Pointer to plugin initialization function
247   0,                                 // Pointer to plugin deinitialization function
248   0x0100,                            // Numeric version 0xAABB means AA.BB version
249   NULL,                              // Status variables
250   NULL,                              // System variables
251   "1.0",                             // String version representation
252   MariaDB_PLUGIN_MATURITY_STABLE     // Maturity (see include/mysql/plugin.h)
253 }
254 maria_declare_plugin_end;
255