Skip to content

feat: get_objects with single query#87

Merged
Mandukhai-Alimaa merged 5 commits intoadbc-drivers:mainfrom
tokoko:single-query-objects
Mar 26, 2026
Merged

feat: get_objects with single query#87
Mandukhai-Alimaa merged 5 commits intoadbc-drivers:mainfrom
tokoko:single-query-objects

Conversation

@tokoko
Copy link
Copy Markdown
Contributor

@tokoko tokoko commented Mar 23, 2026

  • GetObjects always issues a single query to fetch metadata.
  • All methods use c.Conn in order to take session-scoped objects like temp tables into account

I opted for pushing depth/filter complexity down to the sql query rather than trying to handle all the different types of results on go side. This is the query that's always run on mysql side:

SELECT
      s.SCHEMA_NAME AS CATALOG_NAME,
      sch.DB_SCHEMA_NAME,
      t.TABLE_NAME,
      t.TABLE_TYPE,
      c.ORDINAL_POSITION,
      c.COLUMN_NAME,
      c.COLUMN_COMMENT,
      c.DATA_TYPE,
      c.COLUMN_TYPE,
      c.IS_NULLABLE,
      c.COLUMN_DEFAULT
  FROM INFORMATION_SCHEMA.SCHEMATA s
  LEFT JOIN (SELECT '' AS DB_SCHEMA_NAME) sch
      ON 1=1
      [AND 1=0                              -- if depth = Catalogs]
      [AND sch.DB_SCHEMA_NAME LIKE ?        -- if schemaFilter set]
  LEFT JOIN INFORMATION_SCHEMA.TABLES t
      ON s.SCHEMA_NAME = t.TABLE_SCHEMA
      AND sch.DB_SCHEMA_NAME IS NOT NULL
      [AND 1=0                              -- if depth < Tables]
      [AND t.TABLE_NAME LIKE ?              -- if tableFilter set]
      [AND t.TABLE_TYPE IN (?, ...)         -- if tableType filter set]
  LEFT JOIN INFORMATION_SCHEMA.COLUMNS c
      ON t.TABLE_SCHEMA = c.TABLE_SCHEMA
      AND t.TABLE_NAME = c.TABLE_NAME
      [AND 1=0                              -- if depth < Columns]
      [AND c.COLUMN_NAME LIKE ?             -- if columnFilter set]
  [WHERE s.SCHEMA_NAME LIKE ?               -- if catalogFilter set]
  ORDER BY s.SCHEMA_NAME, t.TABLE_NAME, c.ORDINAL_POSITION

Additional 1=0 and LIKE join predicates are used to handle requested depth/filters. please feel free to disagree on the approach 😄.

@tokoko tokoko requested a review from lidavidm as a code owner March 23, 2026 22:31
@Mandukhai-Alimaa Mandukhai-Alimaa self-requested a review March 23, 2026 22:34
Copy link
Copy Markdown
Contributor

@Mandukhai-Alimaa Mandukhai-Alimaa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a test that verifies GetObjects can actually discover session-scoped objects like temp tables? Maybe something that creates a temp table and verifies GetObjects can find it.

@tokoko
Copy link
Copy Markdown
Contributor Author

tokoko commented Mar 24, 2026

Added the test, just note that this is gonna pass only for mariadb. If we ever decide to add mysql test run in ci as well, we should somehow disable it.

@@ -38,7 +38,7 @@ const (
// GetCurrentCatalog implements driverbase.CurrentNamespacer.
func (c *mysqlConnectionImpl) GetCurrentCatalog() (string, error) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, we should call c.ClearPending() at the start of these connection-level SQL methods (GetCurrentCatalog, SetCurrentCatalog, PrepareDriverInfo, GetTableSchema, GetObjects), since they can run while another reader is still active on the same session and hit busy-connection / out-of-sync errors. That is already the pattern sqlwrapper uses for statement execution before reusing the dedicated connection. See adbc-drivers/driverbase-go#56

go/mysql_test.go Outdated
suite.Run(t, &MySQLTests{Quirks: quirks})
}

func (s *MySQLTestSuite) TestGetObjectsTempTable() {
Copy link
Copy Markdown
Contributor

@Mandukhai-Alimaa Mandukhai-Alimaa Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CI runs tests against MySQL and the tests still seem to be passing even though you mentioned they would only pass on MariaDB. It seems the test does not actually validate the existence of the temp table, but validates the GetObjects does not error and return some data.

This happens on MySQL even when the temp table isn't found (because temp tables are not in INFORMATION_SCHEMA.TABLES), as the LEFT JOIN still returns catalog rows with empty table lists.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my bad, I messed up the test and thought it was mariadb in compose when it was green. Should I drop the test? I don't really see a good way of testing this.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea i think you are right. We can drop the test.

Copy link
Copy Markdown
Contributor

@Mandukhai-Alimaa Mandukhai-Alimaa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thanks

@Mandukhai-Alimaa Mandukhai-Alimaa merged commit a8f3864 into adbc-drivers:main Mar 26, 2026
12 checks passed
@tokoko tokoko deleted the single-query-objects branch March 26, 2026 15:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants