MCPcopy Index your code
hub / github.com/bytebase/bytebase / ToSQL

Method ToSQL

backend/common/qb/qb.go:156–203  ·  view source on GitHub ↗

ToSQL generates PostgreSQL-compatible SQL with $1, $2, ... placeholders. Returns the SQL string, parameters slice, and any error. Placeholder rules: - Single ? → parameter placeholder (converted to $1, $2, etc.) - Double ?? → literal ? in SQL (for PostgreSQL JSONB operators like ?, ?|, ?&)

()

Source from the content-addressed store, hash-verified

154// - Single ? → parameter placeholder (converted to $1, $2, etc.)
155// - Double ?? → literal ? in SQL (for PostgreSQL JSONB operators like ?, ?|, ?&)
156func (q *Query) ToSQL() (string, []any, error) {
157 if q == nil {
158 return "", nil, errors.New("cannot generate SQL from nil Query")
159 }
160
161 // First pass: concatenate all parts and collect params
162 var sqlBuilder strings.Builder
163 params := make([]any, 0)
164
165 for _, part := range q.parts {
166 // Check for errors in this part
167 if len(part.Errs) > 0 {
168 // Return the first error encountered
169 return "", nil, part.Errs[0]
170 }
171 sqlBuilder.WriteString(part.Text)
172 params = append(params, part.Params...)
173 }
174
175 sql := sqlBuilder.String()
176
177 // Second pass: replace ? placeholders with $1, $2, etc., handling ?? escape sequence
178 // Use a unique delimiter that won't appear in SQL
179 const delimiter = "\x00"
180 // Replace ?? with delimiter temporarily
181 sql = strings.ReplaceAll(sql, "??", delimiter)
182 // Split on remaining ? (these are all placeholders)
183 parts := strings.Split(sql, "?")
184
185 // Verify parameter count matches
186 if len(parts)-1 != len(params) {
187 return "", nil, errors.New("mismatched parameters: ? placeholders count does not match params count")
188 }
189
190 // Build final SQL with $1, $2, etc.
191 var builder strings.Builder
192 for i := range params {
193 builder.WriteString(parts[i])
194 builder.WriteString("$")
195 builder.WriteString(strconv.Itoa(i + 1))
196 }
197 builder.WriteString(parts[len(parts)-1])
198
199 // Replace delimiter back to ?
200 finalSQL := strings.ReplaceAll(builder.String(), delimiter, "?")
201
202 return finalSQL, params, nil
203}

Callers 15

BatchGetUsersByEmailsMethod · 0.95
TestQuery_NilQueryFunction · 0.95
CreateReleaseMethod · 0.80
ListReleasesMethod · 0.80
UpdateReleaseMethod · 0.80
CreateChangelogMethod · 0.80
UpdateChangelogMethod · 0.80
ListChangelogsMethod · 0.80
UpdateWorkspaceMethod · 0.80
DeleteWorkspaceMethod · 0.80
ListWorkspacesByEmailMethod · 0.80

Calls 1

StringMethod · 0.65