Skip to content

fix: resolve false-positive conflicts in import and apply#151

Merged
toopay merged 4 commits intomainfrom
fix/imports
Feb 25, 2026
Merged

fix: resolve false-positive conflicts in import and apply#151
toopay merged 4 commits intomainfrom
fix/imports

Conversation

@vani-rf
Copy link
Contributor

@vani-rf vani-rf commented Feb 24, 2026

Fix false-positive conflict detection in raiden imports and false-change detection in raiden apply --dry-run. After running import --force followed by a normal import, the system incorrectly reported
conflicts on identical resources. After running import followed by apply --dry-run, the system incorrectly detected relation creates/deletes, policy table reassignments, RPC updates, and duplicate "New
Table" entries — all without any code changes.

Root causes & fixes

Import false-conflicts:

  • Type comparison: Pointer address comparison for *string Comment field, duplicate comparison block, incorrect slice index iteration for Enum/Attributes
  • Table relation comparison: Constraint name mismatch between remote DB names (fk_mc_division) and locally-generated defaults (public_master_creators_division_id_fkey). Added fallback matching by
    schema.table.column
  • Cross-schema FK filtering: FKs referencing tables in other schemas (e.g., auth.users) caused false diffs since the target isn't in the imported model set
  • RPC comparison: BindRpcFunction overwrites stored CompleteStatement with rebuilt output from BuildRpc(), which differs in formatting from pg_get_functiondef(). Fixed by restoring the state-stored version
    before comparison

Apply false-changes:

  • Duplicate FK deletes: Database has duplicate FK constraints (custom-named + default-named) for the same column. Added matchedSourceCols tracking to skip already-matched columns
  • False index creation: UpdateRelationCreateIndex fired when neither side had an index. Changed condition to only fire when remote has index but local doesn't
  • Policy name collision: CompareList mapped policies by name only — different tables with the same policy name (e.g., "admin full access") collided. Changed to use schema+table+name key
  • RPC CompleteStatement overwrite: Same BindRpcFunction issue as import, but in ExtractRpc. Fixed by preserving state CompleteStatement before/after binding
  • TargetTableName resolution: addModelRelation derived table name from field name instead of type name. Fixed with raiden.GetTableName()
  • Duplicate table registration: Two Go models with the same tableName tag caused the second to be falsely classified as "New Table". Added deduplication in ExtractTable

Other fixes (prior commits in branch):

  • UUID support as RPC return type
  • CROSS JOIN support in RPC SQL parser
  • Hyphen handling in RPC names and param deduplication
  • Public pseudo-role skip in policy role resolution
  • Type Comment generation and skip relations to non-imported tables

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • Unit Tests

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules

Validation

Tested against a real pivot project (dashboard-tiktok-be):

  • raiden imports → zero false conflicts
  • raiden apply --dry-run → only genuinely new resources detected (ai_recommendations RPC)

Files changed

31 files, +1962 / -60 lines across:

  • pkg/resource/ — comparison logic for tables, policies, types, RPC, import orchestration
  • pkg/state/ — table and RPC state extraction
  • pkg/generator/ — RPC, type, and model generation fixes
  • docs/cli/imports.md — comprehensive import CLI documentation
  • openspec/ — spec and archived change proposals

vani-rf and others added 2 commits February 24, 2026 20:33
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Fix multiple bugs causing phantom diffs when running import after import --force:

Type comparison (types/compare.go):
- Fix Comment *string pointer comparison (compare values not addresses)
- Remove duplicate Comment check block
- Fix Enum range iterating indices instead of values
- Fix Attribute range iterating indices instead of values

Table relation comparison (tables/compare.go):
- Add fallback relation matching by schema.table.column when constraint
  name lookup fails (remote uses real DB names, local uses generated names)
- Gate nil-Action diff to apply mode only

Table state extraction (state/table.go):
- Add fallback relation lookup by SourceTableName+SourceColumnName in
  buildTableRelation when constraint name lookup fails

Cross-schema relation filtering (import.go):
- Filter remote relationships to exclude references to tables not in
  local model set before comparison

RPC comparison (import.go):
- Restore state CompleteStatement before comparison instead of using
  rebuilt one from BuildRpc which differs from pg_get_functiondef()

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@codecov
Copy link

codecov bot commented Feb 24, 2026

Codecov Report

❌ Patch coverage is 93.25843% with 6 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
pkg/state/table.go 76.47% 2 Missing and 2 partials ⚠️
pkg/resource/types/compare.go 77.77% 1 Missing and 1 partial ⚠️
Flag Coverage Δ
go-1.22 74.07% <93.25%> (+0.24%) ⬆️
go-1.24 73.33% <93.25%> (+0.29%) ⬆️
go-1.25 73.33% <93.25%> (+1.01%) ⬆️
macos-latest 74.10% <93.25%> (+0.59%) ⬆️
ubuntu-latest 74.09% <93.25%> (+0.17%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
pkg/resource/import.go 85.22% <100.00%> (+1.85%) ⬆️
pkg/resource/policies/compare.go 94.47% <100.00%> (+0.24%) ⬆️
pkg/resource/tables/compare.go 76.55% <100.00%> (+5.35%) ⬆️
pkg/state/rpc.go 73.46% <100.00%> (+10.42%) ⬆️
pkg/resource/types/compare.go 81.35% <77.77%> (+3.57%) ⬆️
pkg/state/table.go 77.14% <76.47%> (+1.40%) ⬆️

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@vani-rf vani-rf changed the title Fix/imports fix: resolve false-positive conflicts in import and apply Feb 24, 2026
- Fix relation comparison: skip duplicate FK deletes for matched columns
- Fix relation comparison: skip cross-schema FK references (e.g., auth.users)
- Fix index creation: only propose when target has index but source doesn't
- Fix policy comparison: use schema+table+name key instead of name-only
- Fix RPC state extraction: preserve stored CompleteStatement from import
- Fix addModelRelation: use raiden.GetTableName() for TargetTableName
- Fix duplicate table registration: skip second model with same tableName

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@toopay toopay merged commit 0185f68 into main Feb 25, 2026
12 checks passed
@toopay toopay deleted the fix/imports branch February 25, 2026 18:41
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