|
1 | 1 | import collections |
2 | 2 | import threading |
3 | | -from sqlalchemy import text |
| 3 | +from sqlalchemy import text, Table, MetaData, Column, String, Boolean, select, tuple_ |
4 | 4 | from sqlalchemy import ARRAY |
5 | 5 | from sqlalchemy import BIGINT |
6 | 6 | from sqlalchemy import BLOB |
@@ -48,6 +48,12 @@ class CockroachDBDialect(PGDialect): |
48 | 48 | preparer = CockroachIdentifierPreparer |
49 | 49 | ddl_compiler = CockroachDDLCompiler |
50 | 50 |
|
| 51 | + multi_entries_to_ignore = [ |
| 52 | + (None, "geography_columns"), |
| 53 | + (None, "geometry_columns"), |
| 54 | + (None, "spatial_ref_sys"), |
| 55 | + ] |
| 56 | + |
51 | 57 | # Override connect so we can take disable_cockroachdb_telemetry as a connect_arg to sqlalchemy. |
52 | 58 | # The option is not used any more, but removing it is a backwards-incompatible change. |
53 | 59 | def connect( |
@@ -137,35 +143,50 @@ def get_multi_columns(self, connection, schema, filter_names, scope, kind, **kw) |
137 | 143 | connection, schema, filter_names, scope, kind, **kw |
138 | 144 | ) |
139 | 145 | to_return = [] |
140 | | - if multi_columns: |
141 | | - current = connection.execute( |
142 | | - text("select current_database() as db, current_schema() as schema") |
143 | | - ).one() |
144 | | - for table, columns in multi_columns: |
145 | | - if table not in [ |
146 | | - (None, "geography_columns"), |
147 | | - (None, "geometry_columns"), |
148 | | - (None, "spatial_ref_sys"), |
149 | | - ]: |
150 | | - table_columns = ( |
151 | | - connection.execute( |
152 | | - text( |
153 | | - "select column_name, is_hidden::bool " |
154 | | - "from information_schema.columns " |
155 | | - "where table_catalog = :tc " |
156 | | - "and table_schema = :ts and table_name = :tn" |
157 | | - ), |
158 | | - dict(tc=current.db, ts=table[0] or current.schema, tn=table[1]), |
159 | | - ) |
160 | | - .mappings() |
161 | | - .all() |
| 146 | + current = connection.execute( |
| 147 | + text("select current_database() as db, current_schema() as schema") |
| 148 | + ).one() |
| 149 | + to_get = [ |
| 150 | + (item[0][0] or current.schema, item[0][1]) |
| 151 | + for item in multi_columns |
| 152 | + if item[0] |
| 153 | + not in self.multi_entries_to_ignore |
| 154 | + ] |
| 155 | + if to_get: |
| 156 | + info_schema_columns = Table( |
| 157 | + "columns", |
| 158 | + MetaData(), |
| 159 | + Column("table_catalog", String), |
| 160 | + Column("table_schema", String), |
| 161 | + Column("table_name", String), |
| 162 | + Column("column_name", String), |
| 163 | + Column("is_hidden", Boolean), |
| 164 | + schema="information_schema", |
| 165 | + ) |
| 166 | + qry = ( |
| 167 | + select(info_schema_columns) |
| 168 | + .where(info_schema_columns.c.table_catalog == current.db) |
| 169 | + .where( |
| 170 | + ( |
| 171 | + tuple_( |
| 172 | + info_schema_columns.c.table_schema, info_schema_columns.c.table_name |
| 173 | + ).in_(to_get) |
162 | 174 | ) |
163 | | - is_hidden = {x["column_name"]: x["is_hidden"] for x in table_columns} |
| 175 | + ) |
| 176 | + ) |
| 177 | + result = connection.execute(qry).all() |
| 178 | + is_hidden = { |
| 179 | + (row.table_schema, row.table_name, row.column_name): (row.is_hidden == "YES") |
| 180 | + for row in result |
| 181 | + } |
| 182 | + for table, columns in multi_columns: |
| 183 | + if table not in self.multi_entries_to_ignore: |
164 | 184 | for col in columns[:]: |
165 | | - if is_hidden[col["name"]] and not _include_hidden: |
| 185 | + key = (table[0] or current.schema, table[1], col["name"]) |
| 186 | + if is_hidden[key] and not _include_hidden: |
166 | 187 | columns.remove(col) |
167 | 188 | else: |
168 | | - col["is_hidden"] = is_hidden[col["name"]] |
| 189 | + col["is_hidden"] = is_hidden[key] |
169 | 190 | if col["default"] == "unique_rowid()": |
170 | 191 | col["autoincrement"] = True |
171 | 192 | if isinstance(col["type"], BIGINT): |
@@ -271,11 +292,7 @@ def get_multi_indexes(self, connection, schema, filter_names, scope, kind, **kw) |
271 | 292 | result = super().get_multi_indexes(connection, schema, filter_names, scope, kind, **kw) |
272 | 293 | if schema is None: |
273 | 294 | result = dict(result) |
274 | | - for k in [ |
275 | | - (None, "spatial_ref_sys"), |
276 | | - (None, "geometry_columns"), |
277 | | - (None, "geography_columns"), |
278 | | - ]: |
| 295 | + for k in self.multi_entries_to_ignore: |
279 | 296 | result.pop(k, None) |
280 | 297 | return result |
281 | 298 |
|
@@ -307,11 +324,7 @@ def get_multi_pk_constraint(self, connection, schema, filter_names, scope, kind, |
307 | 324 | ) |
308 | 325 | if schema is None: |
309 | 326 | result = dict(result) |
310 | | - for k in [ |
311 | | - (None, "spatial_ref_sys"), |
312 | | - (None, "geometry_columns"), |
313 | | - (None, "geography_columns"), |
314 | | - ]: |
| 327 | + for k in self.multi_entries_to_ignore: |
315 | 328 | result.pop(k, None) |
316 | 329 | return result |
317 | 330 |
|
@@ -339,11 +352,7 @@ def get_multi_check_constraints(self, connection, schema, filter_names, scope, k |
339 | 352 | ) |
340 | 353 | if schema is None: |
341 | 354 | result = dict(result) |
342 | | - for k in [ |
343 | | - (None, "spatial_ref_sys"), |
344 | | - (None, "geometry_columns"), |
345 | | - (None, "geography_columns"), |
346 | | - ]: |
| 355 | + for k in self.multi_entries_to_ignore: |
347 | 356 | result.pop(k, None) |
348 | 357 | return result |
349 | 358 |
|
|
0 commit comments