fix(output-mapping): preserve production table typing in branches [AJDA-3014]#540
Open
MiroCillik wants to merge 3 commits into
Open
fix(output-mapping): preserve production table typing in branches [AJDA-3014]#540MiroCillik wants to merge 3 commits into
MiroCillik wants to merge 3 commits into
Conversation
…DA-3014] Co-Authored-By: Miro Čillík <mcillik@gmail.com>
Contributor
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
MiroCillik
marked this pull request as ready for review
July 23, 2026 09:08
keboola-pr-reviewer-bot
left a comment
There was a problem hiding this comment.
Verdict: needs_human (risk 3/5) · profile ajda
Behavior change in published platform-libraries code with no feature flag — load-bearing per policy, so a human should review.
Concerns:
libs/output-mapping/src/LoadTableTaskCreator.php: Typed-table creation semantics changed in published library, no feature flag to disablelibs/output-mapping/src/Storage/StoragePreparer.php: New default-branch getTable call on branch first-write path; ungated observable behavior changelibs/output-mapping/tests/Writer/StorageApiLocalTableWriterTest.php: Bare ->method('hasFeature') without expects(); violates AJDA PHPUnit convention
Suggested reviewers: MiroCillik
Add regression coverage for the AJDA-3014 fix that preserves a production table's typing status when it is first materialized into a development branch: - LoadTableTaskCreatorTest: unit-level tests locking the $canCreateTypedTable gate — typed creation is suppressed when the default-branch table is non-typed, and still allowed when it is typed. - StorageApiLocalTableWriterTest: strengthen the non-typed regression test to assert columns and row data (not just the isTyped flag), and add positive end-to-end cases proving the fix does not over-suppress — branch tables are still created typed when the production table is typed or absent (the latter also exercising the 404 path of getDefaultBranchTableInfoIfExists). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ssed [AJDA-3014] The strengthened regression test revealed that when typed-table creation is suppressed for a non-typed production table (AJDA-3014), a schema-based source with a headless CSV fell through to the CreateAndLoadTableTask "unknown columns" branch (schema-only => hasColumns() is false). That path creates and loads in a single queueTableCreate call with no pre-created columns, so the Storage API took the first data row as the header — the branch table ended up with columns named after the data (e.g. "2", "development"). Add a dedicated branch: when typed creation is suppressed but the schema is known, create a plain non-typed table with the schema's column names (the same DDL-first path used for manifest columns), so a headless CSV is loaded correctly. Gated on !$canCreateTypedTable so no currently-passing scenario changes behaviour. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes AJDA-3014 (SUPPORT-16987): Branched Storage was creating non-typed production tables as typed on their first write inside a development branch, because automatic typed-table creation was applied to what is effectively a pre-existing table just being materialized into the branch for the first time. After merge to production the transformation (built/tested against the typed branch table) then breaks against the still non-typed production table.
The fix consults the corresponding default-branch table when a destination is created for the first time in Branched Storage, and only allows automatic typed-table creation when the production table doesn't exist yet or is already typed:
A production non-typed table therefore stays non-typed in the dev branch even when the output has an authoritative schema. New branch-only tables and existing branch tables keep their current behavior.
When typed creation is suppressed for a schema-based source,
LoadTableTaskCreatornow creates a plain non-typed table using the schema's column names (the DDL-firstcreateTablepath) instead of falling through to theCreateAndLoadTableTask"unknown columns" branch. Without this, a headless CSV (as produced by native-types transformations) would be imported with its first data row taken as the header, leaving the branch table with garbage column names. This branch is gated on!$canCreateTypedTable, so no previously-passing scenario changes behavior.This ports the reviewed fix from the read-only standalone repo (keboola/output-mapping#1) into the monorepo source at
libs/output-mapping, since that repo is a read-only publish target.Test coverage
LoadTableTaskCreatorTest— unit-level tests locking the$canCreateTypedTablegate: typed creation is suppressed when the default-branch table is non-typed (asserting the resulting table is non-typed with the correct columns), and still allowed when the default-branch table is typed.StorageApiLocalTableWriterTest—testFirstDevBranchWritePreservesNonTypedProductionTablenow asserts columns and row data (not just theisTypedflag), plus two positive end-to-end cases proving the fix does not over-suppress: branch tables are still created typed when the production table is typed or absent (the latter also exercising the 404 path ofgetDefaultBranchTableInfoIfExists).Scope & known limitations
This is deliberately a step-1 "stop the bleeding" stopgap, not the full fix:
output-mapping. Structurally it belongs in Branched Storage (Connection/Storage side), where lazy branch-table creation actually happens. This change is localized and trivially removable once the invariant moves down, so it introduces no architectural lock-in.Follow-ups tracked separately:
Release Notes
Justification
Plans for Customer Communication
Impact Analysis
getTablecall against the default branch in that narrow path. No impact on production writes, non-branch writes, or writes to tables already present in the branch. No single-tenant-specific impact.Deployment Plan
Rollback Plan
output-mappingand can be reverted/redeployed independently; reverting restores the previous (buggy) behavior with no data migration needed.Post-Release Support Plan
Link to Devin session: https://app.devin.ai/sessions/2cf3e8a34494418daea07c967b0cd25e
Requested by: @MiroCillik