demo: LEFT JOIN validation in Goqu and SQLAlchemy#8
Conversation
| _, _, err := goqulib.From("users"). | ||
| LeftJoin( | ||
| goqulib.T("orders"), | ||
| goqulib.On(goqulib.I("orders.user_id").Eq(goqulib.I("users.id"))), | ||
| ). | ||
| Select("users.id", "users.email", "orders.ghost_status"). | ||
| Where(goqulib.I("orders.missing_flag").Eq("pending")). | ||
| ToSQL() |
There was a problem hiding this comment.
VG004: SELECT without LIMIT may return unbounded rows; add LIMIT or FETCH FIRST | Origin: goqu query builder | Query: SELECT users.id, users.email, orders.ghost_status FROM users LEFT JOIN orders ON 1=1 WHERE...
| _, _, err := goqulib.From("users"). | ||
| LeftJoin( | ||
| goqulib.T("orders"), | ||
| goqulib.On(goqulib.I("orders.user_id").Eq(goqulib.I("users.id"))), | ||
| ). | ||
| Select("users.id", "users.email", "orders.ghost_status"). | ||
| Where(goqulib.I("orders.missing_flag").Eq("pending")). | ||
| ToSQL() |
There was a problem hiding this comment.
🚫 [valk-guard] reported by reviewdog 🐶
VG105: projection column "ghost_status" not found in table "orders" schema; check SELECT list and schema/model mappings | Origin: goqu query builder | Query: SELECT users.id, users.email, orders.ghost_status FROM users LEFT JOIN orders ON 1=1 WHERE...
| _, _, err := goqulib.From("users"). | ||
| LeftJoin( | ||
| goqulib.T("orders"), | ||
| goqulib.On(goqulib.I("orders.user_id").Eq(goqulib.I("users.id"))), | ||
| ). | ||
| Select("users.id", "users.email", "orders.ghost_status"). | ||
| Where(goqulib.I("orders.missing_flag").Eq("pending")). | ||
| ToSQL() |
There was a problem hiding this comment.
🚫 [valk-guard] reported by reviewdog 🐶
VG106: filter predicate column "missing_flag" not found in table "orders" schema; check predicate/group/order columns in schema/model mappings | Origin: goqu query builder | Query: SELECT users.id, users.email, orders.ghost_status FROM users LEFT JOIN orders ON 1=1 WHERE...
| session.query(User.id, User.email, Order.ghost_status) | ||
| .outerjoin(Order, Order.user_id == User.id) | ||
| .filter(Order.missing_flag == "pending") | ||
| .all() |
There was a problem hiding this comment.
VG004: SELECT without LIMIT may return unbounded rows; add LIMIT or FETCH FIRST | Origin: SQLAlchemy query builder | Query: SELECT "users"."id", "users"."email", "orders"."ghost_status" FROM "users" LEFT JOIN "orde...
| session.query(User.id, User.email, Order.ghost_status) | ||
| .outerjoin(Order, Order.user_id == User.id) | ||
| .filter(Order.missing_flag == "pending") | ||
| .all() |
There was a problem hiding this comment.
🚫 [valk-guard] reported by reviewdog 🐶
VG105: projection column "ghost_status" not found in table "orders" schema; check SELECT list and schema/model mappings | Origin: SQLAlchemy query builder | Query: SELECT "users"."id", "users"."email", "orders"."ghost_status" FROM "users" LEFT JOIN "orde...
| session.query(User.id, User.email, Order.ghost_status) | ||
| .outerjoin(Order, Order.user_id == User.id) | ||
| .filter(Order.missing_flag == "pending") | ||
| .all() |
There was a problem hiding this comment.
🚫 [valk-guard] reported by reviewdog 🐶
VG106: filter predicate column "missing_flag" not found in table "orders" schema; check predicate/group/order columns in schema/model mappings | Origin: SQLAlchemy query builder | Query: SELECT "users"."id", "users"."email", "orders"."ghost_status" FROM "users" LEFT JOIN "orde...
a2b7622 to
9bac6b0
Compare
What this shows
This PR demonstrates LEFT JOIN analysis in both Goqu and SQLAlchemy on
valk-guard@v0.1.3.It includes:
Expected result
This PR should produce exactly
6findings:4errors2warningsRule breakdown:
VG004x2: both broken joins are unbounded (SELECTwithoutLIMIT)VG105x2: both broken joins projectorders.ghost_status, which does not existVG106x2: both broken joins filter onorders.missing_flag, which does not existWhy the clean model/migration files are touched
This branch keeps the workflow aligned with the changed-files-only docs example.
Schema-aware rules like
VG105andVG106need the schema/model context in the scan input, so this PR includes harmless comment-only changes in the clean schema/model files to keep them in the changed-file set without changing baseline behavior onmain.What we gain
This gives a compact demo PR that proves:
v0.1.3release matches local validation and GitHub review comments