@@ -233,29 +233,40 @@ interface ProjectionBudget {
233233 bytes : number
234234}
235235
236+ function projectColumns ( table : KustoTable ) : AzureDataExplorerResultTable [ 'columns' ] {
237+ return ( table . Columns ?? [ ] ) . map ( ( column ) => ( {
238+ name : column . ColumnName ?? '' ,
239+ type : column . ColumnType ?? null ,
240+ dataType : column . DataType ?? null ,
241+ } ) )
242+ }
243+
244+ /** Serialized size of a table's projection without its rows, reserved before any rows are kept. */
245+ function envelopeBytes ( table : KustoTable | null ) : number {
246+ if ( ! table ) return Buffer . byteLength ( JSON . stringify ( EMPTY_PROJECTION ) )
247+ const rowTotal = ( table . Rows ?? [ ] ) . length
248+ return Buffer . byteLength (
249+ JSON . stringify ( {
250+ tableName : table . TableName ?? null ,
251+ columns : projectColumns ( table ) ,
252+ rows : [ ] ,
253+ records : [ ] ,
254+ rowCount : rowTotal ,
255+ totalRowCount : rowTotal ,
256+ truncated : false ,
257+ } )
258+ )
259+ }
260+
236261function projectTable (
237262 table : KustoTable | null ,
238263 budget : ProjectionBudget
239264) : AzureDataExplorerResultTable {
240265 if ( ! table ) return EMPTY_PROJECTION
241- const columns = ( table . Columns ?? [ ] ) . map ( ( column ) => ( {
242- name : column . ColumnName ?? '' ,
243- type : column . ColumnType ?? null ,
244- dataType : column . DataType ?? null ,
245- } ) )
266+ const columns = projectColumns ( table )
246267 const allRows = table . Rows ?? [ ]
247268 const rows : unknown [ ] [ ] = [ ]
248269 const records : Array < Record < string , unknown > > = [ ]
249- const envelope : AzureDataExplorerResultTable = {
250- tableName : table . TableName ?? null ,
251- columns,
252- rows : [ ] ,
253- records : [ ] ,
254- rowCount : allRows . length ,
255- totalRowCount : allRows . length ,
256- truncated : false ,
257- }
258- budget . bytes -= Buffer . byteLength ( JSON . stringify ( envelope ) )
259270 for ( const row of allRows ) {
260271 if ( budget . rows <= 0 ) break
261272 const record : Record < string , unknown > = { }
@@ -288,9 +299,16 @@ function projectResults(
288299 tables : KustoTable [ ] ,
289300 contents : TableOfContents | null
290301) : AzureDataExplorerTable {
291- const budget : ProjectionBudget = { rows : MAX_PROJECTED_ROWS , bytes : MAX_PROJECTED_BYTES }
292- const primary = projectTable ( selectPrimaryTable ( tables , contents ) , budget )
302+ const primaryTable = selectPrimaryTable ( tables , contents )
293303 const additionalOrdinals = contents ?. resultOrdinals . slice ( 1 ) ?? [ ]
304+ const reserved = [ primaryTable , ...additionalOrdinals . map ( ( ordinal ) => tables [ ordinal ] ?? null ) ]
305+ . map ( envelopeBytes )
306+ . reduce ( ( total , bytes ) => total + bytes , 0 )
307+ const budget : ProjectionBudget = {
308+ rows : MAX_PROJECTED_ROWS ,
309+ bytes : MAX_PROJECTED_BYTES - reserved ,
310+ }
311+ const primary = projectTable ( primaryTable , budget )
294312 if ( additionalOrdinals . length === 0 ) return primary
295313 return {
296314 ...primary ,
0 commit comments