1 /*
2  * Copyright (C) 2009 - 2012 Vivien Malerba <malerba@gnome-db.org>
3  * Copyright (C) 2010 David King <davidk@openismus.com>
4  * Copyright (C) 2011 Murray Cumming <murrayc@murrayc.com>
5  * Copyright (C) 2012 Daniel Espinosa <despinosa@src.gnome.org>
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,
Camellia_ctr128_encrypt(const unsigned char * in,unsigned char * out,size_t length,const CAMELLIA_KEY * key,unsigned char ivec[CAMELLIA_BLOCK_SIZE],unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE],unsigned int * num)13  * 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-postgres-meta.h"
25 #include <libgda/gda-data-model-array.h>
26 #include <libgda/gda-set.h>
27 #include <libgda/gda-holder.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/gda-connection-private.h>
33 #include <libgda/providers-support/gda-meta-column-types.h>
34 #include <libgda/gda-debug-macros.h>
35 
36 #include "gda-postgres-reuseable.h"
37 #include "gda-postgres-parser.h"
38 
39 /*
40  * predefined statements' IDs
41  */
42 typedef enum {
43         I_STMT_CATALOG,
44 	I_STMT_BTYPES,
45 	I_STMT_SCHEMAS,
46 	I_STMT_SCHEMAS_ALL,
47 	I_STMT_SCHEMA_NAMED,
48 	I_STMT_TABLES,
49 	I_STMT_TABLES_ALL,
50 	I_STMT_TABLE_NAMED,
51 	I_STMT_VIEWS,
52 	I_STMT_VIEWS_ALL,
53 	I_STMT_VIEW_NAMED,
54 	I_STMT_COLUMNS_OF_TABLE,
55 	I_STMT_COLUMNS_ALL,
56 	I_STMT_TABLES_CONSTRAINTS,
57 	I_STMT_TABLES_CONSTRAINTS_ALL,
58 	I_STMT_TABLES_CONSTRAINT_NAMED,
59 	I_STMT_REF_CONSTRAINTS,
60 	I_STMT_REF_CONSTRAINTS_ALL,
61 	I_STMT_KEY_COLUMN_USAGE,
62 	I_STMT_KEY_COLUMN_USAGE_ALL,
63 	I_STMT_CHECK_COLUMN_USAGE,
64 	I_STMT_CHECK_COLUMN_USAGE_ALL,
65 	I_STMT_UDT,
66 	I_STMT_UDT_ALL,
67 	I_STMT_UDT_COLUMNS,
68 	I_STMT_UDT_COLUMNS_ALL,
69 	I_STMT_DOMAINS,
70 	I_STMT_DOMAINS_ALL,
71 	I_STMT_DOMAINS_CONSTRAINTS,
72 	I_STMT_DOMAINS_CONSTRAINTS_ALL,
73 	I_STMT_VIEWS_COLUMNS,
74 	I_STMT_VIEWS_COLUMNS_ALL,
75 	I_STMT_TRIGGERS,
76 	I_STMT_TRIGGERS_ALL,
77 	I_STMT_EL_TYPES_COL,
78 	I_STMT_EL_TYPES_DOM,
79 	I_STMT_EL_TYPES_UDT,
80 	I_STMT_EL_TYPES_ROUT_PAR,
81 	I_STMT_EL_TYPES_ROUT_COL,
82 	I_STMT_EL_TYPES_ALL,
83 	I_STMT_ROUTINES_ALL,
84 	I_STMT_ROUTINES,
85 	I_STMT_ROUTINES_ONE,
86 	I_STMT_ROUTINE_PAR_ALL,
87 	I_STMT_ROUTINE_PAR,
88 	I_STMT_ROUTINE_COL_ALL,
89 	I_STMT_ROUTINE_COL,
90 	I_STMT_INDEXES,
91 	I_STMT_INDEXES_ALL,
92 	I_STMT_INDEXES_NAMED,
93 	I_STMT_INDEXES_COLUMNS_GET_ALL_INDEXES,
94 	I_STMT_INDEXES_COLUMNS_GET_NAMED_INDEXES,
95 	I_STMT_INDEXES_COLUMNS_FOR_INDEX
96 } InternalStatementItem;
97 
98 
99 /*
100  * predefined statements' SQL
101  */
102 static gchar *internal_sql[] = {
103 	/* I_STMT_CATALOG */
104 	"SELECT pg_catalog.current_database()",
105 
106 	/* I_STMT_BTYPES */
107 	"SELECT t.typname, 'pg_catalog.' || t.typname, 'gchararray', pg_catalog.obj_description(t.oid), NULL, CASE WHEN t.typname ~ '^_' THEN TRUE WHEN typtype = 'p' THEN TRUE WHEN t.typname in ('any', 'anyarray', 'anyelement', 'cid', 'cstring', 'int2vector', 'internal', 'language_handler', 'oidvector', 'opaque', 'record', 'refcursor', 'regclass', 'regoper', 'regoperator', 'regproc', 'regprocedure', 'regtype', 'SET', 'smgr', 'tid', 'trigger', 'unknown', 'void', 'xid', 'oid', 'aclitem') THEN TRUE ELSE FALSE END, CAST (t.oid AS varchar) FROM pg_catalog.pg_type t, pg_catalog.pg_user u, pg_catalog.pg_namespace n WHERE t.typowner=u.usesysid AND n.oid = t.typnamespace AND pg_catalog.pg_type_is_visible(t.oid) AND (typtype='b' OR typtype='p') AND typelem = 0",
108 
109 	/* I_STMT_SCHEMAS */
110 	"SELECT current_database() AS catalog_name, n.nspname AS schema_name, u.rolname AS schema_owner, CASE WHEN n.nspname ~ '^pg_' THEN TRUE WHEN n.nspname = 'information_schema' THEN TRUE ELSE FALSE END, CASE WHEN n.nspname = 'public' THEN TRUE ELSE FALSE END AS schema_default FROM pg_namespace n, pg_roles u WHERE n.nspowner = u.oid AND current_database() = ##cat::string",
111 
112 	/* I_STMT_SCHEMAS_ALL */
113 	"SELECT current_database() AS catalog_name, n.nspname AS schema_name, u.rolname AS schema_owner, CASE WHEN n.nspname ~ '^pg_' THEN TRUE WHEN n.nspname = 'information_schema' THEN TRUE ELSE FALSE END, CASE WHEN n.nspname = 'public' THEN TRUE ELSE FALSE END AS schema_default FROM pg_namespace n, pg_roles u WHERE n.nspowner = u.oid",
114 
115 	/* I_STMT_SCHEMA_NAMED */
116 	"SELECT current_database() AS catalog_name, n.nspname AS schema_name, u.rolname AS schema_owner, CASE WHEN n.nspname ~ '^pg_' THEN TRUE WHEN n.nspname = 'information_schema' THEN TRUE ELSE FALSE END, CASE WHEN n.nspname = 'public' THEN TRUE ELSE FALSE END AS schema_default FROM pg_namespace n, pg_roles u WHERE n.nspowner = u.oid AND current_database() = ##cat::string AND n.nspname = ##name::string",
117 
118 	/* I_STMT_TABLES */
119 	"SELECT current_database() AS table_catalog, nc.nspname AS table_schema, c.relname AS table_name, CASE WHEN nc.oid = pg_my_temp_schema() THEN 'LOCAL TEMPORARY' WHEN c.relkind = 'r' THEN 'BASE TABLE' WHEN c.relkind = 'v' THEN 'VIEW' ELSE NULL END AS table_type, CASE WHEN c.relkind = 'r' THEN TRUE ELSE FALSE END, pg_catalog.obj_description(c.oid), CASE WHEN pg_catalog.pg_table_is_visible(c.oid) IS TRUE AND nc.nspname!='pg_catalog' THEN c.relname ELSE coalesce (nc.nspname || '.', '') || c.relname END, coalesce (nc.nspname || '.', '') || c.relname, o.rolname FROM pg_namespace nc, pg_class c, pg_roles o WHERE current_database() = ##cat::string AND nc.nspname = ##schema::string AND c.relnamespace = nc.oid AND (c.relkind = ANY (ARRAY['r', 'v'])) AND NOT pg_is_other_temp_schema(nc.oid) AND (pg_has_role(c.relowner, 'USAGE') OR has_table_privilege(c.oid, 'SELECT') OR has_table_privilege(c.oid, 'INSERT') OR has_table_privilege(c.oid, 'UPDATE') OR has_table_privilege(c.oid, 'DELETE') OR has_table_privilege(c.oid, 'REFERENCES') OR has_table_privilege(c.oid, 'TRIGGER')) AND o.oid=c.relowner",
120 
121 	/* I_STMT_TABLES_ALL */
122 	"SELECT current_database() AS table_catalog, nc.nspname AS table_schema, c.relname AS table_name, CASE WHEN nc.oid = pg_my_temp_schema() THEN 'LOCAL TEMPORARY' WHEN c.relkind = 'r' THEN 'BASE TABLE' WHEN c.relkind = 'v' THEN 'VIEW' ELSE NULL END AS table_type, CASE WHEN c.relkind = 'r' THEN TRUE ELSE FALSE END, pg_catalog.obj_description(c.oid), CASE WHEN pg_catalog.pg_table_is_visible(c.oid) IS TRUE AND nc.nspname!='pg_catalog' THEN c.relname ELSE coalesce (nc.nspname || '.', '') || c.relname END, coalesce (nc.nspname || '.', '') || c.relname, o.rolname FROM pg_namespace nc, pg_class c, pg_roles o WHERE c.relnamespace = nc.oid AND (c.relkind = ANY (ARRAY['r', 'v'])) AND NOT pg_is_other_temp_schema(nc.oid) AND (pg_has_role(c.relowner, 'USAGE') OR has_table_privilege(c.oid, 'SELECT') OR has_table_privilege(c.oid, 'INSERT') OR has_table_privilege(c.oid, 'UPDATE') OR has_table_privilege(c.oid, 'DELETE') OR has_table_privilege(c.oid, 'REFERENCES') OR has_table_privilege(c.oid, 'TRIGGER')) AND o.oid=c.relowner",
123 
124 	/* I_STMT_TABLE_NAMED */
125 	"SELECT current_database() AS table_catalog, nc.nspname AS table_schema, c.relname AS table_name, CASE WHEN nc.oid = pg_my_temp_schema() THEN 'LOCAL TEMPORARY' WHEN c.relkind = 'r' THEN 'BASE TABLE' WHEN c.relkind = 'v' THEN 'VIEW' ELSE NULL END AS table_type, CASE WHEN c.relkind = 'r' THEN TRUE ELSE FALSE END, pg_catalog.obj_description(c.oid), CASE WHEN pg_catalog.pg_table_is_visible(c.oid) IS TRUE AND nc.nspname!='pg_catalog' THEN c.relname ELSE coalesce (nc.nspname || '.', '') || c.relname END, coalesce (nc.nspname || '.', '') || c.relname, o.rolname FROM pg_namespace nc, pg_class c, pg_roles o WHERE current_database() = ##cat::string AND nc.nspname = ##schema::string AND c.relnamespace = nc.oid AND (c.relkind = ANY (ARRAY['r', 'v'])) AND NOT pg_is_other_temp_schema(nc.oid) AND (pg_has_role(c.relowner, 'USAGE') OR has_table_privilege(c.oid, 'SELECT') OR has_table_privilege(c.oid, 'INSERT') OR has_table_privilege(c.oid, 'UPDATE') OR has_table_privilege(c.oid, 'DELETE') OR has_table_privilege(c.oid, 'REFERENCES') OR has_table_privilege(c.oid, 'TRIGGER')) AND o.oid=c.relowner AND c.relname = ##name::string",
126 
127 	/* I_STMT_VIEWS */
128 	"SELECT current_database() AS table_catalog, nc.nspname AS table_schema, c.relname AS table_name, pg_catalog.pg_get_viewdef(c.oid, TRUE), NULL, CASE WHEN c.relkind = 'r' THEN TRUE ELSE FALSE END FROM pg_namespace nc, pg_class c WHERE current_database() = ##cat::string AND nc.nspname = ##schema::string AND c.relnamespace = nc.oid AND c.relkind = 'v' AND NOT pg_is_other_temp_schema(nc.oid) AND (pg_has_role(c.relowner, 'USAGE') OR has_table_privilege(c.oid, 'SELECT') OR has_table_privilege(c.oid, 'INSERT') OR has_table_privilege(c.oid, 'UPDATE') OR has_table_privilege(c.oid, 'DELETE') OR has_table_privilege(c.oid, 'REFERENCES') OR has_table_privilege(c.oid, 'TRIGGER'))",
129 
130 	/* I_STMT_VIEWS_ALL */
131 	"SELECT current_database() AS table_catalog, nc.nspname AS table_schema, c.relname AS table_name, pg_catalog.pg_get_viewdef(c.oid, TRUE), NULL, CASE WHEN c.relkind = 'r' THEN TRUE ELSE FALSE END FROM pg_namespace nc, pg_class c WHERE c.relnamespace = nc.oid AND c.relkind = 'v' AND NOT pg_is_other_temp_schema(nc.oid) AND (pg_has_role(c.relowner, 'USAGE') OR has_table_privilege(c.oid, 'SELECT') OR has_table_privilege(c.oid, 'INSERT') OR has_table_privilege(c.oid, 'UPDATE') OR has_table_privilege(c.oid, 'DELETE') OR has_table_privilege(c.oid, 'REFERENCES') OR has_table_privilege(c.oid, 'TRIGGER'))",
132 
133 	/* I_STMT_VIEW_NAMED */
134 	"SELECT current_database() AS table_catalog, nc.nspname AS table_schema, c.relname AS table_name, pg_catalog.pg_get_viewdef(c.oid, TRUE), NULL, CASE WHEN c.relkind = 'r' THEN TRUE ELSE FALSE END FROM pg_namespace nc, pg_class c WHERE current_database() = ##cat::string AND nc.nspname = ##schema::string AND c.relnamespace = nc.oid AND c.relkind = 'v' AND NOT pg_is_other_temp_schema(nc.oid) AND (pg_has_role(c.relowner, 'USAGE') OR has_table_privilege(c.oid, 'SELECT') OR has_table_privilege(c.oid, 'INSERT') OR has_table_privilege(c.oid, 'UPDATE') OR has_table_privilege(c.oid, 'DELETE') OR has_table_privilege(c.oid, 'REFERENCES') OR has_table_privilege(c.oid, 'TRIGGER')) AND c.relname = ##name::string",
135 
136 	/* I_STMT_COLUMNS_OF_TABLE */
137 	"SELECT current_database(), nc.nspname, c.relname, a.attname, a.attnum, pg_get_expr(ad.adbin, ad.adrelid), CASE WHEN a.attnotnull OR t.typtype = 'd' AND t.typnotnull THEN FALSE ELSE TRUE END, CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN NULL ELSE coalesce (nt.nspname || '.', '') || t.typname END, CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN 'COL' || current_database() || '.' || nc.nspname || '.' || c.relname || '.' || a.attnum ELSE NULL END, 'gchararray', information_schema._pg_char_max_length(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_char_octet_length(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_numeric_precision(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_numeric_scale(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_datetime_precision(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), NULL, NULL, NULL, NULL, NULL, NULL, CASE WHEN pg_get_expr(ad.adbin, ad.adrelid) LIKE 'nextval(%' THEN '" GDA_EXTRA_AUTO_INCREMENT "' ELSE NULL END, CASE WHEN c.relkind = 'r' THEN TRUE ELSE FALSE END, pg_catalog.col_description(c.oid, a.attnum), CAST (t.oid AS varchar) FROM pg_attribute a LEFT JOIN pg_attrdef ad ON a.attrelid = ad.adrelid AND a.attnum = ad.adnum, pg_class c, pg_namespace nc, pg_type t JOIN pg_namespace nt ON t.typnamespace = nt.oid LEFT JOIN (pg_type bt JOIN pg_namespace nbt ON bt.typnamespace = nbt.oid) ON t.typtype = 'd' AND t.typbasetype = bt.oid WHERE current_database() = ##cat::string AND nc.nspname = ##schema::string AND c.relname = ##name::string AND a.attrelid = c.oid AND a.atttypid = t.oid AND nc.oid = c.relnamespace AND NOT pg_is_other_temp_schema(nc.oid) AND a.attnum > 0 AND NOT a.attisdropped AND (c.relkind = ANY (ARRAY['r', 'v'])) AND (pg_has_role(c.relowner, 'USAGE') OR has_table_privilege(c.oid, 'SELECT') OR has_table_privilege(c.oid, 'INSERT') OR has_table_privilege(c.oid, 'UPDATE') OR has_table_privilege(c.oid, 'REFERENCES'))",
138 
139 	/* I_STMT_COLUMNS_ALL */
140 	"SELECT current_database(), nc.nspname, c.relname, a.attname, a.attnum, pg_get_expr(ad.adbin, ad.adrelid), CASE WHEN a.attnotnull OR t.typtype = 'd' AND t.typnotnull THEN FALSE ELSE TRUE END, CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN NULL ELSE coalesce (nt.nspname || '.', '') || t.typname END, CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN 'COL' || current_database() || '.' || nc.nspname || '.' || c.relname || '.' || a.attnum ELSE NULL END, 'gchararray', information_schema._pg_char_max_length(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_char_octet_length(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_numeric_precision(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_numeric_scale(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_datetime_precision(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), NULL, NULL, NULL, NULL, NULL, NULL, CASE WHEN pg_get_expr(ad.adbin, ad.adrelid) LIKE 'nextval(%' THEN '" GDA_EXTRA_AUTO_INCREMENT "' ELSE NULL END, CASE WHEN c.relkind = 'r' THEN TRUE ELSE FALSE END, pg_catalog.col_description(c.oid, a.attnum), CAST (t.oid AS varchar) FROM pg_attribute a LEFT JOIN pg_attrdef ad ON a.attrelid = ad.adrelid AND a.attnum = ad.adnum, pg_class c, pg_namespace nc, pg_type t JOIN pg_namespace nt ON t.typnamespace = nt.oid LEFT JOIN (pg_type bt JOIN pg_namespace nbt ON bt.typnamespace = nbt.oid) ON t.typtype = 'd' AND t.typbasetype = bt.oid WHERE a.attrelid = c.oid AND a.atttypid = t.oid AND nc.oid = c.relnamespace AND NOT pg_is_other_temp_schema(nc.oid) AND a.attnum > 0 AND NOT a.attisdropped AND (c.relkind = ANY (ARRAY['r', 'v'])) AND (pg_has_role(c.relowner, 'USAGE') OR has_table_privilege(c.oid, 'SELECT') OR has_table_privilege(c.oid, 'INSERT') OR has_table_privilege(c.oid, 'UPDATE') OR has_table_privilege(c.oid, 'REFERENCES'))",
141 
142 	/* I_STMT_TABLES_CONSTRAINTS */
143 	"SELECT current_database() AS constraint_catalog, nc.nspname AS constraint_schema, c.conname AS constraint_name, current_database() AS table_catalog, nr.nspname AS table_schema, r.relname AS table_name, CASE c.contype WHEN 'c' THEN 'CHECK' WHEN 'f' THEN 'FOREIGN KEY' WHEN 'p' THEN 'PRIMARY KEY' WHEN 'u' THEN 'UNIQUE' ELSE NULL END AS constraint_type, CASE c.contype WHEN 'c' THEN c.consrc ELSE NULL END, CASE WHEN c.condeferrable THEN TRUE ELSE FALSE END AS is_deferrable, CASE WHEN c.condeferred THEN TRUE ELSE FALSE END AS initially_deferred FROM pg_namespace nc, pg_namespace nr, pg_constraint c, pg_class r WHERE nc.oid = c.connamespace AND nr.oid = r.relnamespace AND c.conrelid = r.oid AND r.relkind = 'r' AND NOT pg_is_other_temp_schema(nr.oid) AND (pg_has_role(r.relowner, 'USAGE') OR has_table_privilege(r.oid, 'INSERT') OR has_table_privilege(r.oid, 'UPDATE') OR has_table_privilege(r.oid, 'DELETE') OR has_table_privilege(r.oid, 'REFERENCES') OR has_table_privilege(r.oid, 'TRIGGER')) AND current_database() = ##cat::string AND nr.nspname = ##schema::string AND r.relname = ##name::string "
144 	"UNION SELECT current_database() AS constraint_catalog, nr.nspname AS constraint_schema, (((((nr.oid || '_') || r.oid) || '_') || a.attnum) || '_not_null') AS constraint_name, current_database() AS table_catalog, nr.nspname AS table_schema, r.relname AS table_name, 'CHECK' AS constraint_type, a.attname || ' IS NOT NULL', FALSE AS is_deferrable, FALSE AS initially_deferred FROM pg_namespace nr, pg_class r, pg_attribute a WHERE nr.oid = r.relnamespace AND r.oid = a.attrelid AND a.attnotnull AND a.attnum > 0 AND NOT a.attisdropped AND r.relkind = 'r' AND NOT pg_is_other_temp_schema(nr.oid) AND (pg_has_role(r.relowner, 'USAGE') OR has_table_privilege(r.oid, 'SELECT') OR has_table_privilege(r.oid, 'INSERT') OR has_table_privilege(r.oid, 'UPDATE') OR has_table_privilege(r.oid, 'DELETE') OR has_table_privilege(r.oid, 'REFERENCES') OR has_table_privilege(r.oid, 'TRIGGER')) AND current_database() = ##cat::string AND nr.nspname = ##schema::string AND r.relname = ##name::string",
145 
146 	/* I_STMT_TABLES_CONSTRAINTS_ALL */
147 	"SELECT current_database() AS constraint_catalog, nc.nspname AS constraint_schema, c.conname AS constraint_name, current_database() AS table_catalog, nr.nspname AS table_schema, r.relname AS table_name, CASE c.contype WHEN 'c' THEN 'CHECK' WHEN 'f' THEN 'FOREIGN KEY' WHEN 'p' THEN 'PRIMARY KEY' WHEN 'u' THEN 'UNIQUE' ELSE NULL END AS constraint_type, CASE c.contype WHEN 'c' THEN c.consrc ELSE NULL END, CASE WHEN c.condeferrable THEN TRUE ELSE FALSE END AS is_deferrable, CASE WHEN c.condeferred THEN TRUE ELSE FALSE END AS initially_deferred FROM pg_namespace nc, pg_namespace nr, pg_constraint c, pg_class r WHERE nc.oid = c.connamespace AND nr.oid = r.relnamespace AND c.conrelid = r.oid AND r.relkind = 'r' AND NOT pg_is_other_temp_schema(nr.oid) AND (pg_has_role(r.relowner, 'USAGE') OR has_table_privilege(r.oid, 'INSERT') OR has_table_privilege(r.oid, 'UPDATE') OR has_table_privilege(r.oid, 'DELETE') OR has_table_privilege(r.oid, 'REFERENCES') OR has_table_privilege(r.oid, 'TRIGGER')) "
148 	"UNION SELECT current_database() AS constraint_catalog, nr.nspname AS constraint_schema, (((((nr.oid || '_') || r.oid) || '_') || a.attnum) || '_not_null') AS constraint_name, current_database() AS table_catalog, nr.nspname AS table_schema, r.relname AS table_name, 'CHECK' AS constraint_type, a.attname || ' IS NOT NULL', FALSE AS is_deferrable, FALSE AS initially_deferred FROM pg_namespace nr, pg_class r, pg_attribute a WHERE nr.oid = r.relnamespace AND r.oid = a.attrelid AND a.attnotnull AND a.attnum > 0 AND NOT a.attisdropped AND r.relkind = 'r' AND NOT pg_is_other_temp_schema(nr.oid) AND (pg_has_role(r.relowner, 'USAGE') OR has_table_privilege(r.oid, 'SELECT') OR has_table_privilege(r.oid, 'INSERT') OR has_table_privilege(r.oid, 'UPDATE') OR has_table_privilege(r.oid, 'DELETE') OR has_table_privilege(r.oid, 'REFERENCES') OR has_table_privilege(r.oid, 'TRIGGER'))",
149 
150 	/* I_STMT_TABLES_CONSTRAINT_NAMED */
151 	"SELECT constraint_catalog, constraint_schema, constraint_name, table_catalog, table_schema, table_name, constraint_type, NULL, CASE WHEN is_deferrable = 'YES' THEN TRUE ELSE FALSE END, CASE WHEN initially_deferred = 'YES' THEN TRUE ELSE FALSE END FROM information_schema.table_constraints WHERE table_catalog = ##cat::string AND table_schema = ##schema::string AND table_name = ##name::string AND constraint_name = ##name2::string",
152 
153 	/* I_STMT_REF_CONSTRAINTS */
154 	"SELECT current_database(), nt.nspname, t.relname, c.conname, current_database(), nref.nspname, ref.relname, pkc.conname, CASE c.confmatchtype WHEN 'f' THEN 'FULL' WHEN 'p' THEN 'PARTIAL' WHEN 'u' THEN 'NONE' ELSE NULL END AS match_option, CASE c.confupdtype WHEN 'c' THEN 'CASCADE' WHEN 'n' THEN 'SET NULL' WHEN 'd' THEN 'SET DEFAULT' WHEN 'r' THEN 'RESTRICT' WHEN 'a' THEN 'NO ACTION' ELSE NULL END AS update_rule, CASE c.confdeltype WHEN 'c' THEN 'CASCADE' WHEN 'n' THEN 'SET NULL' WHEN 'd' THEN 'SET DEFAULT' WHEN 'r' THEN 'RESTRICT' WHEN 'a' THEN 'NO ACTION' ELSE NULL END AS delete_rule FROM pg_constraint c INNER JOIN pg_class t ON (c.conrelid=t.oid) INNER JOIN pg_namespace nt ON (nt.oid=t.relnamespace) INNER JOIN pg_class ref ON (c.confrelid=ref.oid) INNER JOIN pg_namespace nref ON (nref.oid=ref.relnamespace) INNER JOIN pg_constraint pkc ON (c.confrelid = pkc.conrelid AND information_schema._pg_keysequal(c.confkey, pkc.conkey) AND pkc.contype='p') WHERE c.contype = 'f' AND current_database() = ##cat::string AND nt.nspname = ##schema::string AND t.relname = ##name::string AND c.conname = ##name2::string",
155 
156 	/* I_STMT_REF_CONSTRAINTS_ALL */
157 	"SELECT current_database(), nt.nspname, t.relname, c.conname, current_database(), nref.nspname, ref.relname, pkc.conname, CASE c.confmatchtype WHEN 'f' THEN 'FULL' WHEN 'p' THEN 'PARTIAL' WHEN 'u' THEN 'NONE' ELSE NULL END AS match_option, CASE c.confupdtype WHEN 'c' THEN 'CASCADE' WHEN 'n' THEN 'SET NULL' WHEN 'd' THEN 'SET DEFAULT' WHEN 'r' THEN 'RESTRICT' WHEN 'a' THEN 'NO ACTION' ELSE NULL END AS update_rule, CASE c.confdeltype WHEN 'c' THEN 'CASCADE' WHEN 'n' THEN 'SET NULL' WHEN 'd' THEN 'SET DEFAULT' WHEN 'r' THEN 'RESTRICT' WHEN 'a' THEN 'NO ACTION' ELSE NULL END AS delete_rule FROM pg_constraint c INNER JOIN pg_class t ON (c.conrelid=t.oid) INNER JOIN pg_namespace nt ON (nt.oid=t.relnamespace) INNER JOIN pg_class ref ON (c.confrelid=ref.oid) INNER JOIN pg_namespace nref ON (nref.oid=ref.relnamespace) INNER JOIN pg_constraint pkc ON (c.confrelid = pkc.conrelid AND information_schema._pg_keysequal(c.confkey, pkc.conkey) AND pkc.contype='p') WHERE c.contype = 'f'",
158 
159 	/* I_STMT_KEY_COLUMN_USAGE */
160 	"SELECT table_catalog, table_schema, table_name, constraint_name, column_name, ordinal_position FROM information_schema.key_column_usage WHERE table_catalog = ##cat::string AND table_schema = ##schema::string AND table_name = ##name::string AND constraint_name = ##name2::string",
161 
162 	/* I_STMT_KEY_COLUMN_USAGE_ALL */
163 	"SELECT table_catalog, table_schema, table_name, constraint_name, column_name, ordinal_position FROM information_schema.key_column_usage",
164 
165 	/* I_STMT_CHECK_COLUMN_USAGE */
166 	"SELECT current_database() AS table_catalog, nr.nspname AS table_schema, r.relname AS table_name, c.conname AS constraint_name,a.attname FROM pg_namespace nc, pg_namespace nr, pg_constraint c, pg_class r, pg_attribute a, (SELECT sc.oid, information_schema._pg_expandarray (sc.conkey) as x FROM pg_constraint sc WHERE sc.contype = 'c') ss WHERE nc.oid = c.connamespace AND nr.oid = r.relnamespace AND c.conrelid = r.oid AND r.relkind = 'r' AND NOT pg_is_other_temp_schema(nr.oid) AND (pg_has_role(r.relowner, 'USAGE') OR has_table_privilege(r.oid, 'INSERT') OR has_table_privilege(r.oid, 'UPDATE') OR has_table_privilege(r.oid, 'DELETE') OR has_table_privilege(r.oid, 'REFERENCES') OR has_table_privilege(r.oid, 'TRIGGER')) AND c.contype = 'c' AND ss.oid = c.oid AND a.attrelid = r.oid AND a.attnum = (ss.x).x AND current_database() = ##cat::string AND nr.nspname = ##schema::string AND r.relname = ##name::string AND c.conname = ##name2::string "
167 	"UNION SELECT current_database() AS table_catalog, nr.nspname AS table_schema, r.relname AS table_name, (((((nr.oid || '_') || r.oid) || '_') || a.attnum) || '_not_null') AS constraint_name, a.attname FROM pg_namespace nr, pg_class r, pg_attribute a WHERE nr.oid = r.relnamespace AND r.oid = a.attrelid AND a.attnotnull AND a.attnum > 0 AND NOT a.attisdropped AND r.relkind = 'r' AND NOT pg_is_other_temp_schema(nr.oid) AND (pg_has_role(r.relowner, 'USAGE') OR has_table_privilege(r.oid, 'SELECT') OR has_table_privilege(r.oid, 'INSERT') OR has_table_privilege(r.oid, 'UPDATE') OR has_table_privilege(r.oid, 'DELETE') OR has_table_privilege(r.oid, 'REFERENCES') OR has_table_privilege(r.oid, 'TRIGGER')) AND current_database() = ##cat::string AND nr.nspname = ##schema::string AND r.relname = ##name::string AND (((((nr.oid || '_') || r.oid) || '_') || a.attnum) || '_not_null') = ##name2::string",
168 
169 	/* I_STMT_CHECK_COLUMN_USAGE_ALL */
170 	"SELECT current_database() AS table_catalog, nr.nspname AS table_schema, r.relname AS table_name, c.conname AS constraint_name,a.attname FROM pg_namespace nc, pg_namespace nr, pg_constraint c, pg_class r, pg_attribute a, (SELECT sc.oid, information_schema._pg_expandarray (sc.conkey) as x FROM pg_constraint sc WHERE sc.contype = 'c') ss WHERE nc.oid = c.connamespace AND nr.oid = r.relnamespace AND c.conrelid = r.oid AND r.relkind = 'r' AND NOT pg_is_other_temp_schema(nr.oid) AND (pg_has_role(r.relowner, 'USAGE') OR has_table_privilege(r.oid, 'INSERT') OR has_table_privilege(r.oid, 'UPDATE') OR has_table_privilege(r.oid, 'DELETE') OR has_table_privilege(r.oid, 'REFERENCES') OR has_table_privilege(r.oid, 'TRIGGER')) AND c.contype = 'c' AND ss.oid = c.oid AND a.attrelid = r.oid AND a.attnum = (ss.x).x "
171 	"UNION SELECT current_database() AS table_catalog, nr.nspname AS table_schema, r.relname AS table_name, (((((nr.oid || '_') || r.oid) || '_') || a.attnum) || '_not_null') AS constraint_name, a.attname FROM pg_namespace nr, pg_class r, pg_attribute a WHERE nr.oid = r.relnamespace AND r.oid = a.attrelid AND a.attnotnull AND a.attnum > 0 AND NOT a.attisdropped AND r.relkind = 'r' AND NOT pg_is_other_temp_schema(nr.oid) AND (pg_has_role(r.relowner, 'USAGE') OR has_table_privilege(r.oid, 'SELECT') OR has_table_privilege(r.oid, 'INSERT') OR has_table_privilege(r.oid, 'UPDATE') OR has_table_privilege(r.oid, 'DELETE') OR has_table_privilege(r.oid, 'REFERENCES') OR has_table_privilege(r.oid, 'TRIGGER'))",
172 
173 	/* I_STMT_UDT */
174 	"SELECT pg_catalog.current_database() as cat, n.nspname, t.typname, 'gchararray', pg_catalog.obj_description(t.oid), CASE WHEN pg_catalog.pg_type_is_visible(t.oid) IS TRUE THEN t.typname ELSE coalesce (n.nspname || '.', '') || t.typname END, coalesce (n.nspname || '.', '') || t.typname, CASE WHEN t.typname ~ '^_' THEN TRUE WHEN t.typname in ('any', 'anyarray', 'anyelement', 'cid', 'cstring', 'int2vector', 'internal', 'language_handler', 'oidvector', 'opaque', 'record', 'refcursor', 'regclass', 'regoper', 'regoperator', 'regproc', 'regprocedure', 'regtype', 'SET', 'smgr', 'tid', 'trigger', 'unknown', 'void', 'xid', 'oid', 'aclitem') THEN TRUE ELSE FALSE END, o.rolname FROM pg_catalog.pg_type t, pg_catalog.pg_user u, pg_catalog.pg_namespace n , pg_roles o WHERE t.typowner=u.usesysid AND n.oid = t.typnamespace AND pg_catalog.pg_type_is_visible(t.oid) AND (t.typrelid != 0 AND (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid)) AND o.oid=t.typowner AND pg_catalog.current_database() = ##cat::string AND n.nspname = ##schema::string",
175 
176 	/* I_STMT_UDT_ALL */
177 	"SELECT pg_catalog.current_database(), n.nspname, t.typname, 'gchararray', pg_catalog.obj_description(t.oid), CASE WHEN pg_catalog.pg_type_is_visible(t.oid) IS TRUE THEN t.typname ELSE coalesce (n.nspname || '.', '') || t.typname END, coalesce (n.nspname || '.', '') || t.typname, CASE WHEN t.typname ~ '^_' THEN TRUE WHEN t.typname in ('any', 'anyarray', 'anyelement', 'cid', 'cstring', 'int2vector', 'internal', 'language_handler', 'oidvector', 'opaque', 'record', 'refcursor', 'regclass', 'regoper', 'regoperator', 'regproc', 'regprocedure', 'regtype', 'SET', 'smgr', 'tid', 'trigger', 'unknown', 'void', 'xid', 'oid', 'aclitem') THEN TRUE ELSE FALSE END, o.rolname FROM pg_catalog.pg_type t, pg_catalog.pg_user u, pg_catalog.pg_namespace n , pg_roles o WHERE t.typowner=u.usesysid AND n.oid = t.typnamespace AND pg_catalog.pg_type_is_visible(t.oid) AND (t.typrelid != 0 AND (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid)) AND o.oid=t.typowner",
178 
179 	/* I_STMT_UDT_COLUMNS */
180 	"select pg_catalog.current_database(), n.nspname, udt.typname, a.attname, a.attnum, CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN NULL ELSE coalesce (nt.nspname || '.', '') || t.typname END, CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN 'UDT' || current_database() || '.' || n.nspname || '.' || udt.typname || '.' || a.attnum ELSE NULL END, information_schema._pg_char_max_length(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_char_octet_length(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_numeric_precision(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_numeric_scale(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_datetime_precision(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), NULL, NULL , NULL, NULL, NULL, NULL FROM pg_type udt INNER JOIN pg_namespace n ON (udt.typnamespace=n.oid) INNER JOIN pg_attribute a ON (a.attrelid=udt.typrelid) INNER JOIN pg_type t ON (a.atttypid=t.oid) INNER JOIN pg_namespace nt ON (t.typnamespace = nt.oid) WHERE udt.typrelid != 0 AND (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = udt.typrelid) AND pg_catalog.current_database() = ##cat::string AND n.nspname = ##schema::string AND udt.typname = ##name::string",
181 
182 	/* I_STMT_UDT_COLUMNS_ALL */
183 	"select pg_catalog.current_database(), n.nspname, udt.typname, a.attname, a.attnum, CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN NULL ELSE coalesce (nt.nspname || '.', '') || t.typname END, CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN 'UDT' || current_database() || '.' || n.nspname || '.' || udt.typname || '.' || a.attnum ELSE NULL END, information_schema._pg_char_max_length(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_char_octet_length(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_numeric_precision(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_numeric_scale(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_datetime_precision(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), NULL, NULL , NULL, NULL, NULL, NULL FROM pg_type udt INNER JOIN pg_namespace n ON (udt.typnamespace=n.oid) INNER JOIN pg_attribute a ON (a.attrelid=udt.typrelid) INNER JOIN pg_type t ON (a.atttypid=t.oid) INNER JOIN pg_namespace nt ON (t.typnamespace = nt.oid) WHERE udt.typrelid != 0 AND (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = udt.typrelid)",
184 
185 	/* I_STMT_DOMAINS */
186 	"SELECT pg_catalog.current_database(), nt.nspname, t.typname, CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN NULL ELSE coalesce (nbt.nspname || '.', '') || bt.typname END, CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN 'DOM' || current_database() || '.' || nt.nspname || '.' || t.typname ELSE NULL END, 'gchararray', information_schema._pg_char_max_length(t.typbasetype, t.typtypmod), information_schema._pg_char_octet_length(t.typbasetype, t.typtypmod),  NULL, NULL, NULL, NULL, NULL, NULL,  information_schema._pg_numeric_precision(t.typbasetype, t.typtypmod), information_schema._pg_numeric_scale(t.typbasetype, t.typtypmod), t.typdefault, pg_catalog.obj_description(t.oid), CASE WHEN pg_catalog.pg_type_is_visible(t.oid) IS TRUE THEN t.typname ELSE coalesce (nt.nspname || '.', '') || t.typname END, coalesce (nt.nspname || '.', '') || t.typname, FALSE, o.rolname FROM pg_type t, pg_namespace nt, pg_type bt, pg_namespace nbt, pg_roles o WHERE t.typnamespace = nt.oid AND t.typbasetype = bt.oid AND bt.typnamespace = nbt.oid AND t.typtype = 'd' AND o.oid=t.typowner AND pg_catalog.current_database() = ##cat::string AND nt.nspname = ##schema::string",
187 
188 	/* I_STMT_DOMAINS_ALL */
189 	"SELECT pg_catalog.current_database(), nt.nspname, t.typname, CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN NULL ELSE coalesce (nbt.nspname || '.', '') || bt.typname END, CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN 'DOM' || current_database() || '.' || nt.nspname || '.' || t.typname ELSE NULL END, 'gchararray', information_schema._pg_char_max_length(t.typbasetype, t.typtypmod), information_schema._pg_char_octet_length(t.typbasetype, t.typtypmod),  NULL, NULL, NULL, NULL, NULL, NULL,  information_schema._pg_numeric_precision(t.typbasetype, t.typtypmod), information_schema._pg_numeric_scale(t.typbasetype, t.typtypmod), t.typdefault, pg_catalog.obj_description(t.oid), CASE WHEN pg_catalog.pg_type_is_visible(t.oid) IS TRUE THEN t.typname ELSE coalesce (nt.nspname || '.', '') || t.typname END, coalesce (nt.nspname || '.', '') || t.typname, FALSE, o.rolname FROM pg_type t, pg_namespace nt, pg_type bt, pg_namespace nbt, pg_roles o WHERE t.typnamespace = nt.oid AND t.typbasetype = bt.oid AND bt.typnamespace = nbt.oid AND t.typtype = 'd' AND o.oid=t.typowner",
190 
191 	/* I_STMT_DOMAINS_CONSTRAINTS */
192 	"SELECT constraint_catalog, constraint_schema, constraint_name, domain_catalog, domain_schema, domain_name, NULL, CASE WHEN is_deferrable = 'YES' THEN TRUE ELSE FALSE END, CASE WHEN initially_deferred = 'YES' THEN TRUE ELSE FALSE END FROM information_schema.domain_constraints WHERE domain_catalog = ##cat::string AND domain_schema = ##schema::string AND domain_name = ##name::string",
193 
194 	/* I_STMT_DOMAINS_CONSTRAINTS_ALL */
195 	"SELECT constraint_catalog, constraint_schema, constraint_name, domain_catalog, domain_schema, domain_name, NULL, CASE WHEN is_deferrable = 'YES' THEN TRUE ELSE FALSE END, CASE WHEN initially_deferred = 'YES' THEN TRUE ELSE FALSE END FROM information_schema.domain_constraints",
196 
197 	/* I_STMT_VIEWS_COLUMNS */
198 	"SELECT view_catalog, view_schema, view_name, table_catalog, table_schema, table_name, column_name FROM information_schema.view_column_usage WHERE view_catalog = ##cat::string AND view_schema = ##schema::string AND view_name = ##name::string",
199 
200 	/* I_STMT_VIEWS_COLUMNS_ALL */
201 	"SELECT view_catalog, view_schema, view_name, table_catalog, table_schema, table_name, column_name FROM information_schema.view_column_usage",
202 
203 	/* I_STMT_TRIGGERS */
204 	"SELECT current_database(), n.nspname, t.tgname, em.text, current_database(), n.nspname, c.relname, \"substring\"(pg_get_triggerdef(t.oid), \"position\"(\"substring\"(pg_get_triggerdef(t.oid), 48), 'EXECUTE PROCEDURE') + 47) AS action_statement, CASE WHEN (t.tgtype & 1) = 1 THEN 'ROW' ELSE 'STATEMENT' END AS action_orientation, CASE WHEN (t.tgtype & 2) = 2 THEN 'BEFORE' ELSE 'AFTER' END AS condition_timing, pg_catalog.obj_description(t.oid), t.tgname, t.tgname FROM pg_namespace n, pg_class c, pg_trigger t, (( SELECT 4, 'INSERT' UNION ALL SELECT 8, 'DELETE') UNION ALL SELECT 16, 'UPDATE') em(num, text) WHERE n.oid = c.relnamespace AND c.oid = t.tgrelid AND (t.tgtype & em.num) <> 0 AND (t.tgconstraint = 0) AND NOT pg_is_other_temp_schema(n.oid) AND (pg_has_role(c.relowner, 'USAGE') OR has_table_privilege(c.oid, 'INSERT') OR has_table_privilege(c.oid, 'UPDATE') OR has_table_privilege(c.oid, 'DELETE') OR has_table_privilege(c.oid, 'REFERENCES') OR has_table_privilege(c.oid, 'TRIGGER')) AND current_database() = ##cat::string AND n.nspname = ##schema::string AND c.relname = ##name::string",
205 
206 	/* I_STMT_TRIGGERS_ALL */
207 	"SELECT current_database(), n.nspname, t.tgname, em.text, current_database(), n.nspname, c.relname, \"substring\"(pg_get_triggerdef(t.oid), \"position\"(\"substring\"(pg_get_triggerdef(t.oid), 48), 'EXECUTE PROCEDURE') + 47) AS action_statement, CASE WHEN (t.tgtype & 1) = 1 THEN 'ROW' ELSE 'STATEMENT' END AS action_orientation, CASE WHEN (t.tgtype & 2) = 2 THEN 'BEFORE' ELSE 'AFTER' END AS condition_timing, pg_catalog.obj_description(t.oid), t.tgname, t.tgname FROM pg_namespace n, pg_class c, pg_trigger t, (( SELECT 4, 'INSERT' UNION ALL SELECT 8, 'DELETE') UNION ALL SELECT 16, 'UPDATE') em(num, text) WHERE n.oid = c.relnamespace AND c.oid = t.tgrelid AND (t.tgtype & em.num) <> 0 AND NOT (t.tgconstraint = 0) AND NOT pg_is_other_temp_schema(n.oid) AND (pg_has_role(c.relowner, 'USAGE') OR has_table_privilege(c.oid, 'INSERT') OR has_table_privilege(c.oid, 'UPDATE') OR has_table_privilege(c.oid, 'DELETE') OR has_table_privilege(c.oid, 'REFERENCES') OR has_table_privilege(c.oid, 'TRIGGER'))",
208 
209 	/* I_STMT_EL_TYPES_COL */
210 	"SELECT 'COL' || current_database() || '.' || nc.nspname || '.' || c.relname || '.' || a.attnum, current_database(), nc.nspname, c.relname, 'TABLE_COL', coalesce (nbt.nspname || '.', '') || bt.typname, NULL, NULL, NULL FROM pg_attribute a, pg_class c, pg_namespace nc, pg_type t JOIN pg_namespace nt ON t.typnamespace = nt.oid LEFT JOIN (pg_type bt JOIN pg_namespace nbt ON bt.typnamespace = nbt.oid) ON t.typelem = bt.oid WHERE a.attrelid = c.oid AND a.atttypid = t.oid AND nc.oid = c.relnamespace AND NOT pg_is_other_temp_schema(nc.oid) AND a.attnum > 0 AND NOT a.attisdropped AND (c.relkind = ANY (ARRAY['r', 'v'])) AND (pg_has_role(c.relowner, 'USAGE') OR has_table_privilege(c.oid, 'SELECT') OR has_table_privilege(c.oid, 'INSERT') OR has_table_privilege(c.oid, 'UPDATE') OR has_table_privilege(c.oid, 'REFERENCES')) AND t.typelem <> 0 AND t.typlen = -1 AND 'COL' || current_database() || '.' || nc.nspname || '.' || c.relname || '.' || a.attnum = ##name::string",
211 
212 	/* I_STMT_EL_TYPES_DOM */
213 	"SELECT 'DOM' || current_database() || '.' || nt.nspname || '.' || t.typname, current_database(), nt.nspname, t.typname, 'DOMAIN', coalesce (nbt.nspname || '.', '') || bt.typname, NULL, NULL, NULL FROM pg_type t, pg_namespace nt, pg_type bt, pg_namespace nbt WHERE t.typnamespace = nt.oid AND t.typelem = bt.oid AND bt.typnamespace = nbt.oid AND t.typtype = 'd' AND t.typlen = -1 AND 'DOM' || current_database() || '.' || nt.nspname || '.' || t.typname = ##name::string",
214 
215 	/* I_STMT_EL_TYPES_UDT */
216 	"SELECT 'UDT' || current_database() || '.' || n.nspname || '.' || udt.typname || '.' || a.attnum, pg_catalog.current_database(), n.nspname, udt.typname, 'UDT_COL', coalesce (nbt.nspname || '.', '') || bt.typname, NULL, NULL, NULL FROM pg_type udt INNER JOIN pg_namespace n ON (udt.typnamespace=n.oid) INNER JOIN pg_attribute a ON (a.attrelid=udt.typrelid) INNER JOIN pg_type t ON (a.atttypid=t.oid) INNER JOIN pg_namespace nt ON (t.typnamespace = nt.oid), pg_type bt, pg_namespace nbt where udt.typrelid != 0 AND (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = udt.typrelid) AND t.typelem = bt.oid AND bt.typnamespace = nbt.oid AND t.typlen = -1 AND 'UDT' || current_database() || '.' || n.nspname || '.' || udt.typname || '.' || a.attnum = ##name::string",
217 
218 	/* I_STMT_EL_TYPES_ROUT_PAR */
219 	"SELECT 'ROUP' || current_database() || '.' || ss.n_nspname || '.' || ((ss.proname || '_') || ss.p_oid) || '.' || (ss.x).n, current_database(), ss.n_nspname, ((ss.proname || '_') || ss.p_oid), 'ROUTINE_PAR', coalesce (nbt.nspname || '.', '') || bt.typname, NULL, NULL, NULL FROM pg_type t, pg_type bt, pg_namespace nbt, ( SELECT n.nspname AS n_nspname, p.proname, p.oid AS p_oid, p.proargnames, p.proargmodes, information_schema._pg_expandarray(COALESCE(p.proallargtypes, p.proargtypes::oid[])) AS x FROM pg_namespace n, pg_proc p WHERE n.oid = p.pronamespace AND (pg_has_role(p.proowner, 'USAGE') OR has_function_privilege(p.oid, 'EXECUTE'))) ss WHERE t.oid = (ss.x).x AND bt.oid= t.typelem AND bt.typnamespace = nbt.oid AND t.typelem <> 0 AND t.typlen = -1 AND 'ROUP' || current_database() || '.' || ss.n_nspname || '.' || ((ss.proname || '_') || ss.p_oid) || '.' || (ss.x).n = ##name::string",
220 
221 	/* I_STMT_EL_TYPES_ROUT_COL */
222 	"SELECT 'ROUC' || current_database() || '.' || ss.n_nspname || '.' || ((ss.proname || '_') || ss.p_oid) || '.' || (ss.x).n, current_database(), ss.n_nspname, ((ss.proname || '_') || ss.p_oid), 'ROUTINE_COL', CASE WHEN at.typelem <> 0 AND at.typlen = -1 THEN 'array_spec' ELSE coalesce (ant.nspname || '.', '') || at.typname END, CASE WHEN at.typelem <> 0 AND at.typlen = -1 THEN 'ARR' || at.typelem ELSE NULL END, NULL, NULL FROM pg_type t, pg_namespace nt, ( SELECT n.nspname AS n_nspname, p.proname, p.oid AS p_oid, p.proargnames, p.proargmodes, information_schema._pg_expandarray(COALESCE(p.proallargtypes, p.proargtypes::oid[])) AS x FROM pg_namespace n, pg_proc p WHERE n.oid = p.pronamespace AND (pg_has_role(p.proowner, 'USAGE') OR has_function_privilege(p.oid, 'EXECUTE'))) ss, pg_type at, pg_namespace ant WHERE t.oid = (ss.x).x AND t.typnamespace = nt.oid AND at.oid = t.typelem AND at.typnamespace = ant.oid AND (ss.proargmodes[(ss.x).n] = 'o' OR ss.proargmodes[(ss.x).n] = 'b') AND 'ROUC' || current_database() || '.' || ss.n_nspname || '.' || ((ss.proname || '_') || ss.p_oid) || '.' || (ss.x).n = ##name::string",
223 
224 	/* I_STMT_EL_TYPES_ALL */
225 	"SELECT 'UDT' || current_database() || '.' || n.nspname || '.' || udt.typname || '.' || a.attnum, pg_catalog.current_database(), n.nspname, udt.typname, 'UDT_COL', coalesce (nbt.nspname || '.', '') || bt.typname, NULL, NULL, NULL FROM pg_type udt INNER JOIN pg_namespace n ON (udt.typnamespace=n.oid) INNER JOIN pg_attribute a ON (a.attrelid=udt.typrelid) INNER JOIN pg_type t ON (a.atttypid=t.oid) INNER JOIN pg_namespace nt ON (t.typnamespace = nt.oid), pg_type bt, pg_namespace nbt where udt.typrelid != 0 AND (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = udt.typrelid) AND t.typelem = bt.oid AND bt.typnamespace = nbt.oid AND t.typlen = -1 "
226 	"UNION SELECT 'DOM' || current_database() || '.' || nt.nspname || '.' || t.typname, current_database(), nt.nspname, t.typname, 'DOMAIN', coalesce (nbt.nspname || '.', '') || bt.typname, NULL, NULL, NULL FROM pg_type t, pg_namespace nt, pg_type bt, pg_namespace nbt WHERE t.typnamespace = nt.oid AND t.typelem = bt.oid AND bt.typnamespace = nbt.oid AND t.typtype = 'd' AND t.typlen = -1 "
227 	"UNION SELECT 'COL' || current_database() || '.' || nc.nspname || '.' || c.relname || '.' || a.attnum, current_database(), nc.nspname, c.relname, 'TABLE_COL', coalesce (nbt.nspname || '.', '') || bt.typname, NULL, NULL, NULL FROM pg_attribute a, pg_class c, pg_namespace nc, pg_type t JOIN pg_namespace nt ON t.typnamespace = nt.oid LEFT JOIN (pg_type bt JOIN pg_namespace nbt ON bt.typnamespace = nbt.oid) ON t.typelem = bt.oid WHERE a.attrelid = c.oid AND a.atttypid = t.oid AND nc.oid = c.relnamespace AND NOT pg_is_other_temp_schema(nc.oid) AND a.attnum > 0 AND NOT a.attisdropped AND (c.relkind = ANY (ARRAY['r', 'v'])) AND (pg_has_role(c.relowner, 'USAGE') OR has_table_privilege(c.oid, 'SELECT') OR has_table_privilege(c.oid, 'INSERT') OR has_table_privilege(c.oid, 'UPDATE') OR has_table_privilege(c.oid, 'REFERENCES')) AND t.typelem <> 0 AND t.typlen = -1 "
228 	"UNION SELECT 'ROUP' || current_database() || '.' || ss.n_nspname || '.' || ((ss.proname || '_') || ss.p_oid) || '.' || (ss.x).n, current_database(), ss.n_nspname, ((ss.proname || '_') || ss.p_oid), 'ROUTINE_PAR', coalesce (nbt.nspname || '.', '') || bt.typname, NULL, NULL, NULL FROM pg_type t, pg_type bt, pg_namespace nbt, ( SELECT n.nspname AS n_nspname, p.proname, p.oid AS p_oid, p.proargnames, p.proargmodes, information_schema._pg_expandarray(COALESCE(p.proallargtypes, p.proargtypes::oid[])) AS x FROM pg_namespace n, pg_proc p WHERE n.oid = p.pronamespace AND (pg_has_role(p.proowner, 'USAGE') OR has_function_privilege(p.oid, 'EXECUTE'))) ss WHERE t.oid = (ss.x).x AND bt.oid= t.typelem AND bt.typnamespace = nbt.oid AND t.typelem <> 0 AND t.typlen = -1 "
229 	"UNION SELECT 'ROUC' || current_database() || '.' || ss.n_nspname || '.' || ((ss.proname || '_') || ss.p_oid) || '.' || (ss.x).n, current_database(), ss.n_nspname, ((ss.proname || '_') || ss.p_oid), 'ROUTINE_COL', CASE WHEN at.typelem <> 0 AND at.typlen = -1 THEN 'array_spec' ELSE coalesce (ant.nspname || '.', '') || at.typname END, CASE WHEN at.typelem <> 0 AND at.typlen = -1 THEN 'ARR' || at.typelem ELSE NULL END, NULL, NULL FROM pg_type t, pg_namespace nt, ( SELECT n.nspname AS n_nspname, p.proname, p.oid AS p_oid, p.proargnames, p.proargmodes, information_schema._pg_expandarray(COALESCE(p.proallargtypes, p.proargtypes::oid[])) AS x FROM pg_namespace n, pg_proc p WHERE n.oid = p.pronamespace AND (pg_has_role(p.proowner, 'USAGE') OR has_function_privilege(p.oid, 'EXECUTE'))) ss, pg_type at, pg_namespace ant WHERE t.oid = (ss.x).x AND t.typnamespace = nt.oid AND at.oid = t.typelem AND at.typnamespace = ant.oid AND (ss.proargmodes[(ss.x).n] = 'o' OR ss.proargmodes[(ss.x).n] = 'b')",
230 
231 	/* I_STMT_ROUTINES_ALL */
232 	"SELECT current_database(), n.nspname, ((p.proname || '_') || p.oid), current_database(), n.nspname, p.proname, CASE WHEN p.proisagg THEN 'AGGREGATE' ELSE 'FUNCTION' END, CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN 'ROUC' || current_database() || '.' || n.nspname || '.' || p.proname || '.' || p.oid ELSE coalesce (nt.nspname || '.', '') || t.typname END AS rettype, p.proretset, p.pronargs, CASE WHEN l.lanname = 'sql' THEN 'SQL' ELSE 'EXTERNAL' END, CASE WHEN pg_has_role(p.proowner, 'USAGE') THEN p.prosrc ELSE NULL END, CASE WHEN l.lanname = 'c' THEN p.prosrc ELSE NULL END, upper(l.lanname) AS external_language, 'GENERAL' AS parameter_style, CASE WHEN p.provolatile = 'i' THEN TRUE ELSE FALSE END, 'MODIFIES' AS sql_data_access, CASE WHEN p.proisstrict THEN TRUE ELSE FALSE END, pg_catalog.obj_description(p.oid), CASE WHEN pg_catalog.pg_function_is_visible(p.oid) IS TRUE THEN p.proname ELSE coalesce (n.nspname || '.', '') || p.proname END, coalesce (n.nspname || '.', '') || p.proname, o.rolname FROM pg_namespace n, pg_proc p, pg_language l, pg_type t, pg_namespace nt, pg_roles o WHERE n.oid = p.pronamespace AND p.prolang = l.oid AND p.prorettype = t.oid AND t.typnamespace = nt.oid AND (pg_has_role(p.proowner, 'USAGE') OR has_function_privilege(p.oid, 'EXECUTE')) AND o.oid=p.proowner",
233 
234 	/* I_STMT_ROUTINES */
235 	"SELECT current_database(), n.nspname, ((p.proname || '_') || p.oid), current_database(), n.nspname, p.proname, CASE WHEN p.proisagg THEN 'AGGREGATE' ELSE 'FUNCTION' END, CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN 'ROUC' || current_database() || '.' || n.nspname || '.' || p.proname || '.' || p.oid ELSE coalesce (nt.nspname || '.', '') || t.typname END AS rettype, p.proretset, p.pronargs, CASE WHEN l.lanname = 'sql' THEN 'SQL' ELSE 'EXTERNAL' END, CASE WHEN pg_has_role(p.proowner, 'USAGE') THEN p.prosrc ELSE NULL END, CASE WHEN l.lanname = 'c' THEN p.prosrc ELSE NULL END, upper(l.lanname) AS external_language, 'GENERAL' AS parameter_style, CASE WHEN p.provolatile = 'i' THEN TRUE ELSE FALSE END, 'MODIFIES' AS sql_data_access, CASE WHEN p.proisstrict THEN TRUE ELSE FALSE END, pg_catalog.obj_description(p.oid), CASE WHEN pg_catalog.pg_function_is_visible(p.oid) IS TRUE THEN p.proname ELSE coalesce (n.nspname || '.', '') || p.proname END, coalesce (n.nspname || '.', '') || p.proname, o.rolname FROM pg_namespace n, pg_proc p, pg_language l, pg_type t, pg_namespace nt, pg_roles o WHERE current_database() = ##cat::string AND n.nspname = ##schema::string AND n.oid = p.pronamespace AND p.prolang = l.oid AND p.prorettype = t.oid AND t.typnamespace = nt.oid AND (pg_has_role(p.proowner, 'USAGE') OR has_function_privilege(p.oid, 'EXECUTE')) AND o.oid=p.proowner",
236 
237 	/* I_STMT_ROUTINES_ONE */
238 	"SELECT current_database(), n.nspname, ((p.proname || '_') || p.oid), current_database(), n.nspname, p.proname, CASE WHEN p.proisagg THEN 'AGGREGATE' ELSE 'FUNCTION' END, CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN 'ROUC' || current_database() || '.' || n.nspname || '.' || p.proname || '.' || p.oid ELSE coalesce (nt.nspname || '.', '') || t.typname END AS rettype, p.proretset, p.pronargs, CASE WHEN l.lanname = 'sql' THEN 'SQL' ELSE 'EXTERNAL' END, CASE WHEN pg_has_role(p.proowner, 'USAGE') THEN p.prosrc ELSE NULL END, CASE WHEN l.lanname = 'c' THEN p.prosrc ELSE NULL END, upper(l.lanname) AS external_language, 'GENERAL' AS parameter_style, CASE WHEN p.provolatile = 'i' THEN TRUE ELSE FALSE END, 'MODIFIES' AS sql_data_access, CASE WHEN p.proisstrict THEN TRUE ELSE FALSE END, pg_catalog.obj_description(p.oid), CASE WHEN pg_catalog.pg_function_is_visible(p.oid) IS TRUE THEN p.proname ELSE coalesce (n.nspname || '.', '') || p.proname END, coalesce (n.nspname || '.', '') || p.proname, o.rolname FROM pg_namespace n, pg_proc p, pg_language l, pg_type t, pg_namespace nt, pg_roles o WHERE current_database() = ##cat::string AND n.nspname = ##schema::string AND ((p.proname || '_') || p.oid) = ##name::string AND n.oid = p.pronamespace AND p.prolang = l.oid AND p.prorettype = t.oid AND t.typnamespace = nt.oid AND (pg_has_role(p.proowner, 'USAGE') OR has_function_privilege(p.oid, 'EXECUTE')) AND o.oid=p.proowner",
239 
240 	/* I_STMT_ROUTINE_PAR_ALL */
241 	"SELECT current_database(), ss.n_nspname, ((ss.proname || '_') || ss.p_oid), (ss.x).n, CASE WHEN ss.proargmodes IS NULL THEN 'IN' WHEN ss.proargmodes[(ss.x).n] = 'i' THEN 'IN' WHEN ss.proargmodes[(ss.x).n] = 'o' THEN 'OUT' WHEN ss.proargmodes[(ss.x).n] = 'b' THEN 'INOUT' ELSE NULL END, NULLIF(ss.proargnames[(ss.x).n], ''), CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN 'array_spec' ELSE coalesce (nt.nspname || '.', '') || t.typname END, CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN 'ROUP' || current_database() || '.' || ss.n_nspname || '.' || ((ss.proname || '_') || ss.p_oid) || '.' || (ss.x).n ELSE NULL END FROM pg_type t, pg_namespace nt, ( SELECT n.nspname AS n_nspname, p.proname, p.oid AS p_oid, p.proargnames, p.proargmodes, information_schema._pg_expandarray(COALESCE(p.proallargtypes, p.proargtypes::oid[])) AS x FROM pg_namespace n, pg_proc p WHERE n.oid = p.pronamespace AND (pg_has_role(p.proowner, 'USAGE') OR has_function_privilege(p.oid, 'EXECUTE'))) ss WHERE ((ss.proargmodes[(ss.x).n] != 't' AND ss.proargmodes[(ss.x).n] != 'v') OR ss.proargmodes[(ss.x).n] IS NULL) AND t.oid = (ss.x).x AND t.typnamespace = nt.oid",
242 
243 	/* I_STMT_ROUTINE_PAR */
244 	"SELECT current_database(), ss.n_nspname, ((ss.proname || '_') || ss.p_oid), (ss.x).n, CASE WHEN ss.proargmodes IS NULL THEN 'IN' WHEN ss.proargmodes[(ss.x).n] = 'i' THEN 'IN' WHEN ss.proargmodes[(ss.x).n] = 'o' THEN 'OUT' WHEN ss.proargmodes[(ss.x).n] = 'b' THEN 'INOUT' ELSE NULL END, NULLIF(ss.proargnames[(ss.x).n], ''), CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN 'array_spec' ELSE coalesce (nt.nspname || '.', '') || t.typname END, CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN 'ROUP' || current_database() || '.' || ss.n_nspname || '.' || ((ss.proname || '_') || ss.p_oid) || '.' || (ss.x).n ELSE NULL END FROM pg_type t, pg_namespace nt, ( SELECT n.nspname AS n_nspname, p.proname, p.oid AS p_oid, p.proargnames, p.proargmodes, information_schema._pg_expandarray(COALESCE(p.proallargtypes, p.proargtypes::oid[])) AS x FROM pg_namespace n, pg_proc p WHERE n.oid = p.pronamespace AND (pg_has_role(p.proowner, 'USAGE') OR has_function_privilege(p.oid, 'EXECUTE'))) ss WHERE ((ss.proargmodes[(ss.x).n] != 't' AND ss.proargmodes[(ss.x).n] != 'v') OR ss.proargmodes[(ss.x).n] IS NULL) AND t.oid = (ss.x).x AND t.typnamespace = nt.oid AND current_database() = ##cat::string AND ss.n_nspname = ##schema::string AND ((ss.proname || '_') || ss.p_oid) = ##name::string",
245 
246 	/* I_STMT_ROUTINE_COL_ALL */
247 	"SELECT current_database(), ss.n_nspname, ((ss.proname || '_') || ss.p_oid), NULLIF(ss.proargnames[(ss.x).n], ''), (ss.x).n, CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN 'array_spec' ELSE coalesce (nt.nspname || '.', '') || t.typname END, CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN 'ROUC' || current_database() || '.' || ss.n_nspname || '.' || ((ss.proname || '_') || ss.p_oid) || '.' || (ss.x).n ELSE NULL END FROM pg_type t, pg_namespace nt, ( SELECT n.nspname AS n_nspname, p.proname, p.oid AS p_oid, p.proargnames, p.proargmodes, information_schema._pg_expandarray(COALESCE(p.proallargtypes, p.proargtypes::oid[])) AS x FROM pg_namespace n, pg_proc p WHERE n.oid = p.pronamespace AND (pg_has_role(p.proowner, 'USAGE') OR has_function_privilege(p.oid, 'EXECUTE'))) ss WHERE t.oid = (ss.x).x AND t.typnamespace = nt.oid AND (ss.proargmodes[(ss.x).n] = 'o' OR ss.proargmodes[(ss.x).n] = 'b') ORDER BY 1, 2, 3, 4, 5",
248 
249 	/* I_STMT_ROUTINE_COL */
250 	"SELECT current_database(), ss.n_nspname, ((ss.proname || '_') || ss.p_oid), NULLIF(ss.proargnames[(ss.x).n], ''), (ss.x).n, CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN 'array_spec' ELSE coalesce (nt.nspname || '.', '') || t.typname END, CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN 'ROUC' || current_database() || '.' || ss.n_nspname || '.' || ((ss.proname || '_') || ss.p_oid) || '.' || (ss.x).n ELSE NULL END FROM pg_type t, pg_namespace nt, ( SELECT n.nspname AS n_nspname, p.proname, p.oid AS p_oid, p.proargnames, p.proargmodes, information_schema._pg_expandarray(COALESCE(p.proallargtypes, p.proargtypes::oid[])) AS x FROM pg_namespace n, pg_proc p WHERE n.oid = p.pronamespace AND (pg_has_role(p.proowner, 'USAGE') OR has_function_privilege(p.oid, 'EXECUTE'))) ss WHERE t.oid = (ss.x).x AND t.typnamespace = nt.oid AND (ss.proargmodes[(ss.x).n] = 'o' OR ss.proargmodes[(ss.x).n] = 'b') AND current_database() = ##cat::string AND ss.n_nspname = ##schema::string AND ((ss.proname || '_') || ss.p_oid) = ##name::string ORDER BY 1, 2, 3, 4, 5",
251 
252 	/* I_STMT_INDEXES */
253 	"SELECT current_database() AS index_catalog, nc2.nspname AS index_schema, c2.relname AS index_name, current_database() AS table_catalog, nc.nspname AS table_schema, c.relname AS table_name, i.indisunique, pg_get_indexdef (i.indexrelid, 0, false), NULL, NULL, o.rolname, pg_catalog.obj_description (c2.oid), i.indexrelid FROM pg_catalog.pg_class c INNER JOIN pg_namespace nc ON (c.relnamespace = nc.oid), pg_catalog.pg_class c2 INNER JOIN pg_namespace nc2 ON (c2.relnamespace = nc2.oid) LEFT JOIN pg_roles o ON (o.oid=c2.relowner), pg_catalog.pg_index i WHERE c.oid = i.indrelid AND i.indexrelid = c2.oid AND NOT i.indisprimary AND pg_catalog.pg_table_is_visible(c.oid) AND nc.nspname = ##schema::string AND c.relname = ##name::string ORDER BY c.relname",
254 
255 	/* I_STMT_INDEXES_ALL */
256 	"SELECT current_database() AS index_catalog, nc2.nspname AS index_schema, c2.relname AS index_name, current_database() AS table_catalog, nc.nspname AS table_schema, c.relname AS table_name, i.indisunique, pg_get_indexdef (i.indexrelid, 0, false), NULL, NULL, o.rolname, pg_catalog.obj_description (c2.oid), i.indexrelid FROM pg_catalog.pg_class c INNER JOIN pg_namespace nc ON (c.relnamespace = nc.oid), pg_catalog.pg_class c2 INNER JOIN pg_namespace nc2 ON (c2.relnamespace = nc2.oid) LEFT JOIN pg_roles o ON (o.oid=c2.relowner), pg_catalog.pg_index i WHERE c.oid = i.indrelid AND i.indexrelid = c2.oid AND NOT i.indisprimary AND pg_catalog.pg_table_is_visible(c.oid) ORDER BY c.relname",
257 
258 	/* I_STMT_INDEXES_NAMED */
259 	"SELECT current_database() AS index_catalog, nc2.nspname AS index_schema, c2.relname AS index_name, current_database() AS table_catalog, nc.nspname AS table_schema, c.relname AS table_name, i.indisunique, pg_get_indexdef (i.indexrelid, 0, false), NULL, NULL, o.rolname, pg_catalog.obj_description (c2.oid), i.indexrelid FROM pg_catalog.pg_class c INNER JOIN pg_namespace nc ON (c.relnamespace = nc.oid), pg_catalog.pg_class c2 INNER JOIN pg_namespace nc2 ON (c2.relnamespace = nc2.oid) LEFT JOIN pg_roles o ON (o.oid=c2.relowner), pg_catalog.pg_index i WHERE c.oid = i.indrelid AND i.indexrelid = c2.oid AND NOT i.indisprimary AND pg_catalog.pg_table_is_visible(c.oid) AND nc.nspname = ##schema::string AND c.relname = ##name::string AND c2.relname = ##name2::string ORDER BY c.relname",
260 
261 	/* I_STMT_INDEXES_COLUMNS_GET_ALL_INDEXES */
262 	"SELECT i.indexrelid FROM pg_catalog.pg_class c, pg_catalog.pg_index i WHERE c.oid = i.indrelid AND NOT i.indisprimary AND pg_catalog.pg_table_is_visible(c.oid)",
263 
264 	/* I_STMT_INDEXES_COLUMNS_GET_NAMED_INDEXES */
265 	"SELECT i.indexrelid FROM pg_catalog.pg_class c INNER JOIN pg_namespace nc ON (c.relnamespace = nc.oid), pg_catalog.pg_index i, pg_catalog.pg_class c2 INNER JOIN pg_namespace nc2 ON (c2.relnamespace = nc2.oid) WHERE c.oid = i.indrelid AND NOT i.indisprimary AND pg_catalog.pg_table_is_visible(c.oid) AND i.indexrelid = c2.oid AND c.relname = ##name::string AND nc.nspname = ##schema::string AND c2.relname=##name2::string",
266 
267 	/* I_STMT_INDEXES_COLUMNS_FOR_INDEX */
268 	"SELECT current_database() AS index_catalog, nc2.nspname AS index_schema, c2.relname AS index_name, current_database() AS table_catalog, nc.nspname AS table_schema, c.relname AS table_name, a.attname, NULL, (ss.a).n FROM pg_catalog.pg_index i, (SELECT information_schema._pg_expandarray(indkey) AS a FROM pg_catalog.pg_index WHERE indexrelid = ##oid::guint) ss, pg_catalog.pg_class c INNER JOIN pg_namespace nc ON (c.relnamespace = nc.oid) INNER JOIN pg_catalog.pg_attribute a ON (a.attrelid = c.oid), pg_catalog.pg_class c2 INNER JOIN pg_namespace nc2 ON (c2.relnamespace = nc2.oid) WHERE i.indexrelid = ##oid::guint AND (ss.a).x != 0 AND a.attnum = (ss.a).x AND c.oid = i.indrelid AND i.indexrelid = c2.oid AND pg_catalog.pg_table_is_visible(c.oid) UNION SELECT current_database() AS index_catalog, nc2.nspname AS index_schema, c2.relname AS index_name, current_database() AS table_catalog, nc.nspname AS table_schema, c.relname AS table_name, NULL, pg_get_indexdef (i.indexrelid, (ss.a).n, false), (ss.a).n FROM pg_catalog.pg_index i, (SELECT information_schema._pg_expandarray(indkey) AS a FROM pg_catalog.pg_index WHERE indexrelid = ##oid::guint) ss, pg_catalog.pg_class c INNER JOIN pg_namespace nc ON (c.relnamespace = nc.oid), pg_catalog.pg_class c2 INNER JOIN pg_namespace nc2 ON (c2.relnamespace = nc2.oid) WHERE i.indexrelid = ##oid::guint AND (ss.a).x = 0 AND c.oid = i.indrelid AND i.indexrelid = c2.oid AND pg_catalog.pg_table_is_visible(c.oid) order by 9"
269 };
270 
271 /*
272  * global static values, and
273  * predefined statements' GdaStatement, all initialized in _gda_postgres_provider_meta_init()
274  */
275 static GMutex init_mutex;
276 static GdaStatement **internal_stmt = NULL;
277 static GdaSet       *i_set = NULL;
278 
279 /*
280  * Meta initialization
281  */
282 void
283 _gda_postgres_provider_meta_init (GdaServerProvider *provider)
284 {
285 	g_mutex_lock (&init_mutex);
286 
287 	if (!internal_stmt) {
288 		InternalStatementItem i;
289 		GdaSqlParser *parser;
290 
291 		if (provider)
292 			parser = gda_server_provider_internal_get_parser (provider);
293 		else
294 			parser = GDA_SQL_PARSER (g_object_new (GDA_TYPE_POSTGRES_PARSER, NULL));
295 		internal_stmt = g_new0 (GdaStatement *, sizeof (internal_sql) / sizeof (gchar*));
296 		for (i = I_STMT_CATALOG; i < sizeof (internal_sql) / sizeof (gchar*); i++) {
297 			internal_stmt[i] = gda_sql_parser_parse_string (parser, internal_sql[i], NULL, NULL);
298 			if (!internal_stmt[i])
299 				g_error ("Could not parse internal statement: %s\n", internal_sql[i]);
300 		}
301 		if (!provider)
302 			g_object_unref (parser);
303 
304 		i_set = gda_set_new_inline (5, "cat", G_TYPE_STRING, "",
305 					    "name", G_TYPE_STRING, "",
306 					    "schema", G_TYPE_STRING, "",
307 					    "name2", G_TYPE_STRING, "",
308 					    "oid", G_TYPE_UINT, 0);
309 	}
310 
311 	g_mutex_unlock (&init_mutex);
312 
313 #ifdef GDA_DEBUG
314 	_gda_postgres_test_keywords ();
315 #endif
316 }
317 
318 #define GDA_POSTGRES_GET_REUSEABLE_DATA(cdata) ((cdata) ? * ((GdaPostgresReuseable**) (cdata)) : NULL)
319 
320 gboolean
321 _gda_postgres_meta__info (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
322 			  GdaMetaStore *store, GdaMetaContext *context, GError **error)
323 {
324 	GdaDataModel *model;
325 	gboolean retval;
326 	GdaPostgresReuseable *rdata;
327 
328 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
329 	if (!rdata)
330 		return FALSE;
331 
332 	model = gda_connection_statement_execute_select_full (cnc,
333 							      internal_stmt[I_STMT_CATALOG],
334 							      NULL,
335 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
336 							      _col_types_information_schema_catalog_name,
337 							      error);
338 	if (!model)
339 		return FALSE;
340 
341 	gda_meta_store_set_reserved_keywords_func (store,
342 						   _gda_postgres_reuseable_get_reserved_keywords_func
343 						   ((GdaProviderReuseable*) rdata));
344 	retval = gda_meta_store_modify (store, context->table_name, model, NULL, error, NULL);
345 	g_object_unref (model);
346 
347 	return retval;
348 }
349 
350 gboolean
351 _gda_postgres_meta__btypes (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
352 			    GdaMetaStore *store, GdaMetaContext *context, GError **error)
353 {
354 	GdaDataModel *model, *proxy;
355 	gboolean retval = TRUE;
356 	gint i, nrows;
357 	GdaPostgresReuseable *rdata;
358 
359 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
360 	if (!rdata)
361 		return FALSE;
362 
363 	/* use a prepared statement for the "base" model */
364 	model = gda_connection_statement_execute_select_full (cnc,
365 							      internal_stmt[I_STMT_BTYPES],
366 							      NULL,
367 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
368 							      _col_types_builtin_data_types, error);
369 	if (!model)
370 		return FALSE;
371 
372 	/* use a proxy to customize @model */
373 	proxy = (GdaDataModel*) gda_data_proxy_new (model);
374 	g_object_set (G_OBJECT (proxy), "defer-sync", FALSE, "sample-size", 0, NULL);
375 	nrows = gda_data_model_get_n_rows (model);
376 	for (i = 0; i < nrows; i++) {
377 		const GValue *value;
378 		GType type;
379 		value = gda_data_model_get_value_at (model, 6, i, error);
380 		if (!value) {
381 			retval = FALSE;
382 			break;
383 		}
384 
385 		guint oid = (guint) g_ascii_strtoull (g_value_get_string (value), NULL, 10);
386 		type = _gda_postgres_type_oid_to_gda (cnc, rdata, oid);
387 		if (type != G_TYPE_STRING) {
388 			GValue *v;
389 			g_value_set_string (v = gda_value_new (G_TYPE_STRING), g_type_name (type));
390 			retval = gda_data_model_set_value_at (proxy, 2, i, v, error);
391 			gda_value_free (v);
392 			if (!retval)
393 				break;
394 		}
395 	}
396 
397 	/* modify meta store with @proxy */
398 	if (retval) {
399 		gda_meta_store_set_reserved_keywords_func (store,
400 							   _gda_postgres_reuseable_get_reserved_keywords_func
401 							   ((GdaProviderReuseable*) rdata));
402 		retval = gda_meta_store_modify (store, context->table_name, proxy, NULL, error, NULL);
403 	}
404 	g_object_unref (proxy);
405 	g_object_unref (model);
406 
407 	return retval;
408 }
409 
410 gboolean
411 _gda_postgres_meta__udt (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
412 			 GdaMetaStore *store, GdaMetaContext *context, GError **error)
413 {
414 	GdaDataModel *model;
415 	gboolean retval;
416 	GdaPostgresReuseable *rdata;
417 
418 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
419 	if (!rdata)
420 		return FALSE;
421 
422 	model = gda_connection_statement_execute_select_full (cnc,
423 							      internal_stmt[I_STMT_UDT_ALL],
424 							      NULL,
425 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
426 							      _col_types_udt, error);
427 	if (!model)
428 		return FALSE;
429 
430 	gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
431 						   ((GdaProviderReuseable*) rdata));
432 	retval = gda_meta_store_modify_with_context (store, context, model, error);
433 	g_object_unref (model);
434 
435 	return retval;
436 }
437 
438 gboolean
439 _gda_postgres_meta_udt (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
440 			GdaMetaStore *store, GdaMetaContext *context, GError **error,
441 			const GValue *udt_catalog, const GValue *udt_schema)
442 {
443 	GdaDataModel *model;
444 	gboolean retval = TRUE;
445 	GdaPostgresReuseable *rdata;
446 
447 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
448 	if (!rdata)
449 		return FALSE;
450 
451 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "cat"), udt_catalog, error))
452 		return FALSE;
453 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "schema"), udt_schema, error))
454 		return FALSE;
455 	model = gda_connection_statement_execute_select_full (cnc,
456 							      internal_stmt[I_STMT_UDT],
457 							      i_set,
458 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
459 							      _col_types_udt, error);
460 	if (!model)
461 		return FALSE;
462 
463 	gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
464 						   ((GdaProviderReuseable*) rdata));
465 	retval = gda_meta_store_modify_with_context (store, context, model, error);
466 	g_object_unref (model);
467 
468 	return retval;
469 }
470 
471 gboolean
472 _gda_postgres_meta__udt_cols (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
473 			      GdaMetaStore *store, GdaMetaContext *context, GError **error)
474 {
475 	GdaDataModel *model;
476 	gboolean retval;
477 	GdaPostgresReuseable *rdata;
478 
479 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
480 	if (!rdata)
481 		return FALSE;
482 
483 	model = gda_connection_statement_execute_select_full (cnc,
484 							      internal_stmt[I_STMT_UDT_COLUMNS_ALL],
485 							      NULL,
486 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
487 							      _col_types_udt_columns, error);
488 
489 	if (!model)
490 		return FALSE;
491 
492 	gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
493 						   ((GdaProviderReuseable*) rdata));
494 	retval = gda_meta_store_modify_with_context (store, context, model, error);
495 	g_object_unref (model);
496 
497 	return retval;
498 }
499 
500 gboolean
501 _gda_postgres_meta_udt_cols (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
502 			     GdaMetaStore *store, GdaMetaContext *context, GError **error,
503 			     const GValue *udt_catalog, const GValue *udt_schema, const GValue *udt_name)
504 {
505 	GdaDataModel *model;
506 	gboolean retval = TRUE;
507 	GdaPostgresReuseable *rdata;
508 
509 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
510 	if (!rdata)
511 		return FALSE;
512 
513 	if (!gda_holder_set_value (gda_set_get_holder (i_set, "cat"), udt_catalog, error))
514 		return FALSE;
515 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "schema"), udt_schema, error))
516 		return FALSE;
517 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "name"), udt_name, error))
518 		return FALSE;
519 	model = gda_connection_statement_execute_select_full (cnc,
520 							      internal_stmt[I_STMT_UDT_COLUMNS],
521 							      i_set,
522 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
523 							      _col_types_udt_columns, error);
524 	if (!model)
525 		return FALSE;
526 
527 	gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
528 						   ((GdaProviderReuseable*) rdata));
529 	retval = gda_meta_store_modify_with_context (store, context, model, error);
530 	g_object_unref (model);
531 
532 	return retval;
533 }
534 
535 gboolean
536 _gda_postgres_meta__enums (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
537 			   G_GNUC_UNUSED GdaMetaStore *store, G_GNUC_UNUSED GdaMetaContext *context,
538 			   G_GNUC_UNUSED GError **error)
539 {
540 	GdaPostgresReuseable *rdata;
541 
542 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
543 	if (!rdata)
544 		return FALSE;
545 	/*
546 	if (rdata->version_float >= 8.3)
547 	        TO_IMPLEMENT;
548 	*/
549 
550 	return TRUE;
551 }
552 
553 gboolean
554 _gda_postgres_meta_enums (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
555 			  G_GNUC_UNUSED GdaMetaStore *store, G_GNUC_UNUSED GdaMetaContext *context,
556 			  G_GNUC_UNUSED GError **error, G_GNUC_UNUSED const GValue *udt_catalog,
557 			  G_GNUC_UNUSED const GValue *udt_schema, G_GNUC_UNUSED const GValue *udt_name)
558 {
559 	GdaPostgresReuseable *rdata;
560 
561 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
562 	if (!rdata)
563 		return FALSE;
564 	/*
565 	if (rdata->version_float >= 8.3)
566 		TO_IMPLEMENT;
567 	*/
568 
569 	return TRUE;
570 }
571 
572 gboolean
573 _gda_postgres_meta__domains (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
574 			     GdaMetaStore *store, GdaMetaContext *context, GError **error)
575 {
576 	GdaDataModel *model;
577 	gboolean retval;
578 	GdaPostgresReuseable *rdata;
579 
580 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
581 	if (!rdata)
582 		return FALSE;
583 
584 	model = gda_connection_statement_execute_select_full (cnc,
585 							      internal_stmt[I_STMT_DOMAINS_ALL],
586 							      NULL,
587 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
588 							      _col_types_domains, error);
589 	if (!model)
590 		return FALSE;
591 
592 	gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
593 						   ((GdaProviderReuseable*) rdata));
594 	retval = gda_meta_store_modify_with_context (store, context, model, error);
595 	g_object_unref (model);
596 
597 	return retval;
598 }
599 
600 gboolean
601 _gda_postgres_meta_domains (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
602 			    GdaMetaStore *store, GdaMetaContext *context, GError **error,
603 			    const GValue *domain_catalog, const GValue *domain_schema)
604 {
605 	GdaDataModel *model;
606 	gboolean retval = TRUE;
607 	GdaPostgresReuseable *rdata;
608 
609 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
610 	if (!rdata)
611 		return FALSE;
612 
613 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "cat"), domain_catalog, error))
614 		return FALSE;
615 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "schema"), domain_schema, error))
616 		return FALSE;
617 
618 	model = gda_connection_statement_execute_select_full (cnc,
619 							      internal_stmt[I_STMT_DOMAINS],
620 							      i_set,
621 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
622 							      _col_types_domains, error);
623 	if (!model)
624 		return FALSE;
625 
626 	gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
627 						   ((GdaProviderReuseable*) rdata));
628 	retval = gda_meta_store_modify_with_context (store, context, model, error);
629 	g_object_unref (model);
630 
631 	return retval;
632 }
633 
634 gboolean
635 _gda_postgres_meta__constraints_dom (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
636 				     GdaMetaStore *store, GdaMetaContext *context, GError **error)
637 {
638 	GdaDataModel *model;
639 	gboolean retval;
640 	GdaPostgresReuseable *rdata;
641 
642 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
643 	if (!rdata)
644 		return FALSE;
645 
646 	model = gda_connection_statement_execute_select_full (cnc,
647 							      internal_stmt[I_STMT_DOMAINS_CONSTRAINTS_ALL],
648 							      NULL,
649 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
650 							      _col_types_domain_constraints, error);
651 	if (!model)
652 		return FALSE;
653 
654 	gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
655 						   ((GdaProviderReuseable*) rdata));
656 	retval = gda_meta_store_modify_with_context (store, context, model, error);
657 	g_object_unref (model);
658 
659 	return retval;
660 }
661 
662 gboolean
663 _gda_postgres_meta_constraints_dom (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
664 				    GdaMetaStore *store, GdaMetaContext *context, GError **error,
665 				    const GValue *domain_catalog, const GValue *domain_schema,
666 				    const GValue *domain_name)
667 {
668 	GdaDataModel *model;
669 	gboolean retval = TRUE;
670 	GdaPostgresReuseable *rdata;
671 
672 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
673 	if (!rdata)
674 		return FALSE;
675 
676 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "cat"), domain_catalog, error))
677 		return FALSE;
678 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "schema"), domain_schema, error))
679 		return FALSE;
680 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "name"), domain_name, error))
681 		return FALSE;
682 
683 	model = gda_connection_statement_execute_select_full (cnc,
684 							      internal_stmt[I_STMT_DOMAINS_CONSTRAINTS],
685 							      i_set,
686 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
687 							      _col_types_domain_constraints, error);
688 	if (!model)
689 		return FALSE;
690 
691 	gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
692 						   ((GdaProviderReuseable*) rdata));
693 	retval = gda_meta_store_modify_with_context (store, context, model, error);
694 	g_object_unref (model);
695 
696 	return retval;
697 }
698 
699 gboolean
700 _gda_postgres_meta__el_types (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
701 			      GdaMetaStore *store, GdaMetaContext *context, GError **error)
702 {
703 	GdaDataModel *model;
704 	gboolean retval;
705 
706 	/* check correct postgres server version */
707 	GdaPostgresReuseable *rdata;
708 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
709 	if (!rdata)
710 		return FALSE;
711 	if (rdata->version_float < 8.2) {
712 		/* nothing for this version of PostgreSQL */
713 		return TRUE;
714 	}
715 
716 	model = gda_connection_statement_execute_select_full (cnc,
717 							      internal_stmt[I_STMT_EL_TYPES_ALL],
718 							      NULL,
719 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
720 							      _col_types_element_types, error);
721 	if (!model)
722 		return FALSE;
723 
724 	gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
725 						   ((GdaProviderReuseable*) rdata));
726 	retval = gda_meta_store_modify_with_context (store, context, model, error);
727 	g_object_unref (model);
728 
729 	return retval;
730 }
731 
732 gboolean
733 _gda_postgres_meta_el_types (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
734 			     GdaMetaStore *store, GdaMetaContext *context, GError **error,
735 			     const GValue *specific_name)
736 {
737 	const gchar *cstr;
738 	GdaDataModel *model = NULL;
739 	gboolean retval;
740 	GdaPostgresReuseable *rdata;
741 
742 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
743 	if (!rdata)
744 		return FALSE;
745 
746 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "name"), specific_name, error))
747 		return FALSE;
748 	cstr = g_value_get_string (specific_name);
749 	if (*cstr == 'C') {
750 		/* check correct postgres server version */
751 		if (rdata->version_float < 8.2) {
752 			/* nothing for this version of PostgreSQL */
753 			return TRUE;
754 		}
755 
756 		model = gda_connection_statement_execute_select_full (cnc,
757 								      internal_stmt[I_STMT_EL_TYPES_COL],
758 								      i_set,
759 								      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
760 								      _col_types_element_types, error);
761 	}
762 	else if (*cstr == 'D')
763 		model = gda_connection_statement_execute_select_full (cnc,
764 								      internal_stmt[I_STMT_EL_TYPES_DOM],
765 								      i_set,
766 								      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
767 								      _col_types_element_types, error);
768 	else if (*cstr == 'U')
769 		model = gda_connection_statement_execute_select_full (cnc,
770 								      internal_stmt[I_STMT_EL_TYPES_UDT],
771 								      i_set,
772 								      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
773 								      _col_types_element_types, error);
774 	else if (!strcmp (cstr, "ROUTINE_PAR"))
775 		model = gda_connection_statement_execute_select_full (cnc,
776 								      internal_stmt[I_STMT_EL_TYPES_ROUT_PAR],
777 								      i_set,
778 								      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
779 								      _col_types_element_types, error);
780 	else if (!strcmp (cstr, "ROUTINE_COL"))
781 		model = gda_connection_statement_execute_select_full (cnc,
782 								      internal_stmt[I_STMT_EL_TYPES_ROUT_COL],
783 								      i_set,
784 								      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
785 								      _col_types_element_types, error);
786 	else
787 		TO_IMPLEMENT;
788 
789 	if (!model)
790 		return FALSE;
791 
792 	gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
793 						   ((GdaProviderReuseable*) rdata));
794 	retval = gda_meta_store_modify_with_context (store, context, model, error);
795 	g_object_unref (model);
796 
797 	return retval;
798 }
799 
800 gboolean
801 _gda_postgres_meta__collations (G_GNUC_UNUSED GdaServerProvider *prov, G_GNUC_UNUSED GdaConnection *cnc,
802 				G_GNUC_UNUSED GdaMetaStore *store, G_GNUC_UNUSED GdaMetaContext *context,
803 				G_GNUC_UNUSED GError **error)
804 {
805 	/* nothing to do */
806 	return TRUE;
807 }
808 
809 gboolean
810 _gda_postgres_meta_collations (G_GNUC_UNUSED GdaServerProvider *prov, G_GNUC_UNUSED GdaConnection *cnc,
811 			       G_GNUC_UNUSED GdaMetaStore *store, G_GNUC_UNUSED GdaMetaContext *context,
812 			       G_GNUC_UNUSED GError **error, G_GNUC_UNUSED const
813 			       G_GNUC_UNUSED GValue *collation_catalog,
814 			       G_GNUC_UNUSED const GValue *collation_schema,
815 			       G_GNUC_UNUSED const GValue *collation_name_n)
816 {
817 	/* nothing to do */
818 	return TRUE;
819 }
820 
821 gboolean
822 _gda_postgres_meta__character_sets (G_GNUC_UNUSED GdaServerProvider *prov, G_GNUC_UNUSED GdaConnection *cnc,
823 				    G_GNUC_UNUSED GdaMetaStore *store, G_GNUC_UNUSED GdaMetaContext *context,
824 				    G_GNUC_UNUSED GError **error)
825 {
826 	/* nothing to do */
827 	return TRUE;
828 }
829 
830 gboolean
831 _gda_postgres_meta_character_sets (G_GNUC_UNUSED GdaServerProvider *prov, G_GNUC_UNUSED GdaConnection *cnc,
832 				   G_GNUC_UNUSED GdaMetaStore *store, G_GNUC_UNUSED GdaMetaContext *context,
833 				   G_GNUC_UNUSED GError **error, G_GNUC_UNUSED const GValue *chset_catalog,
834 				   G_GNUC_UNUSED const GValue *chset_schema,
835 				   G_GNUC_UNUSED const GValue *chset_name_n)
836 {
837 	/* nothing to do */
838 	return TRUE;
839 }
840 
841 gboolean
842 _gda_postgres_meta__schemata (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
843 			      GdaMetaStore *store, GdaMetaContext *context, GError **error)
844 {
845 	GdaDataModel *model;
846 	gboolean retval;
847 	GdaPostgresReuseable *rdata;
848 
849 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
850 	if (!rdata)
851 		return FALSE;
852 
853 	model = gda_connection_statement_execute_select_full (cnc,
854 							      internal_stmt[I_STMT_SCHEMAS_ALL],
855 							      NULL,
856 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
857 							      _col_types_schemata, error);
858 	if (!model)
859 		return FALSE;
860 
861 	gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
862 						   ((GdaProviderReuseable*) rdata));
863 	retval = gda_meta_store_modify_with_context (store, context, model, error);
864 	g_object_unref (model);
865 
866 	return retval;
867 }
868 
869 gboolean
870 _gda_postgres_meta_schemata (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
871 			     GdaMetaStore *store, GdaMetaContext *context, GError **error,
872 			     const GValue *catalog_name, const GValue *schema_name_n)
873 {
874 	GdaDataModel *model;
875 	gboolean retval;
876 	GdaPostgresReuseable *rdata;
877 
878 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
879 	if (!rdata)
880 		return FALSE;
881 
882 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "cat"), catalog_name, error))
883 		return FALSE;
884 	if (!schema_name_n) {
885 		model = gda_connection_statement_execute_select_full (cnc,
886 								      internal_stmt[I_STMT_SCHEMAS],
887 								      i_set,
888 								      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
889 								      _col_types_schemata, error);
890 		if (!model)
891 			return FALSE;
892 
893 		gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
894 						   ((GdaProviderReuseable*) rdata));
895 		retval = gda_meta_store_modify (store, context->table_name, model, NULL, error, NULL);
896 	}
897 	else {
898 		if (! gda_holder_set_value (gda_set_get_holder (i_set, "name"), schema_name_n, error))
899 			return FALSE;
900 		model = gda_connection_statement_execute_select_full (cnc,
901 								      internal_stmt[I_STMT_SCHEMA_NAMED],
902 								      i_set,
903 								      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
904 								      _col_types_schemata, error);
905 		if (!model)
906 			return FALSE;
907 
908 		gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
909 						   ((GdaProviderReuseable*) rdata));
910 		retval = gda_meta_store_modify (store, context->table_name, model, "schema_name = ##name::string", error,
911 						"name", schema_name_n, NULL);
912 	}
913 	g_object_unref (model);
914 
915 	return retval;
916 }
917 
918 gboolean
919 _gda_postgres_meta__tables_views (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
920 				  GdaMetaStore *store, GdaMetaContext *context, GError **error)
921 {
922 	GdaDataModel *tables_model, *views_model;
923 	gboolean retval = TRUE;
924 
925 	/* check correct postgres server version */
926 	GdaPostgresReuseable *rdata;
927 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
928 	if (!rdata)
929 		return FALSE;
930 	if ((rdata->version_float == 0) && ! _gda_postgres_compute_version (cnc, rdata, error))
931 		return FALSE;
932 	if (rdata->version_float < 8.2) {
933 		/* nothing for this version of PostgreSQL */
934 		return TRUE;
935 	}
936 
937 	tables_model = gda_connection_statement_execute_select_full (cnc,
938 								     internal_stmt[I_STMT_TABLES_ALL],
939 								     NULL,
940 								     GDA_STATEMENT_MODEL_RANDOM_ACCESS,
941 								     _col_types_tables, error);
942 	if (!tables_model)
943 		return FALSE;
944 	views_model = gda_connection_statement_execute_select_full (cnc,
945 								    internal_stmt[I_STMT_VIEWS_ALL],
946 								    NULL,
947 								    GDA_STATEMENT_MODEL_RANDOM_ACCESS,
948 								    _col_types_views, error);
949 	if (!views_model) {
950 		g_object_unref (tables_model);
951 		return FALSE;
952 	}
953 
954 	GdaMetaContext c2;
955 	c2 = *context; /* copy contents, just because we need to modify @context->table_name */
956 	if (retval) {
957 		c2.table_name = "_tables";
958 		gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
959 						   ((GdaProviderReuseable*) rdata));
960 		retval = gda_meta_store_modify_with_context (store, &c2, tables_model, error);
961 	}
962 	if (retval) {
963 		c2.table_name = "_views";
964 		gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
965 						   ((GdaProviderReuseable*) rdata));
966 		retval = gda_meta_store_modify_with_context (store, &c2, views_model, error);
967 	}
968 	g_object_unref (tables_model);
969 	g_object_unref (views_model);
970 
971 
972 	return retval;
973 }
974 
975 gboolean
976 _gda_postgres_meta_tables_views (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
977 				 GdaMetaStore *store, GdaMetaContext *context, GError **error,
978 				 const GValue *table_catalog, const GValue *table_schema, const GValue *table_name_n)
979 {
980 	GdaDataModel *tables_model, *views_model;
981 	gboolean retval = TRUE;
982 
983 	/* check correct postgres server version */
984 	GdaPostgresReuseable *rdata;
985 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
986 	if (!rdata)
987 		return FALSE;
988 	if (rdata->version_float < 8.2) {
989 		/* nothing for this version of PostgreSQL */
990 		return TRUE;
991 	}
992 
993 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "cat"), table_catalog, error))
994 		return FALSE;
995 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "schema"), table_schema, error))
996 		return FALSE;
997 	if (!table_name_n) {
998 		tables_model = gda_connection_statement_execute_select_full (cnc,
999 									     internal_stmt[I_STMT_TABLES],
1000 									     i_set,
1001 									     GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1002 									     _col_types_tables, error);
1003 		if (!tables_model)
1004 			return FALSE;
1005 		views_model = gda_connection_statement_execute_select_full (cnc,
1006 									    internal_stmt[I_STMT_VIEWS],
1007 									    i_set,
1008 									    GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1009 									    _col_types_views, error);
1010 		if (!views_model) {
1011 			g_object_unref (tables_model);
1012 			return FALSE;
1013 		}
1014 	}
1015 	else {
1016 		if (! gda_holder_set_value (gda_set_get_holder (i_set, "name"), table_name_n, error))
1017 			return FALSE;
1018 		tables_model = gda_connection_statement_execute_select_full (cnc,
1019 									     internal_stmt[I_STMT_TABLE_NAMED],
1020 									     i_set,
1021 									     GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1022 									     _col_types_tables, error);
1023 		if (!tables_model)
1024 			return FALSE;
1025 		views_model = gda_connection_statement_execute_select_full (cnc,
1026 									    internal_stmt[I_STMT_VIEW_NAMED],
1027 									    i_set,
1028 									    GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1029 									    _col_types_views, error);
1030 		if (!views_model) {
1031 			g_object_unref (tables_model);
1032 			return FALSE;
1033 		}
1034 	}
1035 
1036 	GdaMetaContext c2;
1037 	c2 = *context; /* copy contents, just because we need to modify @context->table_name */
1038 	if (retval) {
1039 		c2.table_name = "_tables";
1040 		gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
1041 						   ((GdaProviderReuseable*) rdata));
1042 		retval = gda_meta_store_modify_with_context (store, &c2, tables_model, error);
1043 	}
1044 	if (retval) {
1045 		c2.table_name = "_views";
1046 		gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
1047 						   ((GdaProviderReuseable*) rdata));
1048 		retval = gda_meta_store_modify_with_context (store, &c2, views_model, error);
1049 	}
1050 	g_object_unref (tables_model);
1051 	g_object_unref (views_model);
1052 
1053 	return retval;
1054 }
1055 
1056 gboolean _gda_postgres_meta__columns (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
1057 				      GdaMetaStore *store, GdaMetaContext *context, GError **error)
1058 {
1059 	GdaDataModel *model, *proxy;
1060 	gboolean retval = TRUE;
1061 	gint i, nrows;
1062 	GdaPostgresReuseable *rdata;
1063 
1064 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1065 	if (!rdata)
1066 		return FALSE;
1067 
1068 	/* use a prepared statement for the "base" model */
1069 	model = gda_connection_statement_execute_select_full (cnc,
1070 							      internal_stmt[I_STMT_COLUMNS_ALL],
1071 							      NULL,
1072 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1073 							      _col_types_columns, error);
1074 	if (!model)
1075 		return FALSE;
1076 
1077 	/* use a proxy to customize @model */
1078 	proxy = (GdaDataModel*) gda_data_proxy_new (model);
1079 	g_object_set (G_OBJECT (proxy), "defer-sync", FALSE, "sample-size", 0, NULL);
1080 	nrows = gda_data_model_get_n_rows (model);
1081 	for (i = 0; i < nrows; i++) {
1082 		const GValue *value;
1083 		GType type;
1084 
1085 		/* GType */
1086 		value = gda_data_model_get_value_at (model, 24, i, error);
1087 		if (!value) {
1088 			retval = FALSE;
1089 			break;
1090 		}
1091 
1092 		guint oid = (guint) g_ascii_strtoull (g_value_get_string (value), NULL, 10);
1093 		type = _gda_postgres_type_oid_to_gda (cnc, rdata, oid);
1094 		if (type != G_TYPE_STRING) {
1095 			GValue *v;
1096 			g_value_set_string (v = gda_value_new (G_TYPE_STRING), g_type_name (type));
1097 			retval = gda_data_model_set_value_at (proxy, 9, i, v, error);
1098 			gda_value_free (v);
1099 			if (!retval)
1100 				break;
1101 		}
1102 
1103 		/* column default: remove the datatype cast on strings:
1104 		 * 'abd'::character varying  => 'abd' */
1105 		value = gda_data_model_get_value_at (model, 5, i, error);
1106 		if (!value) {
1107 			retval = FALSE;
1108 			break;
1109 		}
1110 
1111 		if (G_VALUE_TYPE (value) == G_TYPE_STRING) {
1112 			const gchar *cstr;
1113 			cstr = g_value_get_string (value);
1114 			if (cstr && (*cstr == '\'')) {
1115 				gint len;
1116 				len = strlen (cstr);
1117 				if (cstr [len-1] != '\'') {
1118 					gchar *tmp = g_strdup (cstr);
1119 					gint k;
1120 					for (k = len - 1; k > 0; k--) {
1121 						if (tmp [k] == '\'') {
1122 							tmp [k+1] = 0;
1123 							break;
1124 						}
1125 					}
1126 					GValue *v;
1127 					g_value_take_string (v = gda_value_new (G_TYPE_STRING), tmp);
1128 					retval = gda_data_model_set_value_at (proxy, 5, i, v, error);
1129 					gda_value_free (v);
1130 					if (!retval)
1131 						break;
1132 				}
1133 			}
1134 		}
1135 	}
1136 
1137 	/* modify meta store with @proxy */
1138 	if (retval) {
1139 		gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
1140 						   ((GdaProviderReuseable*) rdata));
1141 		retval = gda_meta_store_modify_with_context (store, context, proxy, error);
1142 	}
1143 	g_object_unref (proxy);
1144 	g_object_unref (model);
1145 
1146 	return retval;
1147 }
1148 
1149 gboolean
1150 _gda_postgres_meta_columns (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
1151 			    GdaMetaStore *store, GdaMetaContext *context, GError **error,
1152 			    const GValue *table_catalog, const GValue *table_schema, const GValue *table_name)
1153 {
1154 	GdaDataModel *model, *proxy;
1155 	gboolean retval = TRUE;
1156 	gint i, nrows;
1157 	GdaPostgresReuseable *rdata;
1158 
1159 	/* check correct postgres server version */
1160 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1161 	if (!rdata)
1162 		return FALSE;
1163 	if (rdata->version_float < 8.2) {
1164 		/* nothing for this version of PostgreSQL */
1165 		return TRUE;
1166 	}
1167 
1168 	/* use a prepared statement for the "base" model */
1169 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "cat"), table_catalog, error))
1170 		return FALSE;
1171 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "schema"), table_schema, error))
1172 		return FALSE;
1173 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "name"), table_name, error))
1174 		return FALSE;
1175 	model = gda_connection_statement_execute_select_full (cnc,
1176 							      internal_stmt[I_STMT_COLUMNS_OF_TABLE],
1177 							      i_set,
1178 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1179 							      _col_types_columns, error);
1180 	if (!model)
1181 		return FALSE;
1182 
1183 	/* use a proxy to customize @model */
1184 	proxy = (GdaDataModel*) gda_data_proxy_new (model);
1185 	g_object_set (G_OBJECT (proxy), "defer-sync", FALSE, "sample-size", 0, NULL);
1186 	nrows = gda_data_model_get_n_rows (model);
1187 	for (i = 0; i < nrows; i++) {
1188 		const GValue *value;
1189 		GType type;
1190 
1191 		/* GType */
1192 		value = gda_data_model_get_value_at (model, 24, i, error);
1193 		if (!value) {
1194 			retval = FALSE;
1195 			break;
1196 		}
1197 
1198 		guint oid = (guint) g_ascii_strtoull (g_value_get_string (value), NULL, 10);
1199 		type = _gda_postgres_type_oid_to_gda (cnc, rdata, oid);
1200 		if (type != G_TYPE_STRING) {
1201 			GValue *v;
1202 			g_value_set_string (v = gda_value_new (G_TYPE_STRING), g_type_name (type));
1203 			retval = gda_data_model_set_value_at (proxy, 9, i, v, error);
1204 			gda_value_free (v);
1205 			if (!retval)
1206 				break;
1207 		}
1208 
1209 		/* column default: remove the datatype cast on strings:
1210 		 * 'abd'::character varying  => 'abd' */
1211 		value = gda_data_model_get_value_at (model, 5, i, error);
1212 		if (!value) {
1213 			retval = FALSE;
1214 			break;
1215 		}
1216 
1217 		if (G_VALUE_TYPE (value) == G_TYPE_STRING) {
1218 			const gchar *cstr;
1219 			cstr = g_value_get_string (value);
1220 			if (cstr && (*cstr == '\'')) {
1221 				gint len;
1222 				len = strlen (cstr);
1223 				if (cstr [len-1] != '\'') {
1224 					gchar *tmp = g_strdup (cstr);
1225 					gint k;
1226 					for (k = len - 1; k > 0; k--) {
1227 						if (tmp [k] == '\'') {
1228 							tmp [k+1] = 0;
1229 							break;
1230 						}
1231 					}
1232 					GValue *v;
1233 					g_value_take_string (v = gda_value_new (G_TYPE_STRING), tmp);
1234 					retval = gda_data_model_set_value_at (proxy, 5, i, v, error);
1235 					gda_value_free (v);
1236 					if (!retval)
1237 						break;
1238 				}
1239 			}
1240 		}
1241 	}
1242 
1243 	/* modify meta store with @proxy */
1244 	if (retval) {
1245 		gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
1246 						   ((GdaProviderReuseable*) rdata));
1247 		retval = gda_meta_store_modify (store, context->table_name, proxy,
1248 						"table_schema = ##schema::string AND table_name = ##name::string", error,
1249 						"schema", table_schema, "name", table_name, NULL);
1250 	}
1251 	g_object_unref (proxy);
1252 	g_object_unref (model);
1253 
1254 	return retval;
1255 }
1256 
1257 gboolean
1258 _gda_postgres_meta__view_cols (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
1259 			       GdaMetaStore *store, GdaMetaContext *context, GError **error)
1260 {
1261 	GdaDataModel *model;
1262 	gboolean retval;
1263 
1264 	/* check correct postgres server version */
1265 	GdaPostgresReuseable *rdata;
1266 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1267 	if (!rdata)
1268 		return FALSE;
1269 	if (rdata->version_float < 8.2) {
1270 		/* nothing for this version of PostgreSQL */
1271 		return TRUE;
1272 	}
1273 
1274 	model = gda_connection_statement_execute_select_full (cnc,
1275 							      internal_stmt[I_STMT_VIEWS_COLUMNS_ALL],
1276 							      NULL,
1277 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1278 							      _col_types_view_column_usage, error);
1279 	if (!model)
1280 		return FALSE;
1281 
1282 	gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
1283 						   ((GdaProviderReuseable*) rdata));
1284 	retval = gda_meta_store_modify_with_context (store, context, model, error);
1285 	g_object_unref (model);
1286 
1287 	return retval;
1288 }
1289 
1290 gboolean
1291 _gda_postgres_meta_view_cols (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
1292 			      GdaMetaStore *store, GdaMetaContext *context, GError **error,
1293 			      const GValue *view_catalog, const GValue *view_schema,
1294 			      const GValue *view_name)
1295 {
1296 	GdaDataModel *model;
1297 	gboolean retval = TRUE;
1298 	GdaPostgresReuseable *rdata;
1299 
1300 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1301 	if (!rdata)
1302 		return FALSE;
1303 
1304 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "cat"), view_catalog, error))
1305 		return FALSE;
1306 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "schema"), view_schema, error))
1307 		return FALSE;
1308 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "name"), view_name, error))
1309 		return FALSE;
1310 
1311 	model = gda_connection_statement_execute_select_full (cnc,
1312 							      internal_stmt[I_STMT_VIEWS_COLUMNS],
1313 							      i_set,
1314 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1315 							      _col_types_view_column_usage, error);
1316 	if (!model)
1317 		return FALSE;
1318 
1319 	gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
1320 						   ((GdaProviderReuseable*) rdata));
1321 	retval = gda_meta_store_modify_with_context (store, context, model, error);
1322 	g_object_unref (model);
1323 
1324 	return retval;
1325 }
1326 
1327 gboolean
1328 _gda_postgres_meta__constraints_tab (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
1329 				     GdaMetaStore *store, GdaMetaContext *context, GError **error)
1330 {
1331 	GdaDataModel *model;
1332 	gboolean retval;
1333 	GdaPostgresReuseable *rdata;
1334 
1335 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1336 	if (!rdata)
1337 		return FALSE;
1338 
1339 	model = gda_connection_statement_execute_select_full (cnc,
1340 							      internal_stmt[I_STMT_TABLES_CONSTRAINTS_ALL],
1341 							      NULL,
1342 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1343 							      _col_types_table_constraints, error);
1344 	if (!model)
1345 		return FALSE;
1346 
1347 	gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
1348 						   ((GdaProviderReuseable*) rdata));
1349 	retval = gda_meta_store_modify_with_context (store, context, model, error);
1350 	g_object_unref (model);
1351 
1352 	return retval;
1353 }
1354 
1355 gboolean
1356 _gda_postgres_meta_constraints_tab (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
1357 				    GdaMetaStore *store, GdaMetaContext *context, GError **error,
1358 				    const GValue *table_catalog, const GValue *table_schema, const GValue *table_name,
1359 				    const GValue *constraint_name_n)
1360 {
1361 	GdaDataModel *model;
1362 	gboolean retval = TRUE;
1363 	GdaPostgresReuseable *rdata;
1364 
1365 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1366 	if (!rdata)
1367 		return FALSE;
1368 
1369 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "cat"), table_catalog, error))
1370 		return FALSE;
1371 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "schema"), table_schema, error))
1372 		return FALSE;
1373 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "name"), table_name, error))
1374 		return FALSE;
1375 
1376 	if (!constraint_name_n) {
1377 		model = gda_connection_statement_execute_select_full (cnc,
1378 								      internal_stmt[I_STMT_TABLES_CONSTRAINTS],
1379 								      i_set,
1380 								      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1381 								      _col_types_table_constraints, error);
1382 		if (!model)
1383 			return FALSE;
1384 		if (retval) {
1385 			gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
1386 						   ((GdaProviderReuseable*) rdata));
1387 			retval = gda_meta_store_modify (store, context->table_name, model,
1388 							"table_schema = ##schema::string AND table_name = ##name::string",
1389 							error,
1390 							"schema", table_schema, "name", table_name, NULL);
1391 		}
1392 
1393 	}
1394 	else {
1395 		if (! gda_holder_set_value (gda_set_get_holder (i_set, "name2"), constraint_name_n, error))
1396 			return FALSE;
1397 		model = gda_connection_statement_execute_select_full (cnc,
1398 								      internal_stmt[I_STMT_TABLES_CONSTRAINT_NAMED],
1399 								      i_set,
1400 								      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1401 								      _col_types_table_constraints, error);
1402 		if (!model)
1403 			return FALSE;
1404 		if (retval) {
1405 			gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
1406 						   ((GdaProviderReuseable*) rdata));
1407 			retval = gda_meta_store_modify (store, context->table_name, model,
1408 							"table_schema = ##schema::string AND table_name = ##name::string AND constraint_name = ##name2::string", error,
1409 							"schema", table_schema, "name", table_name, "name2", constraint_name_n, NULL);
1410 		}
1411 	}
1412 
1413 	g_object_unref (model);
1414 
1415 	return retval;
1416 }
1417 
1418 gboolean
1419 _gda_postgres_meta__constraints_ref (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
1420 				     GdaMetaStore *store, GdaMetaContext *context, GError **error)
1421 {
1422 	GdaDataModel *model;
1423 	gboolean retval;
1424 	GdaPostgresReuseable *rdata;
1425 
1426 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1427 	if (!rdata)
1428 		return FALSE;
1429 
1430 	model = gda_connection_statement_execute_select_full (cnc,
1431 							      internal_stmt[I_STMT_REF_CONSTRAINTS_ALL],
1432 							      NULL,
1433 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1434 							     _col_types_referential_constraints, error);
1435 	if (!model)
1436 		return FALSE;
1437 
1438 	gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
1439 						   ((GdaProviderReuseable*) rdata));
1440 	retval = gda_meta_store_modify_with_context (store, context, model, error);
1441 	g_object_unref (model);
1442 
1443 	return retval;
1444 }
1445 
1446 gboolean
1447 _gda_postgres_meta_constraints_ref (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
1448 				    GdaMetaStore *store, GdaMetaContext *context, GError **error,
1449 				    const GValue *table_catalog, const GValue *table_schema, const GValue *table_name,
1450 				    const GValue *constraint_name)
1451 {
1452 	GdaDataModel *model;
1453 	gboolean retval = TRUE;
1454 	GdaPostgresReuseable *rdata;
1455 
1456 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1457 	if (!rdata)
1458 		return FALSE;
1459 
1460 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "cat"), table_catalog, error))
1461 		return FALSE;
1462 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "schema"), table_schema, error))
1463 		return FALSE;
1464 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "name"), table_name, error))
1465 		return FALSE;
1466 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "name2"), constraint_name, error))
1467 		return FALSE;
1468 
1469 	model = gda_connection_statement_execute_select_full (cnc,
1470 							      internal_stmt[I_STMT_REF_CONSTRAINTS],
1471 							      i_set,
1472 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1473 							     _col_types_referential_constraints, error);
1474 	if (!model)
1475 		return FALSE;
1476 
1477 
1478 	/* modify meta store */
1479 	if (retval) {
1480 		gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
1481 						   ((GdaProviderReuseable*) rdata));
1482 		retval = gda_meta_store_modify (store, context->table_name, model,
1483 						"table_schema = ##schema::string AND table_name = ##name::string AND constraint_name = ##name2::string",
1484 						error,
1485 						"schema", table_schema, "name", table_name, "name2", constraint_name, NULL);
1486 	}
1487 	g_object_unref (model);
1488 
1489 	return retval;
1490 }
1491 
1492 gboolean
1493 _gda_postgres_meta__key_columns (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
1494 				 GdaMetaStore *store, GdaMetaContext *context, GError **error)
1495 {
1496 	GdaDataModel *model;
1497 	gboolean retval;
1498 	GdaPostgresReuseable *rdata;
1499 
1500 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1501 	if (!rdata)
1502 		return FALSE;
1503 
1504 	model = gda_connection_statement_execute_select_full (cnc,
1505 							      internal_stmt[I_STMT_KEY_COLUMN_USAGE_ALL],
1506 							      NULL,
1507 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1508 							     _col_types_key_column_usage, error);
1509 	if (!model)
1510 		return FALSE;
1511 
1512 	gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
1513 						   ((GdaProviderReuseable*) rdata));
1514 	retval = gda_meta_store_modify_with_context (store, context, model, error);
1515 	g_object_unref (model);
1516 
1517 	return retval;
1518 }
1519 
1520 gboolean
1521 _gda_postgres_meta_key_columns (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
1522 				GdaMetaStore *store, GdaMetaContext *context, GError **error,
1523 				const GValue *table_catalog, const GValue *table_schema, const GValue *table_name,
1524 				const GValue *constraint_name)
1525 {
1526 	GdaDataModel *model;
1527 	gboolean retval = TRUE;
1528 	GdaPostgresReuseable *rdata;
1529 
1530 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1531 	if (!rdata)
1532 		return FALSE;
1533 
1534 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "cat"), table_catalog, error))
1535 		return FALSE;
1536 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "schema"), table_schema, error))
1537 		return FALSE;
1538 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "name"), table_name, error))
1539 		return FALSE;
1540 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "name2"), constraint_name, error))
1541 		return FALSE;
1542 
1543 	model = gda_connection_statement_execute_select_full (cnc,
1544 							      internal_stmt[I_STMT_KEY_COLUMN_USAGE],
1545 							      i_set,
1546 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1547 							      _col_types_key_column_usage, error);
1548 	if (!model)
1549 		return FALSE;
1550 
1551 
1552 	/* modify meta store */
1553 	if (retval) {
1554 		gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
1555 						   ((GdaProviderReuseable*) rdata));
1556 		retval = gda_meta_store_modify (store, context->table_name, model,
1557 						"table_schema = ##schema::string AND table_name = ##name::string AND constraint_name = ##name2::string",
1558 						error,
1559 						"schema", table_schema, "name", table_name, "name2", constraint_name, NULL);
1560 	}
1561 	g_object_unref (model);
1562 
1563 	return retval;
1564 }
1565 
1566 gboolean
1567 _gda_postgres_meta__check_columns (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
1568 				   GdaMetaStore *store, GdaMetaContext *context, GError **error)
1569 {
1570 	GdaDataModel *model;
1571 	gboolean retval;
1572 	GdaPostgresReuseable *rdata;
1573 
1574 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1575 	if (!rdata)
1576 		return FALSE;
1577 
1578 	model = gda_connection_statement_execute_select_full (cnc,
1579 							      internal_stmt[I_STMT_CHECK_COLUMN_USAGE_ALL],
1580 							      NULL,
1581 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1582 							      _col_types_check_column_usage, error);
1583 	if (!model)
1584 		return FALSE;
1585 
1586 	gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
1587 						   ((GdaProviderReuseable*) rdata));
1588 	retval = gda_meta_store_modify_with_context (store, context, model, error);
1589 	g_object_unref (model);
1590 
1591 	return retval;
1592 }
1593 
1594 gboolean
1595 _gda_postgres_meta_check_columns (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
1596 				  GdaMetaStore *store, GdaMetaContext *context, GError **error,
1597 				  const GValue *table_catalog, const GValue *table_schema,
1598 				  const GValue *table_name, const GValue *constraint_name)
1599 {
1600 	GdaDataModel *model;
1601 	gboolean retval = TRUE;
1602 	GdaPostgresReuseable *rdata;
1603 
1604 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1605 	if (!rdata)
1606 		return FALSE;
1607 
1608 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "cat"), table_catalog, error))
1609 		return FALSE;
1610 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "schema"), table_schema, error))
1611 		return FALSE;
1612 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "name"), table_name, error))
1613 		return FALSE;
1614 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "name2"), constraint_name, error))
1615 		return FALSE;
1616 
1617 	model = gda_connection_statement_execute_select_full (cnc,
1618 							      internal_stmt[I_STMT_CHECK_COLUMN_USAGE],
1619 							      i_set,
1620 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1621 							      _col_types_check_column_usage, error);
1622 	if (!model)
1623 		return FALSE;
1624 
1625 
1626 	/* modify meta store */
1627 	if (retval) {
1628 		gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
1629 						   ((GdaProviderReuseable*) rdata));
1630 		retval = gda_meta_store_modify (store, context->table_name, model,
1631 						"table_schema = ##schema::string AND table_name = ##name::string AND constraint_name = ##name2::string",
1632 						error,
1633 						"schema", table_schema, "name", table_name, "name2", constraint_name, NULL);
1634 	}
1635 	g_object_unref (model);
1636 
1637 	return retval;
1638 }
1639 
1640 gboolean
1641 _gda_postgres_meta__triggers (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
1642 			      GdaMetaStore *store, GdaMetaContext *context, GError **error)
1643 {
1644 	GdaDataModel *model;
1645 	gboolean retval;
1646 
1647 	/* check correct postgres server version */
1648 	GdaPostgresReuseable *rdata;
1649 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1650 	if (!rdata)
1651 		return FALSE;
1652 	if (rdata->version_float < 8.2) {
1653 		/* nothing for this version of PostgreSQL */
1654 		return TRUE;
1655 	}
1656 
1657 	model = gda_connection_statement_execute_select_full (cnc,
1658 							      internal_stmt[I_STMT_TRIGGERS_ALL],
1659 							      NULL,
1660 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1661 							      _col_types_triggers, error);
1662 	if (!model)
1663 		return FALSE;
1664 
1665 	gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
1666 						   ((GdaProviderReuseable*) rdata));
1667 	retval = gda_meta_store_modify_with_context (store, context, model, error);
1668 	g_object_unref (model);
1669 
1670 	return retval;
1671 }
1672 
1673 gboolean
1674 _gda_postgres_meta_triggers (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
1675 			     GdaMetaStore *store, GdaMetaContext *context, GError **error,
1676 			     const GValue *table_catalog, const GValue *table_schema,
1677 			     const GValue *table_name)
1678 {
1679 	GdaDataModel *model;
1680 	gboolean retval = TRUE;
1681 
1682 	/* check correct postgres server version */
1683 	GdaPostgresReuseable *rdata;
1684 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1685 	if (!rdata)
1686 		return FALSE;
1687 	if (rdata->version_float < 8.2) {
1688 		/* nothing for this version of PostgreSQL */
1689 		return TRUE;
1690 	}
1691 
1692 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "cat"), table_catalog, error))
1693 		return FALSE;
1694 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "schema"), table_schema, error))
1695 		return FALSE;
1696 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "name"), table_name, error))
1697 		return FALSE;
1698 
1699 	model = gda_connection_statement_execute_select_full (cnc,
1700 							      internal_stmt[I_STMT_TRIGGERS],
1701 							      i_set,
1702 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1703 							      _col_types_triggers, error);
1704 	if (!model)
1705 		return FALSE;
1706 
1707 	gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
1708 						   ((GdaProviderReuseable*) rdata));
1709 	retval = gda_meta_store_modify_with_context (store, context, model, error);
1710 	g_object_unref (model);
1711 
1712 	return retval;
1713 }
1714 
1715 gboolean
1716 _gda_postgres_meta__routines (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
1717 			      GdaMetaStore *store, GdaMetaContext *context, GError **error)
1718 {
1719 	GdaDataModel *model;
1720 	gboolean retval;
1721 
1722 	/* check correct postgres server version */
1723 	GdaPostgresReuseable *rdata;
1724 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1725 	if (!rdata)
1726 		return FALSE;
1727 	if (rdata->version_float < 8.2) {
1728 		/* nothing for this version of PostgreSQL */
1729 		return TRUE;
1730 	}
1731 
1732 	model = gda_connection_statement_execute_select_full (cnc,
1733 							      internal_stmt[I_STMT_ROUTINES_ALL],
1734 							      NULL,
1735 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1736 							      _col_types_routines, error);
1737 	if (!model)
1738 		return FALSE;
1739 
1740 	gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
1741 						   ((GdaProviderReuseable*) rdata));
1742 	retval = gda_meta_store_modify_with_context (store, context, model, error);
1743 	g_object_unref (model);
1744 
1745 	return retval;
1746 }
1747 
1748 gboolean
1749 _gda_postgres_meta_routines (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
1750 			     GdaMetaStore *store, GdaMetaContext *context, GError **error,
1751 			     const GValue *routine_catalog, const GValue *routine_schema,
1752 			     const GValue *routine_name_n)
1753 {
1754 	GdaDataModel *model;
1755 	gboolean retval = TRUE;
1756 
1757 	/* check correct postgres server version */
1758 	GdaPostgresReuseable *rdata;
1759 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1760 	if (!rdata)
1761 		return FALSE;
1762 	if (rdata->version_float < 8.2) {
1763 		/* nothing for this version of PostgreSQL */
1764 		return TRUE;
1765 	}
1766 
1767 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "cat"), routine_catalog, error))
1768 		return FALSE;
1769 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "schema"), routine_schema, error))
1770 		return FALSE;
1771 	if (routine_name_n) {
1772 		if (! gda_holder_set_value (gda_set_get_holder (i_set, "name"), routine_name_n, error))
1773 			return FALSE;
1774 		model = gda_connection_statement_execute_select_full (cnc,
1775 								      internal_stmt[I_STMT_ROUTINES_ONE],
1776 								      i_set,
1777 								      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1778 								      _col_types_routines, error);
1779 	}
1780 	else
1781 		model = gda_connection_statement_execute_select_full (cnc,
1782 								      internal_stmt[I_STMT_ROUTINES],
1783 								      i_set,
1784 								      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1785 								      _col_types_routines, error);
1786 	if (!model)
1787 		return FALSE;
1788 
1789 	gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
1790 						   ((GdaProviderReuseable*) rdata));
1791 	retval = gda_meta_store_modify_with_context (store, context, model, error);
1792 	g_object_unref (model);
1793 
1794 	return retval;
1795 }
1796 
1797 gboolean
1798 _gda_postgres_meta__routine_col (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
1799 				 GdaMetaStore *store, GdaMetaContext *context, GError **error)
1800 {
1801 	GdaDataModel *model, *proxy;
1802 	gint ordinal_pos, i, nrows;
1803 	const GValue *spname = NULL;
1804 	gboolean retval;
1805 
1806 	/* check correct postgres server version */
1807 	GdaPostgresReuseable *rdata;
1808 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1809 	if (!rdata)
1810 		return FALSE;
1811 	if (rdata->version_float < 8.2) {
1812 		/* nothing for this version of PostgreSQL */
1813 		return TRUE;
1814 	}
1815 
1816 	model = gda_connection_statement_execute_select_full (cnc,
1817 							      internal_stmt[I_STMT_ROUTINE_COL_ALL],
1818 							      NULL,
1819 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1820 							      _col_types_routine_columns, error);
1821 	if (!model)
1822 		return FALSE;
1823 
1824 	/* use a proxy to customize @model */
1825 	proxy = (GdaDataModel*) gda_data_proxy_new (model);
1826 	g_object_set (G_OBJECT (proxy), "defer-sync", FALSE, "sample-size", 0, NULL);
1827 	nrows = gda_data_model_get_n_rows (model);
1828 	for (i = 0; i < nrows; i++) {
1829 		const GValue *cvalue;
1830 		GValue *v;
1831 
1832 		cvalue = gda_data_model_get_value_at (model, 2, i, error);
1833 		if (!cvalue) {
1834 			retval = FALSE;
1835 			break;
1836 		}
1837 		if (!spname || gda_value_compare (spname, cvalue))
1838 			/* reinit ordinal position */
1839 			ordinal_pos = 1;
1840 		spname = cvalue;
1841 
1842 		g_value_set_int ((v = gda_value_new (G_TYPE_INT)), ordinal_pos++);
1843 		retval = gda_data_model_set_value_at (proxy, 4, i, v, error);
1844 		gda_value_free (v);
1845 		if (!retval)
1846 			break;
1847 	}
1848 
1849 	if (retval) {
1850 		gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
1851 						   ((GdaProviderReuseable*) rdata));
1852 		retval = gda_meta_store_modify_with_context (store, context, proxy, error);
1853 	}
1854 	g_object_unref (model);
1855 	g_object_unref (proxy);
1856 
1857 	return retval;
1858 }
1859 
1860 gboolean
1861 _gda_postgres_meta_routine_col (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
1862 				GdaMetaStore *store, GdaMetaContext *context, GError **error,
1863 				const GValue *rout_catalog, const GValue *rout_schema,
1864 				const GValue *rout_name)
1865 {
1866 	GdaDataModel *model, *proxy;
1867 	gint ordinal_pos, i, nrows;
1868 	const GValue *spname = NULL;
1869 	gboolean retval;
1870 
1871 	/* check correct postgres server version */
1872 	GdaPostgresReuseable *rdata;
1873 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1874 	if (!rdata)
1875 		return FALSE;
1876 	if (rdata->version_float < 8.2) {
1877 		/* nothing for this version of PostgreSQL */
1878 		return TRUE;
1879 	}
1880 
1881 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "cat"), rout_catalog, error))
1882 		return FALSE;
1883 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "schema"), rout_schema, error))
1884 		return FALSE;
1885 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "name"), rout_name, error))
1886 		return FALSE;
1887 
1888 	model = gda_connection_statement_execute_select_full (cnc,
1889 							      internal_stmt[I_STMT_ROUTINE_COL],
1890 							      i_set,
1891 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1892 							      _col_types_routine_columns, error);
1893 	if (!model)
1894 		return FALSE;
1895 
1896 	/* use a proxy to customize @model */
1897 	proxy = (GdaDataModel*) gda_data_proxy_new (model);
1898 	g_object_set (G_OBJECT (proxy), "defer-sync", FALSE, "sample-size", 0, NULL);
1899 	nrows = gda_data_model_get_n_rows (model);
1900 	for (i = 0; i < nrows; i++) {
1901 		const GValue *cvalue;
1902 		GValue *v;
1903 
1904 		cvalue = gda_data_model_get_value_at (model, 2, i, error);
1905 		if (!cvalue) {
1906 			retval = FALSE;
1907 			break;
1908 		}
1909 
1910 		if (!spname || gda_value_compare (spname, cvalue))
1911 			/* reinit ordinal position */
1912 			ordinal_pos = 1;
1913 		spname = cvalue;
1914 
1915 		g_value_set_int ((v = gda_value_new (G_TYPE_INT)), ordinal_pos++);
1916 		retval = gda_data_model_set_value_at (proxy, 4, i, v, error);
1917 		gda_value_free (v);
1918 		if (!retval)
1919 			break;
1920 	}
1921 
1922 	if (retval) {
1923 		gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
1924 						   ((GdaProviderReuseable*) rdata));
1925 		retval = gda_meta_store_modify_with_context (store, context, proxy, error);
1926 	}
1927 	g_object_unref (model);
1928 	g_object_unref (proxy);
1929 
1930 	return retval;
1931 }
1932 
1933 gboolean
1934 _gda_postgres_meta__routine_par (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
1935 				 GdaMetaStore *store, GdaMetaContext *context, GError **error)
1936 {
1937 	GdaDataModel *model;
1938 	gboolean retval;
1939 
1940 	/* check correct postgres server version */
1941 	GdaPostgresReuseable *rdata;
1942 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1943 	if (!rdata)
1944 		return FALSE;
1945 	if (rdata->version_float < 8.2) {
1946 		/* nothing for this version of PostgreSQL */
1947 		return TRUE;
1948 	}
1949 
1950 	model = gda_connection_statement_execute_select_full (cnc,
1951 							      internal_stmt[I_STMT_ROUTINE_PAR_ALL],
1952 							      NULL,
1953 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1954 							      _col_types_parameters, error);
1955 	if (!model)
1956 		return FALSE;
1957 
1958 	gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
1959 						   ((GdaProviderReuseable*) rdata));
1960 	retval = gda_meta_store_modify_with_context (store, context, model, error);
1961 	g_object_unref (model);
1962 
1963 	return retval;
1964 }
1965 
1966 gboolean
1967 _gda_postgres_meta_routine_par (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
1968 				GdaMetaStore *store, GdaMetaContext *context, GError **error,
1969 				const GValue *rout_catalog, const GValue *rout_schema,
1970 				const GValue *rout_name)
1971 {
1972 	GdaDataModel *model;
1973 	gboolean retval = TRUE;
1974 
1975 	/* check correct postgres server version */
1976 	GdaPostgresReuseable *rdata;
1977 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
1978 	if (!rdata)
1979 		return FALSE;
1980 	if (rdata->version_float < 8.2) {
1981 		/* nothing for this version of PostgreSQL */
1982 		return TRUE;
1983 	}
1984 
1985 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "cat"), rout_catalog, error))
1986 		return FALSE;
1987 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "schema"), rout_schema, error))
1988 		return FALSE;
1989 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "name"), rout_name, error))
1990 		return FALSE;
1991 
1992 	model = gda_connection_statement_execute_select_full (cnc,
1993 							      internal_stmt[I_STMT_ROUTINE_PAR],
1994 							      i_set,
1995 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
1996 							      _col_types_parameters, error);
1997 	if (!model)
1998 		return FALSE;
1999 
2000 	gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
2001 						   ((GdaProviderReuseable*) rdata));
2002 	retval = gda_meta_store_modify_with_context (store, context, model, error);
2003 	g_object_unref (model);
2004 
2005 	return retval;
2006 }
2007 
2008 gboolean
2009 _gda_postgres_meta__indexes_tab (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
2010 				 GdaMetaStore *store, GdaMetaContext *context, GError **error)
2011 {
2012 	GdaDataModel *model;
2013 	gboolean retval;
2014 	GType *types;
2015 
2016 	/* check correct postgres server version */
2017 	GdaPostgresReuseable *rdata;
2018 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
2019 	if (!rdata)
2020 		return FALSE;
2021 	if (rdata->version_float < 8.2) {
2022 		/* nothing for this version of PostgreSQL */
2023 		return TRUE;
2024 	}
2025 
2026 	gint tsize;
2027 	tsize = sizeof (_col_types_table_indexes) / sizeof (GType);
2028 	types = g_new (GType, tsize + 1);
2029 	memcpy (types, _col_types_table_indexes, tsize * sizeof (GType));
2030 	types [tsize-1] = G_TYPE_UINT;
2031 	types [tsize] = G_TYPE_NONE;
2032 
2033 	model = gda_connection_statement_execute_select_full (cnc,
2034 							      internal_stmt[I_STMT_INDEXES_ALL],
2035 							      NULL,
2036 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
2037 							      types, error);
2038 	g_free (types);
2039 	if (!model)
2040 		return FALSE;
2041 
2042 	gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
2043 						   ((GdaProviderReuseable*) rdata));
2044 	retval = gda_meta_store_modify_with_context (store, context, model, error);
2045 	g_object_unref (model);
2046 
2047 	return retval;
2048 }
2049 
2050 gboolean
2051 _gda_postgres_meta_indexes_tab (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
2052 				GdaMetaStore *store, GdaMetaContext *context, GError **error,
2053 				const GValue *table_catalog, const GValue *table_schema, const GValue *table_name,
2054 				const GValue *index_name_n)
2055 {
2056 	GdaDataModel *model;
2057 	gboolean retval = TRUE;
2058 	GType *types;
2059 
2060 	/* check correct postgres server version */
2061 	GdaPostgresReuseable *rdata;
2062 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
2063 	if (!rdata)
2064 		return FALSE;
2065 	if (rdata->version_float < 8.2) {
2066 		/* nothing for this version of PostgreSQL */
2067 		return TRUE;
2068 	}
2069 
2070 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "cat"), table_catalog, error))
2071 		return FALSE;
2072 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "schema"), table_schema, error))
2073 		return FALSE;
2074 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "name"), table_name, error))
2075 		return FALSE;
2076 
2077 	gint tsize;
2078 	tsize = sizeof (_col_types_table_indexes) / sizeof (GType);
2079 	types = g_new (GType, tsize + 1);
2080 	memcpy (types, _col_types_table_indexes, tsize * sizeof (GType));
2081 	types [tsize-1] = G_TYPE_UINT;
2082 	types [tsize] = G_TYPE_NONE;
2083 
2084 	if (index_name_n) {
2085 		if (! gda_holder_set_value (gda_set_get_holder (i_set, "name2"), index_name_n, error)) {
2086 			g_free (types);
2087 			return FALSE;
2088 		}
2089 		model = gda_connection_statement_execute_select_full (cnc,
2090 								      internal_stmt[I_STMT_INDEXES_NAMED],
2091 								      i_set,
2092 								      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
2093 								      types, error);
2094 	}
2095 	else
2096 		model = gda_connection_statement_execute_select_full (cnc,
2097 								      internal_stmt[I_STMT_INDEXES],
2098 								      i_set,
2099 								      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
2100 								      types, error);
2101 	g_free (types);
2102 	if (!model)
2103 		return FALSE;
2104 
2105 	gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
2106 						   ((GdaProviderReuseable*) rdata));
2107 	retval = gda_meta_store_modify_with_context (store, context, model, error);
2108 	g_object_unref (model);
2109 
2110 	return retval;
2111 }
2112 
2113 static GdaDataModel *
2114 concatenate_index_details (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
2115 			   G_GNUC_UNUSED GdaMetaStore *store, GdaDataModel *index_oid_model, GError **error)
2116 {
2117 	GdaDataModel *concat = NULL;
2118 	gint i, nrows;
2119 	nrows = gda_data_model_get_n_rows (index_oid_model);
2120 	if (nrows == 0) {
2121 		g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_INTERNAL_ERROR,
2122 			     "%s", _("could not determine the indexed columns for index"));
2123 		return NULL;
2124 	}
2125 	for (i = 0; i < nrows; i++) {
2126 		const GValue *value;
2127 		value = gda_data_model_get_value_at (index_oid_model, 0, i, error);
2128 		if (!value) {
2129 			if (concat)
2130 				g_object_unref (concat);
2131 			return NULL;
2132 		}
2133 
2134 		if (G_VALUE_TYPE (value) == GDA_TYPE_NULL)
2135 			continue;
2136 
2137 		/* get index's columns details */
2138 		GdaDataModel *tmpmodel;
2139 		if (! gda_holder_set_value (gda_set_get_holder (i_set, "oid"), value, error)) {
2140 			if (concat)
2141 				g_object_unref (concat);
2142 			return NULL;
2143 		}
2144 		tmpmodel = gda_connection_statement_execute_select_full (cnc,
2145 									 internal_stmt[I_STMT_INDEXES_COLUMNS_FOR_INDEX],
2146 									 i_set,
2147 									 GDA_STATEMENT_MODEL_RANDOM_ACCESS,
2148 									 _col_types_index_column_usage, error);
2149 		if (!tmpmodel) {
2150 			if (concat)
2151 				g_object_unref (concat);
2152 			return NULL;
2153 		}
2154 
2155 		/* create a concatenated model of all the @tmpmodel's contents */
2156 		if (!concat) {
2157 			concat = (GdaDataModel*) gda_data_model_array_copy_model (tmpmodel, error);
2158 			if (!concat) {
2159 				g_object_unref (tmpmodel);
2160 				return NULL;
2161 			}
2162 		}
2163 		else {
2164 			gint tnrows, ti, tncols;
2165 			tnrows = gda_data_model_get_n_rows (tmpmodel);
2166 			tncols = gda_data_model_get_n_columns (tmpmodel);
2167 			for (ti = 0; ti < tnrows; ti++) {
2168 				GList *list = NULL;
2169 				gint tj;
2170 				for (tj = tncols - 1; tj >= 0 ; tj--) {
2171 					value = gda_data_model_get_value_at (tmpmodel, tj, ti, error);
2172 					if (!value) {
2173 						g_list_free (list);
2174 						g_object_unref (tmpmodel);
2175 						if (concat)
2176 							g_object_unref (concat);
2177 						return NULL;
2178 					}
2179 					list = g_list_prepend (list, (gpointer) value);
2180 				}
2181 				if (gda_data_model_append_values (concat, list, error) == -1) {
2182 					g_list_free (list);
2183 					g_object_unref (tmpmodel);
2184 					if (concat)
2185 						g_object_unref (concat);
2186 					return NULL;
2187 				}
2188 				g_list_free (list);
2189 			}
2190 		}
2191 	}
2192 	return concat;
2193 }
2194 
2195 gboolean
2196 _gda_postgres_meta__index_cols (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
2197 				GdaMetaStore *store, GdaMetaContext *context, GError **error)
2198 {
2199 	GdaDataModel *model, *concat;
2200 	GType index_oids_types[] = {G_TYPE_UINT, G_TYPE_NONE};
2201 
2202 	/* check correct postgres server version */
2203 	GdaPostgresReuseable *rdata;
2204 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
2205 	if (!rdata)
2206 		return FALSE;
2207 	if (rdata->version_float < 8.2) {
2208 		/* nothing for this version of PostgreSQL */
2209 		return TRUE;
2210 	}
2211 
2212 	model = gda_connection_statement_execute_select_full (cnc,
2213 							      internal_stmt[I_STMT_INDEXES_COLUMNS_GET_ALL_INDEXES],
2214 							      NULL,
2215 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
2216 							      index_oids_types, error);
2217 	if (!model)
2218 		return FALSE;
2219 
2220 	concat = concatenate_index_details (prov, cnc, store, model, error);
2221 	g_object_unref (model);
2222 	if (!concat)
2223 		return FALSE;
2224 
2225 	gboolean retval;
2226 	gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
2227 						   ((GdaProviderReuseable*) rdata));
2228 	retval = gda_meta_store_modify_with_context (store, context, concat, error);
2229 	g_object_unref (concat);
2230 
2231 	return retval;
2232 }
2233 
2234 gboolean
2235 _gda_postgres_meta_index_cols (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
2236 			       GdaMetaStore *store, GdaMetaContext *context, GError **error,
2237 			       const GValue *table_catalog, const GValue *table_schema,
2238 			       const GValue *table_name, const GValue *index_name)
2239 {
2240 	GdaDataModel *model, *concat;
2241 	GType index_oids_types[] = {G_TYPE_UINT, G_TYPE_NONE};
2242 
2243 	/* check correct postgres server version */
2244 	GdaPostgresReuseable *rdata;
2245 	rdata = GDA_POSTGRES_GET_REUSEABLE_DATA (gda_connection_internal_get_provider_data_error (cnc, error));
2246 	if (!rdata)
2247 		return FALSE;
2248 	if (rdata->version_float < 8.2) {
2249 		/* nothing for this version of PostgreSQL */
2250 		return TRUE;
2251 	}
2252 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "cat"), table_catalog, error))
2253 		return FALSE;
2254 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "schema"), table_schema, error))
2255 		return FALSE;
2256 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "name"), table_name, error))
2257 		return FALSE;
2258 	if (! gda_holder_set_value (gda_set_get_holder (i_set, "name2"), index_name, error))
2259 		return FALSE;
2260 	model = gda_connection_statement_execute_select_full (cnc,
2261 							      internal_stmt[I_STMT_INDEXES_COLUMNS_GET_NAMED_INDEXES],
2262 							      i_set,
2263 							      GDA_STATEMENT_MODEL_RANDOM_ACCESS,
2264 							      index_oids_types, error);
2265 	if (!model)
2266 		return FALSE;
2267 
2268 	concat = concatenate_index_details (prov, cnc, store, model, error);
2269 	g_object_unref (model);
2270 	if (!concat)
2271 		return FALSE;
2272 
2273 	gboolean retval;
2274 	gda_meta_store_set_reserved_keywords_func (store, _gda_postgres_reuseable_get_reserved_keywords_func
2275 						   ((GdaProviderReuseable*) rdata));
2276 	retval = gda_meta_store_modify_with_context (store, context, concat, error);
2277 	g_object_unref (concat);
2278 	return retval;
2279 }
2280