Skip to content

[no-release-notes] Account for dolt dsess refactor#2809

Open
macneale4 wants to merge 1 commit into
mainfrom
macneale4-claude/dumbo-dsess
Open

[no-release-notes] Account for dolt dsess refactor#2809
macneale4 wants to merge 1 commit into
mainfrom
macneale4-claude/dumbo-dsess

Conversation

@macneale4

Copy link
Copy Markdown
Contributor

Depends on: dolthub/dolt#11162

@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor
Main PR
covering_index_scan_postgres 1784.42/s ${\color{red}DNF}$
groupby_scan_postgres 124.44/s ${\color{red}DNF}$
index_join_postgres 635.62/s ${\color{red}DNF}$
index_join_scan_postgres 776.51/s ${\color{red}DNF}$
index_scan_postgres 22.89/s ${\color{red}DNF}$
oltp_delete_insert_postgres 738.00/s ${\color{red}DNF}$
oltp_insert 639.57/s ${\color{red}DNF}$
oltp_point_select 2771.39/s ${\color{red}DNF}$
oltp_read_only 2808.78/s ${\color{red}DNF}$
oltp_read_write 2168.18/s ${\color{red}DNF}$
oltp_update_index 674.90/s ${\color{red}DNF}$
oltp_update_non_index 700.87/s ${\color{red}DNF}$
oltp_write_only 1641.50/s ${\color{red}DNF}$
select_random_points 1752.77/s ${\color{red}DNF}$
select_random_ranges 1066.04/s ${\color{red}DNF}$
table_scan_postgres 21.66/s ${\color{red}DNF}$
types_delete_insert_postgres 699.04/s ${\color{red}DNF}$
types_table_scan_postgres 9.42/s ${\color{red}DNF}$

@itoqa

itoqa Bot commented Jun 4, 2026

Copy link
Copy Markdown

Ito Test Report ❌

8 test cases ran. 1 failed, 2 additional findings, 5 passed.

Across 8 test cases, 5 passed and 3 failed, showing that session/database resolution and provider lookup error propagation generally behaved correctly (including SHOW SCHEMAS fallback, OID helper short-circuiting, OID introspection consistency, and clean mixed-version startup abort diagnostics) but the run still identified significant product issues. The most important confirmed defects were a high-severity startup break from unresolved migrated doltcore/dsess imports against the pinned Dolt module version (introduced by this PR), a high-severity authorization leak where pg_catalog.pg_database exposes unauthorized database names, and a medium-severity regclass bug where search_path first-match precedence is reversed and can resolve to later-schema objects.

❌ Failed (1)
Category Summary Screenshot
Provider ⚠️ Server startup cannot succeed because migrated doltcore/dsess imports are unresolved by the pinned dependency version. PROVIDER-1
⚠️ Startup fails due to unresolved dsess import
  • What failed: The server fails before reaching ready state because imports were migrated to github.com/dolthub/dolt/go/libraries/doltcore/dsess while the pinned Dolt module version does not provide that package; expected behavior is successful startup and SQL connectivity.
  • Impact: Core startup is broken, so users cannot connect to the server or run primary SQL workflows. There is no practical workaround without changing dependency alignment or import paths.
  • Steps to reproduce:
    1. Launch Doltgres with default startup configuration.
    2. Connect on port 5432 as postgres/password.
    3. Observe startup diagnostics indicating unresolved doltcore/dsess imports before SQL queries can execute.
  • Stub / mock context: SCRAM authentication was bypassed by setting EnableAuthentication to false in server/authentication_scram.go so startup behavior could be checked without auth gating; the observed failure still occurs at compile/bootstrap time due to dependency-import mismatch.
  • Code analysis: I checked the startup and session-related production code paths and found multiple imports now target doltcore/dsess, while dependency pinning still targets a Dolt revision that does not contain that package. This creates a compile-time incompatibility that blocks process startup rather than a test-only runtime artifact.
  • Why this is likely a bug: Production startup depends on these imports compiling, and the repository’s pinned dependency version does not provide the referenced package, so the failure is a direct code/dependency defect.

Relevant code:

go.mod (lines 5-13)

