apache / apache/datafusion

information_schema.tables contains all tables from all catalogs instead of current catalog

Open
#15,960 1 comment 0 reactions 1 assignee Claimed by @VaibhaveS View on GitHub
bug
Dominant language
Rust
Stars
9.3k
Forks
2.4k
Avg merge
3d 7h
Merged PRs (30d)
344

Description

### Describe the bug

According to [Postgres docs](https://www.postgresql.org/docs/current/infoschema-tables.html) information_schema.tables should contain all tables and views defined in the current database.

At the moment we are adding all tables from all catalogs

```rust
async fn make_tables(
&self,
builder: &mut InformationSchemaTablesBuilder,
) -> Result<(), DataFusionError> {
.....
for catalog_name in self.catalog_list.catalog_names() {
let catalog = self.catalog_list.catalog(&catalog_name).unwrap();

for schema_name in catalog.schema_names() {
if schema_name != INFORMATION_SCHEMA {
// schema name may not exist in the catalog, so we need to check
if let Some(schema) = catalog.schema(&schema_name) {
for table_name in schema.table_names() {
if let Some(table) = schema.table(&table_name).await? {
builder.add_table(
&catalog_name,
&schema_name,
&table_name,
table.table_type(),
);
}
}
}
}
}
...
```

because of this, when calling a specific **catalog.information_schema.tables**, we get a list of all tables from all catalogs
There may be problems with access rights to other catalogs, as well as incorrect information about the list of tables in the current catalog

### To Reproduce

Register several catalogs with schemas and tables and run the query
```sql
SELECT * FROM catalog_name.information_schema.tables
```

### Expected behavior

The list of tables only from the **current catalog**

### Additional context

The possible solution here is to pass catalog name from resolved table reference here to InformationSchemaProvider::new
and

```rust
pub fn schema_for_ref(
&self,
table_ref: impl Into,
) -> datafusion_common::Result> {
let resolved_ref = self.resolve_table_ref(table_ref);
if self.config.information_schema() && *resolved_ref.schema == *INFORMATION_SCHEMA
{
return Ok(Arc::new(InformationSchemaProvider::new(Arc::clone(
&self.catalog_list,
))));
}
```

remove this part
```rust
for catalog_name in self.catalog_list.catalog_names() {
```
and work with specific catalog (if exists, information_schema.tables without fully qualified name will use default catalog and if default catalog is not enabled in this session it will trigger unwrap panic, so we need to check)
```rust
impl InformationSchemaConfig {
/// Construct the `information_schema.tables` virtual table
async fn make_tables(
&self,
builder: &mut InformationSchemaTablesBuilder,
) -> Result<(), DataFusionError> {
let catalog = self.catalog_list.catalog(&self.catalog_name);
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.