@@ -1212,6 +1212,28 @@ Frame_cursor *get_frame_cursor(Window_frame *frame, bool is_top_bound)
1212
1212
return NULL ;
1213
1213
}
1214
1214
1215
+ List<Frame_cursor> get_window_func_required_cursors (
1216
+ const Item_window_func* item_win)
1217
+ {
1218
+ List<Frame_cursor> result;
1219
+
1220
+ /*
1221
+ If it is not a regular window function that follows frame specifications,
1222
+ specific cursors are required.
1223
+ */
1224
+ if (item_win->is_frame_prohibited ())
1225
+ {
1226
+ DBUG_ASSERT (0 ); // TODO-cvicentiu not-implemented yet.
1227
+ }
1228
+
1229
+ /* A regular window function follows the frame specification. */
1230
+ result.push_back (get_frame_cursor (item_win->window_spec ->window_frame ,
1231
+ false ));
1232
+ result.push_back (get_frame_cursor (item_win->window_spec ->window_frame ,
1233
+ true ));
1234
+
1235
+ return result;
1236
+ }
1215
1237
1216
1238
/*
1217
1239
Streamed window function computation with window frames.
@@ -1254,21 +1276,21 @@ bool compute_window_func_with_frames(Item_window_func *item_win,
1254
1276
{
1255
1277
THD *thd= current_thd;
1256
1278
int err= 0 ;
1257
- Frame_cursor *top_bound;
1258
- Frame_cursor *bottom_bound;
1259
1279
1260
1280
Item_sum *sum_func= item_win->window_func ();
1261
1281
/* This algorithm doesn't support DISTINCT aggregator */
1262
1282
sum_func->set_aggregator (Aggregator::SIMPLE_AGGREGATOR);
1263
-
1264
- Window_frame *window_frame= item_win->window_spec ->window_frame ;
1265
- top_bound= get_frame_cursor (window_frame, true );
1266
- bottom_bound= get_frame_cursor (window_frame, false );
1267
-
1268
- top_bound->init (thd, info, item_win->window_spec ->partition_list ,
1269
- item_win->window_spec ->order_list );
1270
- bottom_bound->init (thd, info, item_win->window_spec ->partition_list ,
1271
- item_win->window_spec ->order_list );
1283
+
1284
+ List<Frame_cursor> cursors= get_window_func_required_cursors (item_win);
1285
+
1286
+
1287
+ List_iterator_fast<Frame_cursor> it (cursors);
1288
+ Frame_cursor *c;
1289
+ while ((c= it++))
1290
+ {
1291
+ c->init (thd, info, item_win->window_spec ->partition_list ,
1292
+ item_win->window_spec ->order_list );
1293
+ }
1272
1294
1273
1295
bool is_error= false ;
1274
1296
longlong rownum= 0 ;
@@ -1293,24 +1315,28 @@ bool compute_window_func_with_frames(Item_window_func *item_win,
1293
1315
pre_XXX functions assume that tbl->record[0] contains current_row, and
1294
1316
they may not change it.
1295
1317
*/
1296
- bottom_bound->pre_next_partition (rownum, sum_func);
1297
- top_bound->pre_next_partition (rownum, sum_func);
1318
+ it.rewind ();
1319
+ while ((c= it++))
1320
+ c->pre_next_partition (rownum, sum_func);
1298
1321
/*
1299
1322
We move bottom_bound first, because we want rows to be added into the
1300
1323
aggregate before top_bound attempts to remove them.
1301
1324
*/
1302
- bottom_bound->next_partition (rownum, sum_func);
1303
- top_bound->next_partition (rownum, sum_func);
1325
+ it.rewind ();
1326
+ while ((c= it++))
1327
+ c->next_partition (rownum, sum_func);
1304
1328
}
1305
1329
else
1306
1330
{
1307
1331
/* Again, both pre_XXX function can find current_row in tbl->record[0] */
1308
- bottom_bound->pre_next_row (sum_func);
1309
- top_bound->pre_next_row (sum_func);
1332
+ it.rewind ();
1333
+ while ((c= it++))
1334
+ c->pre_next_row (sum_func);
1310
1335
1311
1336
/* These make no assumptions about tbl->record[0] and may change it */
1312
- bottom_bound->next_row (sum_func);
1313
- top_bound->next_row (sum_func);
1337
+ it.rewind ();
1338
+ while ((c= it++))
1339
+ c->next_row (sum_func);
1314
1340
}
1315
1341
rownum++;
1316
1342
@@ -1331,8 +1357,7 @@ bool compute_window_func_with_frames(Item_window_func *item_win,
1331
1357
}
1332
1358
1333
1359
my_free (rowid_buf);
1334
- delete top_bound;
1335
- delete bottom_bound;
1360
+ cursors.delete_elements ();
1336
1361
return is_error? true : false ;
1337
1362
}
1338
1363
0 commit comments