Repository: tobymao/sqlglot

Issue:
BigQuery INFORMATION_SCHEMA views not parsed properly?
BigQuery has [INFORMATION_SCHEMA views](https://cloud.google.com/bigquery/docs/information-schema-intro#project_qualifier) that don't seem to parse properly using sqlglot?

For example: `sqlglot.parse_one("SELECT * FROM project.dataset.INFORMATION_SCHEMA.TABLES", read="bigquery")` gives:
```
(SELECT expressions:
  (STAR ), from:
  (FROM expressions:
    (TABLE this:
      (IDENTIFIER this: TABLES, quoted: False), db:
      (IDENTIFIER this: INFORMATION_SCHEMA, quoted: False), catalog:
      (IDENTIFIER this: dataset, quoted: False))))
```

which leaves out the `project` part completely. Not quite sure what the correct behavior would be though!



Discussion:
Maybe we could parse this into:

```
(SELECT expressions:
  (STAR ), from:
  (FROM expressions:
    (TABLE this:
      (IDENTIFIER this: TABLES, quoted: False), db:
      (IDENTIFIER this: dataset.INFORMATION_SCHEMA, quoted: False), catalog:
      (IDENTIFIER this: project, quoted: False))))
```

From what I understand, qualifying INFORMATION_SCHEMA with a db or region simply results in a new db, right? @tobymao 

Didn't we used to parse an arbitrary number of Dot expressions?

Something like...
```
(SELECT expressions:
  (STAR ), from:
  (FROM expressions:
    (DOT this:
      (TABLE this:
        (IDENTIFIER this: project, quoted: False), db:
        (IDENTIFIER this: dataset, quoted: False), catalog:
        (IDENTIFIER this: INFORMATION_SCHEMA, quoted: False)), expression:
    (IDENTIFIER this: TABLES, quoted: False))
```

that's done for columns but i don't think it's done for tables. so the fix here is to add the arbitrary dot modifier to table names as well
Regarding columns, is the following syntax tree what we're after?

```python
>>> sqlglot.parse_one("SELECT INFORMATION_SCHEMA.TABLES.TABLE_NAME")
(SELECT expressions:
  (DOT this:
    (COLUMN this:
      (IDENTIFIER this: TABLES, quoted: False), table:
      (IDENTIFIER this: INFORMATION_SCHEMA, quoted: False)), expression:
    (IDENTIFIER this: TABLE_NAME, quoted: False)), from:
  (FROM expressions:
    (TABLE this:
      (IDENTIFIER this: TABLES, quoted: False), db:
      (IDENTIFIER this: INFORMATION_SCHEMA, quoted: False))))
```

The alternative form I had in mind given the context is:

```python
>>> sqlglot.parse_one("SELECT INFORMATION_SCHEMA.TABLES.TABLE_NAME")
(SELECT expressions:
  (COLUMN this:
    (IDENTIFIER this: TABLE_NAME, quoted: False), table:
    (IDENTIFIER this: TABLES, quoted: False), db:
    (IDENTIFIER this: INFORMATION_SCHEMA, quoted: False)), from:
  (FROM expressions:
    (TABLE this:
      (IDENTIFIER this: TABLES, quoted: False), db:
      (IDENTIFIER this: INFORMATION_SCHEMA, quoted: False))))
```
I don't think it makes sense for a column to have a `db`.
Columns select from the tables available in the current scope. They aren't references to the column itself.

But I think the matter at hand is Table expressions, not Column expressions.

Tables allow for `catalog`, `db`, and `table`. Seems like Bigquery allows for further namespacing, which I don't think is standard. So we want to gracefully handle this case by nesting the table in an arbitrary number of Dot expressions.

Resolving patch:
diff --git a/sqlglot/parser.py b/sqlglot/parser.py
--- a/sqlglot/parser.py
+++ b/sqlglot/parser.py
@@ -1136,9 +1136,13 @@ def _parse_table(self, schema=False):
         table = (not schema and self._parse_function()) or self._parse_id_var(False)
 
         while self._match(TokenType.DOT):
-            catalog = db
-            db = table
-            table = self._parse_id_var()
+            if catalog:
+                # This allows nesting the table in arbitrarily many dot expressions if needed
+                table = self.expression(exp.Dot, this=table, expression=self._parse_id_var())
+            else:
+                catalog = db
+                db = table
+                table = self._parse_id_var()
 
         if not table:
             self.raise_error("Expected table name")


Test patch:
diff --git a/tests/fixtures/identity.sql b/tests/fixtures/identity.sql
--- a/tests/fixtures/identity.sql
+++ b/tests/fixtures/identity.sql
@@ -521,3 +521,4 @@ WITH a AS ((SELECT b.foo AS foo, b.bar AS bar FROM b) UNION ALL (SELECT c.foo AS
 WITH a AS ((SELECT 1 AS b) UNION ALL (SELECT 1 AS b)) SELECT * FROM a
 SELECT (WITH x AS (SELECT 1 AS y) SELECT * FROM x) AS z
 SELECT ((SELECT 1) + 1)
+SELECT * FROM project.dataset.INFORMATION_SCHEMA.TABLES