Skip to content

Commit bd77a02

Browse files
committed
fix: fixed issue 4332, now type checks for consistency when the same parameter is repeated
1 parent ce83d3f commit bd77a02

File tree

9 files changed

+207
-56
lines changed

9 files changed

+207
-56
lines changed

internal/compiler/analyze.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,11 +169,18 @@ func (c *Compiler) _analyzeQuery(raw *ast.RawStmt, query string, failfast bool)
169169
}
170170
errors = append(errors, errs...)
171171
}
172-
refs = uniqueParamRefs(refs, dollar)
172+
refs = numberParamRefs(refs, dollar)
173173
if c.conf.Engine == config.EngineMySQL || !dollar {
174-
sort.Slice(refs, func(i, j int) bool { return refs[i].ref.Location < refs[j].ref.Location })
174+
sort.SliceStable(refs, func(i, j int) bool {
175+
return refs[i].ref.Location < refs[j].ref.Location
176+
})
175177
} else {
176-
sort.Slice(refs, func(i, j int) bool { return refs[i].ref.Number < refs[j].ref.Number })
178+
sort.SliceStable(refs, func(i, j int) bool {
179+
if refs[i].ref.Number == refs[j].ref.Number {
180+
return refs[i].ref.Location < refs[j].ref.Location
181+
}
182+
return refs[i].ref.Number < refs[j].ref.Number
183+
})
177184
}
178185
raw, embeds := rewrite.Embeds(raw)
179186
qc, err := c.buildQueryCatalog(c.catalog, raw.Stmt, embeds)

internal/compiler/parse.go

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -193,28 +193,29 @@ func rangeVars(root ast.Node) []*ast.RangeVar {
193193
return vars
194194
}
195195

196-
func uniqueParamRefs(in []paramRef, dollar bool) []paramRef {
197-
m := make(map[int]bool, len(in))
198-
o := make([]paramRef, 0, len(in))
196+
func numberParamRefs(in []paramRef, dollar bool) []paramRef {
197+
if dollar {
198+
return in
199+
}
200+
201+
used := make(map[int]bool, len(in))
199202
for _, v := range in {
200-
if !m[v.ref.Number] {
201-
m[v.ref.Number] = true
202-
if v.ref.Number != 0 {
203-
o = append(o, v)
204-
}
205-
}
206-
}
207-
if !dollar {
208-
start := 1
209-
for _, v := range in {
210-
if v.ref.Number == 0 {
211-
for m[start] {
212-
start++
213-
}
214-
v.ref.Number = start
215-
o = append(o, v)
216-
}
217-
}
218-
}
219-
return o
203+
if v.ref.Number != 0 {
204+
used[v.ref.Number] = true
205+
}
206+
}
207+
208+
start := 1
209+
for i := range in {
210+
if in[i].ref.Number != 0 {
211+
continue
212+
}
213+
for used[start] {
214+
start++
215+
}
216+
in[i].ref.Number = start
217+
used[start] = true
218+
}
219+
220+
return in
220221
}

0 commit comments

Comments
 (0)