refactor: extract BIGQUERY into feature/bigquery (part of #778)#781
Conversation
Move the BIGQUERY statement family out of core internal/mycli into the new internal/mycli/feature/bigquery package through the Feature seam (#779), so core no longer imports cloud.google.com/go/bigquery. What moved: - BigQueryStatement, the #775 fail-closed first-keyword classifier, and formatBigQueryValue now live in feature/bigquery (cloud dep aliased as bq). The statement embeds mycli.MutationClassifier (Classify wired over its own SQL) and mycli.MarksDetachedCompatible; compile-time assertions for ConditionallyMutatingStatement and DetachedCompatible move with it. - The BIGQUERY def moves out of client_side_statement_def.go into Feature(), which allocates a FRESH feature-owned config per call and captures it in the def closure, the Variable handlers, and constructed statements (no package-level mutable state; session-isolation commitment from the #779 review thread). - CLI_BIGQUERY_PROJECT/LOCATION/MAX_BYTES_BILLED become FeatureVars with their descriptions moved verbatim; the nullable-int NULL display for MAX_BYTES_BILLED is preserved via mycli.NullableIntVar. - The lazy client cache with rebuild-on-project/location-change is reimplemented on mycli.FeatureState ("bigquery.client"), using Session.AuthOptions; the old lock-free field cache is replaced by a mutex-guarded cache (atomic check-then-act per styleguide Concurrency). Credential re-homing (deletes #775 carry-over machinery): the raw --credential bytes get a durable home on the startup-config group, exposed via Session.CredentialBytes() (defensive copy). This survives USE/DETACH by construction, so SessionHandler.credential, applyBigQueryCredential, and newSessionHandlerWithCredential are deleted and NewSessionHandler is restored to the simple form. (The long-dead Cli.Credential field referenced in #778 §4.6 no longer exists in the tree; nothing to delete there.) Order-contract change and one-time diff: features append after the core table, so the final registration order is fixed as (llm, cql, bigquery). Extracting BIGQUERY first moves its statement-help row after CQL's, producing a single 2-row swap (BIGQUERY and CQL) in the generated statement help; PR2 (CQL) and PR3 (LLM) then re-append at the same relative positions and stay byte-identical. docs/system_variables.md is byte-identical (variables are listed alphabetically; ListVariableInfo now also enumerates feature varDefs and renderSystemVariablesHelp is threaded with the feature set so the generated reference keeps documenting the full binary's surface). Tests: classifier, formatBigQueryValue, def dispatch, FeatureVar Get/Set semantics, and fresh-per-Feature() isolation are covered in the feature package; the dispatch-level READONLY guard (#775 regression) moves to an external mycli_test that registers bigquery.Feature() and drives the real guard; the #728 invariant tests now iterate MergedStatementDefs(all.All()...) so they keep covering BIGQUERY. Dep hygiene: go list -deps ./internal/mycli no longer contains cloud.google.com/go/bigquery (root main still does, via feature/all — correct). Part of #778. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V28qKRVwUCkpT5pepTksgr
Code Metrics Report📊 View detailed coverage report (available for 7 days)
Details | | main (3c53157) | #781 (569be50) | +/- |
|---------------------|----------------|----------------|-------|
+ | Coverage | 73.2% | 73.3% | +0.0% |
| Files | 89 | 91 | +2 |
| Lines | 7907 | 7917 | +10 |
+ | Covered | 5793 | 5805 | +12 |
+ | Code to Test Ratio | 1:1.3 | 1:1.3 | +0.0 |
| Code | 18426 | 18473 | +47 |
+ | Test | 24867 | 25062 | +195 |
- | Test Execution Time | 1m38s | 1m40s | +2s |Code coverage of files in pull request scope (70.6% → 70.8%)
Reported by octocov |
There was a problem hiding this comment.
Code Review
This pull request extracts the BIGQUERY statement family and its associated configuration variables from the core mycli package into an optional feature package under internal/mycli/feature/bigquery. It introduces a feature registration seam to allow optional statement families to register their own statement definitions and system variables. To support this, the raw credential bytes are now stored in the durable StartupConfig so that feature packages can securely retrieve them via Session.CredentialBytes() across session replacements. Additionally, tests for the BigQuery read-only guard, formatting, and variable resolution have been moved and adapted to the new package structure. No review comments were provided, so there is no feedback to address.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
apstndb
left a comment
There was a problem hiding this comment.
REQUEST-CHANGES: I found one blocking regression.
Finding:
- [P2] Feature variables disappear from
SHOW VARIABLESand variable-name completion.ListVariableInfowas updated to includer.sv.featureVarDefs, soHELP VARIABLESand generated docs still seeCLI_BIGQUERY_PROJECT,CLI_BIGQUERY_LOCATION, andCLI_BIGQUERY_MAX_BYTES_BILLED. ButVarRegistry.ListVariablesstill iterates only the corevarDefstable.SHOW VARIABLEScallssession.systemVariables.ListVariables(), and fuzzy variable-name completion uses the same map, so after this extraction the full binary canSET/SHOW VARIABLEthe BigQuery vars by exact name but no longer lists them inSHOW VARIABLESor completion. Those rows existed before the move because they were in corevarDefs. Please make the variable enumeration path iterate feature var defs as well (and the analogousListMultiValuespath for consistency/future feature vars), then add regression coverage forSHOW VARIABLESor the registry listing withbigquery.Feature().
References:
internal/mycli/var_registry.go:205-214internal/mycli/statements_system_variable.go:46-52internal/mycli/fuzzy_finder.go:846-853
Validation:
- Clean merge into current
origin/main(3c5315727cf246c7e1c23533cb0b65342f788d07) in a temporary clone. go test ./internal/mycli ./internal/mycli/feature/bigquery -run 'TestFeature|TestBigQuery|TestFormatBigQueryValue|TestReadOnlyGuard.*BigQuery|TestClientSideStatementDefsNonShadowing|TestClientSideStatementDefsCompletionConsistency'go list -deps -f '{{if eq .ImportPath "cloud.google.com/go/bigquery"}}{{.ImportPath}}{{end}}' ./internal/mycliproduced no output, so the core package dependency split holds.
Review finding on #781: ListVariableInfo (HELP VARIABLES, generated docs) was taught about feature-contributed varDefs but VarRegistry.ListVariables was not, so SHOW VARIABLES and fuzzy variable-name completion dropped CLI_BIGQUERY_PROJECT/LOCATION/MAX_BYTES_BILLED after the extraction while exact-name SET/SHOW VARIABLE still worked. Route ListVariables, ListMultiValues, and ListVariableInfo through a single forEachDef iterator (core varDefs followed by feature varDefs) so no enumeration surface can drift from the others again. Regression coverage: an external-package test asserts the listing behind SHOW VARIABLES/completion includes the three BigQuery variables with the real bigquery feature registered; an internal test pins the mechanism for both single-value and multi-value feature vars. Also picks up two non-blocking review items: the stale statements.go comment pointing at the deleted statements_bigquery.go, and MutationClassifier now fails closed (classifies as mutating) on a nil Classify instead of panicking on a zero-value statement. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V28qKRVwUCkpT5pepTksgr
|
Addressed the REQUEST-CHANGES finding in abba75f.
Validation: |
apstndb
left a comment
There was a problem hiding this comment.
APPROVE: previous blocking finding is resolved; I found no new blocking issues.
Reviewed the delta from b6cdb60 to abba75f. The feature-variable listing fix routes ListVariables, ListMultiValues, and ListVariableInfo through the same core+feature def iterator, and the added tests cover both the mechanism and the real BIGQUERY feature variables behind SHOW VARIABLES / completion.
Validation:
- Clean merge into current
origin/main(3c5315727cf246c7e1c23533cb0b65342f788d07) in a temporary clone. go test ./internal/mycli ./internal/mycli/feature/bigquery -run 'TestVariableListingIncludesBigQueryVars|TestFeatureVarsAppearInEnumerationSurfaces|TestMutationClassifierDelegates|TestFeature|TestBigQuery|TestFormatBigQueryValue|TestReadOnlyGuard.*BigQuery|TestClientSideStatementDefsNonShadowing|TestClientSideStatementDefsCompletionConsistency'go list -deps -f '{{if eq .ImportPath "cloud.google.com/go/bigquery"}}{{.ImportPath}}{{end}}' ./internal/mycliproduced no output.
Part of #778 (PR1 in the migration plan). First extraction on top of the Feature seam (#779) and the def-table reorder (#780).
Scope
Move the BIGQUERY statement family out of core
internal/mycliinto the newinternal/mycli/feature/bigquerypackage (cloud dep aliased asbq), so core no longer importscloud.google.com/go/bigquery.BigQueryStatement, the fix: honor BigQuery safety contracts #775 fail-closed first-keyword classifier (bigQueryStatementMutatesand helpers), andformatBigQueryValue. The statement embedsmycli.MutationClassifier(Classifywired in the constructor over its own SQL) andmycli.MarksDetachedCompatible; theConditionallyMutatingStatement/DetachedCompatiblecompile-time assertions move with it. The core assertion forBigQueryStatementis removed.Feature(). EachFeature()call allocates a fresh feature-owned config captured by the def closure, theVariablehandlers, and constructed statements — no package-level mutable state (session-isolation commitment from the refactor: introduce the Feature registration seam (part of #778) #779 review thread).CLI_BIGQUERY_PROJECT/CLI_BIGQUERY_LOCATION/CLI_BIGQUERY_MAX_BYTES_BILLEDbecomeFeatureVars with their descriptions moved verbatim; the nullable-int NULL display forMAX_BYTES_BILLEDis preserved viamycli.NullableIntVar. TheBigQuery*fields are removed fromFeatureVars. TheCLI_BIGQUERY_PROJECT->CLI_PROJECTfallback stays in client-build code (viaSession.ProjectID()).mycli.FeatureState(key"bigquery.client") usingSession.AuthOptions. It preserves the rebuild-on-project/location-change rule and closes the client atSession.Closeviaio.Closer. The old deliberately lock-free field cache is replaced by a mutex-guarded cache (atomic check-then-act, per styleguide Concurrency).Credential re-homing (deletes #775 carry-over machinery)
The raw
--credentialbytes get a durable home on the startup-config group (StartupConfig.Credential, read-only, not a registered variable), exposed viaSession.CredentialBytes()(defensive copy). Because startup config is shared across USE/DETACH session replacement, the credential resolves the same way regardless of session switches by construction. This lets the PR delete:SessionHandler.credential,applyBigQueryCredential,newSessionHandlerWithCredential(restoring the simpleNewSessionHandler);session.bqCredentialassignment increateSession, plus thebqCredential/bqClient/bqClientKeyfields,bigQueryClientKey,bigQueryClient(),createBigQueryClientOptions,bigQueryProject(), and thebqClientclose block inSession.Close.The #775 credential-handoff regression is preserved, adapted to the new accessor (
TestSessionCredentialBytesFromDurableConfig).Note: the long-dead
Cli.Credentialfield referenced in #778 section 4.6 no longer exists in the current tree, so there was nothing to delete there (see Deviations).Order-contract change + disclosed one-time diff
Features append after the core table, so extracting BIGQUERY first moves its statement-help row after CQL's. The final registration order is fixed as (llm, cql, bigquery) (not the pre-extraction core order llm, bigquery, cql), and
all.All()'s doc comment is updated accordingly. This front-loads the single 2-row swap (BIGQUERY and CQL) into this PR; PR2 (CQL) and PR3 (LLM) re-append at the same relative positions and stay byte-identical.docs/system_variables.md: byte-identical (variables are listed alphabetically;ListVariableInfonow also enumerates featurevarDefs andrenderSystemVariablesHelpis threaded with the feature set, so the generated reference keeps documenting the full binary's surface).README.md: exactly the disclosed BIGQUERY/CQL statement-help row swap, nothing else.Tests
formatBigQueryValue, def dispatch viamycli.BuildStatementWithDefs,FeatureVarGet/Set semantics (incl. NULL display), fresh-per-Feature()isolation, and the project fallback.mycli_testthat registersbigquery.Feature()and drives the real guard throughSession.ExecuteStatement(both blocks-mutating and allows-read-only, the latter proving the SELECT reaches Execute and fails on config, not READONLY). A small test-only bridge (export_test.go) exposes a READONLY test session and the READONLY-error predicate without widening the production API.MergedStatementDefs(all.All()...), so they keep covering BIGQUERY after extraction.createBigQueryClientOptions' emulator-auth-skip coverage is preserved as a core test over the exportedSession.AuthOptions(..., false).Validation
make check(test + lint + fmt-check): passmake check-race: passgo vet ./...: cleanmake docs-updatethengit diff:docs/system_variables.mdbyte-identical;README.mdshows only the BIGQUERY/CQL 2-row swapgo list -deps ./internal/mycli | grep cloud.google.com/go/bigquery-> empty (root main still imports it viafeature/all, which is correct)Tracked debt
The typed-export limitation (BigQuery values export as display strings, not typed cells) is recorded in the feature package doc comment.
Deviations from the spec
Cli.Credentialfield named in Quarantine optional statement families (GEMINI/CQL/BIGQUERY) behind an explicit Feature seam and ship a slim build variant #778 section 4.6 for deletion is not present in the current tree (already removed in an earlier change); no code change was needed for it.ListVariableInfonow iterates featurevarDefs in addition to the corevarDefstable, andrenderSystemVariablesHelpis threaded with the feature set. Without these, the three BigQuery rows would drop out ofdocs/system_variables.mdandHELP VARIABLESin the full binary.Part of #778.
🤖 Generated with Claude Code
https://claude.ai/code/session_01V28qKRVwUCkpT5pepTksgr