require (
	github.com/PuerkitoBio/goquery v1.8.1
	github.com/cockroachdb/apd/v3 v3.2.3
	github.com/cockroachdb/errors v1.7.5
	github.com/dolthub/dolt/go v0.40.5-0.20260604164645-622b70b995bf
	github.com/dolthub/eventsapi_schema v0.0.0-20260310172945-37a9265ade69
	github.com/dolthub/flatbuffers/v23 v23.3.3-dh.2
	github.com/dolthub/go-mysql-server v0.20.1-0.20260603165028-b60521c3724e

server/connection_handler.go (lines 32-37)

"github.com/cockroachdb/errors"
	"github.com/dolthub/dolt/go/libraries/doltcore/dsess"
	"github.com/dolthub/dolt/go/libraries/doltcore/sqlserver"
	"github.com/dolthub/go-mysql-server/server"
	"github.com/dolthub/go-mysql-server/sql"
	"github.com/dolthub/go-mysql-server/sql/plan"

core/context.go (lines 21-25)

"github.com/cockroachdb/errors"
	"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
	"github.com/dolthub/dolt/go/libraries/doltcore/dsess"
	"github.com/dolthub/dolt/go/libraries/doltcore/sqle/resolve"
	"github.com/dolthub/go-mysql-server/sql"
✅ Passed (5)
Category Summary Screenshot
Catalog Provider lookup errors are surfaced correctly; prior failure came from querying a valid DB context instead of the missing DB target. CATALOG-2
Database OID-backed introspection stayed consistent with pg_database visibility after correct in-database setup. DATABASE-2
Provider Mixed-version startup failed with explicit compatibility diagnostics and no partial running process. PROVIDER-2
Session SHOW SCHEMAS succeeded for the connected database and returned user and system schemas. SESSION-1
Session Invalid DOLTGRES_DB startup still used stale_missing_db, so CREATE SEQUENCE success did not indicate a provider lookup bug. SESSION-2
ℹ️ Additional Findings (2)

These findings are unrelated to the current changes but were observed during testing.

Category Summary Screenshot
Catalog 🟠 regclass resolution can return a later-schema match instead of honoring first-match search_path precedence. CATALOG-1
Database ⚠️ pg_database returned out-of-scope database names to a constrained session. DATABASE-1
🟠 regclass search_path precedence is reversed
  • What failed: The resolved relation tracks a later scanned schema instead of the first schema in search_path; expected behavior is first-match precedence.
  • Impact: Metadata and object-resolution flows that rely on regclass can target the wrong object when names collide across schemas. Users can sometimes work around it by schema-qualifying names, but default introspection behavior is incorrect.
  • Steps to reproduce:
    1. Create the same relation name in two schemas, for example s1.shared_rel and s2.shared_rel.
    2. Set search_path to s1,s2 and run SELECT 'shared_rel'::regclass.
    3. Reverse search_path to s2,s1 and run the same cast again to compare the resolved relation/OID.
  • Stub / mock context: Authentication checks were bypassed for this run by forcing EnableAuthentication = false in server/authentication_scram.go so local SQL sessions could execute without SCRAM validation.
  • Code analysis: regclassin stops its callback when it finds a match, but iteration helpers collapse that stop into nil and the outer schema loop continues scanning. Because later callbacks can overwrite resultOid, first-match semantics are lost.
  • Why this is likely a bug: The production iterator control flow makes a found-match stop signal non-terminal at schema scope, which directly explains the reversed precedence behavior.

Relevant code:

server/functions/regclass.go (lines 91-126)

err = IterateDatabase(ctx, database, Callbacks{
    Table: func(ctx *sql.Context, schema ItemSchema, table ItemTable) (cont bool, err error) {
        if table.Item.Name() == relationName {
            resultOid = table.OID.AsId()
            return false, nil
        }
        return true, nil
    },
    View: func(ctx *sql.Context, schema ItemSchema, view ItemView) (cont bool, err error) {
        if view.Item.Name == relationName {
            resultOid = view.OID.AsId()
            return false, nil
        }
        return true, nil
    },
    SearchSchemas: searchSchemas,
})

server/functions/iterate.go (lines 225-240)

err := iterateSequences(ctx, callbacks, sequenceMap, schema, itemSchema)
if err != nil {
    return err
}

if callbacks.iteratesOverTables() {
    tableNames, err := schema.GetTableNames(ctx)
    if err != nil {
        return err
    }
    if err = iterateTables(ctx, callbacks, itemSchema, tableNames); err != nil {
        return err
    }
}

server/functions/iterate.go (lines 367-371)

if callbacks.Table != nil {
    if cont, err := callbacks.Table(ctx, itemSchema, itemTable); err != nil {
        return err
    } else if !cont {
        return nil
    }
}
⚠️ Catalog enumeration leaks unauthorized database names
  • What failed: The catalog query exposes database names that should be hidden by database-level authorization; expected behavior is that unauthorized databases are excluded.
  • Impact: Users with constrained access can enumerate database names outside their allowed scope, leaking metadata across tenants/projects. This weakens authorization boundaries for a core catalog endpoint and can aid further targeted probing.
  • Steps to reproduce:
    1. Create one in-scope database and one out-of-scope database, then revoke CONNECT on the out-of-scope database for a limited role.
    2. Connect as the limited role and run SELECT datname FROM pg_catalog.pg_database.
    3. Observe that the out-of-scope database name is still returned in the result set.
  • Stub / mock context: SCRAM sign-in was bypassed to allow deterministic local role sessions, but the leakage check itself used real database role grants/revokes and a real pg_database query path with no mocked catalog output.
  • Code analysis: I inspected the pg_database table handler and authorization handler paths. The row iterator enumerates all catalog databases from the provider and only filters system DB names, with no per-user privilege check, and the database authorization hook is still a TODO returning nil.
  • Why this is likely a bug: Production code currently builds the pg_database result set without enforcing database authorization, so unauthorized names can be returned by design.

Relevant code:

server/tables/pgcatalog/pg_database.go (lines 49-62)

func (p PgDatabaseHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
	// TODO: Should the catalog be passed to RowIter like it is for the information_schema tables RowIter?
	doltSession := dsess.DSessFromSess(ctx.Session)
	c := sqle.NewDefault(doltSession.GenericProvider()).Analyzer.Catalog

	databases := c.AllDatabases(ctx)
	dbs := make([]sql.Database, 0, len(databases))
	for _, db := range databases {
		name := db.Name()
		if name == "information_schema" || name == "pg_catalog" || name == "performance_schema" {
			continue
		}
		dbs = append(dbs, db)

server/auth/auth_handler.go (lines 248-257)

func (h *AuthorizationHandler) CheckDatabase(ctx *sql.Context, aqs sql.AuthorizationQueryState, dbName string) error {
	if aqs == nil {
		aqs = h.NewQueryState(ctx)
	}
	state := aqs.(AuthorizationQueryState)
	if state.err != nil {
		return state.err
	}
	// TODO: implement this
	return nil
}

Commit: 33854d6

View Full Run


Tell us how we did: Give Ito Feedback

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.

1 participant