1 /*
2  * Copyright (C) 2008 - 2012 Murray Cumming <murrayc@murrayc.com>
3  * Copyright (C) 2008 - 2012 Vivien Malerba <malerba@gnome-db.org>
4  * Copyright (C) 2009 Bas Driessen <bas.driessen@xobas.com>
5  * Copyright (C) 2010 David King <davidk@openismus.com>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
hash_page_typenull13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20  * Boston, MA  02110-1301, USA.
21  */
22 
23 #include <string.h>
24 #include "gda-mysql-meta.h"
25 #include "gda-mysql-reuseable.h"
26 #include "gda-mysql-parser.h"
27 #include <libgda/gda-meta-store.h>
28 #include <libgda/gda-data-proxy.h>
29 #include <libgda/sql-parser/gda-sql-parser.h>
30 #include <glib/gi18n-lib.h>
31 #include <libgda/gda-server-provider-extra.h>
32 #include <libgda/providers-support/gda-meta-column-types.h>
33 #include <libgda/gda-connection-private.h>
34 #include <libgda/gda-data-model-array.h>
35 #include <libgda/gda-set.h>
36 #include <libgda/gda-holder.h>
37 
38 /*
39  * predefined statements' IDs
40  */
41 typedef enum {
42 	I_STMT_CATALOG,
43         /* I_STMT_BTYPES, */
44         I_STMT_SCHEMAS,
45         I_STMT_SCHEMAS_ALL,
46         I_STMT_SCHEMA_NAMED,
47         I_STMT_TABLES,
48         I_STMT_TABLES_ALL,
49         I_STMT_TABLE_NAMED,
50 	I_STMT_VIEWS,
51         I_STMT_VIEWS_ALL,
52         I_STMT_VIEW_NAMED,
53         I_STMT_COLUMNS_OF_TABLE,
54         I_STMT_COLUMNS_ALL,
55         I_STMT_TABLES_CONSTRAINTS,
56         I_STMT_TABLES_CONSTRAINTS_ALL,
57         I_STMT_TABLES_CONSTRAINTS_NAMED,
58         I_STMT_REF_CONSTRAINTS,
59         I_STMT_REF_CONSTRAINTS_ALL,
60         I_STMT_KEY_COLUMN_USAGE,
61         I_STMT_KEY_COLUMN_USAGE_ALL,
62         /* I_STMT_UDT, */
63         /* I_STMT_UDT_ALL, */
64         /* I_STMT_UDT_COLUMNS, */
65         /* I_STMT_UDT_COLUMNS_ALL, */
66         /* I_STMT_DOMAINS, */
67         /* I_STMT_DOMAINS_ALL, */
68         /* I_STMT_DOMAINS_CONSTRAINTS, */
69         /* I_STMT_DOMAINS_CONSTRAINTS_ALL, */
70         I_STMT_CHARACTER_SETS,
71         I_STMT_CHARACTER_SETS_ALL,
72         I_STMT_VIEWS_COLUMNS,
73         I_STMT_VIEWS_COLUMNS_ALL,
74         I_STMT_TRIGGERS,
75         I_STMT_TRIGGERS_ALL,
76         /* I_STMT_EL_TYPES_COL, */
77         /* I_STMT_EL_TYPES_DOM, */
78         /* I_STMT_EL_TYPES_UDT, */
79         /* I_STMT_EL_TYPES_ALL, */
80         I_STMT_ROUTINES_ALL,
81         I_STMT_ROUTINES,
82         I_STMT_ROUTINES_ONE,
83         I_STMT_ROUTINES_PAR_ALL,
84         I_STMT_ROUTINES_PAR,
85         /* I_STMT_ROUTINES_COL_ALL, */
86         /* I_STMT_ROUTINES_COL, */
87 
88 	I_STMT_INDEXES_ALL,
89 	I_STMT_INDEXES_TABLE,
90 	I_STMT_INDEXES_ONE,
91 	I_STMT_INDEX_COLUMNS_ALL,
92 	I_STMT_INDEX_COLUMNS_NAMED
93 } InternalStatementItem;
94 
95 
96 /*
97  * predefined statements' SQL
98  */
99 #define SHORT_NAME(t,s,f) "CASE WHEN " t "= DATABASE() THEN " s " ELSE " f " END"
100 #define CATALOG_NAME "'mysql'"
101 static gchar *internal_sql[] = {
102 	/* I_STMT_CATALOG */
103         "SELECT " CATALOG_NAME,
104 
105         /* I_STMT_BTYPES */
106 
107         /* I_STMT_SCHEMAS */
108 	"SELECT " CATALOG_NAME " AS catalog_name, schema_name, NULL, CASE WHEN schema_name = 'information_schema' OR schema_name = 'mysql' THEN TRUE ELSE FALSE END AS schema_internal, NULL FROM INFORMATION_SCHEMA.schemata",
109 
110         /* I_STMT_SCHEMAS_ALL */
111 	"SELECT " CATALOG_NAME " AS catalog_name, schema_name, NULL, CASE WHEN schema_name = 'information_schema' OR schema_name = 'mysql' THEN TRUE ELSE FALSE END AS schema_internal, NULL FROM INFORMATION_SCHEMA.schemata",
112 
113         /* I_STMT_SCHEMA_NAMED */
114 	"SELECT " CATALOG_NAME " AS catalog_name, schema_name, NULL, CASE WHEN schema_name = 'information_schema' OR schema_name = 'mysql' THEN TRUE ELSE FALSE END AS schema_internal FROM INFORMATION_SCHEMA.schemata WHERE schema_name = ##name::string",
115 
116         /* I_STMT_TABLES */
117 	"SELECT " CATALOG_NAME " AS table_catalog, table_schema, table_name, CASE WHEN table_type LIKE '%VIEW%' THEN 'VIEW' ELSE table_type END, CASE table_type WHEN 'BASE TABLE' THEN TRUE ELSE FALSE END AS table_type, table_comment, " SHORT_NAME("table_schema", "table_name", "CONCAT(table_schema, '.', table_name)") " AS short_name, CONCAT(table_schema, '.', table_name) AS table_full_name, NULL AS table_owner FROM INFORMATION_SCHEMA.tables WHERE table_schema = BINARY ##schema::string",
118 
119         /* I_STMT_TABLES_ALL */
120 	"SELECT " CATALOG_NAME " AS table_catalog, table_schema, table_name, CASE WHEN table_type LIKE '%VIEW%' THEN 'VIEW' ELSE table_type END, CASE table_type WHEN 'BASE TABLE' THEN TRUE ELSE FALSE END AS table_type, table_comment, " SHORT_NAME("table_schema", "table_name", "CONCAT(table_schema, '.', table_name)") " AS short_name, CONCAT(table_schema, '.', table_name) AS table_full_name, NULL AS table_owner FROM INFORMATION_SCHEMA.tables",
121 
122         /* I_STMT_TABLE_NAMED */
123 	"SELECT " CATALOG_NAME " AS table_catalog, table_schema, table_name, CASE WHEN table_type LIKE '%VIEW%' THEN 'VIEW' ELSE table_type END, CASE table_type WHEN 'BASE TABLE' THEN TRUE ELSE FALSE END AS table_type, table_comment, " SHORT_NAME("table_schema", "table_name", "CONCAT(table_schema, '.', table_name)") " as short_name, CONCAT(table_schema, '.', table_name) AS table_full_name, NULL AS table_owner FROM INFORMATION_SCHEMA.tables WHERE table_schema = BINARY ##schema::string AND table_name = BINARY ##name::string",
124 
125 	/* I_STMT_VIEWS */
126 	"SELECT " CATALOG_NAME " AS table_catalog, table_schema, table_name, view_definition, check_option, is_updatable FROM INFORMATION_SCHEMA.views WHERE table_schema = BINARY ##schema::string  UNION SELECT " CATALOG_NAME " AS table_catalog, table_schema, table_name, NULL, NULL, FALSE FROM INFORMATION_SCHEMA.tables WHERE table_schema='information_schema' AND table_type LIKE '%VIEW%' AND table_schema = BINARY ##schema::string",
127 
128         /* I_STMT_VIEWS_ALL */
129 	"SELECT " CATALOG_NAME " AS table_catalog, table_schema, table_name, view_definition, check_option, is_updatable FROM INFORMATION_SCHEMA.views UNION SELECT " CATALOG_NAME " AS table_catalog, table_schema, table_name, NULL, NULL, FALSE FROM INFORMATION_SCHEMA.tables WHERE table_schema='information_schema' and table_type LIKE '%VIEW%'",
130 
131         /* I_STMT_VIEW_NAMED */
132 	"SELECT " CATALOG_NAME " AS table_catalog, table_schema, table_name, view_definition, check_option, is_updatable FROM INFORMATION_SCHEMA.views WHERE table_schema = BINARY ##schema::string AND table_name = BINARY ##name::string UNION SELECT " CATALOG_NAME " AS table_catalog, table_schema, table_name, NULL, NULL, FALSE FROM INFORMATION_SCHEMA.tables WHERE table_schema='information_schema' AND table_type LIKE '%VIEW%' AND table_schema = BINARY ##schema::string AND table_name = BINARY ##name::string",
133 
134         /* I_STMT_COLUMNS_OF_TABLE */
135 	"SELECT " CATALOG_NAME " AS table_catalog, table_schema, table_name, column_name, ordinal_position, column_default, CASE is_nullable WHEN 'YES' THEN TRUE ELSE FALSE END AS is_nullable, data_type, NULL, 'gchararray', character_maximum_length,character_octet_length, numeric_precision, numeric_scale, 0, character_set_name, character_set_name, character_set_name, collation_name, collation_name, collation_name, CASE WHEN extra = 'auto_increment' then '" GDA_EXTRA_AUTO_INCREMENT "' ELSE extra END, IF(FIND_IN_SET('insert', privileges) != 0 OR FIND_IN_SET('update', privileges) != 0, TRUE, FALSE) AS is_updatable, column_comment FROM INFORMATION_SCHEMA.columns WHERE table_schema = BINARY ##schema::string AND table_name = BINARY ##name::string",
136 
137         /* I_STMT_COLUMNS_ALL */
138 	"SELECT " CATALOG_NAME " AS table_catalog, table_schema, table_name, column_name, ordinal_position, column_default, CASE is_nullable WHEN 'YES' THEN TRUE ELSE FALSE END AS is_nullable, data_type, NULL, 'gchararray', character_maximum_length, character_octet_length, numeric_precision, numeric_scale, 0, character_set_name, character_set_name, character_set_name, collation_name, collation_name, collation_name, CASE WHEN extra = 'auto_increment' then '" GDA_EXTRA_AUTO_INCREMENT "' ELSE extra END, IF(FIND_IN_SET('insert', privileges) != 0 OR FIND_IN_SET('update', privileges) != 0, TRUE, FALSE) AS is_updatable, column_comment FROM INFORMATION_SCHEMA.columns",
139 
140         /* I_STMT_TABLES_CONSTRAINTS */
141 	"SELECT " CATALOG_NAME " AS constraint_catalog, constraint_schema, constraint_name, " CATALOG_NAME " AS constraint_catalog, table_schema, table_name, constraint_type, NULL, FALSE, FALSE FROM INFORMATION_SCHEMA.table_constraints WHERE constraint_schema = BINARY ##schema::string AND table_name = BINARY ##name::string",
142 
143         /* I_STMT_TABLES_CONSTRAINTS_ALL */
144 	"SELECT " CATALOG_NAME " AS constraint_catalog, constraint_schema, constraint_name, " CATALOG_NAME " AS constraint_catalog, table_schema, table_name, constraint_type, NULL, FALSE, FALSE FROM INFORMATION_SCHEMA.table_constraints",
145 
146         /* I_STMT_TABLES_CONSTRAINTS_NAMED */
147 	"SELECT " CATALOG_NAME " AS constraint_catalog, constraint_schema, constraint_name, " CATALOG_NAME " AS table_catalog, table_schema, table_name, constraint_type, NULL, FALSE, FALSE FROM INFORMATION_SCHEMA.table_constraints WHERE constraint_schema = BINARY ##schema::string AND table_name = BINARY ##name::string AND constraint_name = BINARY ##name2::string",
148 
149         /* I_STMT_REF_CONSTRAINTS */
150 	"select " CATALOG_NAME " AS constraint_catalog, constraint_schema, table_name, constraint_name, " CATALOG_NAME " AS ref_table_cat, constraint_schema, referenced_table_name, unique_constraint_name, match_option, update_rule, delete_rule from information_schema.referential_constraints WHERE constraint_schema = BINARY ##schema::string AND table_name = BINARY ##name::string AND constraint_name = BINARY ##name2::string AND unique_constraint_name IS NOT NULL",
151 
152         /* I_STMT_REF_CONSTRAINTS_ALL */
153 	"select " CATALOG_NAME " AS constraint_catalog, constraint_schema, table_name, constraint_name, " CATALOG_NAME " AS ref_table_cat, constraint_schema, referenced_table_name, unique_constraint_name, match_option, update_rule, delete_rule from information_schema.referential_constraints WHERE unique_constraint_name IS NOT NULL",
154 
155         /* I_STMT_KEY_COLUMN_USAGE */
156 	"SELECT " CATALOG_NAME " AS table_catalog, table_schema, table_name, constraint_name, column_name, ordinal_position FROM INFORMATION_SCHEMA.key_column_usage WHERE table_schema = BINARY ##schema::string AND table_name = BINARY ##name::string AND constraint_name = BINARY ##name2::string",
157 
158         /* I_STMT_KEY_COLUMN_USAGE_ALL */
159 	"SELECT " CATALOG_NAME " AS table_catalog, table_schema, table_name, constraint_name, column_name, ordinal_position FROM INFORMATION_SCHEMA.key_column_usage",
160 
161         /* I_STMT_CHARACTER_SETS */
162 	"SELECT " CATALOG_NAME " AS character_set_catalog, DATABASE() AS character_set_schema, character_set_name, default_collate_name, default_collate_name, default_collate_name, description, character_set_name, character_set_name FROM INFORMATION_SCHEMA.character_sets WHERE character_set_schema = BINARY ##schema::string AND character_set_name = BINARY ##name::string",
163 
164         /* I_STMT_CHARACTER_SETS_ALL */
165 	"SELECT " CATALOG_NAME " AS character_set_catalog, DATABASE() AS character_set_schema, character_set_name, default_collate_name, default_collate_name, default_collate_name, description, character_set_name, character_set_name FROM INFORMATION_SCHEMA.character_sets",
166 
167         /* I_STMT_UDT */
168 
169         /* I_STMT_UDT_ALL */
170 
171         /* I_STMT_UDT_COLUMNS */
172 
173         /* I_STMT_UDT_COLUMNS_ALL */
174 
175         /* I_STMT_DOMAINS */
176 
177         /* I_STMT_DOMAINS_ALL */
178 
179         /* I_STMT_DOMAINS_CONSTRAINTS */
180 
181         /* I_STMT_DOMAINS_CONSTRAINTS_ALL */
182 
183         /* I_STMT_VIEWS_COLUMNS */
184 	"SELECT " CATALOG_NAME " AS table_catalog, v.table_schema, v.table_name, " CATALOG_NAME " AS table_catalog, c.table_schema, c.table_name, c.column_name FROM INFORMATION_SCHEMA.columns c INNER JOIN INFORMATION_SCHEMA.views v ON c.table_schema=v.table_schema AND c.table_name=v.table_name WHERE v.table_schema = BINARY ##schema::string AND v.table_name = BINARY ##name::string",
185 
186         /* I_STMT_VIEWS_COLUMNS_ALL */
187 	"SELECT " CATALOG_NAME " AS table_catalog, v.table_schema, v.table_name, " CATALOG_NAME " AS table_catalog, c.table_schema, c.table_name, c.column_name FROM INFORMATION_SCHEMA.columns c INNER JOIN INFORMATION_SCHEMA.views v ON c.table_schema=v.table_schema AND c.table_name=v.table_name",
188 
189         /* I_STMT_TRIGGERS */
190 	"SELECT " CATALOG_NAME " AS trigger_catalog, trigger_schema, trigger_name, event_manipulation, " CATALOG_NAME " AS event_object_catalog, event_object_schema, event_object_table, action_statement, action_orientation, action_timing, NULL, trigger_name, trigger_name FROM INFORMATION_SCHEMA.triggers WHERE trigger_schema =  BINARY ##schema::string AND trigger_name = BINARY ##name::string",
191 
192         /* I_STMT_TRIGGERS_ALL */
193 	"SELECT " CATALOG_NAME " AS trigger_catalog, trigger_schema, trigger_name, event_manipulation, " CATALOG_NAME " AS event_object_catalog, event_object_schema, event_object_table, action_statement, action_orientation, action_timing, NULL, trigger_name, trigger_name FROM INFORMATION_SCHEMA.triggers",
194 
195         /* I_STMT_EL_TYPES_COL */
196 
197         /* I_STMT_EL_TYPES_DOM */
198 
199         /* I_STMT_EL_TYPES_UDT */
200 
201         /* I_STMT_EL_TYPES_ALL */
202 
203         /* I_STMT_ROUTINES_ALL */
204 	"SELECT " CATALOG_NAME " AS specific_catalog, routine_schema AS specific_schema, routine_name AS specific_name, " CATALOG_NAME " AS routine_catalog, routine_schema, routine_name, routine_type, dtd_identifier AS return_type, FALSE AS returns_set, 0 AS nb_args, routine_body, routine_definition, external_name, external_language, parameter_style, CASE is_deterministic WHEN 'YES' THEN TRUE ELSE FALSE END AS is_deterministic, sql_data_access, FALSE AS is_null_call, routine_comment, routine_name, routine_name, definer FROM INFORMATION_SCHEMA.routines",
205 
206         /* I_STMT_ROUTINES */
207 	"SELECT " CATALOG_NAME " AS specific_catalog, routine_schema AS specific_schema, routine_name AS specific_name, " CATALOG_NAME " AS routine_catalog, routine_schema, routine_name, routine_type, dtd_identifier AS return_type, FALSE AS returns_set, 0 AS nb_args, routine_body, routine_definition, external_name, external_language, parameter_style, CASE is_deterministic WHEN 'YES' THEN TRUE ELSE FALSE END AS is_deterministic, sql_data_access, FALSE AS is_null_call, routine_comment, routine_name, routine_name, definer FROM INFORMATION_SCHEMA.routines WHERE routine_schema =  BINARY ##schema::string",
208 
209         /* I_STMT_ROUTINES_ONE */
210 	"SELECT " CATALOG_NAME " AS specific_catalog, routine_schema AS specific_schema, routine_name AS specific_name, " CATALOG_NAME " AS routine_catalog, routine_schema, routine_name, routine_type, dtd_identifier AS return_type, FALSE AS returns_set, 0 AS nb_args, routine_body, routine_definition, external_name, external_language, parameter_style, CASE is_deterministic WHEN 'YES' THEN TRUE ELSE FALSE END AS is_deterministic, sql_data_access, FALSE AS is_null_call, routine_comment, routine_name, routine_name, definer FROM INFORMATION_SCHEMA.routines WHERE routine_schema =  BINARY ##schema::string AND routine_name = BINARY ##name::string",
211 
212         /* I_STMT_ROUTINES_PAR_ALL */
213 	"SELECT " CATALOG_NAME " AS specific_catalog, routine_schema AS specific_schema, routine_name AS specific_name, " CATALOG_NAME " AS routine_catalog, routine_schema, routine_name, routine_type, dtd_identifier AS return_type, FALSE AS returns_set, 0 AS nb_args, routine_body, routine_definition, external_name, external_language, parameter_style, CASE is_deterministic WHEN 'YES' THEN TRUE ELSE FALSE END AS is_deterministic, sql_data_access, FALSE AS is_null_call, routine_comment, routine_name, routine_name, definer FROM INFORMATION_SCHEMA.routines",
214 
215         /* I_STMT_ROUTINES_PAR */
216 	"SELECT " CATALOG_NAME " AS specific_catalog, routine_schema AS specific_schema, routine_name AS specific_name, " CATALOG_NAME " AS routine_catalog, routine_schema, routine_name, routine_type, dtd_identifier AS return_type, FALSE AS returns_set, 0 AS nb_args, routine_body, routine_definition, external_name, external_language, parameter_style, CASE is_deterministic WHEN 'YES' THEN TRUE ELSE FALSE END AS is_deterministic, sql_data_access, FALSE AS is_null_call, routine_comment, routine_name, routine_name, definer FROM INFORMATION_SCHEMA.routines WHERE routine_schema = BINARY ##schema::string AND routine_name = BINARY ##name::string",
217 
218         /* I_STMT_ROUTINES_COL_ALL */
219 
220         /* I_STMT_ROUTINES_COL */
221 
222 	/* I_STMT_INDEXES_ALL */
223 	"SELECT DISTINCT " CATALOG_NAME ", INDEX_SCHEMA, INDEX_NAME, " CATALOG_NAME ", TABLE_SCHEMA, TABLE_NAME, NOT NON_UNIQUE, NULL, INDEX_TYPE, NULL, NULL, COMMENT FROM INFORMATION_SCHEMA.STATISTICS WHERE INDEX_NAME <> 'PRIMARY'",
224 
225 	/* I_STMT_INDEXES_TABLE */
226 	"SELECT DISTINCT " CATALOG_NAME ", INDEX_SCHEMA, INDEX_NAME, " CATALOG_NAME ", TABLE_SCHEMA, TABLE_NAME, NOT NON_UNIQUE, NULL, INDEX_TYPE, NULL, NULL, COMMENT FROM INFORMATION_SCHEMA.STATISTICS WHERE INDEX_NAME <> 'PRIMARY' AND TABLE_SCHEMA = BINARY ##schema::string AND TABLE_NAME = BINARY ##name::string",
227 
228 	/* I_STMT_INDEXES_ONE */
229 	"SELECT DISTINCT " CATALOG_NAME ", INDEX_SCHEMA, INDEX_NAME, " CATALOG_NAME ", TABLE_SCHEMA, TABLE_NAME, NOT NON_UNIQUE, NULL, INDEX_TYPE, NULL, NULL, COMMENT FROM INFORMATION_SCHEMA.STATISTICS WHERE INDEX_NAME <> 'PRIMARY' AND TABLE_SCHEMA = BINARY ##schema::string AND TABLE_NAME = BINARY ##name::string AND INDEX_NAME = ##name2::string",
230 
231 	/* I_STMT_INDEX_COLUMNS_ALL */
232 	"SELECT DISTINCT " CATALOG_NAME ", INDEX_SCHEMA, INDEX_NAME, " CATALOG_NAME ", TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, COLUMN_NAME, SEQ_IN_INDEX FROM INFORMATION_SCHEMA.STATISTICS WHERE INDEX_NAME <> 'PRIMARY' ORDER BY INDEX_SCHEMA, INDEX_NAME, SEQ_IN_INDEX",
233 
234 	/* I_STMT_INDEX_COLUMNS_NAMED */
235 	"SELECT DISTINCT " CATALOG_NAME ", INDEX_SCHEMA, INDEX_NAME, " CATALOG_NAME ", TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, COLUMN_NAME, SEQ_IN_INDEX FROM INFORMATION_SCHEMA.STATISTICS WHERE INDEX_NAME <> 'PRIMARY' AND TABLE_SCHEMA = BINARY ##schema::string AND TABLE_NAME = BINARY ##name::string AND INDEX_NAME = ##name2::string ORDER BY INDEX_SCHEMA, INDEX_NAME, SEQ_IN_INDEX"
236 };
237 
238 /*
239  * global static values, and
240  * predefined statements' GdaStatement, all initialized in _gda_postgres_provider_meta_init()
241  */
242 static GMutex init_mutex;
243 static GdaStatement **internal_stmt = NULL;
244 static GdaSet        *i_set = NULL;
245 
246 /*
247  * Meta initialization
248  */
249 void
250 _gda_mysql_provider_meta_init (GdaServerProvider  *provider)
251 {
252 	g_mutex_lock (&init_mutex);
253 
254 	if (!internal_stmt) {
255 		InternalStatementItem i;
256 		GdaSqlParser *parser;
257 
258 		if (provider)
259 			parser = gda_server_provider_internal_get_parser (provider);
260 		else
261 			parser = GDA_SQL_PARSER (g_object_new (GDA_TYPE_MYSQL_PARSER, NULL));
262 		internal_stmt = g_new0 (GdaStatement *, sizeof (internal_sql) / sizeof (gchar*));
263 		for (i = I_STMT_CATALOG; i < sizeof (internal_sql) / sizeof (gchar*); i++) {
264 			internal_stmt[i] = gda_sql_parser_parse_string (parser, internal_sql[i], NULL, NULL);
265 			if (!internal_stmt[i])
266 				g_error ("Could not parse internal statement: %s\n", internal_sql[i]);
267 		}
268 
269 		if (!provider)
270 			g_object_unref (parser);
271 
272 		/* initialize static values here */
273 		i_set = gda_set_new_inline (3, "name", G_TYPE_STRING, "",
274 					    "schema", G_TYPE_STRING, "",
275 					    "name2", G_TYPE_STRING, "");
276 	}
277 
278 	g_mutex_unlock (&init_mutex);
279 
280 #ifdef GDA_DEBUG
281 	_gda_mysql_test_keywords ();
282 #endif
283 }
284 
285 #define GDA_MYSQL_GET_REUSEABLE_DATA(cdata) ((cdata) ? * ((GdaMysqlReuseable**) (cdata)) : NULL)
286 
287 gboolean
288 _gda_mysql_meta__info (G_GNUC_UNUSED GdaServerProvider  *prov,
289 		       GdaConnection      *cnc,
290 		       GdaMetaStore       *store,
291 		       GdaMetaContext     *context,
292 		       GError            **error)
293 {
294 	GdaDataModel *model;
295         gboolean retval;
296 	GdaMysqlReuseable *rdata;
297 	rdata = GDA_MYSQL_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
298 	if (!rdata)
299 		return FALSE;
300 
301 	model = gda_connection_statement_execute_select_full (cnc,
302 							      internal_stmt[I_STMT_CATALOG],
303 							      NULL,
304 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
305 							      _col_types_information_schema_catalog_name,
306 							      error);
307         if (model == NULL)
308                 retval = FALSE;
309 	else {
310 		gda_meta_store_set_reserved_keywords_func (store,
311 							   _gda_mysql_reuseable_get_reserved_keywords_func
312 							   ((GdaProviderReuseable*) rdata));
313 		retval = gda_meta_store_modify (store, context->table_name, model, NULL, error, NULL);
314 		g_object_unref (G_OBJECT (model));
315 	}
316 
317         return retval;
318 }
319 
320 gboolean
321 _gda_mysql_meta__btypes (G_GNUC_UNUSED GdaServerProvider  *prov,
322 			 GdaConnection      *cnc,
323 			 GdaMetaStore       *store,
324 			 GdaMetaContext     *context,
325 			 GError            **error)
326 {
327 	typedef struct
328 	{
329 		gchar  *tname;
330 		gchar  *gtype;
331 		gchar  *comments;
332 		gchar  *synonyms;
333 	} BuiltinDataType;
334 	BuiltinDataType data_types[] = {
335 		{ "AUTO_INCREMENT", "gint", "The AUTO_INCREMENT attribute can be used to generate a unique identity for new rows", "" },
336 		{ "BIGINT", "gint64", "A large integer. The signed range is -9223372036854775808 to 9223372036854775807. The unsigned range is 0 to 18446744073709551615.", "" },
337 		{ "BINARY", "GdaBinary", "The BINARY type is similar to the CHAR type, but stores binary byte strings rather than non-binary character strings. M represents the column length in bytes.", "CHAR BYTE" },
338 		{ "BIT", "gint", "A bit-field type. M indicates the number of bits per value, from 1 to 64. The default is 1 if M is omitted.", "" },
339 		{ "BLOB", "GdaBinary", "A BLOB column with a maximum length of 65,535 (216 - 1) bytes. Each BLOB value is stored using a two-byte length prefix that indicates the number of bytes in the value.", "" },
340 		{ "BLOB DATA TYPE", "GdaBinary", "A BLOB is a binary large object that can hold a variable amount of data. The four BLOB types are TINYBLOB, BLOB, MEDIUMBLOB, and LONGBLOB. These differ only in the maximum length of the values they can hold.", "" },
341 		{ "BOOLEAN", "gboolean", "These types are synonyms for TINYINT(1). A value of zero is considered false. Non-zero values are considered true", "" },
342 		{ "CHAR", "gchararray", "A fixed-length string that is always right-padded with spaces to the specified length when stored. M represents the column length in characters. The range of M is 0 to 255. If M is omitted, the length is 1.", "" },
343 		{ "DATE", "GDate", "A date. The supported range is '1000-01-01' to '9999-12-31'. MySQL displays DATE values in 'YYYY-MM-DD' format, but allows assignment of values to DATE columns using either strings or numbers.", "" },
344 		{ "DATETIME", "GdaTimestamp", "A date and time combination. The supported range is '1000-01-01 00:00:00' to '9999-12-31 23:59:59'. MySQL displays DATETIME values in 'YYYY-MM-DD HH:MM:SS' format, but allows assignment of values to DATETIME columns using either strings or numbers.", "" },
345 		{ "DECIMAL", "GdaNumeric", "A packed \"exact\" fixed-point number. M is the total number of digits (the precision) and D is the number of digits after the decimal point (the scale). The decimal point and (for negative numbers) the \"-\" sign are not counted in M. If D is 0, values have no decimal point or fractional part. The maximum number of digits (M) for DECIMAL is 65 (64 from 5.0.3 to 5.0.5). The maximum number of supported decimals (D) is 30. If D is omitted, the default is 0. If M is omitted, the default is 10.", "DEC" },
346 		{ "DOUBLE", "gdouble", "A normal-size (double-precision) floating-point number. Allowable values are -1.7976931348623157E+308 to -2.2250738585072014E-308, 0, and 2.2250738585072014E-308 to 1.7976931348623157E+308. These are the theoretical limits, based on the IEEE standard. The actual range might be slightly smaller depending on your hardware or operating system.", "DOUBLE PRECISION" },
347 		{ "ENUM", "gchararray", "An enumeration. A string object that can have only one value, chosen from the list of values 'value1', 'value2', ..., NULL or the special '' error value. An ENUM column can have a maximum of 65,535 distinct values. ENUM values are represented internally as integers.", "" },
348 		{ "FLOAT", "gfloat", "A small (single-precision) floating-point number. Allowable values are -3.402823466E+38 to -1.175494351E-38, 0, and 1.175494351E-38 to 3.402823466E+38. These are the theoretical limits, based on the IEEE standard. The actual range might be slightly smaller depending on your hardware or operating system.", "" },
349 		{ "INT", "gint", "A normal-size integer. The signed range is -2147483648 to 2147483647. The unsigned range is 0 to 4294967295.", "INTEGER" },
350 		{ "LONGBLOB", "GdaBinary", "A BLOB column with a maximum length of 4,294,967,295 or 4GB (232 - 1) bytes. The effective maximum length of LONGBLOB columns depends on the configured maximum packet size in the client/server protocol and available memory. Each LONGBLOB value is stored using a four-byte length prefix that indicates the number of bytes in the value.", "" },
351 		{ "LONGTEXT", "GdaBinary", "A TEXT column with a maximum length of 4,294,967,295 or 4GB (232 - 1) characters. The effective maximum length is less if the value contains multi-byte characters. The effective maximum length of LONGTEXT columns also depends on the configured maximum packet size in the client/server protocol and available memory. Each LONGTEXT value is stored using a four-byte length prefix that indicates the number of bytes in the value.", "" },
352 		{ "MEDIUMBLOB", "GdaBinary", "A BLOB column with a maximum length of 16,777,215 (224 - 1) bytes. Each MEDIUMBLOB value is stored using a three-byte length prefix that indicates the number of bytes in the value.", "" },
353 		{ "MEDIUMINT", "gint", "A medium-sized integer. The signed range is -8388608 to 8388607. The unsigned range is 0 to 16777215.", "" },
354 		{ "MEDIUMTEXT", "GdaBinary", "A TEXT column with a maximum length of 16,777,215 (224 - 1) characters. The effective maximum length is less if the value contains multi-byte characters. Each MEDIUMTEXT value is stored using a three-byte length prefix that indicates the number of bytes in the value.", "" },
355 		{ "SET DATA TYPE", "gchararray", "A set. A string object that can have zero or more values, each of which must be chosen from the list of values 'value1', 'value2', ... A SET column can have a maximum of 64 members. SET values are represented internally as integers.", "" },
356 		{ "SMALLINT", "gshort", "A small integer. The signed range is -32768 to 32767. The unsigned range is 0 to 65535.", "" },
357 		{ "TEXT", "GdaBinary", "A TEXT column with a maximum length of 65,535 (216 - 1) characters. The effective maximum length is less if the value contains multi-byte characters. Each TEXT value is stored using a two-byte length prefix that indicates the number of bytes in the value.", "" },
358 		{ "TIME", "GdaTime", "A time. The range is '-838:59:59' to '838:59:59'. MySQL displays TIME values in 'HH:MM:SS' format, but allows assignment of values to TIME columns using either strings or numbers.", "" },
359 		{ "TIMESTAMP", "GdaTimestamp", "A timestamp. The range is '1970-01-01 00:00:01' UTC to partway through the year 2038. TIMESTAMP values are stored as the number of seconds since the epoch ('1970-01-01 00:00:00' UTC). A TIMESTAMP cannot represent the value '1970-01-01 00:00:00' because that is equivalent to 0 seconds from the epoch and the value 0 is reserved for representing '0000-00-00 00:00:00', the \"zero\" TIMESTAMP value.", "" },
360 		{ "TINYBLOB", "GdaBinary", "A BLOB column with a maximum length of 255 (28 - 1) bytes. Each TINYBLOB value is stored using a one-byte length prefix that indicates the number of bytes in the value.", "" },
361 		{ "TINYINT", "gchar", "A very small integer. The signed range is -128 to 127. The unsigned range is 0 to 255.", "" },
362 		{ "TINYTEXT", "GdaBinary", "A TEXT column with a maximum length of 255 (28 - 1) characters. The effective maximum length is less if the value contains multi-byte characters. Each TINYTEXT value is stored using a one-byte length prefix that indicates the number of bytes in the value.", "" },
363 		{ "VARBINARY", "GdaBinary", "The VARBINARY type is similar to the VARCHAR type, but stores binary byte strings rather than non-binary character strings. M represents the maximum column length in bytes.", "" },
364 		{ "VARCHAR", "gchararray", "A variable-length string. M represents the maximum column length in characters. In MySQL 5.0, the range of M is 0 to 255 before MySQL 5.0.3, and 0 to 65,535 in MySQL 5.0.3 and later. The effective maximum length of a VARCHAR in MySQL 5.0.3 and later is subject to the maximum row size (65,535 bytes, which is shared among all columns) and the character set used. For example, utf8 characters can require up to three bytes per character, so a VARCHAR column that uses the utf8 character set can be declared to be a maximum of 21,844 characters.", "" },
365 		{ "YEAR DATA TYPE", "gint", "A year in two-digit or four-digit format. The default is four-digit format. In four-digit format, the allowable values are 1901 to 2155, and 0000. In two-digit format, the allowable values are 70 to 69, representing years from 1970 to 2069. MySQL displays YEAR values in YYYY format, but allows you to assign values to YEAR columns using either strings or numbers.", "" }
366 	};
367         GdaDataModel *model;
368         gboolean retval = TRUE;
369 	GdaMysqlReuseable *rdata;
370 	rdata = GDA_MYSQL_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
371 	if (!rdata)
372 		return FALSE;
373 
374 	model = gda_meta_store_create_modify_data_model (store, context->table_name);
375         if (model == NULL)
376                 retval = FALSE;
377 	else {
378 		gsize i;
379 		for (i = 0; i < sizeof(data_types) / sizeof(BuiltinDataType); ++i) {
380 			BuiltinDataType *data_type = &(data_types[i]);
381 			GList *values = NULL;
382 			GValue *tmp_value = NULL;
383 
384 			g_value_set_string (tmp_value = gda_value_new (G_TYPE_STRING), data_type->tname);
385 			values = g_list_append (values, tmp_value);
386 
387 			g_value_set_string (tmp_value = gda_value_new (G_TYPE_STRING), data_type->tname);
388 			values = g_list_append (values, tmp_value);
389 
390 			g_value_set_string (tmp_value = gda_value_new (G_TYPE_STRING), data_type->gtype);
391 			values = g_list_append (values, tmp_value);
392 
393 			g_value_set_string (tmp_value = gda_value_new (G_TYPE_STRING), data_type->comments);
394 			values = g_list_append (values, tmp_value);
395 
396 			if (data_type->synonyms && *(data_type->synonyms))
397 				g_value_set_string (tmp_value = gda_value_new (G_TYPE_STRING), data_type->synonyms);
398 			else
399 				tmp_value = gda_value_new_null ();
400 			values = g_list_append (values, tmp_value);
401 
402 			g_value_set_boolean (tmp_value = gda_value_new (G_TYPE_BOOLEAN), FALSE);
403 			values = g_list_append (values, tmp_value);
404 
405 			if (gda_data_model_append_values (model, values, NULL) < 0) {
406 				retval = FALSE;
407 				break;
408 			}
409 
410 			g_list_foreach (values, (GFunc) gda_value_free, NULL);
411 			g_list_free (values);
412 		}
413 
414 		if (retval) {
415 			gda_meta_store_set_reserved_keywords_func (store,
416 								   _gda_mysql_reuseable_get_reserved_keywords_func
417 								   ((GdaProviderReuseable*) rdata));
418 			retval = gda_meta_store_modify (store, context->table_name, model, NULL, error, NULL);
419 		}
420 		g_object_unref (G_OBJECT(model));
421 	}
422 
423         return retval;
424 }
425 
426 gboolean
427 _gda_mysql_meta__udt (G_GNUC_UNUSED GdaServerProvider  *prov,
428 		      G_GNUC_UNUSED GdaConnection      *cnc,
429 		      G_GNUC_UNUSED GdaMetaStore       *store,
430 		      G_GNUC_UNUSED GdaMetaContext     *context,
431 		      G_GNUC_UNUSED GError            **error)
432 {
433 	// TO_IMPLEMENT;
434 	return TRUE;
435 }
436 
437 gboolean
438 _gda_mysql_meta_udt (G_GNUC_UNUSED GdaServerProvider  *prov,
439 		     G_GNUC_UNUSED GdaConnection      *cnc,
440 		     G_GNUC_UNUSED GdaMetaStore       *store,
441 		     G_GNUC_UNUSED GdaMetaContext     *context,
442 		     G_GNUC_UNUSED GError            **error,
443 		     G_GNUC_UNUSED const GValue       *udt_catalog,
444 		     G_GNUC_UNUSED const GValue       *udt_schema)
445 {
446 	// TO_IMPLEMENT;
447 	return TRUE;
448 }
449 
450 
451 gboolean
452 _gda_mysql_meta__udt_cols (G_GNUC_UNUSED GdaServerProvider  *prov,
453 			   G_GNUC_UNUSED GdaConnection      *cnc,
454 			   G_GNUC_UNUSED GdaMetaStore       *store,
455 			   G_GNUC_UNUSED GdaMetaContext     *context,
456 			   G_GNUC_UNUSED GError            **error)
457 {
458 	// TO_IMPLEMENT;
459 	return TRUE;
460 }
461 
462 gboolean
463 _gda_mysql_meta_udt_cols (G_GNUC_UNUSED GdaServerProvider  *prov,
464 			  G_GNUC_UNUSED GdaConnection      *cnc,
465 			  G_GNUC_UNUSED GdaMetaStore       *store,
466 			  G_GNUC_UNUSED GdaMetaContext     *context,
467 			  G_GNUC_UNUSED GError            **error,
468 			  G_GNUC_UNUSED const GValue       *udt_catalog,
469 			  G_GNUC_UNUSED const GValue       *udt_schema,
470 			  G_GNUC_UNUSED const GValue       *udt_name)
471 {
472 	// TO_IMPLEMENT;
473 	return TRUE;
474 }
475 
476 gboolean
477 _gda_mysql_meta__enums (G_GNUC_UNUSED GdaServerProvider  *prov,
478 			G_GNUC_UNUSED GdaConnection      *cnc,
479 			G_GNUC_UNUSED GdaMetaStore       *store,
480 			G_GNUC_UNUSED GdaMetaContext     *context,
481 			G_GNUC_UNUSED GError            **error)
482 {
483 	/* Feature not supported by MySQL. */
484 	return TRUE;
485 }
486 
487 gboolean
488 _gda_mysql_meta_enums (G_GNUC_UNUSED GdaServerProvider  *prov,
489 		       G_GNUC_UNUSED GdaConnection      *cnc,
490 		       G_GNUC_UNUSED GdaMetaStore       *store,
491 		       G_GNUC_UNUSED GdaMetaContext     *context,
492 		       G_GNUC_UNUSED GError            **error,
493 		       G_GNUC_UNUSED const GValue       *udt_catalog,
494 		       G_GNUC_UNUSED const GValue       *udt_schema,
495 		       G_GNUC_UNUSED const GValue       *udt_name)
496 {
497 	/* Feature not supported by MySQL. */
498 	return TRUE;
499 }
500 
501 
502 gboolean
503 _gda_mysql_meta__domains (G_GNUC_UNUSED GdaServerProvider  *prov,
504 			  G_GNUC_UNUSED GdaConnection      *cnc,
505 			  G_GNUC_UNUSED GdaMetaStore       *store,
506 			  G_GNUC_UNUSED GdaMetaContext     *context,
507 			  G_GNUC_UNUSED GError            **error)
508 {
509 	/* Feature not supported by MySQL. */
510 	return TRUE;
511 }
512 
513 gboolean
514 _gda_mysql_meta_domains (G_GNUC_UNUSED GdaServerProvider  *prov,
515 			 G_GNUC_UNUSED GdaConnection      *cnc,
516 			 G_GNUC_UNUSED GdaMetaStore       *store,
517 			 G_GNUC_UNUSED GdaMetaContext     *context,
518 			 G_GNUC_UNUSED GError            **error,
519 			 G_GNUC_UNUSED const GValue       *domain_catalog,
520 			 G_GNUC_UNUSED const GValue       *domain_schema)
521 {
522 	/* Feature not supported by MySQL. */
523 	return TRUE;
524 }
525 
526 gboolean
527 _gda_mysql_meta__constraints_dom (G_GNUC_UNUSED GdaServerProvider  *prov,
528 				  G_GNUC_UNUSED GdaConnection      *cnc,
529 				  G_GNUC_UNUSED GdaMetaStore       *store,
530 				  G_GNUC_UNUSED GdaMetaContext     *context,
531 				  G_GNUC_UNUSED GError            **error)
532 {
533 	/* Feature not supported by MySQL. */
534 	return TRUE;
535 }
536 
537 gboolean
538 _gda_mysql_meta_constraints_dom (G_GNUC_UNUSED GdaServerProvider  *prov,
539 				 G_GNUC_UNUSED GdaConnection      *cnc,
540 				 G_GNUC_UNUSED GdaMetaStore       *store,
541 				 G_GNUC_UNUSED GdaMetaContext     *context,
542 				 G_GNUC_UNUSED GError            **error,
543 				 G_GNUC_UNUSED const GValue       *domain_catalog,
544 				 G_GNUC_UNUSED const GValue       *domain_schema,
545 				 G_GNUC_UNUSED const GValue       *domain_name)
546 {
547 	/* Feature not supported by MySQL. */
548 	return TRUE;
549 }
550 
551 gboolean
552 _gda_mysql_meta__el_types (G_GNUC_UNUSED GdaServerProvider  *prov,
553 			   G_GNUC_UNUSED GdaConnection      *cnc,
554 			   G_GNUC_UNUSED GdaMetaStore       *store,
555 			   G_GNUC_UNUSED GdaMetaContext     *context,
556 			   G_GNUC_UNUSED GError            **error)
557 {
558 	/* Feature not supported by MySQL. */
559 	return TRUE;
560 }
561 
562 gboolean
563 _gda_mysql_meta_el_types (G_GNUC_UNUSED GdaServerProvider  *prov,
564 			  G_GNUC_UNUSED GdaConnection      *cnc,
565 			  G_GNUC_UNUSED GdaMetaStore       *store,
566 			  G_GNUC_UNUSED GdaMetaContext     *context,
567 			  G_GNUC_UNUSED GError            **error,
568 			  G_GNUC_UNUSED const GValue       *specific_name)
569 {
570 	/* Feature not supported by MySQL. */
571         return TRUE;
572 }
573 
574 gboolean
575 _gda_mysql_meta__collations (G_GNUC_UNUSED GdaServerProvider  *prov,
576 			     G_GNUC_UNUSED GdaConnection      *cnc,
577 			     G_GNUC_UNUSED GdaMetaStore       *store,
578 			     G_GNUC_UNUSED GdaMetaContext     *context,
579 			     G_GNUC_UNUSED GError            **error)
580 {
581 	/* Feature not supported by MySQL. */
582 	return TRUE;
583 }
584 
585 gboolean
586 _gda_mysql_meta_collations (G_GNUC_UNUSED GdaServerProvider  *prov,
587 			    G_GNUC_UNUSED GdaConnection      *cnc,
588 			    G_GNUC_UNUSED GdaMetaStore       *store,
589 			    G_GNUC_UNUSED GdaMetaContext     *context,
590 			    G_GNUC_UNUSED GError            **error,
591 			    G_GNUC_UNUSED const GValue       *collation_catalog,
592 			    G_GNUC_UNUSED const GValue       *collation_schema,
593 			    G_GNUC_UNUSED const GValue       *collation_name_n)
594 {
595 	/* Feature not supported by MySQL. */
596 	return TRUE;
597 }
598 
599 gboolean
600 _gda_mysql_meta__character_sets (G_GNUC_UNUSED GdaServerProvider  *prov,
601 				 GdaConnection      *cnc,
602 				 GdaMetaStore       *store,
603 				 GdaMetaContext     *context,
604 				 GError            **error)
605 {
606 	GdaDataModel *model;
607 	gboolean retval;
608 	GdaMysqlReuseable *rdata;
609 	rdata = GDA_MYSQL_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
610 	if (!rdata)
611 		return FALSE;
612 
613 	model = gda_connection_statement_execute_select_full (cnc,
614 							      internal_stmt[I_STMT_CHARACTER_SETS_ALL],
615 							      NULL,
616 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
617 							      _col_types_character_sets,
618 							      error);
619 	if (model == NULL)
620 		retval = FALSE;
621 	else {
622 		gda_meta_store_set_reserved_keywords_func (store,
623 							   _gda_mysql_reuseable_get_reserved_keywords_func
624 							   ((GdaProviderReuseable*) rdata));
625 		retval = gda_meta_store_modify_with_context (store, context, model, error);
626 		g_object_unref (G_OBJECT(model));
627 	}
628 
629 	return retval;
630 }
631 
632 gboolean
633 _gda_mysql_meta_character_sets (G_GNUC_UNUSED GdaServerProvider  *prov,
634 				GdaConnection      *cnc,
635 				GdaMetaStore       *store,
636 				GdaMetaContext     *context,
637 				GError            **error,
638 				G_GNUC_UNUSED const GValue       *chset_catalog,
639 				const GValue       *chset_schema,
640 				const GValue       *chset_name_n)
641 {
642 	GdaDataModel *model;
643 	gboolean retval;
644 	GdaMysqlReuseable *rdata;
645 	rdata = GDA_MYSQL_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
646 	if (!rdata)
647 		return FALSE;
648 
649 	if (!gda_holder_set_value (gda_set_get_holder (i_set, "schema"), chset_schema, error))
650 		return FALSE;
651 	if (!gda_holder_set_value (gda_set_get_holder (i_set, "name"), chset_name_n, error))
652 		return FALSE;
653 
654 	model = gda_connection_statement_execute_select_full (cnc,
655 							      internal_stmt[I_STMT_CHARACTER_SETS],
656 							      i_set,
657 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
658 							      _col_types_character_sets,
659 							      error);
660 	if (model == NULL)
661 		retval = FALSE;
662 	else {
663 		gda_meta_store_set_reserved_keywords_func (store,
664 							   _gda_mysql_reuseable_get_reserved_keywords_func
665 							   ((GdaProviderReuseable*) rdata));
666 		retval = gda_meta_store_modify_with_context (store, context, model, error);
667 		g_object_unref (G_OBJECT(model));
668 
669 	}
670 
671 	return retval;
672 }
673 
674 gboolean
675 _gda_mysql_meta__schemata (G_GNUC_UNUSED GdaServerProvider  *prov,
676 			   GdaConnection      *cnc,
677 			   GdaMetaStore       *store,
678 			   GdaMetaContext     *context,
679 			   GError            **error)
680 {
681 	GdaDataModel *model;
682 	gboolean retval;
683 	GdaMysqlReuseable *rdata;
684 	rdata = GDA_MYSQL_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
685 	if (!rdata)
686 		return FALSE;
687 
688 	model = gda_connection_statement_execute_select_full (cnc,
689 							      internal_stmt[I_STMT_SCHEMAS_ALL],
690 							      NULL,
691 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
692 							      _col_types_schemata, error);
693 	if (model == NULL)
694 		retval = FALSE;
695 	else {
696 		gda_meta_store_set_reserved_keywords_func (store,
697 							   _gda_mysql_reuseable_get_reserved_keywords_func
698 							   ((GdaProviderReuseable*) rdata));
699 		retval = gda_meta_store_modify_with_context (store, context, model, error);
700 		g_object_unref (G_OBJECT(model));
701 	}
702 
703 	return retval;
704 }
705 
706 gboolean
707 _gda_mysql_meta_schemata (G_GNUC_UNUSED GdaServerProvider  *prov,
708 			  GdaConnection      *cnc,
709 			  GdaMetaStore       *store,
710 			  GdaMetaContext     *context,
711 			  GError            **error,
712 			  G_GNUC_UNUSED const GValue       *catalog_name,
713 			  const GValue       *schema_name_n)
714 {
715 	GdaDataModel *model;
716 	gboolean retval;
717 	GdaMysqlReuseable *rdata;
718 	rdata = GDA_MYSQL_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
719 	if (!rdata)
720 		return FALSE;
721 
722 	if (!schema_name_n) {
723 		model = gda_connection_statement_execute_select_full (cnc,
724 								      internal_stmt[I_STMT_SCHEMAS],
725 								      i_set,
726 								      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
727 								      _col_types_schemata,
728 								      error);
729 		if (model == NULL)
730 			retval = FALSE;
731 		else {
732 			gda_meta_store_set_reserved_keywords_func (store,
733 								   _gda_mysql_reuseable_get_reserved_keywords_func
734 								   ((GdaProviderReuseable*) rdata));
735 			retval = gda_meta_store_modify (store, context->table_name, model, NULL, error, NULL);
736 			g_object_unref (G_OBJECT(model));
737 		}
738 	} else {
739 		if (!gda_holder_set_value (gda_set_get_holder (i_set, "name"), schema_name_n, error))
740 			return FALSE;
741 		model = gda_connection_statement_execute_select_full (cnc,
742 								      internal_stmt[I_STMT_SCHEMA_NAMED],
743 								      i_set,
744 								      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
745 								      _col_types_schemata,
746 								      error);
747 		if (model == NULL)
748 			retval = FALSE;
749 		else {
750 			gda_meta_store_set_reserved_keywords_func (store,
751 								   _gda_mysql_reuseable_get_reserved_keywords_func
752 								   ((GdaProviderReuseable*) rdata));
753 			retval = gda_meta_store_modify (store, context->table_name, model,
754 							"schema_name=##name::string",
755 							error,
756 							"name", schema_name_n, NULL);
757 			g_object_unref (G_OBJECT(model));
758 		}
759 	}
760 
761 	return retval;
762 }
763 
764 gboolean
765 _gda_mysql_meta__tables_views (G_GNUC_UNUSED GdaServerProvider  *prov,
766 			       GdaConnection      *cnc,
767 			       GdaMetaStore       *store,
768 			       GdaMetaContext     *context,
769 			       GError            **error)
770 {
771 	GdaDataModel *model_tables, *model_views;
772 	gboolean retval;
773 	/* Check correct mysql server version. */
774 	GdaMysqlReuseable *rdata;
775 	rdata = GDA_MYSQL_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
776 	if (!rdata)
777 		return FALSE;
778 	if ((rdata->version_long == 0) && ! _gda_mysql_compute_version (cnc, rdata, error))
779 		return FALSE;
780 	if (rdata->version_long < 50000) {
781 		g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_SERVER_VERSION_ERROR,
782 			     "%s", _("Mysql version 5.0 at least is required"));
783 		return FALSE;
784 	}
785 
786 	/* Copy contents, just because we need to modify @context->table_name */
787 	GdaMetaContext copy = *context;
788 
789 	model_tables = gda_connection_statement_execute_select_full (cnc,
790 								     internal_stmt[I_STMT_TABLES_ALL],
791 								     NULL,
792 								     GDA_STATEMENT_MODEL_RANDOM_ACCESS,
793 								     _col_types_tables, error);
794 	if (model_tables == NULL)
795 		retval = FALSE;
796 	else {
797 		copy.table_name = "_tables";
798 		gda_meta_store_set_reserved_keywords_func (store,
799 							   _gda_mysql_reuseable_get_reserved_keywords_func
800 							   ((GdaProviderReuseable*) rdata));
801 		retval = gda_meta_store_modify_with_context (store, &copy, model_tables, error);
802 		g_object_unref (G_OBJECT(model_tables));
803 	}
804 
805 	model_views = gda_connection_statement_execute_select_full (cnc,
806 								    internal_stmt[I_STMT_VIEWS_ALL],
807 								    NULL,
808 								    GDA_STATEMENT_MODEL_RANDOM_ACCESS,
809 								    _col_types_views, error);
810 	if (model_views == NULL)
811 		retval = FALSE;
812 	else {
813 		copy.table_name = "_views";
814 		gda_meta_store_set_reserved_keywords_func (store,
815 							   _gda_mysql_reuseable_get_reserved_keywords_func
816 							   ((GdaProviderReuseable*) rdata));
817 		retval = gda_meta_store_modify_with_context (store, &copy, model_views, error);
818 		g_object_unref (G_OBJECT(model_views));
819 	}
820 
821 	return retval;
822 }
823 
824 gboolean
825 _gda_mysql_meta_tables_views (G_GNUC_UNUSED GdaServerProvider  *prov,
826 			      GdaConnection      *cnc,
827 			      GdaMetaStore       *store,
828 			      GdaMetaContext     *context,
829 			      GError            **error,
830 			      G_GNUC_UNUSED const GValue       *table_catalog,
831 			      const GValue       *table_schema,
832 			      const GValue       *table_name_n)
833 {
834 	GdaDataModel *model_tables, *model_views;
835 	gboolean retval;
836 	/* Check correct mysql server version. */
837 	GdaMysqlReuseable *rdata;
838 	rdata = GDA_MYSQL_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
839 	if (!rdata)
840 		return FALSE;
841 	if ((rdata->version_long == 0) && ! _gda_mysql_compute_version (cnc, rdata, error))
842 		return FALSE;
843 	if (rdata->version_long < 50000) {
844 		g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_SERVER_VERSION_ERROR,
845 			     "%s", _("Mysql version 5.0 at least is required"));
846 		return FALSE;
847 	}
848 
849 
850 	/* Copy contents, just because we need to modify @context->table_name */
851 	GdaMetaContext copy = *context;
852 
853 	if (!gda_holder_set_value (gda_set_get_holder (i_set, "schema"), table_schema, error))
854 		return FALSE;
855 	if (!table_name_n) {
856 		model_tables = gda_connection_statement_execute_select_full (cnc,
857 									     internal_stmt[I_STMT_TABLES],
858 									     i_set,
859 									     GDA_STATEMENT_MODEL_RANDOM_ACCESS,
860 									     _col_types_tables,
861 									     error);
862 		if (model_tables == NULL)
863 			retval = FALSE;
864 		else {
865 			copy.table_name = "_tables";
866 			gda_meta_store_set_reserved_keywords_func (store,
867 								   _gda_mysql_reuseable_get_reserved_keywords_func
868 								   ((GdaProviderReuseable*) rdata));
869 			retval = gda_meta_store_modify_with_context (store, &copy, model_tables, error);
870 			g_object_unref (G_OBJECT (model_tables));
871 		}
872 
873 		if (!retval)
874 			return FALSE;
875 
876 		model_views = gda_connection_statement_execute_select_full (cnc,
877 									    internal_stmt[I_STMT_VIEWS],
878 									    i_set,
879 									    GDA_STATEMENT_MODEL_RANDOM_ACCESS,
880 									    _col_types_views,
881 									    error);
882 		if (model_views == NULL)
883 			retval = FALSE;
884 		else {
885 			copy.table_name = "_views";
886 			gda_meta_store_set_reserved_keywords_func (store,
887 								   _gda_mysql_reuseable_get_reserved_keywords_func
888 								   ((GdaProviderReuseable*) rdata));
889 			retval = gda_meta_store_modify_with_context (store, &copy, model_views, error);
890 			g_object_unref (G_OBJECT (model_views));
891 		}
892 
893 	} else {
894 		if (!gda_holder_set_value (gda_set_get_holder (i_set, "name"), table_name_n, error))
895 			return FALSE;
896 		model_tables = gda_connection_statement_execute_select_full (cnc,
897 									     internal_stmt[I_STMT_TABLE_NAMED],
898 									     i_set,
899 									     GDA_STATEMENT_MODEL_RANDOM_ACCESS,
900 									     _col_types_tables,
901 									     error);
902 		if (model_tables == NULL)
903 			retval = FALSE;
904 		else {
905 			copy.table_name = "_tables";
906 			gda_meta_store_set_reserved_keywords_func (store,
907 								   _gda_mysql_reuseable_get_reserved_keywords_func
908 								   ((GdaProviderReuseable*) rdata));
909 			retval = gda_meta_store_modify_with_context (store, &copy, model_tables, error);
910 			g_object_unref (G_OBJECT(model_tables));
911 		}
912 
913 		if (!retval)
914 			return FALSE;
915 		model_views = gda_connection_statement_execute_select_full (cnc,
916 									    internal_stmt[I_STMT_VIEW_NAMED],
917 									    i_set,
918 									    GDA_STATEMENT_MODEL_RANDOM_ACCESS,
919 									    _col_types_views,
920 									    error);
921 		if (model_views == NULL)
922 			retval = FALSE;
923 		else {
924 			copy.table_name = "_views";
925 			gda_meta_store_set_reserved_keywords_func (store,
926 								   _gda_mysql_reuseable_get_reserved_keywords_func
927 								   ((GdaProviderReuseable*) rdata));
928 			retval = gda_meta_store_modify_with_context (store, &copy, model_views, error);
929 			g_object_unref (G_OBJECT(model_views));
930 		}
931 
932 	}
933 
934 	return retval;
935 }
936 
937 /*
938  * map_mysql_type_to_gda:
939  * @value: a #GValue string.
940  *
941  * It maps a mysql type to a gda type.  This means that when a
942  * mysql type is given, it will return its mapped gda type.
943  *
944  * Returns a newly created GValue string.
945  */
946 static inline GValue *
947 map_mysql_type_to_gda (const GValue *value, const gchar *vlength)
948 {
949 	const gchar *string = g_value_get_string (value);
950 	GValue *newvalue;
951 	const gchar *newstring;
952 
953 	if (!strcmp (string, "bool"))
954 		newstring = "gboolean";
955 	else if (!strcmp (string, "blob"))
956 		newstring = "GdaBinary";
957 	else if (!strcmp (string, "bigint"))
958 		newstring = "gint64";
959 	else if (!strcmp (string, "bigint unsigned"))
960 		newstring = "guint64";
961 	else if (!strcmp (string, "char")) {
962 		if (vlength && (G_VALUE_TYPE ((GValue*)vlength) == G_TYPE_INT) &&
963 		    (g_value_get_int ((GValue*)vlength) > 1))
964 			newstring = "gchararray";
965 		else
966 			newstring = "gchar";
967 	}
968 	else if (!strcmp (string, "date"))
969 		newstring = "GDate";
970 	else if (!strcmp (string, "datetime"))
971 		newstring = "GdaTimestamp";
972 	else if (!strcmp (string, "decimal"))
973 		newstring = "GdaNumeric";
974 	else if (!strcmp (string, "double"))
975 		newstring = "gdouble";
976 	else if (!strcmp (string, "double unsigned"))
977 		newstring = "double";
978 	else if (!strcmp (string, "enum"))
979 		newstring = "gchararray";
980 	else if (!strcmp (string, "float"))
981 		newstring = "gfloat";
982 	else if (!strcmp (string, "float unsigned"))
983 		newstring = "gfloat";
984 	else if (!strcmp (string, "int"))
985 		newstring = "int";
986 	else if (!strcmp (string, "unsigned int"))
987 		newstring = "guint";
988 	else if (!strcmp (string, "long"))
989 		newstring = "glong";
990 	else if (!strcmp (string, "unsigned long"))
991 		newstring = "gulong";
992 	else if (!strcmp (string, "longblob"))
993 		newstring = "GdaBinary";
994 	else if (!strcmp (string, "longtext"))
995 		newstring = "GdaBinary";
996 	else if (!strcmp (string, "mediumint"))
997 		newstring = "gint";
998 	else if (!strcmp (string, "mediumint unsigned"))
999 		newstring = "guint";
1000 	else if (!strcmp (string, "mediumblob"))
1001 		newstring = "GdaBinary";
1002 	else if (!strcmp (string, "mediumtext"))
1003 		newstring = "GdaBinary";
1004 	else if (!strcmp (string, "set"))
1005 		newstring = "gchararray";
1006 	else if (!strcmp (string, "smallint"))
1007 		newstring = "gshort";
1008 	else if (!strcmp (string, "smallint unsigned"))
1009 		newstring = "gushort";
1010 	else if (!strcmp (string, "text"))
1011 		newstring = "GdaBinary";
1012 	else if (!strcmp (string, "tinyint"))
1013 		newstring = "gchar";
1014 	else if (!strcmp (string, "tinyint unsigned"))
1015 		newstring = "guchar";
1016 	else if (!strcmp (string, "tinyblob"))
1017 		newstring = "GdaBinary";
1018 	else if (!strcmp (string, "time"))
1019 		newstring = "GdaTime";
1020 	else if (!strcmp (string, "timestamp"))
1021 		newstring = "GdaTimestamp";
1022 	else if (!strcmp (string, "varchar"))
1023 		newstring = "gchararray";
1024 	else if (!strcmp (string, "year"))
1025 		newstring = "gint";
1026 	else
1027 		newstring = "gchararray";
1028 
1029 	g_value_set_string (newvalue = gda_value_new (G_TYPE_STRING),
1030 			    newstring);
1031 
1032 	return newvalue;
1033 }
1034 
1035 gboolean
1036 _gda_mysql_meta__columns (G_GNUC_UNUSED GdaServerProvider  *prov,
1037 			  GdaConnection      *cnc,
1038 			  GdaMetaStore       *store,
1039 			  GdaMetaContext     *context,
1040 			  GError            **error)
1041 {
1042 	GdaDataModel *model, *proxy;
1043 	gboolean retval = TRUE;
1044 	/* Check correct mysql server version. */
1045 	GdaMysqlReuseable *rdata;
1046 	rdata = GDA_MYSQL_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1047 	if (!rdata)
1048 		return FALSE;
1049 	if ((rdata->version_long == 0) && ! _gda_mysql_compute_version (cnc, rdata, error))
1050 		return FALSE;
1051 	if (rdata->version_long < 50000) {
1052 		g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_SERVER_VERSION_ERROR,
1053 			     "%s", _("Mysql version 5.0 at least is required"));
1054 		return FALSE;
1055 	}
1056 
1057 	/* Use a prepared statement for the "base" model. */
1058 	model = gda_connection_statement_execute_select_full (cnc,
1059 							      internal_stmt[I_STMT_COLUMNS_ALL], NULL,
1060 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1061 							      _col_types_columns, error);
1062 	if (model == NULL)
1063 		retval = FALSE;
1064 	else {
1065 		proxy = (GdaDataModel *) gda_data_proxy_new (model);
1066 		gda_data_proxy_set_sample_size ((GdaDataProxy *) proxy, 0);
1067 		gint n_rows = gda_data_model_get_n_rows (model);
1068 		gint i;
1069 		for (i = 0; i < n_rows; ++i) {
1070 			const GValue *value1, *value2 = NULL;
1071 			value1 = gda_data_model_get_value_at (model, 7, i, error);
1072 			if (value1)
1073 				value2 = gda_data_model_get_value_at (model, 10, i, error);
1074 			if (!value1 || !value2) {
1075 				retval = FALSE;
1076 				break;
1077 			}
1078 
1079 			GValue *newvalue = map_mysql_type_to_gda (value1, (const char*)(value2));
1080 
1081 			retval = gda_data_model_set_value_at (GDA_DATA_MODEL(proxy), 9, i, newvalue, error);
1082 			gda_value_free (newvalue);
1083 			if (!retval)
1084 				break;
1085 		}
1086 
1087 		if (retval) {
1088 			gda_meta_store_set_reserved_keywords_func (store,
1089 								   _gda_mysql_reuseable_get_reserved_keywords_func
1090 								   ((GdaProviderReuseable*) rdata));
1091 			retval = gda_meta_store_modify_with_context (store, context, proxy, error);
1092 		}
1093 
1094 		g_object_unref (G_OBJECT(proxy));
1095 		g_object_unref (G_OBJECT(model));
1096 	}
1097 
1098 	return retval;
1099 }
1100 
1101 gboolean
1102 _gda_mysql_meta_columns (G_GNUC_UNUSED GdaServerProvider  *prov,
1103 			 GdaConnection      *cnc,
1104 			 GdaMetaStore       *store,
1105 			 GdaMetaContext     *context,
1106 			 GError            **error,
1107 			 G_GNUC_UNUSED const GValue       *table_catalog,
1108 			 const GValue       *table_schema,
1109 			 const GValue       *table_name)
1110 {
1111 	GdaDataModel *model, *proxy;
1112 	gboolean retval;
1113 	/* Check correct mysql server version. */
1114 	GdaMysqlReuseable *rdata;
1115 	rdata = GDA_MYSQL_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1116 	if (!rdata)
1117 		return FALSE;
1118 	if ((rdata->version_long == 0) && ! _gda_mysql_compute_version (cnc, rdata, error))
1119 		return FALSE;
1120 	if (rdata->version_long < 50000) {
1121 		g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_SERVER_VERSION_ERROR,
1122 			     "%s", _("Mysql version 5.0 at least is required"));
1123 		return FALSE;
1124 	}
1125 
1126 	/* Use a prepared statement for the "base" model. */
1127 	if (!gda_holder_set_value (gda_set_get_holder (i_set, "schema"), table_schema, error))
1128 		return FALSE;
1129 	if (!gda_holder_set_value (gda_set_get_holder (i_set, "name"), table_name, error))
1130 		return FALSE;
1131 
1132 	model = gda_connection_statement_execute_select_full (cnc,
1133 							      internal_stmt[I_STMT_COLUMNS_OF_TABLE],
1134 							      i_set,
1135 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1136 							      _col_types_columns, error);
1137 	if (model == NULL)
1138 		retval = FALSE;
1139 	else {
1140 		proxy = (GdaDataModel *) gda_data_proxy_new (model);
1141 		gda_data_proxy_set_sample_size ((GdaDataProxy *) proxy, 0);
1142 		gint n_rows = gda_data_model_get_n_rows (model);
1143 		gint i;
1144 		for (i = 0; i < n_rows; ++i) {
1145 			const GValue *value1, *value2 = NULL;
1146 			value1 = gda_data_model_get_value_at (model, 7, i, error);
1147 			if (value1)
1148 				value2 = gda_data_model_get_value_at (model, 10, i, error);
1149 			if (!value1 || !value2) {
1150 				retval = FALSE;
1151 				break;
1152 			}
1153 
1154 			GValue *newvalue = map_mysql_type_to_gda (value1, (const char*)value2);
1155 
1156 			retval = gda_data_model_set_value_at (GDA_DATA_MODEL(proxy), 9, i, newvalue, error);
1157 			gda_value_free (newvalue);
1158 			if (!retval)
1159 				break;
1160 		}
1161 
1162 		if (retval) {
1163 			gda_meta_store_set_reserved_keywords_func (store,
1164 								   _gda_mysql_reuseable_get_reserved_keywords_func
1165 								   ((GdaProviderReuseable*) rdata));
1166 			retval = gda_meta_store_modify (store, context->table_name, proxy,
1167 							"table_schema=##schema::string AND table_name=##name::string",
1168 							error,
1169 							"schema", table_schema, "name", table_name, NULL);
1170 		}
1171 		g_object_unref (G_OBJECT(proxy));
1172 		g_object_unref (G_OBJECT(model));
1173 	}
1174 
1175 	return retval;
1176 }
1177 
1178 gboolean
1179 _gda_mysql_meta__view_cols (G_GNUC_UNUSED GdaServerProvider  *prov,
1180 			    GdaConnection      *cnc,
1181 			    GdaMetaStore       *store,
1182 			    GdaMetaContext     *context,
1183 			    GError            **error)
1184 {
1185 	GdaDataModel *model;
1186 	gboolean retval;
1187 	/* Check correct mysql server version. */
1188 	GdaMysqlReuseable *rdata;
1189 	rdata = GDA_MYSQL_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1190 	if (!rdata)
1191 		return FALSE;
1192 	if ((rdata->version_long == 0) && ! _gda_mysql_compute_version (cnc, rdata, error))
1193 		return FALSE;
1194 	if (rdata->version_long < 50000) {
1195 		g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_SERVER_VERSION_ERROR,
1196 			     "%s", _("Mysql version 5.0 at least is required"));
1197 		return FALSE;
1198 	}
1199 
1200 	model = gda_connection_statement_execute_select_full (cnc,
1201 							      internal_stmt[I_STMT_VIEWS_COLUMNS_ALL],
1202 							      NULL,
1203 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1204 							      _col_types_view_column_usage, error);
1205 	if (model == NULL)
1206 		retval = FALSE;
1207 	else {
1208 		gda_meta_store_set_reserved_keywords_func (store,
1209 							   _gda_mysql_reuseable_get_reserved_keywords_func
1210 							   ((GdaProviderReuseable*) rdata));
1211 		retval = gda_meta_store_modify_with_context (store, context, model, error);
1212 		g_object_unref (G_OBJECT(model));
1213 	}
1214 
1215 	return retval;
1216 }
1217 
1218 gboolean
1219 _gda_mysql_meta_view_cols (G_GNUC_UNUSED GdaServerProvider  *prov,
1220 			   GdaConnection      *cnc,
1221 			   GdaMetaStore       *store,
1222 			   GdaMetaContext     *context,
1223 			   GError            **error,
1224 			   G_GNUC_UNUSED const GValue       *view_catalog,
1225 			   const GValue       *view_schema,
1226 			   const GValue       *view_name)
1227 {
1228 	GdaDataModel *model;
1229 	gboolean retval;
1230 	GdaMysqlReuseable *rdata;
1231 	rdata = GDA_MYSQL_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1232 	if (!rdata)
1233 		return FALSE;
1234 
1235 	if (!gda_holder_set_value (gda_set_get_holder (i_set, "schema"), view_schema, error))
1236 		return FALSE;
1237 	if (!gda_holder_set_value (gda_set_get_holder (i_set, "name"), view_name, error))
1238 		return FALSE;
1239 	model = gda_connection_statement_execute_select_full (cnc,
1240 							      internal_stmt[I_STMT_VIEWS_COLUMNS],
1241 							      i_set,
1242 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1243 							      _col_types_view_column_usage, error);
1244 	if (model == NULL)
1245 		retval = FALSE;
1246 	else {
1247 		gda_meta_store_set_reserved_keywords_func (store,
1248 							   _gda_mysql_reuseable_get_reserved_keywords_func
1249 							   ((GdaProviderReuseable*) rdata));
1250 		retval = gda_meta_store_modify_with_context (store, context, model, error);
1251 		g_object_unref (G_OBJECT(model));
1252 
1253 	}
1254 
1255 	return retval;
1256 }
1257 
1258 gboolean
1259 _gda_mysql_meta__constraints_tab (G_GNUC_UNUSED GdaServerProvider  *prov,
1260 				  GdaConnection      *cnc,
1261 				  GdaMetaStore       *store,
1262 				  GdaMetaContext     *context,
1263 				  GError            **error)
1264 {
1265 	GdaDataModel *model;
1266 	gboolean retval;
1267 	GdaMysqlReuseable *rdata;
1268 	rdata = GDA_MYSQL_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1269 	if (!rdata)
1270 		return FALSE;
1271 
1272 	model = gda_connection_statement_execute_select_full (cnc,
1273 							      internal_stmt[I_STMT_TABLES_CONSTRAINTS_ALL],
1274 							      NULL,
1275 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1276 							      _col_types_table_constraints, error);
1277 	if (model == NULL)
1278 		retval = FALSE;
1279 	else {
1280 		gda_meta_store_set_reserved_keywords_func (store,
1281 							   _gda_mysql_reuseable_get_reserved_keywords_func
1282 							   ((GdaProviderReuseable*) rdata));
1283 		retval = gda_meta_store_modify_with_context (store, context, model, error);
1284 		g_object_unref (G_OBJECT(model));
1285 	}
1286 
1287 	return retval;
1288 }
1289 
1290 gboolean
1291 _gda_mysql_meta_constraints_tab (G_GNUC_UNUSED GdaServerProvider  *prov,
1292 				 GdaConnection      *cnc,
1293 				 GdaMetaStore       *store,
1294 				 GdaMetaContext     *context,
1295 				 GError            **error,
1296 				 G_GNUC_UNUSED const GValue       *table_catalog,
1297 				 const GValue       *table_schema,
1298 				 const GValue       *table_name,
1299 				 const GValue       *constraint_name_n)
1300 {
1301 	GdaDataModel *model;
1302 	gboolean retval;
1303 	GdaMysqlReuseable *rdata;
1304 	rdata = GDA_MYSQL_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1305 	if (!rdata)
1306 		return FALSE;
1307 
1308 	if (!gda_holder_set_value (gda_set_get_holder (i_set, "schema"), table_schema, error))
1309 		return FALSE;
1310 	if (!gda_holder_set_value (gda_set_get_holder (i_set, "name"), table_name, error))
1311 		return FALSE;
1312 	if (!constraint_name_n) {
1313 		model = gda_connection_statement_execute_select_full (cnc,
1314 								      internal_stmt[I_STMT_TABLES_CONSTRAINTS],
1315 								      i_set,
1316 								      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1317 								      _col_types_table_constraints, error);
1318 		if (model == NULL)
1319 			retval = FALSE;
1320 		else {
1321 			gda_meta_store_set_reserved_keywords_func (store,
1322 								   _gda_mysql_reuseable_get_reserved_keywords_func
1323 								   ((GdaProviderReuseable*) rdata));
1324 			retval = gda_meta_store_modify (store, context->table_name, model,
1325 							"table_schema = ##schema::string AND table_name = ##name::string",
1326 							error,
1327 							"schema", table_schema, "name", table_name, NULL);
1328 			g_object_unref (G_OBJECT(model));
1329 		}
1330 	} else {
1331 		if (!gda_holder_set_value (gda_set_get_holder (i_set, "name2"), constraint_name_n, error))
1332 			return FALSE;
1333 		model = gda_connection_statement_execute_select_full (cnc,
1334 								      internal_stmt[I_STMT_TABLES_CONSTRAINTS_NAMED],
1335 								      i_set,
1336 								      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1337 								      _col_types_table_constraints, error);
1338 		if (model == NULL)
1339 			retval = FALSE;
1340 		else {
1341 			gda_meta_store_set_reserved_keywords_func (store,
1342 								   _gda_mysql_reuseable_get_reserved_keywords_func
1343 								   ((GdaProviderReuseable*) rdata));
1344 			retval = gda_meta_store_modify (store, context->table_name, model,
1345 							"table_schema=##schema::string AND table_name=##name::string AND constraint_name=##name2::string",
1346 							error,
1347 							"schema", table_schema, "name", table_name, "name2", constraint_name_n, NULL);
1348 			g_object_unref (G_OBJECT(model));
1349 		}
1350 	}
1351 
1352 	return retval;
1353 }
1354 
1355 gboolean
1356 _gda_mysql_meta__constraints_ref (G_GNUC_UNUSED GdaServerProvider  *prov,
1357 				  GdaConnection      *cnc,
1358 				  GdaMetaStore       *store,
1359 				  GdaMetaContext     *context,
1360 				  GError            **error)
1361 {
1362 	GdaMysqlReuseable *rdata;
1363 
1364 	rdata = GDA_MYSQL_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1365 	g_return_val_if_fail (rdata, FALSE);
1366 
1367 	if ((rdata->version_long == 0) && ! _gda_mysql_compute_version (cnc, rdata, error))
1368 		return FALSE;
1369 	if (rdata->version_long >= 50110) {
1370 		GdaDataModel *model;
1371 		gboolean retval;
1372 		model = gda_connection_statement_execute_select_full (cnc,
1373 								      internal_stmt[I_STMT_REF_CONSTRAINTS_ALL],
1374 								      NULL,
1375 								      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1376 								      _col_types_referential_constraints, error);
1377 		if (model == NULL)
1378 			retval = FALSE;
1379 		else {
1380 			gda_meta_store_set_reserved_keywords_func (store,
1381 								   _gda_mysql_reuseable_get_reserved_keywords_func
1382 								   ((GdaProviderReuseable*) rdata));
1383 			retval = gda_meta_store_modify_with_context (store, context, model, error);
1384 			g_object_unref (G_OBJECT(model));
1385 		}
1386 
1387 		return retval;
1388 	}
1389 	else {
1390 		// TO_IMPLEMENT;
1391 		return TRUE;
1392 	}
1393 }
1394 
1395 gboolean
1396 _gda_mysql_meta_constraints_ref (G_GNUC_UNUSED GdaServerProvider  *prov,
1397 				 GdaConnection      *cnc,
1398 				 GdaMetaStore       *store,
1399 				 GdaMetaContext     *context,
1400 				 GError            **error,
1401 				 G_GNUC_UNUSED const GValue       *table_catalog,
1402 				 const GValue       *table_schema,
1403 				 const GValue       *table_name,
1404 				 const GValue       *constraint_name)
1405 {
1406 	GdaMysqlReuseable *rdata;
1407 
1408 	rdata = GDA_MYSQL_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1409 	g_return_val_if_fail (rdata, FALSE);
1410 
1411 	if ((rdata->version_long == 0) && ! _gda_mysql_compute_version (cnc, rdata, error))
1412 		return FALSE;
1413 	if (rdata->version_long >= 50110) {
1414 		GdaDataModel *model;
1415 		gboolean retval;
1416 
1417 		/* Use a prepared statement for the "base" model. */
1418 		if (!gda_holder_set_value (gda_set_get_holder (i_set, "schema"), table_schema, error))
1419 			return FALSE;
1420 		if (!gda_holder_set_value (gda_set_get_holder (i_set, "name"), table_name, error))
1421 			return FALSE;
1422 		if (!gda_holder_set_value (gda_set_get_holder (i_set, "name2"), constraint_name, error))
1423 			return FALSE;
1424 		model = gda_connection_statement_execute_select_full (cnc,
1425 								      internal_stmt[I_STMT_REF_CONSTRAINTS],
1426 								      i_set,
1427 								      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1428 								      _col_types_referential_constraints, error);
1429 		if (model == NULL)
1430 			retval = FALSE;
1431 		else {
1432 			gda_meta_store_set_reserved_keywords_func (store,
1433 								   _gda_mysql_reuseable_get_reserved_keywords_func
1434 								   ((GdaProviderReuseable*) rdata));
1435 			retval = gda_meta_store_modify (store, context->table_name, model,
1436 							"table_schema=##schema::string AND table_name=##name::string AND constraint_name=##name2::string",
1437 							error,
1438 							"schema", table_schema, "name", table_name, "name2", constraint_name, NULL);
1439 			g_object_unref (G_OBJECT(model));
1440 
1441 		}
1442 
1443 		return retval;
1444 	}
1445 	else {
1446 		// TO_IMPLEMENT;
1447 		return TRUE;
1448 	}
1449 }
1450 
1451 gboolean
1452 _gda_mysql_meta__key_columns (G_GNUC_UNUSED GdaServerProvider  *prov,
1453 			      GdaConnection      *cnc,
1454 			      GdaMetaStore       *store,
1455 			      GdaMetaContext     *context,
1456 			      GError            **error)
1457 {
1458 	GdaDataModel *model;
1459 	gboolean retval;
1460 	GdaMysqlReuseable *rdata;
1461 	rdata = GDA_MYSQL_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1462 	if (!rdata)
1463 		return FALSE;
1464 
1465 	model = gda_connection_statement_execute_select_full (cnc,
1466 							      internal_stmt[I_STMT_KEY_COLUMN_USAGE_ALL],
1467 							      NULL,
1468 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1469 							      _col_types_key_column_usage, error);
1470 	if (model == NULL)
1471 		retval = FALSE;
1472 	else {
1473 		gda_meta_store_set_reserved_keywords_func (store,
1474 							   _gda_mysql_reuseable_get_reserved_keywords_func
1475 							   ((GdaProviderReuseable*) rdata));
1476 		retval = gda_meta_store_modify_with_context (store, context, model, error);
1477 		g_object_unref (G_OBJECT(model));
1478 	}
1479 
1480 	return retval;
1481 }
1482 
1483 gboolean
1484 _gda_mysql_meta_key_columns (G_GNUC_UNUSED GdaServerProvider  *prov,
1485 			     GdaConnection      *cnc,
1486 			     GdaMetaStore       *store,
1487 			     GdaMetaContext     *context,
1488 			     GError            **error,
1489 			     G_GNUC_UNUSED const GValue       *table_catalog,
1490 			     const GValue       *table_schema,
1491 			     const GValue       *table_name,
1492 			     const GValue       *constraint_name)
1493 {
1494 	GdaDataModel *model;
1495 	gboolean retval;
1496 	/* Check correct mysql server version. */
1497 	GdaMysqlReuseable *rdata;
1498 	rdata = GDA_MYSQL_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1499 	if (!rdata)
1500 		return FALSE;
1501 	if ((rdata->version_long == 0) && ! _gda_mysql_compute_version (cnc, rdata, error))
1502 		return FALSE;
1503 	if (rdata->version_long < 50000) {
1504 		g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_SERVER_VERSION_ERROR,
1505 			     "%s", _("Mysql version 5.0 at least is required"));
1506 		return FALSE;
1507 	}
1508 
1509 	/* Use a prepared statement for the "base" model. */
1510 	if (!gda_holder_set_value (gda_set_get_holder (i_set, "schema"), table_schema, error))
1511 		return FALSE;
1512 	if (!gda_holder_set_value (gda_set_get_holder (i_set, "name"), table_name, error))
1513 		return FALSE;
1514 	if (!gda_holder_set_value (gda_set_get_holder (i_set, "name2"), constraint_name, error))
1515 		return FALSE;
1516 	model = gda_connection_statement_execute_select_full (cnc,
1517 							      internal_stmt[I_STMT_KEY_COLUMN_USAGE],
1518 							      i_set, GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1519 							      _col_types_key_column_usage,
1520 							      error);
1521 	if (model == NULL)
1522 		retval = FALSE;
1523 	else {
1524 		gda_meta_store_set_reserved_keywords_func (store,
1525 							   _gda_mysql_reuseable_get_reserved_keywords_func
1526 							   ((GdaProviderReuseable*) rdata));
1527 		retval = gda_meta_store_modify (store, context->table_name, model,
1528 						"table_schema=##schema::string AND table_name=##name::string AND constraint_name=##name2::string",
1529 						error,
1530 						"schema", table_schema, "name", table_name, "name2", constraint_name, NULL);
1531 		g_object_unref (G_OBJECT(model));
1532 
1533 	}
1534 
1535 	return retval;
1536 }
1537 
1538 gboolean
1539 _gda_mysql_meta__check_columns (G_GNUC_UNUSED GdaServerProvider  *prov,
1540 				G_GNUC_UNUSED GdaConnection      *cnc,
1541 				G_GNUC_UNUSED GdaMetaStore       *store,
1542 				G_GNUC_UNUSED GdaMetaContext     *context,
1543 				G_GNUC_UNUSED GError            **error)
1544 {
1545 	//TO_IMPLEMENT;
1546 	return TRUE;
1547 }
1548 
1549 gboolean
1550 _gda_mysql_meta_check_columns (G_GNUC_UNUSED GdaServerProvider  *prov,
1551 			       G_GNUC_UNUSED GdaConnection      *cnc,
1552 			       G_GNUC_UNUSED GdaMetaStore       *store,
1553 			       G_GNUC_UNUSED GdaMetaContext     *context,
1554 			       G_GNUC_UNUSED GError            **error,
1555 			       G_GNUC_UNUSED const GValue       *table_catalog,
1556 			       G_GNUC_UNUSED const GValue       *table_schema,
1557 			       G_GNUC_UNUSED const GValue       *table_name,
1558 			       G_GNUC_UNUSED const GValue       *constraint_name)
1559 {
1560 	//TO_IMPLEMENT;
1561 	return TRUE;
1562 }
1563 
1564 gboolean
1565 _gda_mysql_meta__triggers (G_GNUC_UNUSED GdaServerProvider  *prov,
1566 			   GdaConnection      *cnc,
1567 			   GdaMetaStore       *store,
1568 			   GdaMetaContext     *context,
1569 			   GError            **error)
1570 {
1571 	GdaDataModel *model;
1572 	gboolean retval;
1573 	/* Check correct mysql server version. */
1574 	GdaMysqlReuseable *rdata;
1575 	rdata = GDA_MYSQL_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1576 	if (!rdata)
1577 		return FALSE;
1578 	if ((rdata->version_long == 0) && ! _gda_mysql_compute_version (cnc, rdata, error))
1579 		return FALSE;
1580 	if (rdata->version_long < 50000) {
1581 		g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_SERVER_VERSION_ERROR,
1582 			     "%s", _("Mysql version 5.0 at least is required"));
1583 		return FALSE;
1584 	}
1585 
1586 	model = gda_connection_statement_execute_select_full (cnc,
1587 							      internal_stmt[I_STMT_TRIGGERS_ALL],
1588 							      NULL,
1589 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1590 							      _col_types_triggers, error);
1591 	if (model == NULL)
1592 		retval = FALSE;
1593 	else {
1594 		gda_meta_store_set_reserved_keywords_func (store,
1595 							   _gda_mysql_reuseable_get_reserved_keywords_func
1596 							   ((GdaProviderReuseable*) rdata));
1597 		retval = gda_meta_store_modify_with_context (store, context, model, error);
1598 		g_object_unref (G_OBJECT(model));
1599 	}
1600 
1601 	return retval;
1602 }
1603 
1604 gboolean
1605 _gda_mysql_meta_triggers (G_GNUC_UNUSED GdaServerProvider  *prov,
1606 			  GdaConnection      *cnc,
1607 			  GdaMetaStore       *store,
1608 			  GdaMetaContext     *context,
1609 			  GError            **error,
1610 			  G_GNUC_UNUSED const GValue       *table_catalog,
1611 			  const GValue       *table_schema,
1612 			  const GValue       *table_name)
1613 {
1614 	GdaDataModel *model;
1615 	gboolean retval;
1616 	/* Check correct mysql server version. */
1617 	GdaMysqlReuseable *rdata;
1618 	rdata = GDA_MYSQL_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1619 	if (!rdata)
1620 		return FALSE;
1621 	if ((rdata->version_long == 0) && ! _gda_mysql_compute_version (cnc, rdata, error))
1622 		return FALSE;
1623 	if (rdata->version_long < 50000) {
1624 		g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_SERVER_VERSION_ERROR,
1625 			     "%s", _("Mysql version 5.0 at least is required"));
1626 		return FALSE;
1627 	}
1628 
1629 	if (!gda_holder_set_value (gda_set_get_holder (i_set, "schema"), table_schema, error))
1630 		return FALSE;
1631 	if (!gda_holder_set_value (gda_set_get_holder (i_set, "name"), table_name, error))
1632 		return FALSE;
1633 	model = gda_connection_statement_execute_select_full (cnc,
1634 							      internal_stmt[I_STMT_TRIGGERS],
1635 							      i_set,
1636 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1637 							      _col_types_triggers, error);
1638 	if (model == NULL)
1639 		retval = FALSE;
1640 	else {
1641 		gda_meta_store_set_reserved_keywords_func (store,
1642 							   _gda_mysql_reuseable_get_reserved_keywords_func
1643 							   ((GdaProviderReuseable*) rdata));
1644 		retval = gda_meta_store_modify_with_context (store, context, model, error);
1645 		g_object_unref (G_OBJECT(model));
1646 
1647 	}
1648 
1649 	return retval;
1650 }
1651 
1652 gboolean
1653 _gda_mysql_meta__routines (G_GNUC_UNUSED GdaServerProvider  *prov,
1654 			   GdaConnection      *cnc,
1655 			   GdaMetaStore       *store,
1656 			   GdaMetaContext     *context,
1657 			   GError            **error)
1658 {
1659 	GdaDataModel *model;
1660 	gboolean retval;
1661 	GdaMysqlReuseable *rdata;
1662 	rdata = GDA_MYSQL_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1663 	if (!rdata)
1664 		return FALSE;
1665 
1666 	model = gda_connection_statement_execute_select_full (cnc,
1667 							      internal_stmt[I_STMT_ROUTINES_ALL],
1668 							      NULL,
1669 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1670 							      _col_types_routines, error);
1671 	if (model == NULL)
1672 		retval = FALSE;
1673 	else {
1674 		gda_meta_store_set_reserved_keywords_func (store,
1675 							   _gda_mysql_reuseable_get_reserved_keywords_func
1676 							   ((GdaProviderReuseable*) rdata));
1677 		retval = gda_meta_store_modify_with_context (store, context, model, error);
1678 		g_object_unref (G_OBJECT(model));
1679 	}
1680 
1681 	return retval;
1682 }
1683 
1684 gboolean
1685 _gda_mysql_meta_routines (G_GNUC_UNUSED GdaServerProvider  *prov,
1686 			  GdaConnection      *cnc,
1687 			  GdaMetaStore       *store,
1688 			  GdaMetaContext     *context,
1689 			  GError            **error,
1690 			  G_GNUC_UNUSED const GValue       *routine_catalog,
1691 			  const GValue       *routine_schema,
1692 			  const GValue       *routine_name_n)
1693 {
1694 	GdaDataModel *model;
1695 	gboolean retval;
1696 	/* Check correct mysql server version. */
1697 	GdaMysqlReuseable *rdata;
1698 	rdata = GDA_MYSQL_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1699 	if (!rdata)
1700 		return FALSE;
1701 	if ((rdata->version_long == 0) && ! _gda_mysql_compute_version (cnc, rdata, error))
1702 		return FALSE;
1703 	if (rdata->version_long < 50000) {
1704 		g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_SERVER_VERSION_ERROR,
1705 			     "%s", _("Mysql version 5.0 at least is required"));
1706 		return FALSE;
1707 	}
1708 
1709 	if (!gda_holder_set_value (gda_set_get_holder (i_set, "schema"), routine_schema, error))
1710 		return FALSE;
1711 	if (routine_name_n != NULL) {
1712  		if (!gda_holder_set_value (gda_set_get_holder (i_set, "name"), routine_name_n, error))
1713 			return FALSE;
1714 		model = gda_connection_statement_execute_select_full (cnc,
1715 								      internal_stmt[I_STMT_ROUTINES_ONE],
1716 								      i_set,
1717 								      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1718 								      _col_types_routines, error);
1719 	}
1720 	else
1721 		model = gda_connection_statement_execute_select_full (cnc,
1722 								      internal_stmt[I_STMT_ROUTINES],
1723 								      i_set,
1724 								      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1725 								      _col_types_routines, error);
1726 	if (model == NULL)
1727 		retval = FALSE;
1728 	else {
1729 		gda_meta_store_set_reserved_keywords_func (store,
1730 							   _gda_mysql_reuseable_get_reserved_keywords_func
1731 							   ((GdaProviderReuseable*) rdata));
1732 		retval = gda_meta_store_modify_with_context (store, context, model, error);
1733 		g_object_unref (G_OBJECT(model));
1734 
1735 	}
1736 
1737 	return retval;
1738 }
1739 
1740 gboolean
1741 _gda_mysql_meta__routine_col (G_GNUC_UNUSED GdaServerProvider  *prov,
1742 			      G_GNUC_UNUSED GdaConnection      *cnc,
1743 			      G_GNUC_UNUSED GdaMetaStore       *store,
1744 			      G_GNUC_UNUSED GdaMetaContext     *context,
1745 			      G_GNUC_UNUSED GError            **error)
1746 {
1747 	//TO_IMPLEMENT;
1748 	return TRUE;
1749 }
1750 
1751 gboolean
1752 _gda_mysql_meta_routine_col (G_GNUC_UNUSED GdaServerProvider  *prov,
1753 			     G_GNUC_UNUSED GdaConnection      *cnc,
1754 			     G_GNUC_UNUSED GdaMetaStore       *store,
1755 			     G_GNUC_UNUSED GdaMetaContext     *context,
1756 			     G_GNUC_UNUSED GError            **error,
1757 			     G_GNUC_UNUSED const GValue       *rout_catalog,
1758 			     G_GNUC_UNUSED const GValue       *rout_schema,
1759 			     G_GNUC_UNUSED const GValue       *rout_name)
1760 {
1761 	//TO_IMPLEMENT;
1762 	return TRUE;
1763 }
1764 
1765 gboolean
1766 _gda_mysql_meta__routine_par (G_GNUC_UNUSED GdaServerProvider  *prov,
1767 			      G_GNUC_UNUSED GdaConnection      *cnc,
1768 			      G_GNUC_UNUSED GdaMetaStore       *store,
1769 			      G_GNUC_UNUSED GdaMetaContext     *context,
1770 			      G_GNUC_UNUSED GError            **error)
1771 {
1772 	//TO_IMPLEMENT;
1773 	return TRUE;
1774 }
1775 
1776 gboolean
1777 _gda_mysql_meta_routine_par (G_GNUC_UNUSED GdaServerProvider  *prov,
1778 			     G_GNUC_UNUSED GdaConnection      *cnc,
1779 			     G_GNUC_UNUSED GdaMetaStore       *store,
1780 			     G_GNUC_UNUSED GdaMetaContext     *context,
1781 			     G_GNUC_UNUSED GError            **error,
1782 			     G_GNUC_UNUSED const GValue       *rout_catalog,
1783 			     G_GNUC_UNUSED const GValue       *rout_schema,
1784 			     G_GNUC_UNUSED const GValue       *rout_name)
1785 {
1786 	//TO_IMPLEMENT;
1787 	return TRUE;
1788 }
1789 
1790 gboolean
1791 _gda_mysql_meta__indexes_tab (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
1792 			      GdaMetaStore *store, GdaMetaContext *context, GError **error)
1793 {
1794 	GdaDataModel *model;
1795 	gboolean retval;
1796 	GdaMysqlReuseable *rdata;
1797 	rdata = GDA_MYSQL_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1798 	if (!rdata)
1799 		return FALSE;
1800 	/* Check correct mysql server version. */
1801 	if ((rdata->version_long == 0) && ! _gda_mysql_compute_version (cnc, rdata, error))
1802 		return FALSE;
1803 	if (rdata->version_long < 50000) {
1804 		g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_SERVER_VERSION_ERROR,
1805 			     "%s", _("Mysql version 5.0 at least is required"));
1806 		return FALSE;
1807 	}
1808 
1809 	model = gda_connection_statement_execute_select_full (cnc,
1810 							      internal_stmt[I_STMT_INDEXES_ALL],
1811 							      NULL,
1812 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1813 							      _col_types_table_indexes, error);
1814 	if (model == NULL)
1815 		retval = FALSE;
1816 	else {
1817 		gda_meta_store_set_reserved_keywords_func (store,
1818 							   _gda_mysql_reuseable_get_reserved_keywords_func
1819 							   ((GdaProviderReuseable*) rdata));
1820 		retval = gda_meta_store_modify_with_context (store, context, model, error);
1821 		g_object_unref (G_OBJECT(model));
1822 	}
1823 
1824 	return retval;
1825 }
1826 
1827 gboolean
1828 _gda_mysql_meta_indexes_tab (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
1829 			     GdaMetaStore *store, GdaMetaContext *context, GError **error,
1830 			     G_GNUC_UNUSED const GValue *table_catalog, const GValue *table_schema,
1831 			     const GValue *table_name, const GValue *index_name_n)
1832 {
1833 	GdaDataModel *model;
1834 	gboolean retval;
1835 	/* Check correct mysql server version. */
1836 	GdaMysqlReuseable *rdata;
1837 	rdata = GDA_MYSQL_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1838 	if (!rdata)
1839 		return FALSE;
1840 	if ((rdata->version_long == 0) && ! _gda_mysql_compute_version (cnc, rdata, error))
1841 		return FALSE;
1842 	if (rdata->version_long < 50000) {
1843 		g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_SERVER_VERSION_ERROR,
1844 			     "%s", _("Mysql version 5.0 at least is required"));
1845 		return FALSE;
1846 	}
1847 
1848 	if (!gda_holder_set_value (gda_set_get_holder (i_set, "schema"), table_schema, error))
1849 		return FALSE;
1850 	if (!gda_holder_set_value (gda_set_get_holder (i_set, "name"), table_name, error))
1851 		return FALSE;
1852 	if (index_name_n) {
1853 		if (!gda_holder_set_value (gda_set_get_holder (i_set, "name2"), index_name_n, error))
1854 			return FALSE;
1855 		model = gda_connection_statement_execute_select_full (cnc,
1856 								      internal_stmt[I_STMT_INDEXES_ONE],
1857 								      i_set,
1858 								      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1859 								      _col_types_table_indexes, error);
1860 	}
1861 	model = gda_connection_statement_execute_select_full (cnc,
1862 							      internal_stmt[I_STMT_INDEXES_TABLE],
1863 							      i_set,
1864 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1865 							      _col_types_table_indexes, error);
1866 
1867 	if (model == NULL)
1868 		retval = FALSE;
1869 	else {
1870 		gda_meta_store_set_reserved_keywords_func (store,
1871 							   _gda_mysql_reuseable_get_reserved_keywords_func
1872 							   ((GdaProviderReuseable*) rdata));
1873 		retval = gda_meta_store_modify_with_context (store, context, model, error);
1874 		g_object_unref (G_OBJECT(model));
1875 
1876 	}
1877 
1878 	return retval;
1879 }
1880 
1881 gboolean
1882 _gda_mysql_meta__index_cols (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
1883 			     GdaMetaStore *store, GdaMetaContext *context, GError **error)
1884 {
1885 	GdaDataModel *model;
1886 	gboolean retval;
1887 	GdaMysqlReuseable *rdata;
1888 	rdata = GDA_MYSQL_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1889 	if (!rdata)
1890 		return FALSE;
1891 	/* Check correct mysql server version. */
1892 	if ((rdata->version_long == 0) && ! _gda_mysql_compute_version (cnc, rdata, error))
1893 		return FALSE;
1894 	if (rdata->version_long < 50000) {
1895 		g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_SERVER_VERSION_ERROR,
1896 			     "%s", _("Mysql version 5.0 at least is required"));
1897 		return FALSE;
1898 	}
1899 
1900 	model = gda_connection_statement_execute_select_full (cnc,
1901 							      internal_stmt[I_STMT_INDEX_COLUMNS_ALL],
1902 							      NULL,
1903 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1904 							      _col_types_index_column_usage, error);
1905 	if (model == NULL)
1906 		retval = FALSE;
1907 	else {
1908 		gda_meta_store_set_reserved_keywords_func (store,
1909 							   _gda_mysql_reuseable_get_reserved_keywords_func
1910 							   ((GdaProviderReuseable*) rdata));
1911 		retval = gda_meta_store_modify_with_context (store, context, model, error);
1912 		g_object_unref (G_OBJECT(model));
1913 	}
1914 
1915 	return retval;
1916 }
1917 
1918 gboolean
1919 _gda_mysql_meta_index_cols (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
1920 			    GdaMetaStore *store, GdaMetaContext *context, GError **error,
1921 			    G_GNUC_UNUSED const GValue *table_catalog, const GValue *table_schema,
1922 			    const GValue *table_name, const GValue *index_name)
1923 {
1924 	GdaDataModel *model;
1925 	gboolean retval;
1926 	/* Check correct mysql server version. */
1927 	GdaMysqlReuseable *rdata;
1928 	rdata = GDA_MYSQL_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1929 	if (!rdata)
1930 		return FALSE;
1931 	if ((rdata->version_long == 0) && ! _gda_mysql_compute_version (cnc, rdata, error))
1932 		return FALSE;
1933 	if (rdata->version_long < 50000) {
1934 		g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_SERVER_VERSION_ERROR,
1935 			     "%s", _("Mysql version 5.0 at least is required"));
1936 		return FALSE;
1937 	}
1938 
1939 	if (!gda_holder_set_value (gda_set_get_holder (i_set, "schema"), table_schema, error))
1940 		return FALSE;
1941 	if (!gda_holder_set_value (gda_set_get_holder (i_set, "name"), table_name, error))
1942 		return FALSE;
1943 	if (!gda_holder_set_value (gda_set_get_holder (i_set, "name2"), index_name, error))
1944 		return FALSE;
1945 	model = gda_connection_statement_execute_select_full (cnc,
1946 							      internal_stmt[I_STMT_INDEX_COLUMNS_NAMED],
1947 							      i_set,
1948 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1949 							      _col_types_index_column_usage, error);
1950 
1951 	if (model == NULL)
1952 		retval = FALSE;
1953 	else {
1954 		gda_meta_store_set_reserved_keywords_func (store,
1955 							   _gda_mysql_reuseable_get_reserved_keywords_func
1956 							   ((GdaProviderReuseable*) rdata));
1957 		retval = gda_meta_store_modify_with_context (store, context, model, error);
1958 		g_object_unref (G_OBJECT(model));
1959 
1960 	}
1961 
1962 	return retval;
1963 }
1964 
1965