doesRelationExist tests if a relation with the specified |name| exists in this database. If any relation with that name exists, this function returns true for |exists|, the relation type (e.g. index, view, table, sequence) for |relationType|. If any problems are encountered looking up a relation, an
(ctx *sql.Context, name string)
| 299 | // name exists, this function returns true for |exists|, the relation type (e.g. index, view, table, sequence) for |
| 300 | // |relationType|. If any problems are encountered looking up a relation, an error is returned in |err|. |
| 301 | func (d *PgDatabase) doesRelationExist(ctx *sql.Context, name string) (exists bool, relationType string, err error) { |
| 302 | lowerName := strings.ToLower(name) |
| 303 | |
| 304 | // Resolve the effective schema: when the database was obtained without a schema qualifier |
| 305 | // (e.g. from GMS's plan builder for CREATE INDEX), schemaName is "" and we must fall back to |
| 306 | // the session's current schema so that sequence/view checks use the right namespace. |
| 307 | schema := d.Database.Schema() |
| 308 | if schema == "" { |
| 309 | var err error |
| 310 | schema, err = core.GetCurrentSchema(ctx) |
| 311 | if err != nil || schema == "" { |
| 312 | schema = "public" |
| 313 | } |
| 314 | } |
| 315 | |
| 316 | // Tables: use GetTableNames which reads the session's working root directly. |
| 317 | tableNames, err := d.Database.GetTableNames(ctx) |
| 318 | if err != nil { |
| 319 | return false, "", err |
| 320 | } |
| 321 | for _, tableName := range tableNames { |
| 322 | if strings.ToLower(tableName) == lowerName { |
| 323 | return true, "table", nil |
| 324 | } |
| 325 | } |
| 326 | |
| 327 | // Sequences: use the session-cached collection so uncommitted sequences are visible. |
| 328 | seqCollection, err := core.GetSequencesCollectionFromContext(ctx, d.Database.Name()) |
| 329 | if err != nil { |
| 330 | return false, "", err |
| 331 | } |
| 332 | if seqCollection.HasSequence(ctx, id.NewSequence(schema, name)) { |
| 333 | return true, "sequence", nil |
| 334 | } |
| 335 | |
| 336 | // Views: sqle.Database implements sql.ViewDatabase, so call AllViews directly. |
| 337 | views, err := d.Database.AllViews(ctx) |
| 338 | if err != nil { |
| 339 | return false, "", err |
| 340 | } |
| 341 | for _, view := range views { |
| 342 | if strings.ToLower(view.Name) == lowerName { |
| 343 | return true, "view", nil |
| 344 | } |
| 345 | } |
| 346 | |
| 347 | // Indexes are per-table; reuse the tableNames slice from the table check above. |
| 348 | for _, tableName := range tableNames { |
| 349 | tbl, ok, err := d.Database.GetTableInsensitive(ctx, tableName) |
| 350 | if err != nil { |
| 351 | return false, "", err |
| 352 | } |
| 353 | if !ok { |
| 354 | continue |
| 355 | } |
| 356 | idxTbl, ok := tbl.(sql.IndexAddressableTable) |
| 357 | if !ok { |
| 358 | continue |
no test coverage detected