@@ -76,14 +76,25 @@ func MarksToPlaceholders(q string, args []interface{}) (string, []interface{}, e
7676 args = otherArgs
7777
7878 // TODO: make this a bit less ugly
79- // TODO: identify escaped question marks
8079 // TODO: use an actual parser <3
8180 // TODO: structure query segments around SQL-Standard AST
8281 queryWithArgs := & strings.Builder {}
8382 argCounter := 1
8483 argPositioner := 0
8584 expandedArgs := []interface {}{}
86- for _ , queryChar := range q {
85+ skip := false
86+ for i , queryChar := range q {
87+ if skip {
88+ skip = false
89+ continue
90+ }
91+
92+ if queryChar == '\\' && i < len (q )- 1 && q [i + 1 ] == '?' {
93+ // Escaped '?'
94+ queryWithArgs .WriteRune ('?' )
95+ skip = true
96+ continue
97+ }
8798 if queryChar == '?' {
8899 arg := args [argPositioner ]
89100 switch reflect .TypeOf (arg ).Kind () {
@@ -126,7 +137,6 @@ func MarksToPlaceholders(q string, args []interface{}) (string, []interface{}, e
126137
127138// PlaceholdersToPositional converts ? in a query into $<argument number> which postgres expects
128139func PlaceholdersToPositional (q * strings.Builder , argCount int ) (* strings.Builder , int , error ) {
129- // TODO: identify escaped question marks
130140 // TODO: use an actual parser <3
131141 // TODO: structure query segments around SQL-Standard AST
132142 newQ := & strings.Builder {}
@@ -136,8 +146,22 @@ func PlaceholdersToPositional(q *strings.Builder, argCount int) (*strings.Builde
136146 newQ .Grow (renderedLength - newQ .Len ())
137147 }
138148
149+ queryString := q .String ()
139150 argCounter := 1
140- for _ , queryChar := range q .String () {
151+ skip := false
152+ for i , queryChar := range queryString {
153+ if skip {
154+ skip = false
155+ continue
156+ }
157+
158+ if queryChar == '\\' && i < len (queryString )- 1 && queryString [i + 1 ] == '?' {
159+ // Escaped '?'
160+ newQ .WriteRune ('?' )
161+ skip = true
162+ continue
163+ }
164+
141165 if queryChar == '?' {
142166 newQ .WriteRune ('$' )
143167 newQ .WriteString (strconv .Itoa (argCounter ))
0 commit comments