MCPcopy Create free account
hub / github.com/bytebase/bytebase / extractTablesFromUpdate

Function extractTablesFromUpdate

backend/plugin/parser/tidb/backup.go:237–312  ·  view source on GitHub ↗
(databaseName string, n *ast.UpdateStmt, fullSQL string, dbMetadata *model.DatabaseMetadata, isCaseSensitive bool)

Source from the content-addressed store, hash-verified

235}
236
237func extractTablesFromUpdate(databaseName string, n *ast.UpdateStmt, fullSQL string, dbMetadata *model.DatabaseMetadata, isCaseSensitive bool) ([]statementInfo, error) {
238 cteNames := collectCTENames(fullSQL, n.Loc)
239 stmtText := extractStatementText(fullSQL, n.Loc)
240
241 singleTables := collectSingleTables(databaseName, cteNames, n.Tables, isCaseSensitive)
242
243 // Determine which tables the SET clause writes, via column table prefixes.
244 updatedTables := make(map[string]bool)
245 var unqualifiedColumns []string
246 for _, assign := range n.SetList {
247 if assign == nil || assign.Column == nil {
248 continue
249 }
250 table := assign.Column.Table
251 if table == "" {
252 updatedTables[""] = true
253 unqualifiedColumns = append(unqualifiedColumns, assign.Column.Column)
254 continue
255 }
256 // Look up the qualifier case-insensitively (TiDB default): the alias/name
257 // resolves regardless of the case used in the SET clause.
258 key := identifierKey(table, isCaseSensitive)
259 // Skip only if the qualifier resolves to a CTE reference in the FROM — a
260 // CTE can't be a mutation target. A real table aliased with a CTE's name
261 // (its resolved table is real) is still an update target.
262 if ref, ok := singleTables[key]; ok && isCTERef(cteNames, ref) {
263 continue
264 }
265 updatedTables[key] = true
266 }
267
268 // Resolve unqualified SET columns to their owning table(s) via metadata.
269 // Exclude CTE refs from the candidates: a CTE can't be a mutation target,
270 // and resolveUnqualifiedColumns' metadata-unavailable/unresolved fallback
271 // would otherwise mark every candidate (CTEs included).
272 if updatedTables[""] {
273 delete(updatedTables, "")
274 candidates := make(map[string]*TableReference, len(singleTables))
275 for key, ref := range singleTables {
276 if isCTERef(cteNames, ref) {
277 continue
278 }
279 candidates[key] = ref
280 }
281 for t := range resolveUnqualifiedColumns(unqualifiedColumns, candidates, dbMetadata) {
282 updatedTables[t] = true
283 }
284 }
285
286 // Single-table UPDATE: no explicit qualification needed.
287 if len(updatedTables) == 0 && len(singleTables) == 1 {
288 for _, ref := range singleTables {
289 return []statementInfo{{
290 statement: stmtText,
291 table: ref,
292 node: n,
293 fullSQL: fullSQL,
294 }}, nil

Callers 1

extractTablesFunction · 0.70

Calls 7

identifierKeyFunction · 0.85
isCTERefFunction · 0.85
ErrorfMethod · 0.80
collectCTENamesFunction · 0.70
extractStatementTextFunction · 0.70
collectSingleTablesFunction · 0.70

Tested by

no test coverage detected