buildConfigSecret builds a CREATE SECRET statement with explicit credentials
(dlCfg DuckLakeConfig)
| 2103 | expectedNames[i] = ix.name |
| 2104 | } |
| 2105 | checkCtx, checkCancel := context.WithTimeout(context.Background(), 5*time.Second) |
| 2106 | var present int |
| 2107 | err = pgDB.QueryRowContext(checkCtx, "SELECT count(*) FROM pg_indexes WHERE indexname = ANY($1)", expectedNames).Scan(&present) |
| 2108 | checkCancel() |
| 2109 | if err == nil && present == len(duckLakeMetadataIndexes) { |
| 2110 | duckLakeIndexDone.Store(true) |
| 2111 | slog.Info("DuckLake metadata indexes already present; skipped ensure.", "verified", present, "total", len(duckLakeMetadataIndexes)) |
| 2112 | return |
| 2113 | } |
| 2114 | |
| 2115 | // Slow path: create any missing indexes. |
| 2116 | // Use a generous timeout — CREATE INDEX on large tables (e.g., ducklake_file_column_stats |
| 2117 | // at 1.2 GB) can take minutes on first run. |
| 2118 | ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) |
| 2119 | defer cancel() |
| 2120 | |
| 2121 | if err := pgDB.PingContext(ctx); err != nil { |
| 2122 | slog.Warn("Failed to connect to DuckLake metadata store for index creation.", "error", err) |
| 2123 | return |
| 2124 | } |
| 2125 | |
| 2126 | created := 0 |
| 2127 | for _, ix := range duckLakeMetadataIndexes { |
| 2128 | if _, err := pgDB.ExecContext(ctx, ix.stmt); err != nil { |
| 2129 | slog.Warn("Failed to create DuckLake metadata index.", "statement", ix.stmt, "error", err) |
| 2130 | // Continue — create as many indexes as possible |
| 2131 | } else { |
| 2132 | created++ |
| 2133 | } |
| 2134 | } |
| 2135 | |
| 2136 | if created == len(duckLakeMetadataIndexes) { |
| 2137 | duckLakeIndexDone.Store(true) |
| 2138 | } |
| 2139 | slog.Info("Ensured DuckLake metadata indexes.", "created_or_verified", created, "total", len(duckLakeMetadataIndexes)) |
| 2140 | } |
| 2141 | |
| 2142 | // setDuckLakeDefault sets the DuckLake catalog as the default so all queries use it. |
| 2143 | // This should be called AFTER creating per-connection views in memory.main. |
| 2144 | func setDuckLakeDefault(db *sql.DB) error { |
| 2145 | if _, err := db.Exec("USE ducklake"); err != nil { |
| 2146 | return fmt.Errorf("failed to set DuckLake as default catalog: %w", err) |
| 2147 | } |
| 2148 | slog.Info("Set DuckLake as default catalog.") |
| 2149 | return nil |