@@ -95,6 +95,66 @@ extension QueryExecutionCoordinator {
9595 return nil
9696 }
9797
98+ struct ResolvedDisplayMetadata {
99+ var columnDefaults : [ String : String ? ] = [ : ]
100+ var columnForeignKeys : [ String : ForeignKeyInfo ] = [ : ]
101+ var columnEnumValues : [ String : [ String ] ] = [ : ]
102+ var columnNullable : [ String : Bool ] = [ : ]
103+ var columnComments : [ String : String ] = [ : ]
104+ var columnIdentity : [ String : IdentityKind ] = [ : ]
105+ var generatedColumns : Set < String > = [ ]
106+ var foreignKeysFetched = false
107+ }
108+
109+ /// A rerun answered from cache carries no metadata of its own, so it inherits what the tab
110+ /// already holds. That includes the non-writable set, which `configureForTable` clears on every
111+ /// execution and only a schema fetch refills.
112+ private func resolveDisplayMetadata(
113+ metadata: ParsedSchemaMetadata ? ,
114+ existingTabId: UUID ,
115+ columns: [ String ] ,
116+ columnTypes: [ ColumnType ] ,
117+ tabIndex: Int ,
118+ tableName: String ?
119+ ) -> ResolvedDisplayMetadata {
120+ var resolved = ResolvedDisplayMetadata ( )
121+ for (index, colType) in columnTypes. enumerated ( ) {
122+ if case . enumType( _, let values) = colType, let vals = values, index < columns. count {
123+ resolved. columnEnumValues [ columns [ index] ] = vals
124+ }
125+ }
126+
127+ if let metadata {
128+ resolved. columnDefaults = metadata. columnDefaults
129+ resolved. columnForeignKeys = metadata. columnForeignKeys ?? [ : ]
130+ resolved. columnNullable = metadata. columnNullable
131+ resolved. columnComments = metadata. columnComments
132+ resolved. columnIdentity = metadata. columnIdentity
133+ resolved. generatedColumns = metadata. generatedColumns
134+ resolved. foreignKeysFetched = metadata. columnForeignKeys != nil
135+ for (col, vals) in metadata. columnEnumValues {
136+ resolved. columnEnumValues [ col] = vals
137+ }
138+ } else {
139+ let existing = parent. tabSessionRegistry. tableRows ( for: existingTabId)
140+ resolved. columnDefaults = existing. columnDefaults
141+ resolved. columnForeignKeys = existing. columnForeignKeys
142+ resolved. columnNullable = existing. columnNullable
143+ resolved. columnComments = existing. columnComments
144+ resolved. columnIdentity = existing. columnIdentity
145+ resolved. generatedColumns = existing. generatedColumns
146+ resolved. foreignKeysFetched = existing. foreignKeysFetched
147+ for (col, vals) in existing. columnEnumValues where resolved. columnEnumValues [ col] == nil {
148+ resolved. columnEnumValues [ col] = vals
149+ }
150+ }
151+
152+ if resolved. columnForeignKeys. isEmpty, !resolved. foreignKeysFetched, let tableName {
153+ resolved. columnForeignKeys = prefetchedForeignKeys ( tabIndex: tabIndex, tableName: tableName) ?? [ : ]
154+ }
155+ return resolved
156+ }
157+
98158 func applyPhase1Result( // swiftlint:disable:this function_parameter_count
99159 tabId: UUID ,
100160 columns: [ String ] ,
@@ -138,54 +198,28 @@ extension QueryExecutionCoordinator {
138198 }
139199
140200 let existingTabId = parent. tabManager. tabs [ idx] . id
141- var columnEnumValues : [ String : [ String ] ] = [ : ]
142- var columnDefaults : [ String : String ? ] = [ : ]
143- var columnForeignKeys : [ String : ForeignKeyInfo ] = [ : ]
144- var columnNullable : [ String : Bool ] = [ : ]
145- var columnComments : [ String : String ] = [ : ]
146- for (index, colType) in columnTypes. enumerated ( ) {
147- if case . enumType( _, let values) = colType, let vals = values, index < columns. count {
148- columnEnumValues [ columns [ index] ] = vals
149- }
150- }
151-
152- var foreignKeysFetched = false
153-
154- if let metadata {
155- columnDefaults = metadata. columnDefaults
156- columnForeignKeys = metadata. columnForeignKeys ?? [ : ]
157- columnNullable = metadata. columnNullable
158- columnComments = metadata. columnComments
159- foreignKeysFetched = metadata. columnForeignKeys != nil
160- for (col, vals) in metadata. columnEnumValues {
161- columnEnumValues [ col] = vals
162- }
163- } else {
164- let existing = parent. tabSessionRegistry. tableRows ( for: existingTabId)
165- columnDefaults = existing. columnDefaults
166- columnForeignKeys = existing. columnForeignKeys
167- columnNullable = existing. columnNullable
168- columnComments = existing. columnComments
169- foreignKeysFetched = existing. foreignKeysFetched
170- for (col, vals) in existing. columnEnumValues where columnEnumValues [ col] == nil {
171- columnEnumValues [ col] = vals
172- }
173- }
174-
175- if columnForeignKeys. isEmpty, !foreignKeysFetched, let tableName {
176- columnForeignKeys = prefetchedForeignKeys ( tabIndex: idx, tableName: tableName) ?? [ : ]
177- }
201+ let resolved = resolveDisplayMetadata (
202+ metadata: metadata,
203+ existingTabId: existingTabId,
204+ columns: columns,
205+ columnTypes: columnTypes,
206+ tabIndex: idx,
207+ tableName: tableName
208+ )
209+ let generatedColumns = resolved. generatedColumns
178210
179211 let newTableRows = TableRows . from (
180212 queryRows: rows,
181213 columns: columns,
182214 columnTypes: columnTypes,
183- columnDefaults: columnDefaults,
184- columnForeignKeys: columnForeignKeys,
185- columnEnumValues: columnEnumValues,
186- columnNullable: columnNullable,
187- columnComments: columnComments,
188- foreignKeysFetched: foreignKeysFetched
215+ columnDefaults: resolved. columnDefaults,
216+ columnForeignKeys: resolved. columnForeignKeys,
217+ columnEnumValues: resolved. columnEnumValues,
218+ columnNullable: resolved. columnNullable,
219+ columnComments: resolved. columnComments,
220+ columnIdentity: resolved. columnIdentity,
221+ generatedColumns: generatedColumns,
222+ foreignKeysFetched: resolved. foreignKeysFetched
189223 )
190224 let previousTableName = parent. tabManager. tabs [ idx] . tableContext. tableName
191225 parent. flushBufferToActiveResult ( tabId: existingTabId, pinnedOnly: true )
@@ -262,7 +296,8 @@ extension QueryExecutionCoordinator {
262296 schemaName: parent. tabManager. tabs [ idx] . tableContext. schemaName,
263297 columns: columns,
264298 primaryKeyColumns: resolvedPKs,
265- databaseType: conn. type
299+ databaseType: conn. type,
300+ generatedColumns: generatedColumns
266301 )
267302 }
268303
@@ -499,7 +534,9 @@ extension QueryExecutionCoordinator {
499534 columnDefaults: parsed. columnDefaults,
500535 columnForeignKeys: parsed. columnForeignKeys,
501536 columnNullable: parsed. columnNullable,
502- columnComments: parsed. columnComments
537+ columnComments: parsed. columnComments,
538+ columnIdentity: parsed. columnIdentity,
539+ generatedColumns: parsed. generatedColumns
503540 )
504541 }
505542
0 commit comments