@@ -56,6 +56,17 @@ NativeQuery.prototype.handleError = function (err) {
56
56
err [ normalizedFieldName ] = fields [ key ]
57
57
}
58
58
}
59
+
60
+ // For maxResultSize exceeded errors, make sure we emit the error to the client too
61
+ if ( err . code === 'RESULT_SIZE_EXCEEDED' ) {
62
+ if ( this . native && this . native . connection ) {
63
+ // Need to emit the error on the client/connection level too
64
+ process . nextTick ( ( ) => {
65
+ this . native . connection . emit ( 'error' , err )
66
+ } )
67
+ }
68
+ }
69
+
59
70
if ( this . callback ) {
60
71
this . callback ( err )
61
72
} else {
@@ -89,6 +100,9 @@ NativeQuery.prototype.submit = function (client) {
89
100
this . native = client . native
90
101
client . native . arrayMode = this . _arrayMode
91
102
103
+ // Get the maxResultSize from the client if it's set
104
+ this . _maxResultSize = client . _maxResultSize
105
+
92
106
var after = function ( err , rows , results ) {
93
107
client . native . arrayMode = false
94
108
setImmediate ( function ( ) {
@@ -100,6 +114,30 @@ NativeQuery.prototype.submit = function (client) {
100
114
return self . handleError ( err )
101
115
}
102
116
117
+ // Check the result size if maxResultSize is configured
118
+ if ( self . _maxResultSize ) {
119
+ // Calculate result size (rough approximation)
120
+ let resultSize = 0
121
+
122
+ // For multiple result sets
123
+ if ( results . length > 1 ) {
124
+ for ( let i = 0 ; i < rows . length ; i ++ ) {
125
+ resultSize += self . _calculateResultSize ( rows [ i ] )
126
+ }
127
+ } else if ( rows . length > 0 ) {
128
+ resultSize = self . _calculateResultSize ( rows )
129
+ }
130
+
131
+ // If the size limit is exceeded, generate an error
132
+ if ( resultSize > self . _maxResultSize ) {
133
+ const error = new Error ( 'Query result size exceeded the configured limit' )
134
+ error . code = 'RESULT_SIZE_EXCEEDED'
135
+ error . resultSize = resultSize
136
+ error . maxResultSize = self . _maxResultSize
137
+ return self . handleError ( error )
138
+ }
139
+ }
140
+
103
141
// emit row events for each row in the result
104
142
if ( self . _emitRowEvents ) {
105
143
if ( results . length > 1 ) {
@@ -166,3 +204,59 @@ NativeQuery.prototype.submit = function (client) {
166
204
client . native . query ( this . text , after )
167
205
}
168
206
}
207
+
208
+ // Helper method to estimate the size of a result set
209
+ NativeQuery . prototype . _calculateResultSize = function ( rows ) {
210
+ let size = 0
211
+
212
+ // For empty results, return 0
213
+ if ( ! rows || rows . length === 0 ) {
214
+ return 0
215
+ }
216
+
217
+ // For array mode, calculate differently
218
+ if ( this . _arrayMode ) {
219
+ // Just use a rough approximation based on number of rows
220
+ return rows . length * 100
221
+ }
222
+
223
+ // For each row, approximate its size
224
+ for ( let i = 0 ; i < rows . length ; i ++ ) {
225
+ const row = rows [ i ]
226
+
227
+ // Add base row size
228
+ size += 24 // Overhead per row
229
+
230
+ // Add size of each column
231
+ for ( const key in row ) {
232
+ if ( Object . prototype . hasOwnProperty . call ( row , key ) ) {
233
+ const value = row [ key ]
234
+
235
+ // Add key size
236
+ size += key . length * 2 // Assume 2 bytes per character
237
+
238
+ // Add value size based on type
239
+ if ( value === null || value === undefined ) {
240
+ size += 8
241
+ } else if ( typeof value === 'string' ) {
242
+ size += value . length * 2 // Assume 2 bytes per character
243
+ } else if ( typeof value === 'number' ) {
244
+ size += 8
245
+ } else if ( typeof value === 'boolean' ) {
246
+ size += 4
247
+ } else if ( value instanceof Date ) {
248
+ size += 8
249
+ } else if ( Buffer . isBuffer ( value ) ) {
250
+ size += value . length
251
+ } else if ( Array . isArray ( value ) ) {
252
+ size += 16 + value . length * 8
253
+ } else {
254
+ // For objects, use a rough estimate
255
+ size += 32 + JSON . stringify ( value ) . length * 2
256
+ }
257
+ }
258
+ }
259
+ }
260
+
261
+ return size
262
+ }
0 commit comments