{"record":{"id":"9485b9b8dc88a5e1","repo":"vitessio/vitess","slug":"vt12001-9485b9","errorCode":"VT12001","errorMessage":"can't use [%s] with hash joins","messagePattern":"can't use \\[(.+?)\\] with hash joins","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtgate/planbuilder/operators/hash_join.go","lineNumber":261,"sourceCode":"\thj.LHS = op\n}\n\nfunc (hj *HashJoin) SetRHS(op Operator) {\n\thj.RHS = op\n}\n\nfunc (hj *HashJoin) MakeInner() {\n\thj.LeftJoin = false\n}\n\nfunc (hj *HashJoin) IsInner() bool {\n\treturn !hj.LeftJoin\n}\n\nfunc (hj *HashJoin) AddJoinPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr, pushDown bool) { // TODO: consider whether we should honor the pushDown flag\n\tcmp, ok := expr.(*sqlparser.ComparisonExpr)\n\tif !ok || !canBeSolvedWithHashJoin(cmp.Operator) {\n\t\tpanic(vterrors.VT12001(fmt.Sprintf(\"can't use [%s] with hash joins\", sqlparser.String(expr))))\n\t}\n\tlExpr := cmp.Left\n\tlDeps := ctx.SemTable.RecursiveDeps(lExpr)\n\trExpr := cmp.Right\n\trDeps := ctx.SemTable.RecursiveDeps(rExpr)\n\tlID := TableID(hj.LHS)\n\trID := TableID(hj.RHS)\n\tif !lDeps.IsSolvedBy(lID) || !rDeps.IsSolvedBy(rID) {\n\t\t// we'll switch and see if things work out then\n\t\tlExpr, rExpr = rExpr, lExpr\n\t\tlDeps, rDeps = rDeps, lDeps\n\t}\n\n\tif !lDeps.IsSolvedBy(lID) || !rDeps.IsSolvedBy(rID) {\n\t\tpanic(vterrors.VT12001(fmt.Sprintf(\"can't use [%s] with hash joins\", sqlparser.String(expr))))\n\t}\n\n\thj.JoinComparisons = append(hj.JoinComparisons, Comparison{","sourceCodeStart":243,"sourceCodeEnd":279,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtgate/planbuilder/operators/hash_join.go#L243-L279","documentation":"VT12001 is thrown when AddJoinPredicate receives a join predicate that is not a *sqlparser.ComparisonExpr or whose comparison operator is not supported by hash joins (canBeSolvedWithHashJoin fails). Hash joins can only solve equi-join comparisons; anything else (non-comparison predicates, unsupported operators) is rejected as unsupported functionality.","triggerScenarios":"mergeOrJoin (or the TestJoinPredicates harness) hands a predicate to HashJoin.AddJoinPredicate that is not an equality-style comparison - e.g. `a LIKE b`, `a IN (...)`, a boolean expression, or an operator like `<`, `>` when the planner attempts to solve it with a hash join.","commonSituations":"Queries with non-equi JOIN conditions (range joins) that the planner tries (and fails) to solve with a hash join; ORMs generating join predicates with LIKE or inequalities; planner routing choices after predicate pushdown changes.","solutions":["Rewrite the join condition as an equality (`ON a.x = b.y`) so it can be solved with a hash join","Move the non-equi condition from the ON clause into the WHERE clause so it is applied as a filter rather than a join predicate","Restructure the query (e.g. use subqueries or pre-filtered derived tables) so joins are equijoins"],"exampleFix":"// before\nSELECT * FROM a JOIN b ON a.x LIKE b.y\n// after\nSELECT * FROM a JOIN b ON a.id = b.id WHERE a.x LIKE b.y","handlingStrategy":"validation","validationCode":"-- verify join predicates are equijoins before routing through VTGate\n-- reject non-ComparisonExpr / non-equi operators in query construction layer\nif cmp, ok := expr.(*sqlparser.ComparisonExpr); !ok || !isEquiOperator(cmp.Operator) {\n\t// rewrite to WHERE-level filter or reject\n}","typeGuard":null,"tryCatchPattern":"if vterrors.Code(err) == vtrpcpb.Code_UNIMPLEMENTED && strings.Contains(err.Error(), \"hash joins\") {\n\t// fall back to a rewritten equijoin query\n}","preventionTips":["Design joins as equi-joins; move LIKE/range conditions to WHERE","Lint generated SQL (ORM templates) for non-equi ON clauses","Test join-heavy queries against Vitess before rollout"],"tags":["vitess","planbuilder","hash-join","unsupported-feature"],"backgroundTag":"unsupported-join-predicate","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}