Skip to content

Commit d269c5b

Browse files
elianddbclaude
andcommitted
Fix SQL syntax error for mixed named columns and * in SELECT
Dolt was incorrectly allowing queries like `SELECT 'parent' as db, * FROM table` which MySQL rejects with a syntax error. This implements MySQL's rule that named expressions cannot appear before unqualified * in SELECT clauses. The fix: - Validates SELECT expressions in the existing processing loop - Rejects named expressions before unqualified * (matches MySQL behavior) - Allows qualified table.* in any position - Allows expressions after * (e.g., SELECT *, column) Fixes dolthub/dolt#9519 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 60e98ba commit d269c5b

File tree

2 files changed

+27
-0
lines changed

2 files changed

+27
-0
lines changed

sql/planbuilder/parse_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2969,6 +2969,24 @@ func TestPlanBuilderErr(t *testing.T) {
29692969
Query: "select 1 from xy group by 100;",
29702970
Err: "column ordinal out of range: 100",
29712971
},
2972+
2973+
// Test mixed named columns and star expressions
2974+
{
2975+
Query: "SELECT x, * FROM xy",
2976+
Err: "Invalid syntax: cannot mix named columns with '*' in SELECT clause",
2977+
},
2978+
{
2979+
Query: "SELECT 'constant', * FROM xy",
2980+
Err: "Invalid syntax: cannot mix named columns with '*' in SELECT clause",
2981+
},
2982+
{
2983+
Query: "SELECT 1, * FROM xy",
2984+
Err: "Invalid syntax: cannot mix named columns with '*' in SELECT clause",
2985+
},
2986+
{
2987+
Query: "SELECT * FROM (SELECT 'parent' as db, * FROM xy) as combined",
2988+
Err: "Invalid syntax: cannot mix named columns with '*' in SELECT clause",
2989+
},
29722990
}
29732991

29742992
db := memory.NewDatabase("mydb")

sql/planbuilder/project.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,16 @@ func (b *Builder) analyzeSelectList(inScope, outScope *scope, selectExprs ast.Se
4141

4242
// need to transfer aggregation state from out -> in
4343
var exprs []sql.Expression
44+
var hasColumnBeforeStar bool
4445
for _, se := range selectExprs {
46+
// Check for named expressions before unqualified *
47+
if star, ok := se.(*ast.StarExpr); ok {
48+
if star.TableName.IsEmpty() && hasColumnBeforeStar {
49+
b.handleErr(sql.ErrInvalidSyntax.New("cannot mix named columns with '*' in SELECT clause"))
50+
}
51+
} else if _, ok := se.(*ast.AliasedExpr); ok {
52+
hasColumnBeforeStar = true
53+
}
4554
pe := b.selectExprToExpression(inScope, se)
4655

4756
// TODO two passes for symbol res and semantic validation

0 commit comments

Comments
 (0)