MySQL  8.0.23
Source Code Documentation
window.h
Go to the documentation of this file.
1 /* Copyright (c) 2017, 2020, Oracle and/or its affiliates.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License, version 2.0,
5  as published by the Free Software Foundation.
6 
7  This program is also distributed with certain software (including
8  but not limited to OpenSSL) that is licensed under separate terms,
9  as designated in a particular file or component or in included license
10  documentation. The authors of MySQL hereby grant you an additional
11  permission to link the program and your derivative works with the
12  separately licensed software that they have included with MySQL.
13 
14  This program is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License, version 2.0, for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program; if not, write to the Free Software
21  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23 
24 #ifndef WINDOWS_INCLUDED
25 #define WINDOWS_INCLUDED
26 
27 #include <sys/types.h>
28 #include <cstring> // std::memcpy
29 
30 #include "my_dbug.h"
31 #include "my_inttypes.h"
32 #include "sql/enum_query_type.h"
33 #include "sql/handler.h"
34 #include "sql/mem_root_array.h"
35 #include "sql/sql_lex.h"
36 #include "sql/sql_list.h"
37 #include "sql/table.h"
38 
39 /*
40  Some Window-related symbols must be known to sql_lex.h which is a frequently
41  included header.
42  To avoid that any change to window.h causes a recompilation of the whole
43  Server, those symbols go into this header:
44 */
45 #include "sql/window_lex.h"
46 
47 class Cached_item;
48 class Item;
49 class Item_func;
50 class Item_string;
51 class Item_sum;
52 class PT_border;
53 class PT_frame;
54 class PT_order_list;
55 class PT_window;
56 class String;
57 class THD;
58 class Temp_table_param;
59 
60 /**
61  Position hints for the frame buffer are saved for these kind of row
62  accesses, cf. #Window::m_frame_buffer_positions.
63 */
65  WONT_UPDATE_HINT = -1, // special value when using restore_special_record
67  CURRENT = 1,
68  FIRST_IN_FRAME = 2,
69  LAST_IN_FRAME = 3,
70  LAST_IN_PEERSET = 4,
71  MISC_POSITIONS = 5 // NTH_VALUE, LEAD/LAG have dynamic indexes 5..N
72 };
73 
74 /**
75  Represents the (explicit) window of a SQL 2003 section 7.11 <window clause>,
76  or the implicit (inlined) window of a window function call, or a reference to
77  a named window in a window function call (instead of the inlined definition)
78  before resolution. After resolving referencing instances become unused,
79  having been replaced with the window resolved to in the w.f. call.
80 
81  @verbatim
82  Cf. 7.11 <window definition> and <existing window name>
83  6.10 <window name or specification> and
84  <in-line window specification>
85  5.4 <window name>
86  @endverbatim
87 
88  See also PT_window (which wraps Window as a parse_tree_node), and the related
89  classes PT_frame, PT_border and PT_exclusion in parse_tree_nodes.
90 
91  Currently includes both prepared query and execution state information.
92  The latter is marked as such for ease of separation later.
93 */
94 class Window {
95  /*------------------------------------------------------------------------
96  *
97  * Variables stable during execution
98  *
99  *------------------------------------------------------------------------*/
100  protected:
101  SELECT_LEX *m_select; ///< The SELECT the window is on
102  PT_order_list *const m_partition_by; ///< <window partition clause>
103  PT_order_list *const m_order_by; ///< <window order clause>
104  ORDER *m_sorting_order; ///< merged partition/order by
105  PT_frame *const m_frame; ///< <window frame clause>
106  Item_string *m_name; ///< <window name>
107  /**
108  Position of definition in query's text, 1 for leftmost. References don't
109  count. Thus, anonymous windows in SELECT list, then windows of WINDOW
110  clause, then anonymous windows in ORDER BY.
111  */
113  Item_string *const m_inherit_from; ///< <existing window name>
114  /**
115  If true, m_name is an unbound window reference, other fields
116  are unused.
117  */
118  const bool m_is_reference;
119 
120  /**
121  (At least) one window function needs to buffer frame rows for evaluation
122  i.e. it cannot be evaluated on the fly just from previous rows seen
123  */
125 
126  /**
127  (At least) one window function needs the peer set of the current row to
128  evaluate the wf for the current row
129  */
131 
132  /**
133  (At least) one window function (currently JSON_OBJECTAGG) needs the
134  last peer for the current row to evaluate the wf for the current row.
135  (This is used only during inversion/optimization)
136  */
138 
139  /**
140  (At least) one window function needs the cardinality of the partition of
141  the current row to evaluate the wf for the current row
142  */
144 
145  /**
146  The functions are optimizable with ROW unit. For example SUM is, MAX is
147  not always optimizable. Optimized means we can use the optimized evaluation
148  path in process_buffered_windowing_record which uses inversion to avoid
149  revisiting all frame rows for every row being evaluated.
150  */
152 
153  /**
154  The functions are optimizable with RANGE unit. For example SUM is, MAX is
155  not always optimizable. Optimized means we can use the optimized evaluation
156  path in process_buffered_windowing_record which uses inversion to avoid
157  revisiting all frame rows for every row being evaluated.
158  */
160 
161  /**
162  The aggregates (SUM, etc) can be evaluated once for a partition, since it
163  is static, i.e. all rows will have the same value for the aggregates, e.g.
164  ROWS/RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING.
165  */
167 
168  /**
169  Window equires re-evaluation of the first row in optimized moving frame mode
170  e.g. FIRST_VALUE.
171  */
173 
174  /**
175  Window requires re-evaluation of the last row in optimized moving frame mode
176  e.g. LAST_VALUE.
177  */
179 
180  /**
181  Can be true if first window after a join: we may need to restore the input
182  record after buffered window processing if EQRefIterator's caching logic
183  presumes the record hasn't been modified (when last qep_tab uses JT_EQ_REF).
184  */
186 
187  /**
188  The last window to be evaluated at execution time.
189  */
190  bool m_last;
191 
192  public:
193  struct st_offset {
197  /**
198  Used for sorting offsets in ascending order for faster traversal of
199  frame buffer tmp file
200  */
201  bool operator<(const st_offset &a) const { return m_rowno < a.m_rowno; }
202  };
203 
204  struct st_ll_offset {
205  int64 m_rowno; ///< negative values is LEAD
206  st_ll_offset() : m_rowno(INT_MIN64 /* uninitialized marker*/) {}
207  /**
208  Used for sorting offsets in ascending order for faster traversal of
209  frame buffer tmp file
210  */
211  bool operator<(const st_ll_offset &a) const { return m_rowno < a.m_rowno; }
212  };
213 
214  struct st_nth {
216  m_offsets; ///< sorted set of NTH_VALUE offsets
217  };
218 
219  struct st_lead_lag {
221  m_offsets; ///< sorted set of LEAD/LAG offsets
222  };
223 
224  protected:
225  /**
226  Window requires re-evaluation of the Nth row in optimized moving frame mode
227  e.g. NTH_VALUE.
228  */
231 
232  protected:
233  const Window *m_ancestor; ///< resolved from existing window name
234  List<Item_sum> m_functions; ///< window functions based on 'this'
235  List<Cached_item> m_partition_items; ///< items for the PARTITION BY columns
236  List<Cached_item> m_order_by_items; ///< items for the ORDER BY exprs.
237 
238  /*------------------------------------------------------------------------
239  *
240  * Execution state variables
241  *
242  *------------------------------------------------------------------------*/
243  public:
244  /**
245  Cardinality of m_frame_buffer_positions if no NTH_VALUE, LEAD/LAG
246  */
247  static constexpr int FRAME_BUFFER_POSITIONS_CARD =
249 
250  /**
251  Holds information about a position in the buffer frame as stored in a
252  temporary file (cf. m_frame_buffer). We save a number of such positions
253  to speed up lookup when we move the window frame, cf.
254  m_frame_buffer_positions
255  */
257  ///< The size of the file position is determined by handler::ref_length
259  ///< Row number in partition, 1-based
262  : m_position(position), m_rowno(rowno) {}
263  };
264 
265  /**
266  Execution state: used iff m_needs_frame_buffering. Holds pointers to
267  positions in the file in m_frame_buffer. We use these saved positions to
268  avoid having to position to the first row in the partition and then
269  making many read calls to find the desired row. By repositioning to a
270  suitably(*) saved position we normally (**) need to do only one positioned
271  read and one ha_rdn_next call to get at a desired row.
272  @verbatim
273 
274  [0] the first row in the partition: at the
275  beginning of a new partition that is the first row in the partition.
276  Its rowno == 1 by definition.
277  [1] position of the current row N (for jump-back to current row or next
278  current row in combo with ha_rnd_next)
279  [2] position of the current first row M in frame (for aggregation looping
280  jump-back)
281  [3] position of the current last row in a frame
282  [4] position and line number of the row last read
283  and optionally:
284  [5..X] positions of Nth row of X-5+1 NTH_VALUE functions invoked on window
285  [X+1..Y] position of last row of lead/lag functions invoked on window
286 
287  @endverbatim
288  Pointers are lazily initialized if needed.
289 
290  (*) We use the position closest below the desired position, cf logic in
291  read_frame_buffer_row.
292 
293  (**) Unless we have a frame beyond the current row, in which case we need
294  to do some scanning for the first row in the partition.
295  Also NTH_VALUE with RANGE might sometimes needs to read several rows, since
296  the frame start can jump several rows ahead when the current row moves
297  forward.
298  */
300 
301  /**
302  Sometimes we read one row too many, so that the saved position will
303  be too far out because we subsequently need to read an earlier (previous)
304  row of the same kind (reason). For such cases, we first save the
305  current position, read, and if we see we read too far, restore the old
306  position. See #save_pos and #restore_pos.
307  */
309 
310  /**
311  See #m_tmp_pos
312  */
314  int reason_index = static_cast<int>(reason);
315  m_tmp_pos.m_rowno = m_frame_buffer_positions[reason_index].m_rowno;
316  std::memcpy(m_tmp_pos.m_position,
317  m_frame_buffer_positions[reason_index].m_position,
318  frame_buffer()->file->ref_length);
319  }
320 
321  /**
322  See #m_tmp_pos
323  */
325  int reason_index = static_cast<int>(reason);
326  m_frame_buffer_positions[reason_index].m_rowno = m_tmp_pos.m_rowno;
327  std::memcpy(m_frame_buffer_positions[reason_index].m_position,
328  m_tmp_pos.m_position, frame_buffer()->file->ref_length);
329  }
330 
331  /**
332  Copy frame buffer position hint from one to another.
333  */
336  int from_index = static_cast<int>(from_reason);
337  int to_index = static_cast<int>(to_reason);
338  m_frame_buffer_positions[to_index].m_rowno =
339  m_frame_buffer_positions[from_index].m_rowno;
340 
341  std::memcpy(m_frame_buffer_positions[to_index].m_position,
342  m_frame_buffer_positions[from_index].m_position,
343  frame_buffer()->file->ref_length);
344  }
345 
346  /**
347  Keys for m_frame_buffer_cache and m_special_rows_cache, for special
348  rows.
349  */
351  /**
352  We read an incoming row. We notice it is the start of a new
353  partition. We must thus process the just-finished partition, but that
354  processing uses this row's buffer; so, we save this row first, process
355  the partition, and restore it later.
356  */
358  /// The last row cached in the frame buffer; needed to resurrect input row
360  // Insert new values here.
361  // And keep the ones below up to date.
364  };
365 
366  protected:
367  /**
368  Execution state: used iff m_needs_frame_buffering. Holds the temporary
369  file (used for the frame buffering) parameters
370  */
372 
373  /**
374  Execution state: Holds the temporary output table (for next step) parameters
375  */
377 
378  /**
379  Execution state: used iff m_needs_frame_buffering. Holds the TABLE
380  object for the the temporary file used for the frame buffering.
381  */
383 
384  /**
385  Execution state: The frame buffer tmp file is not truncated for each new
386  partition. We need to keep track of where a partition starts in case we
387  need to switch from heap to innodb tmp file on overflow, in order to
388  re-initialize m_frame_buffer_positions with the current partition's row 1
389  (which is the minimum hint required) as we cross over. This number is
390  incremented for each write.
391  */
393 
394  /**
395  Execution state: Snapshot of m_frame_buffer_total_rows when we start a new
396  partition, i.e. for the first row in the first partition we will have a
397  value of 1.
398  */
400 
401  /**
402  If >=1: the row with this number (1-based, relative to start of
403  partition) currently has its fields in the record buffer of the IN table
404  and of the OUT table. 0 means "unset".
405  Usable only with buffering. Set and read by bring_back_frame_row(), so
406  that multiple successive calls to it for same row do only one read from
407  FB (optimization).
408  */
410 
411  /**
412  Holds a fixed number of copies of special rows; each copy can use up to
413  #m_special_rows_cache_max_length bytes.
414  cf. the Special_keys enumeration.
415  */
417  /// Length of each copy in #m_special_rows_cache, in bytes
419  /// Maximum allocated size in #m_special_rows_cache
421 
422  /**
423  Execution state: used iff m_needs_frame_buffering. Holds the row
424  number (in the partition) of the last row (hitherto) saved in the frame
425  buffer
426  */
428 
429  /**
430  Execution state: used iff m_needs_peerset. Holds the rowno
431  for the last row in this peer set.
432  */
434 
435  /**
436  Execution state: used iff m_needs_last_peer_in_frame. True if a row
437  leaving the frame is the last row in the peer set withing the frame.
438  */
440 
441  /**
442  Execution state: the current row number in the current partition.
443  Set in check_partition_boundary. Used while reading input rows, in contrast
444  to m_rowno_in_partition, which is used when processing buffered rows.
445  Cf. check_partition_boundary.
446  */
448 
449  /**
450  Execution state: the current row starts a new partition.
451  Set in check_partition_boundary.
452  */
454 
455  /**
456  Execution state: The number, in the current partition, of the last output
457  row, i.e. the row number of the last row hitherto evaluated and output to
458  the next phase.
459  */
461 
462  /**
463  Execution state: The number of the row being visited for its contribution
464  to a window function, relative to the start of the partition. Note that
465  this will often be different from the current row for which we are
466  processing the window function, reading it for output. That is given by
467  m_rowno_in_partition, q.v.
468  */
470 
471  /**
472  Execution state: the row number of the current row within a frame, cf.
473  m_is_last_row_in_frame, relative to start of the frame. 1-based.
474  */
476 
477  /**
478  Execution state: The row number of the current row being readied for
479  output within the partition. 1-based.
480  */
482 
483  /**
484  Execution state: for optimizable aggregates, cf. m_row_optimizable and
485  m_range_optimizable, we need to keep track of when we have computed the
486  first aggregate, since aggregates for rows 2..N are computed in an optimized
487  way by inverse aggregation of the row moving out of the frame.
488  */
490 
491  /*------------------------------------------------------------------------
492  *
493  * RANGE boundary frame state variables.
494  *
495  *------------------------------------------------------------------------*/
496  public:
497  /**
498  RANGE bound determination computation; first index is a value of the
499  enum_window_border_type enum; second index 0 for the start bound, 1 for
500  the end bound. Each item is Item_func_lt/gt.
501  */
503  /**
504  Each item has inverse operation of the corresponding
505  comparator in m_comparators. Determines if comparison
506  should continue with next field in order by list.
507  */
509 
510  protected:
511  /**
512  Execution state: the row number of the first row in a frame when evaluating
513  RANGE based frame bounds. When using RANGE bounds, we don't know a priori
514  when moving the frame which row number will be the next lower bound, but
515  we know it will have to be a row number higher than the lower bound of
516  the previous frame, since the bounds increase monotonically as long
517  as the frame bounds are static within the query (current limitation).
518  So, it makes sense to remember the first row number in a frame until
519  we have determined the start of the next frame.
520 
521  If the frame for the previous current row in the partition was empty (cf.
522  "current_row" in process_buffered_windowing_record), this should point
523  to the next possible frame start. Relative to partition start, 1-based.
524  */
526 
527  /**
528  Execution state: used for RANGE bounds frame evaluation
529  for the continued evaluation for current row > 2 in a partition.
530  If the frame for the current row visited (cf "current_row" in
531  process_buffered_windowing_record) was empty, the invariant
532 
533  m_last_rowno_in_range_frame < m_first_rowno_in_range_frame
534 
535  should hold after the visit. Relative to partition start. 1-based.
536  */
538 
539  /*------------------------------------------------------------------------
540  *
541  * Window function special behaviour toggles. These boolean flag influence
542  * the action taken when a window function is evaluated, i.e.
543  *
544  * Item_xxx::val_xxx
545  *
546  * They are set locally just before and after a call to evaluate functions,
547  * i.e.
548  *
549  * w.set_<toggle>(true)
550  * copy_<kind>_window_functions() [see process_buffered_windowing_record]
551  * w.set_<toggle>(false)
552  *
553  * to achive a special semantic, since we cannot pass down extra parameters.
554  *
555  *------------------------------------------------------------------------*/
556 
557  /**
558  Execution state: the current row is the last row in a window frame
559  For some aggregate functions, e.g AVG, we can save computation by not
560  evaluating the entire function value before the last row has been read.
561  For AVG, do the summation for each row in the frame, but the division only
562  for the last row, at which time the result is needed for the wf.
563  Probably only useful for ROW based or static frames.
564  For frame with peer set computation, determining the last row in the
565  peer set ahead of processing is not possible, so we use a pessimistic
566  assumption.
567  */
569 
570  /**
571  Execution state: make frame wf produce a NULL (or 0 depending, e.g. if
572  COUNT) value because no rows are available for aggregation: e.g. for first
573  row in partition if frame is ROWS BETWEEN 2 PRECEDING and 1 PRECEDING has
574  no rows for which aggregation can happen
575  */
577 
578  /**
579  Execution state: do inverse, e.g. subtract rather than add in aggregates.
580  Used for optimizing computation of sliding frames for eligible aggregates,
581  cf. Item_sum::check_wf_semantics.
582  */
584 
585  /*------------------------------------------------------------------------
586  *
587  * Constructors
588  *
589  *------------------------------------------------------------------------*/
590  private:
591  /**
592  Generic window constructor, shared
593  */
595  PT_frame *frame, bool is_reference, Item_string *inherit)
596  : m_select(nullptr),
597  m_partition_by(part),
598  m_order_by(ord),
600  m_frame(frame),
601  m_name(name),
602  m_def_pos(0),
603  m_inherit_from(inherit),
615  m_last(false),
617  m_tmp_pos(nullptr, -1),
632  m_rowno_in_frame(0),
640  m_opt_nth_row.m_offsets.init_empty_const();
641  m_opt_lead_lag.m_offsets.init_empty_const();
642  m_frame_buffer_positions.init_empty_const();
643  }
644 
645  public:
646  /**
647  Reference to a named window. This kind is only used before resolution,
648  references to it being replaced by the referenced window object thereafter.
649  */
652 
653  /**
654  Unnamed window. If the window turns out to be named, the name will be set
655  later, cf. #set_name().
656  */
657  Window(PT_order_list *partition_by, PT_order_list *order_by, PT_frame *frame)
658  : Window(nullptr, partition_by, order_by, frame, false, nullptr) {}
659 
660  /**
661  Unnamed window based on a named window. If the window turns out to be
662  named, the name will be set later, cf. #set_name().
663  */
664  Window(PT_order_list *partition_by, PT_order_list *order_by, PT_frame *frame,
665  Item_string *inherit)
666  : Window(nullptr, partition_by, order_by, frame, false, inherit) {}
667 
668  /*------------------------------------------------------------------------
669  *
670  * Methods
671  *
672  *------------------------------------------------------------------------*/
673 
674  /**
675  We have a named window. Now set its name. Used once, if at all, for a
676  window as part of parsing.
677  */
679 
680  /**
681  After resolving an existing window name reference in a window definition,
682  we set the ancestor pointer to easy access later.
683  */
684  void set_ancestor(Window *a) { m_ancestor = a; }
685 
686  /**
687  Get the name of a window. Can be empty, cf. #printable_name which is not.
688  */
689  Item_string *name() const { return m_name; }
690 
691  uint def_pos() const { return m_def_pos; } ///< @see #m_def_pos
692  void set_def_pos(uint pos) { m_def_pos = pos; } ///< @see #m_def_pos
693 
694  /**
695  Get the frame, if any. SQL 2011 7.11 GR 1.b.i.6
696  */
697  const PT_frame *frame() const { return m_frame; }
698 
699  /**
700  Get the ORDER BY, if any. That is, the first we find along
701  the ancestor chain. Uniqueness checked in #setup_windows1
702  SQL 2011 7.11 GR 1.b.i.5.A-C
703  */
705  const PT_order_list *o = m_order_by;
706  const Window *w = m_ancestor;
707 
708  while (o == nullptr && w != nullptr) {
709  o = w->m_order_by;
710  w = w->m_ancestor;
711  }
712  return o;
713  }
714 
715  /**
716  Get the first argument of the ORDER BY clause for this window
717  if any. "ORDER BY" is not checked in ancestor unlike
718  effective_order_by().
719  Use when the goal is to operate on the set of item clauses for
720  all windows of a query. When interrogating the effective order
721  by for a window (specified for it or inherited from another
722  window) use effective_order_by().
723  */
724  ORDER *first_order_by() const;
725 
726  /**
727  Get partition, if any. That is, the partition if any, of the
728  root window. SQL 2011 7.11 GR 1.b.i.4.A-C
729  */
731  const PT_order_list *p = m_partition_by;
732  const Window *w = m_ancestor;
733  while (w != nullptr) {
734  if (w->m_ancestor == nullptr) {
735  /* root */
736  p = w->m_partition_by;
737  } else {
738  /* See #setup_windows for checking */
739  DBUG_ASSERT(w->m_partition_by == nullptr);
740  }
741  w = w->m_ancestor;
742  }
743  return p;
744  }
745  /**
746  Get the first argument of the PARTITION clause for this window
747  if any. "PARTITION BY" is not checked in ancestor unlike
748  effective_partition_by().
749  Use when the goal is to operate on the set of item clauses for
750  all windows of a query. When interrogating the effective
751  partition by for a window (specified for it or inherited from
752  another window) use effective_partition_by().
753  */
754  ORDER *first_partition_by() const;
755 
756  /**
757  Get the list of functions invoked on this window.
758  */
760 
761  /**
762  Concatenation of columns in PARTITION BY and ORDER BY.
763  Columns present in both list (redundancies) are eliminated, while
764  making sure the order of columns in the ORDER BY is maintained
765  in the merged list.
766 
767  @param thd Optional. Session state. If not nullptr,
768  initialize the cache.
769 
770  @param implicit_grouping Optional. If true, we won't sort (single row
771  result set). Presence implies thd != nullptr for
772  the first call when we lazily set up this
773  information. Succeeding calls return the cached
774  value.
775 
776  @returns The start of the concatenated ordering expressions, or nullptr
777  */
778  ORDER *sorting_order(THD *thd = nullptr, bool implicit_grouping = false);
779 
780  /**
781  Check that the semantic requirements for window functions over this
782  window are fulfilled, and accumulate evaluation requirements.
783  This is run at resolution.
784  */
785  bool check_window_functions1(THD *thd, SELECT_LEX *select);
786  /**
787  Like check_window_functions1() but contains checks which must wait until
788  the start of the execution phase.
789  */
790  bool check_window_functions2(THD *thd);
791 
792  /**
793  For RANGE frames we need to do computations involving add/subtract and
794  less than, smaller than. To make this work across types, we construct
795  item trees to do the computations, so we can reuse all the special case
796  handling, e.g. for signed/unsigned int wrap-around, overflow etc.
797  */
798  bool setup_range_expressions(THD *thd);
799 
800  /**
801  Return if this window represents an unresolved window reference seen
802  in a window function OVER clause.
803  */
804  bool is_reference() const { return m_is_reference; }
805 
806  /**
807  Check if the just read input row marks the start of a new partition.
808  Sets the member variables:
809 
810  m_partition_border and m_part_row_number
811 
812  */
814 
815  /**
816  Reset the current row's ORDER BY expressions when starting a new
817  peer set.
818  */
820 
821  /**
822  Determine if the current row is not in the same peer set as the previous
823  row. Used for RANGE frame and implicit RANGE frame (the latter is used by
824  aggregates in the presence of ORDER BY).
825 
826  The current row is in the same peer set if all ORDER BY columns
827  have the same value as in the previous row.
828 
829  For JSON_OBJECTAGG only the first order by column needs to be
830  compared to check if a row is in peer set.
831 
832  @param compare_all_order_by_items If true, compare all the order by items
833  to determine if a row is in peer set.
834  Else, compare only the first order by
835  item to determine peer set.
836 
837  @return true if current row is in a new peer set
838  */
839  bool in_new_order_by_peer_set(bool compare_all_order_by_items = true);
840 
841  /**
842  While processing buffered rows in RANGE frame mode we, determine
843  if the present row revisited from the buffer is before the row
844  being processed; i.e. the current row.
845 
846  @return true if the present row is before the RANGE, i.e. not to
847  be included
848  */
849  bool before_frame() { return before_or_after_frame(true); }
850 
851  ///< See before_frame()
852  bool after_frame() { return before_or_after_frame(false); }
853 
854  /**
855  Check if we have read all the rows in a partition, possibly
856  having buffered them for further processing
857 
858  @returns true if this is the case
859  */
860  bool at_partition_border() const { return m_partition_border; }
861 
862  void save_special_record(uint64 special_rowno, TABLE *t);
863  void restore_special_record(uint64 special_rowno, uchar *record);
864 
865  /**
866  Resolve any named window to its definition
867  and update m_window to point to the definition instead
868  */
869  static bool resolve_reference(THD *thd, Item_sum *wf, PT_window **m_window);
870 
871  /**
872  Semantic checking of windows. Run at resolution.
873 
874  * Process any window inheritance, that is a window, that in its
875  specification refer to another named window.
876 
877  Rules:
878  1) There should be no loops
879  2) The inheriting window can not specify partitioning
880  3) The inheriting window can not specify is already specify by
881  an ancestor.
882  4) An ancestor can not specify window framing clause.
883 
884  Cf. SQL 2011 7.11 window clause SR 10-11.
885 
886  * Check requirements to the window from its using window functions and
887  make a note of those so we know at execution time, for example if we need
888  to buffer rows to process the window functions, whether inversion
889  optimzation will be used for moving frames etc.
890 
891  * Prepare the physical ordering lists used by sorting at execution time.
892 
893  * Set up cached items for partition determination and for range/peer
894  determination based on order by columns.
895 
896  * Check any frame semantics and for RANGE frames, set up bounds computation
897  item trees.
898 
899  @param thd The session's execution thread
900  @param select The select for which we are doing windowing
901  @param ref_item_array The base ref items
902  @param tables The list of tables involved
903  @param fields The list of all fields, including hidden ones
904  @param windows The list of windows defined for this select
905 
906  @return false if success, true if error
907  */
908  static bool setup_windows1(THD *thd, SELECT_LEX *select,
909  Ref_item_array ref_item_array, TABLE_LIST *tables,
910  mem_root_deque<Item *> *fields,
911  List<Window> &windows);
912  /**
913  Like setup_windows1() but contains operations which must wait until
914  the start of the execution phase.
915 
916  @param thd The session's execution thread
917  @param windows The list of windows defined for this select
918 
919  @return false if success, true if error
920  */
921  static bool setup_windows2(THD *thd, List<Window> &windows);
922 
923  /**
924  Check window definitions to remove unused windows. We do this
925  only after syntactic and semantic checking for errors has been performed.
926  Eliminate redundant sorts after unused windows are removed.
927 
928  @param thd The session's execution thread
929  @param windows The list of windows defined for this select
930  */
931  static void eliminate_unused_objects(THD *thd, List<Window> &windows);
932 
933  /**
934  Resolve and set up the PARTITION BY or an ORDER BY list of a window.
935 
936  @param thd The session's execution thread
937  @param ref_item_array The base ref items
938  @param tables The list of tables involved
939  @param fields The list of all fields, including hidden ones
940  @param o A list of order by expressions
941  @param partition_order If true, o represent a windowing PARTITION BY,
942  else it represents a windowing ORDER BY
943  @returns false if success, true if error
944  */
945  bool resolve_window_ordering(THD *thd, Ref_item_array ref_item_array,
946  TABLE_LIST *tables,
947  mem_root_deque<Item *> *fields, ORDER *o,
948  bool partition_order);
949  /**
950  Return true if this window's name is not unique in windows
951  */
952  bool check_unique_name(List<Window> &windows);
953 
954  /**
955  Set up cached items for an partition or an order by list
956  updating m_partition_items or m_order_by_items respectively.
957 
958  @param thd The session's execution thread
959  @param select The select for which we are doing windowing
960  @param o The list of ordering expressions
961  @param partition_order If true, o represents a partition order list,
962  else an ORDER BY list.
963 
964  @returns false if success, true if error
965  */
966  bool setup_ordering_cached_items(THD *thd, SELECT_LEX *select,
967  const PT_order_list *o,
968  bool partition_order);
969 
970  /**
971  Determine if the window had either a partition clause (inclusive) or a
972  ORDER BY clause, either defined by itself or inherited from another window.
973 
974  @return true if we have such a clause, which means we need to sort the
975  input table before evaluating the window functions, unless it has
976  been made redundant by a previous windowing step, cf.
977  reorder_and_eliminate_sorts, or due to a single row result set,
978  cf. SELECT_LEX::is_implicitly_grouped().
979  */
980  bool needs_sorting() const { return m_sorting_order != nullptr; }
981 
982  /**
983  If we cannot compute one of window functions without looking at succeeding
984  rows, return true, else false.
985  */
986  bool needs_buffering() const { return m_needs_frame_buffering; }
987 
988  /**
989  If we cannot compute one of window functions without looking at all
990  rows in the peerset of the current row, return true, else
991  false. E.g. CUME_DIST.
992  */
993  bool needs_peerset() const { return m_needs_peerset; }
994 
995  /**
996  If we cannot compute one of window functions without looking at all
997  rows in the peerset of the current row in this frame, return true, else
998  false. E.g. JSON_OBJECTAGG.
999  */
1001  /**
1002  If we need to read the entire partition before we can evaluate
1003  some window function(s) on this window,
1004  @returns true if that is the case, else false
1005  */
1006  bool needs_card() const { return m_needs_card; }
1007 
1008  /**
1009  Return true if the set of window functions are all ROW unit optimizable.
1010  Only relevant if m_needs_buffering and m_row_optimizable are true.
1011  */
1013 
1014  /**
1015  Return true if the set of window functions are all RANGE unit optimizable.
1016  Only relevant if m_needs_buffering and m_range_optimizable are true.
1017  */
1019 
1020  /**
1021  Return true if the aggregates are static, i.e. the same aggregate values for
1022  all rows in partition. Only relevant if m_needs_buffering is true.
1023  */
1024  bool static_aggregates() const { return m_static_aggregates; }
1025 
1026  /**
1027  See #m_opt_first_row
1028  */
1029  bool opt_first_row() const { return m_opt_first_row; }
1030 
1031  /**
1032  See #m_opt_last_row
1033  */
1034  bool opt_last_row() const { return m_opt_last_row; }
1035 
1036  /**
1037  See #m_last
1038  */
1039  bool is_last() const { return m_last; }
1040 
1041  /**
1042  See #m_needs_restore_input_row
1043  */
1045 
1046  /**
1047  See #m_needs_restore_input_row
1048  */
1050 
1051  /**
1052  See #m_opt_nth_row
1053  */
1054  const st_nth &opt_nth_row() const { return m_opt_nth_row; }
1055 
1056  /**
1057  See #m_opt_lead_lag
1058  */
1059  const st_lead_lag &opt_lead_lag() const { return m_opt_lead_lag; }
1060 
1061  /**
1062  Getter for m_frame_buffer_param, q.v.
1063  */
1065 
1066  /**
1067  Setter for m_frame_buffer_param, q.v.
1068  */
1070 
1071  /**
1072  Getter for m_frame_buffer, q.v.
1073  */
1074  TABLE *frame_buffer() const { return m_frame_buffer; }
1075 
1076  /**
1077  Setter for m_frame_buffer, q.v.
1078  */
1079  void set_frame_buffer(TABLE *tab) { m_frame_buffer = tab; }
1080 
1081  /**
1082  Getter for m_outtable_param, q.v.
1083  */
1085 
1086  /**
1087  Setter for m_outtable_param, q.v.
1088  */
1090 
1091  /**
1092  Getter for m_part_row_number, q.v., the current row number within the
1093  partition.
1094  */
1096 
1097  /**
1098  Allocate the cache for special rows
1099  @param thd thread handle
1100  @param out_tbl The table where this window function's value is written to
1101  @returns true if error.
1102  */
1103  bool make_special_rows_cache(THD *thd, TABLE *out_tbl);
1104 
1105  /**
1106  See #m_last_row_output
1107  */
1109 
1110  /**
1111  See #m_last_row_output
1112  */
1114 
1115  /**
1116  See #m_rowno_being_visited
1117  */
1119 
1120  /**
1121  See #m_rowno_being_visited
1122  */
1124 
1125  /**
1126  See #m_last_rowno_in_cache
1127  */
1129 
1130  /**
1131  See #m_last_rowno_in_cache
1132  */
1134 
1135  /**
1136  See #m_last_rowno_in_range_frame
1137  */
1140  }
1141 
1142  /**
1143  See #m_last_rowno_in_range_frame
1144  */
1147  }
1148 
1149  /**
1150  See #m_last_rowno_in_peerset
1151  */
1153 
1154  /**
1155  See #m_last_rowno_in_peerset
1156  */
1158 
1159  /**
1160  See #m_is_last_row_in_peerset_within_frame
1161  */
1164  }
1165 
1166  /**
1167  See #m_is_last_row_in_peerset_within_frame
1168  */
1171  }
1172 
1173  /**
1174  See #m_do_copy_null
1175  */
1176  bool do_copy_null() const { return m_do_copy_null; }
1177 
1178  /**
1179  See #m_do_copy_null
1180  */
1181  void set_do_copy_null(bool b) { m_do_copy_null = b; }
1182 
1183  /**
1184  See #m_inverse_aggregation
1185  */
1186  bool do_inverse() const { return m_inverse_aggregation; }
1187 
1188  /**
1189  See #m_inverse_aggregation
1190  */
1191  Window &set_inverse(bool b) {
1193  return *this;
1194  }
1195 
1196  /**
1197  See #m_aggregates_primed
1198  */
1199  bool aggregates_primed() const { return m_aggregates_primed; }
1200 
1201  /**
1202  See #m_aggregates_primed
1203  */
1205 
1206  /**
1207  See #m_is_last_row_in_frame
1208  */
1209  bool is_last_row_in_frame() const {
1211  }
1212 
1213  /**
1214  See #m_is_last_row_in_frame
1215  */
1217 
1218  /**
1219  Return the size of the frame in number of rows
1220  @returns frame size
1221  */
1222  // int64 frame_cardinality();
1223 
1224  /**
1225  See #m_rowno_in_frame
1226  */
1228 
1229  /**
1230  See #m_rowno_in_frame
1231  */
1233  m_rowno_in_frame = rowno;
1234  return *this;
1235  }
1236 
1237  /**
1238  See #m_rowno_in_partition
1239  */
1241 
1242  /**
1243  See #m_rowno_in_partition
1244  */
1246 
1247  /**
1248  See #m_first_rowno_in_range_frame
1249  */
1252  }
1253 
1254  /**
1255  See #m_first_rowno_in_range_frame
1256  */
1259  }
1260 
1261  /**
1262  See #m_frame_buffer_total_rows
1263  */
1266  }
1267 
1268  /**
1269  See #m_frame_buffer_total_rows
1270  */
1272 
1273  /**
1274  See #m_frame_buffer_partition_offset
1275  */
1278  }
1279 
1280  /**
1281  See #m_frame_buffer_partition_offset
1282  */
1285  }
1286 
1287  /**
1288  See #m_row_has_fields_in_out_table
1289  */
1292  }
1293 
1294  /**
1295  See #m_row_has_fields_in_out_table
1296  */
1299  }
1300 
1301  /**
1302  Free up any resource used to process the window functions of this window,
1303  e.g. temporary files and in-memory data structures. Called when done
1304  with all window processing steps from SELECT_LEX::cleanup.
1305  */
1306  void cleanup(THD *thd);
1307 
1308  /**
1309  Free structures that were set up during preparation of window functions
1310  */
1311  void destroy();
1312 
1313  /**
1314  Reset window state for a new partition.
1315 
1316  Reset the temporary storage used for window frames, typically when we find
1317  a new partition. The rows in the buffer are then no longer needed.
1318  */
1320 
1321  /**
1322  Reset execution state for next call to JOIN::exec, cf. JOIN::reset,
1323  or using [Buffering]WindowingIterator::Init.
1324  */
1326 
1327  /**
1328  Reset resolution and execution state to prepare for next execution of a
1329  prepared statement.
1330  */
1332 
1333  /**
1334  Reset execution state for LEAD/LAG for the current row in partition.
1335  */
1336  void reset_lead_lag();
1337 
1339 
1340  private:
1341  /// Common function for all types of resetting
1342  void reset_execution_state(Reset_level level);
1343 
1344  public:
1345  /**
1346  Reset the execution state for all window functions defined on this window.
1347  */
1348  void reset_all_wf_state();
1349 
1350  const char *printable_name() const;
1351 
1352  void print(const THD *thd, String *str, enum_query_type qt,
1353  bool expand_definition) const;
1354 
1355  bool has_windowing_steps() const;
1356 
1357  /**
1358  Compute sorting costs for windowing.
1359 
1360  @param cost Cost of sorting result set once
1361  @param windows The set of windows
1362 
1363  @returns the aggregated sorting costs of the windowing
1364  */
1365  static double compute_cost(double cost, List<Window> &windows);
1366 
1367  private:
1368  /**
1369  Common implementation of before_frame() and after_frame().
1370  @param before True if 'before' is wanted; false if 'after' is.
1371  */
1372  bool before_or_after_frame(bool before);
1373  void print_frame(const THD *thd, String *str, enum_query_type qt) const;
1374  void print_border(const THD *thd, String *str, PT_border *b,
1375  enum_query_type qt) const;
1376 
1377  /**
1378  Reorder windows and eliminate redundant ordering. If a window has the
1379  same ordering requirements as another, we will move them next to each other
1380  in the evaluation sequence, so we can sort only once, i.e. before the
1381  first window step. This allows us to fulfill the guarantee given by
1382  SQL standard when it comes to repeatability of non-deterministic (partially
1383  ordered) result sets for windowing inside a query, cf. #equal_sort.
1384  If more than two have the same ordering, the same applies, we only sort
1385  before the first (sort equivalent) window.
1386 
1387  If the result set is implicitly grouped, we also skip any sorting for
1388  windows.
1389 
1390  @param windows list of windows
1391  */
1392  static void reorder_and_eliminate_sorts(List<Window> &windows);
1393 
1394  /**
1395  Return true of the physical[1] sort orderings for the two windows are the
1396  same, cf. guarantee of
1397  SQL 2014 4.15.15 Windowed tables bullet two: The windowing functions are
1398  computed using the same row ordering if they specify the same ordering.
1399 
1400  Collation and null handling is not supported, so moot.
1401 
1402  The two other bullet points are also covered by this test.
1403 
1404  [1] After concatenating effective PARTITION BY and ORDER BY (including
1405  inheritance) expressions.
1406  */
1407  static bool equal_sort(Window *w1, Window *w2);
1408 
1409  /**
1410  Check that a frame border is constant during execution and that it does
1411  not contain subqueries (relevant for INTERVAL only): implementation
1412  limitation.
1413 
1414  @param thd Session thread
1415  @param border The border to check
1416 
1417  @return false if OK, true if error
1418  */
1419  bool check_constant_bound(THD *thd, PT_border *border);
1420 
1421  /**
1422  Check that frame borders are sane; resolution phase.
1423 
1424  @param thd Session thread
1425 
1426  @returns true if error
1427  */
1428  bool check_border_sanity1(THD *thd);
1429  /**
1430  Like check_border_sanity1() but contains checks which must wait until
1431  the start of the execution phase.
1432 
1433  @param thd Session thread
1434 
1435  @returns true if error
1436  */
1437  bool check_border_sanity2(THD *thd);
1438 };
1439 
1440 /**
1441  Collects evaluation requirements from a window function,
1442  used by Item_sum::check_wf_semantics and its overrides.
1443 */
1445  /**
1446  Set to true if window function requires row buffering
1447  */
1449  /**
1450  Set to true if we need peerset for evaluation (e.g. CUME_DIST)
1451  */
1453  /**
1454  Set to true if we need last peer for evaluation within a frame
1455  (e.g. JSON_OBJECTAGG)
1456  */
1458  /**
1459  Set to true if we need FIRST_VALUE or optimized MIN/MAX
1460  */
1462  /**
1463  Set to true if we need LAST_VALUE or optimized MIN/MAX
1464  */
1466  Window::st_offset opt_nth_row; ///< Used if we have NTH_VALUE
1467  Window::st_ll_offset opt_ll_row; ///< Used if we have LEAD or LAG
1468  /**
1469  Set to true if we can compute a sliding window by a combination of
1470  undoing the contribution of rows going out of the frame and adding the
1471  contribution of rows coming into the frame. For example, SUM and AVG
1472  allows this, but MAX/MIN do not. Only applicable if the frame has ROW
1473  bounds unit.
1474  */
1476  /**
1477  Similar to row_optimizable but for RANGE frame bounds unit
1478  */
1480 
1482  : needs_buffer(false),
1489 };
1490 
1491 #endif /* WINDOWS_INCLUDED */
Window::first_partition_by
ORDER * first_partition_by() const
Get the first argument of the PARTITION clause for this window if any.
Definition: window.cc:109
Window::cleanup
void cleanup(THD *thd)
Free up any resource used to process the window functions of this window, e.g.
Definition: window.cc:1345
Window::RL_FULL
@ RL_FULL
Definition: window.h:1338
Item
Definition: item.h:775
Window::frame
const PT_frame * frame() const
Get the frame, if any.
Definition: window.h:697
THD
Definition: sql_class.h:807
Window::st_offset::st_offset
st_offset()
Definition: window.h:196
Window::needs_peerset
bool needs_peerset() const
If we cannot compute one of window functions without looking at all rows in the peerset of the curren...
Definition: window.h:993
Window::FBC_LAST_KEY
@ FBC_LAST_KEY
Definition: window.h:363
Window::check_window_functions1
bool check_window_functions1(THD *thd, SELECT_LEX *select)
Check that the semantic requirements for window functions over this window are fulfilled,...
Definition: window.cc:117
Window::m_is_reference
const bool m_is_reference
If true, m_name is an unbound window reference, other fields are unused.
Definition: window.h:118
Window_retrieve_cached_row_reason::MISC_POSITIONS
@ MISC_POSITIONS
Window::destroy
void destroy()
Free structures that were set up during preparation of window functions.
Definition: window.cc:1361
Window_evaluation_requirements::opt_first_row
bool opt_first_row
Set to true if we need FIRST_VALUE or optimized MIN/MAX.
Definition: window.h:1461
Window::Frame_buffer_position::Frame_buffer_position
Frame_buffer_position(uchar *position, int64 rowno)
Definition: window.h:261
Window::set_last_rowno_in_range_frame
void set_last_rowno_in_range_frame(uint64 rno)
See m_last_rowno_in_range_frame.
Definition: window.h:1145
Window::opt_last_row
bool opt_last_row() const
See m_opt_last_row.
Definition: window.h:1034
mem_root_deque< Item * >
Window::Frame_buffer_position::m_rowno
int64 m_rowno
Definition: window.h:260
Window::first_order_by
ORDER * first_order_by() const
Get the first argument of the ORDER BY clause for this window if any.
Definition: window.cc:113
Window::restore_special_record
void restore_special_record(uint64 special_rowno, uchar *record)
Restore row special_rowno into record from in-memory copy.
Definition: sql_executor.cc:5002
Window::frame_buffer
TABLE * frame_buffer() const
Getter for m_frame_buffer, q.v.
Definition: window.h:1074
Window::m_range_optimizable
bool m_range_optimizable
The functions are optimizable with RANGE unit.
Definition: window.h:159
Window::m_inverse_comparators
Item_func * m_inverse_comparators[WBT_VALUE_FOLLOWING+1][2]
Each item has inverse operation of the corresponding comparator in m_comparators.
Definition: window.h:508
Window::m_row_has_fields_in_out_table
int64 m_row_has_fields_in_out_table
If >=1: the row with this number (1-based, relative to start of partition) currently has its fields i...
Definition: window.h:409
Window::save_pos
void save_pos(Window_retrieve_cached_row_reason reason)
See m_tmp_pos.
Definition: window.h:313
Window::m_partition_border
bool m_partition_border
Execution state: the current row starts a new partition.
Definition: window.h:453
Window::before_or_after_frame
bool before_or_after_frame(bool before)
Common implementation of before_frame() and after_frame().
Definition: window.cc:524
Window::m_last_rowno_in_peerset
int64 m_last_rowno_in_peerset
Execution state: used iff m_needs_peerset.
Definition: window.h:433
Temp_table_param
Object containing parameters used when creating and using temporary tables.
Definition: temp_table_param.h:73
Window::m_needs_frame_buffering
bool m_needs_frame_buffering
(At least) one window function needs to buffer frame rows for evaluation i.e.
Definition: window.h:124
Window::m_order_by
PT_order_list *const m_order_by
<window order clause>
Definition: window.h:103
sql_lex.h
Window::set_aggregates_primed
void set_aggregates_primed(bool b)
See m_aggregates_primed.
Definition: window.h:1204
record
Definition: mi_test3.cc:54
Window::check_constant_bound
bool check_constant_bound(THD *thd, PT_border *border)
Check that a frame border is constant during execution and that it does not contain subqueries (relev...
Definition: window.cc:792
Window::set_frame_buffer
void set_frame_buffer(TABLE *tab)
Setter for m_frame_buffer, q.v.
Definition: window.h:1079
Window::m_def_pos
uint m_def_pos
Position of definition in query's text, 1 for leftmost.
Definition: window.h:112
Window::opt_nth_row
const st_nth & opt_nth_row() const
See m_opt_nth_row.
Definition: window.h:1054
Window::opt_lead_lag
const st_lead_lag & opt_lead_lag() const
See m_opt_lead_lag.
Definition: window.h:1059
nullptr
Dialog Client Authentication nullptr
Definition: dialog.cc:353
Window::setup_windows1
static bool setup_windows1(THD *thd, SELECT_LEX *select, Ref_item_array ref_item_array, TABLE_LIST *tables, mem_root_deque< Item * > *fields, List< Window > &windows)
Semantic checking of windows.
Definition: window.cc:1105
Window::st_offset::m_from_last
bool m_from_last
Definition: window.h:195
uint64
uint64_t uint64
Definition: my_inttypes.h:68
Window::copy_pos
void copy_pos(Window_retrieve_cached_row_reason from_reason, Window_retrieve_cached_row_reason to_reason)
Copy frame buffer position hint from one to another.
Definition: window.h:334
pos
char * pos
Definition: do_ctype.cc:76
Window::set_def_pos
void set_def_pos(uint pos)
Definition: window.h:692
Window::m_sorting_order
ORDER * m_sorting_order
merged partition/order by
Definition: window.h:104
Window
Represents the (explicit) window of a SQL 2003 section 7.11 <window clause>, or the implicit (inlined...
Definition: window.h:94
Window::resolve_reference
static bool resolve_reference(THD *thd, Item_sum *wf, PT_window **m_window)
Resolve any named window to its definition and update m_window to point to the definition instead.
Definition: window.cc:434
Window::set_last_row_output
void set_last_row_output(int64 rno)
See m_last_row_output.
Definition: window.h:1113
my_dbug.h
String
Using this class is fraught with peril, and you need to be very careful when doing so.
Definition: sql_string.h:164
Window_evaluation_requirements::row_optimizable
bool row_optimizable
Set to true if we can compute a sliding window by a combination of undoing the contribution of rows g...
Definition: window.h:1475
TABLE
Definition: table.h:1364
Window::Frame_buffer_position::m_position
uchar * m_position
< The size of the file position is determined by handler::ref_length
Definition: window.h:258
Window::resolve_window_ordering
bool resolve_window_ordering(THD *thd, Ref_item_array ref_item_array, TABLE_LIST *tables, mem_root_deque< Item * > *fields, ORDER *o, bool partition_order)
Resolve and set up the PARTITION BY or an ORDER BY list of a window.
Definition: window.cc:693
Window::set_is_last_row_in_peerset_within_frame
void set_is_last_row_in_peerset_within_frame(bool value)
See m_is_last_row_in_peerset_within_frame.
Definition: window.h:1169
window_lex.h
Window::optimizable_range_aggregates
bool optimizable_range_aggregates() const
Return true if the set of window functions are all RANGE unit optimizable.
Definition: window.h:1018
Window_evaluation_requirements::opt_ll_row
Window::st_ll_offset opt_ll_row
Used if we have LEAD or LAG.
Definition: window.h:1467
Window::st_offset
Definition: window.h:193
Window::print_frame
void print_frame(const THD *thd, String *str, enum_query_type qt) const
Definition: window.cc:1487
Window::optimizable_row_aggregates
bool optimizable_row_aggregates() const
Return true if the set of window functions are all ROW unit optimizable.
Definition: window.h:1012
Window::FBC_FIRST_IN_NEXT_PARTITION
@ FBC_FIRST_IN_NEXT_PARTITION
We read an incoming row.
Definition: window.h:357
Window::rowno_being_visited
int64 rowno_being_visited() const
See m_rowno_being_visited.
Definition: window.h:1118
Window::Window
Window(PT_order_list *partition_by, PT_order_list *order_by, PT_frame *frame)
Unnamed window.
Definition: window.h:657
Window::reinit_before_use
void reinit_before_use()
Reset resolution and execution state to prepare for next execution of a prepared statement.
Definition: window.h:1331
value
const string value("\"Value\"")
Window::m_static_aggregates
bool m_static_aggregates
The aggregates (SUM, etc) can be evaluated once for a partition, since it is static,...
Definition: window.h:166
Window::m_needs_peerset
bool m_needs_peerset
(At least) one window function needs the peer set of the current row to evaluate the wf for the curre...
Definition: window.h:130
Window_retrieve_cached_row_reason
Window_retrieve_cached_row_reason
Position hints for the frame buffer are saved for these kind of row accesses, cf.
Definition: window.h:64
Window::last_rowno_in_range_frame
int64 last_rowno_in_range_frame() const
See m_last_rowno_in_range_frame.
Definition: window.h:1138
Window::check_border_sanity1
bool check_border_sanity1(THD *thd)
Check that frame borders are sane; resolution phase.
Definition: window.cc:822
Window::setup_ordering_cached_items
bool setup_ordering_cached_items(THD *thd, SELECT_LEX *select, const PT_order_list *o, bool partition_order)
Set up cached items for an partition or an order by list updating m_partition_items or m_order_by_ite...
Definition: window.cc:664
Window::m_name
Item_string * m_name
<window name>
Definition: window.h:106
Window::first_rowno_in_range_frame
int64 first_rowno_in_range_frame() const
See m_first_rowno_in_range_frame.
Definition: window.h:1257
Window::m_opt_nth_row
st_nth m_opt_nth_row
Window requires re-evaluation of the Nth row in optimized moving frame mode e.g.
Definition: window.h:229
Window::m_needs_card
bool m_needs_card
(At least) one window function needs the cardinality of the partition of the current row to evaluate ...
Definition: window.h:143
Window::outtable_param
Temp_table_param * outtable_param() const
Getter for m_outtable_param, q.v.
Definition: window.h:1084
Window::set_rowno_in_partition
void set_rowno_in_partition(int64 rowno)
See m_rowno_in_partition.
Definition: window.h:1245
Window_evaluation_requirements::needs_buffer
bool needs_buffer
Set to true if window function requires row buffering.
Definition: window.h:1448
true
#define true
Definition: config_static.h:44
Window::reorder_and_eliminate_sorts
static void reorder_and_eliminate_sorts(List< Window > &windows)
Reorder windows and eliminate redundant ordering.
Definition: window.cc:772
Window_evaluation_requirements::needs_last_peer_in_frame
bool needs_last_peer_in_frame
Set to true if we need last peer for evaluation within a frame (e.g.
Definition: window.h:1457
PT_order_list
Definition: parse_tree_nodes.h:211
Window::set_do_copy_null
void set_do_copy_null(bool b)
See m_do_copy_null.
Definition: window.h:1181
Window::m_do_copy_null
bool m_do_copy_null
Execution state: make frame wf produce a NULL (or 0 depending, e.g.
Definition: window.h:576
Window::is_last_row_in_frame
bool is_last_row_in_frame() const
See m_is_last_row_in_frame.
Definition: window.h:1209
Window::set_needs_restore_input_row
void set_needs_restore_input_row(bool b)
See m_needs_restore_input_row.
Definition: window.h:1044
Window::is_last_row_in_peerset_within_frame
int64 is_last_row_in_peerset_within_frame() const
See m_is_last_row_in_peerset_within_frame.
Definition: window.h:1162
Window::effective_partition_by
const PT_order_list * effective_partition_by() const
Get partition, if any.
Definition: window.h:730
Window::m_comparators
Item_func * m_comparators[WBT_VALUE_FOLLOWING+1][2]
RANGE bound determination computation; first index is a value of the enum_window_border_type enum; se...
Definition: window.h:502
Window::last_rowno_in_peerset
int64 last_rowno_in_peerset() const
See m_last_rowno_in_peerset.
Definition: window.h:1152
Window::reset_round
void reset_round()
Reset execution state for next call to JOIN::exec, cf.
Definition: window.h:1325
Window::m_row_optimizable
bool m_row_optimizable
The functions are optimizable with ROW unit.
Definition: window.h:151
handler.h
Window::check_border_sanity2
bool check_border_sanity2(THD *thd)
Like check_border_sanity1() but contains checks which must wait until the start of the execution phas...
Definition: window.cc:895
Window::aggregates_primed
bool aggregates_primed() const
See m_aggregates_primed.
Definition: window.h:1199
Window::reset_lead_lag
void reset_lead_lag()
Reset execution state for LEAD/LAG for the current row in partition.
Definition: window.cc:1374
Window::frame_buffer_param
Temp_table_param * frame_buffer_param() const
Getter for m_frame_buffer_param, q.v.
Definition: window.h:1064
Window::m_aggregates_primed
bool m_aggregates_primed
Execution state: for optimizable aggregates, cf.
Definition: window.h:489
Item_string
Definition: item.h:4919
Window::reset_partition_state
void reset_partition_state()
Reset window state for a new partition.
Definition: window.h:1319
Window::m_first_rowno_in_range_frame
int64 m_first_rowno_in_range_frame
Execution state: the row number of the first row in a frame when evaluating RANGE based frame bounds.
Definition: window.h:525
Window::needs_buffering
bool needs_buffering() const
If we cannot compute one of window functions without looking at succeeding rows, return true,...
Definition: window.h:986
enum_query_type.h
Window::RL_ROUND
@ RL_ROUND
Definition: window.h:1338
Window::set_rowno_in_frame
Window & set_rowno_in_frame(int64 rowno)
See m_rowno_in_frame.
Definition: window.h:1232
int64
int64_t int64
Definition: my_inttypes.h:67
Window::m_rowno_being_visited
int64 m_rowno_being_visited
Execution state: The number of the row being visited for its contribution to a window function,...
Definition: window.h:469
Window::set_name
void set_name(Item_string *name)
We have a named window.
Definition: window.h:678
Window::is_last
bool is_last() const
See m_last.
Definition: window.h:1039
Window::setup_range_expressions
bool setup_range_expressions(THD *thd)
For RANGE frames we need to do computations involving add/subtract and less than, smaller than.
Definition: window.cc:226
Window::m_last_row_output
int64 m_last_row_output
Execution state: The number, in the current partition, of the last output row, i.e.
Definition: window.h:460
Window::m_frame_buffer_partition_offset
int64 m_frame_buffer_partition_offset
Execution state: Snapshot of m_frame_buffer_total_rows when we start a new partition,...
Definition: window.h:399
my_inttypes.h
Window::m_needs_last_peer_in_frame
bool m_needs_last_peer_in_frame
(At least) one window function (currently JSON_OBJECTAGG) needs the last peer for the current row to ...
Definition: window.h:137
Window::m_last_rowno_in_range_frame
int64 m_last_rowno_in_range_frame
Execution state: used for RANGE bounds frame evaluation for the continued evaluation for current row ...
Definition: window.h:537
Window::set_is_last_row_in_frame
void set_is_last_row_in_frame(bool b)
See m_is_last_row_in_frame.
Definition: window.h:1216
Window::check_unique_name
bool check_unique_name(List< Window > &windows)
Return true if this window's name is not unique in windows.
Definition: window.cc:646
Window::reset_execution_state
void reset_execution_state(Reset_level level)
Common function for all types of resetting.
Definition: window.cc:1385
Window::st_ll_offset::st_ll_offset
st_ll_offset()
Definition: window.h:206
Window::st_lead_lag::m_offsets
Mem_root_array_YY< st_ll_offset > m_offsets
sorted set of LEAD/LAG offsets
Definition: window.h:221
Window::partition_rowno
int64 partition_rowno() const
Getter for m_part_row_number, q.v., the current row number within the partition.
Definition: window.h:1095
Window::set_frame_buffer_total_rows
void set_frame_buffer_total_rows(int64 rows)
See m_frame_buffer_total_rows.
Definition: window.h:1264
Window::m_inverse_aggregation
bool m_inverse_aggregation
Execution state: do inverse, e.g.
Definition: window.h:583
Window::frame_buffer_partition_offset
int64 frame_buffer_partition_offset() const
See m_frame_buffer_partition_offset.
Definition: window.h:1283
Window::print
void print(const THD *thd, String *str, enum_query_type qt, bool expand_definition) const
Definition: window.cc:1500
Window::set_last_rowno_in_peerset
void set_last_rowno_in_peerset(uint64 rno)
See m_last_rowno_in_peerset.
Definition: window.h:1157
Window::m_rowno_in_partition
int64 m_rowno_in_partition
Execution state: The row number of the current row being readied for output within the partition.
Definition: window.h:481
Window_retrieve_cached_row_reason::LAST_IN_FRAME
@ LAST_IN_FRAME
Window::after_frame
bool after_frame()
Definition: window.h:852
Window::m_ancestor
const Window * m_ancestor
resolved from existing window name
Definition: window.h:233
Window::st_offset::m_rowno
int64 m_rowno
Definition: window.h:194
Window::m_last
bool m_last
The last window to be evaluated at execution time.
Definition: window.h:190
Window::m_special_rows_cache
uchar * m_special_rows_cache
Holds a fixed number of copies of special rows; each copy can use up to m_special_rows_cache_max_leng...
Definition: window.h:416
Window::check_partition_boundary
void check_partition_boundary()
Check if the just read input row marks the start of a new partition.
Definition: window.cc:464
Window::do_copy_null
bool do_copy_null() const
See m_do_copy_null.
Definition: window.h:1176
Window::m_opt_last_row
bool m_opt_last_row
Window requires re-evaluation of the last row in optimized moving frame mode e.g.
Definition: window.h:178
Window::functions
List< Item_sum > & functions()
Get the list of functions invoked on this window.
Definition: window.h:759
uint
unsigned int uint
Definition: uca-dump.cc:29
Window::restore_pos
void restore_pos(Window_retrieve_cached_row_reason reason)
See m_tmp_pos.
Definition: window.h:324
Window::opt_first_row
bool opt_first_row() const
See m_opt_first_row.
Definition: window.h:1029
Mem_root_array_YY
A typesafe replacement for DYNAMIC_ARRAY.
Definition: mem_root_array.h:59
Window::set_last_rowno_in_cache
void set_last_rowno_in_cache(uint64 rno)
See m_last_rowno_in_cache.
Definition: window.h:1133
TABLE_LIST
Definition: table.h:2541
Window::rowno_in_partition
int64 rowno_in_partition() const
See m_rowno_in_partition.
Definition: window.h:1240
Window::needs_last_peer_in_frame
bool needs_last_peer_in_frame() const
If we cannot compute one of window functions without looking at all rows in the peerset of the curren...
Definition: window.h:1000
uchar
unsigned char uchar
Definition: my_inttypes.h:51
Window::m_last_rowno_in_cache
int64 m_last_rowno_in_cache
Execution state: used iff m_needs_frame_buffering.
Definition: window.h:427
Window::m_functions
List< Item_sum > m_functions
window functions based on 'this'
Definition: window.h:234
Window::needs_sorting
bool needs_sorting() const
Determine if the window had either a partition clause (inclusive) or a ORDER BY clause,...
Definition: window.h:980
Window::needs_card
bool needs_card() const
If we need to read the entire partition before we can evaluate some window function(s) on this window...
Definition: window.h:1006
Window_retrieve_cached_row_reason::CURRENT
@ CURRENT
Window_evaluation_requirements::opt_nth_row
Window::st_offset opt_nth_row
Used if we have NTH_VALUE.
Definition: window.h:1466
Window::print_border
void print_border(const THD *thd, String *str, PT_border *b, enum_query_type qt) const
Definition: window.cc:1456
Window::st_ll_offset::m_rowno
int64 m_rowno
negative values is LEAD
Definition: window.h:205
Window::m_is_last_row_in_frame
bool m_is_last_row_in_frame
Execution state: the current row is the last row in a window frame For some aggregate functions,...
Definition: window.h:568
enum_query_type
enum_query_type
Query type constants (usable as bitmap flags).
Definition: enum_query_type.h:30
SQL_I_List::elements
uint elements
Definition: sql_list.h:47
Window::static_aggregates
bool static_aggregates() const
Return true if the aggregates are static, i.e.
Definition: window.h:1024
Item_func
Definition: item_func.h:131
Window_retrieve_cached_row_reason::LAST_IN_PEERSET
@ LAST_IN_PEERSET
Window_retrieve_cached_row_reason::FIRST_IN_FRAME
@ FIRST_IN_FRAME
Window_evaluation_requirements::range_optimizable
bool range_optimizable
Similar to row_optimizable but for RANGE frame bounds unit.
Definition: window.h:1479
Window::in_new_order_by_peer_set
bool in_new_order_by_peer_set(bool compare_all_order_by_items=true)
Determine if the current row is not in the same peer set as the previous row.
Definition: window.cc:509
Window::set_outtable_param
void set_outtable_param(Temp_table_param *p)
Setter for m_outtable_param, q.v.
Definition: window.h:1089
Window::m_partition_by
PT_order_list *const m_partition_by
<window partition clause>
Definition: window.h:102
Window::has_windowing_steps
bool has_windowing_steps() const
Definition: window.cc:1551
Window::printable_name
const char * printable_name() const
Definition: window.cc:1534
Cached_item
This is used for segregating rows in groups (e.g.
Definition: item.h:5950
Window::setup_windows2
static bool setup_windows2(THD *thd, List< Window > &windows)
Like setup_windows1() but contains operations which must wait until the start of the execution phase.
Definition: window.cc:1321
Window::set_rowno_being_visited
void set_rowno_being_visited(int64 rno)
See m_rowno_being_visited.
Definition: window.h:1123
WBT_VALUE_FOLLOWING
@ WBT_VALUE_FOLLOWING
Definition: window_lex.h:39
Window::effective_order_by
const PT_order_list * effective_order_by() const
Get the ORDER BY, if any.
Definition: window.h:704
PT_window
Parse tree node for a window; just a shallow wrapper for class Window, q.v.
Definition: parse_tree_window.h:38
Window_retrieve_cached_row_reason::WONT_UPDATE_HINT
@ WONT_UPDATE_HINT
Window::Special_keys
Special_keys
Keys for m_frame_buffer_cache and m_special_rows_cache, for special rows.
Definition: window.h:350
Window::st_nth
Definition: window.h:214
Window::save_special_record
void save_special_record(uint64 special_rowno, TABLE *t)
Save row special_rowno in table t->record[0] to an in-memory copy for later restoration.
Definition: sql_executor.cc:4984
Window::m_opt_lead_lag
st_lead_lag m_opt_lead_lag
Definition: window.h:230
Window::sorting_order
ORDER * sorting_order(THD *thd=nullptr, bool implicit_grouping=false)
Concatenation of columns in PARTITION BY and ORDER BY.
Definition: window.cc:399
Window::needs_restore_input_row
bool needs_restore_input_row() const
See m_needs_restore_input_row.
Definition: window.h:1049
Window::equal_sort
static bool equal_sort(Window *w1, Window *w2)
Return true of the physical[1] sort orderings for the two windows are the same, cf.
Definition: window.cc:756
sql_list.h
Window::frame_buffer_total_rows
int64 frame_buffer_total_rows() const
See m_frame_buffer_total_rows.
Definition: window.h:1271
Window::set_ancestor
void set_ancestor(Window *a)
After resolving an existing window name reference in a window definition, we set the ancestor pointer...
Definition: window.h:684
Window::m_needs_restore_input_row
bool m_needs_restore_input_row
Can be true if first window after a join: we may need to restore the input record after buffered wind...
Definition: window.h:185
DBUG_ASSERT
#define DBUG_ASSERT(A)
Definition: my_dbug.h:199
Window::m_special_rows_cache_length
size_t m_special_rows_cache_length[FBC_FIRST_KEY - FBC_LAST_KEY+1]
Length of each copy in m_special_rows_cache, in bytes.
Definition: window.h:418
Window::Window
Window(Item_string *name)
Reference to a named window.
Definition: window.h:650
Item_sum
Class Item_sum is the base class used for special expressions that SQL calls 'set functions'.
Definition: item_sum.h:394
Window::m_frame
PT_frame *const m_frame
<window frame clause>
Definition: window.h:105
Window::m_inherit_from
Item_string *const m_inherit_from
<existing window name>
Definition: window.h:113
Window::Window
Window(Item_string *name, PT_order_list *part, PT_order_list *ord, PT_frame *frame, bool is_reference, Item_string *inherit)
Generic window constructor, shared.
Definition: window.h:594
INT_MIN64
#define INT_MIN64
Definition: my_inttypes.h:74
Window::m_outtable_param
Temp_table_param * m_outtable_param
Execution state: Holds the temporary output table (for next step) parameters.
Definition: window.h:376
Window::check_window_functions2
bool check_window_functions2(THD *thd)
Like check_window_functions1() but contains checks which must wait until the start of the execution p...
Definition: window.cc:1284
Window::st_nth::m_offsets
Mem_root_array_YY< st_offset > m_offsets
sorted set of NTH_VALUE offsets
Definition: window.h:216
ORDER
Definition: table.h:272
file
Definition: os0file.h:85
Window::m_frame_buffer_param
Temp_table_param * m_frame_buffer_param
Execution state: used iff m_needs_frame_buffering.
Definition: window.h:371
Window::Window
Window(PT_order_list *partition_by, PT_order_list *order_by, PT_frame *frame, Item_string *inherit)
Unnamed window based on a named window.
Definition: window.h:664
Window::make_special_rows_cache
bool make_special_rows_cache(THD *thd, TABLE *out_tbl)
Allocate the cache for special rows.
Definition: window.cc:1335
Window::RL_PARTITION
@ RL_PARTITION
Definition: window.h:1338
Window::FRAME_BUFFER_POSITIONS_CARD
static constexpr int FRAME_BUFFER_POSITIONS_CARD
Cardinality of m_frame_buffer_positions if no NTH_VALUE, LEAD/LAG.
Definition: window.h:247
table.h
PT_frame
Parse tree node for a window's frame, cf.
Definition: parse_tree_nodes.h:1357
Window::m_frame_buffer
TABLE * m_frame_buffer
Execution state: used iff m_needs_frame_buffering.
Definition: window.h:382
Bounds_checked_array< Item * >
Window::set_frame_buffer_partition_offset
void set_frame_buffer_partition_offset(int64 offset)
See m_frame_buffer_partition_offset.
Definition: window.h:1276
Window_retrieve_cached_row_reason::FIRST_IN_PARTITION
@ FIRST_IN_PARTITION
Window::m_opt_first_row
bool m_opt_first_row
Window equires re-evaluation of the first row in optimized moving frame mode e.g.
Definition: window.h:172
List< Item_sum >
Window::last_rowno_in_cache
int64 last_rowno_in_cache() const
See m_last_rowno_in_cache.
Definition: window.h:1128
PT_border
Parse tree node for a single of a window extent's borders, cf.
Definition: parse_tree_nodes.h:1278
Window::st_ll_offset::operator<
bool operator<(const st_ll_offset &a) const
Used for sorting offsets in ascending order for faster traversal of frame buffer tmp file.
Definition: window.h:211
Window::set_first_rowno_in_range_frame
void set_first_rowno_in_range_frame(int64 rowno)
See m_first_rowno_in_range_frame.
Definition: window.h:1250
SELECT_LEX::table_list
SQL_I_List< TABLE_LIST > table_list
List of tables in FROM clause - use TABLE_LIST::next_local to traverse.
Definition: sql_lex.h:1854
Window::m_part_row_number
int64 m_part_row_number
Execution state: the current row number in the current partition.
Definition: window.h:447
Window_evaluation_requirements
Collects evaluation requirements from a window function, used by Item_sum::check_wf_semantics and its...
Definition: window.h:1444
Window::m_is_last_row_in_peerset_within_frame
int64 m_is_last_row_in_peerset_within_frame
Execution state: used iff m_needs_last_peer_in_frame.
Definition: window.h:439
SELECT_LEX
This class represents a query block, aka a query specification, which is a query consisting of a SELE...
Definition: sql_lex.h:1098
Window::reset_all_wf_state
void reset_all_wf_state()
Reset the execution state for all window functions defined on this window.
Definition: window.cc:1541
Window::at_partition_border
bool at_partition_border() const
Check if we have read all the rows in a partition, possibly having buffered them for further processi...
Definition: window.h:860
Window::is_reference
bool is_reference() const
Return if this window represents an unresolved window reference seen in a window function OVER clause...
Definition: window.h:804
Window::row_has_fields_in_out_table
int64 row_has_fields_in_out_table() const
See m_row_has_fields_in_out_table.
Definition: window.h:1290
Window_evaluation_requirements::opt_last_row
bool opt_last_row
Set to true if we need LAST_VALUE or optimized MIN/MAX.
Definition: window.h:1465
Window::compute_cost
static double compute_cost(double cost, List< Window > &windows)
Compute sorting costs for windowing.
Definition: window.cc:1555
Window::do_inverse
bool do_inverse() const
See m_inverse_aggregation.
Definition: window.h:1186
Window::st_lead_lag
Definition: window.h:219
Window::eliminate_unused_objects
static void eliminate_unused_objects(THD *thd, List< Window > &windows)
Check window definitions to remove unused windows.
Definition: window.cc:1044
p
const char * p
Definition: ctype-mb.cc:1235
Window::m_partition_items
List< Cached_item > m_partition_items
items for the PARTITION BY columns
Definition: window.h:235
Window::name
Item_string * name() const
Get the name of a window.
Definition: window.h:689
Window_evaluation_requirements::Window_evaluation_requirements
Window_evaluation_requirements()
Definition: window.h:1481
Window::m_frame_buffer_total_rows
int64 m_frame_buffer_total_rows
Execution state: The frame buffer tmp file is not truncated for each new partition.
Definition: window.h:392
mem_root_array.h
Window::set_inverse
Window & set_inverse(bool b)
See m_inverse_aggregation.
Definition: window.h:1191
Window::rowno_in_frame
int64 rowno_in_frame() const
Return the size of the frame in number of rows.
Definition: window.h:1227
Window::m_special_rows_cache_max_length
size_t m_special_rows_cache_max_length
Maximum allocated size in m_special_rows_cache.
Definition: window.h:420
Window::before_frame
bool before_frame()
While processing buffered rows in RANGE frame mode we, determine if the present row revisited from th...
Definition: window.h:849
Window::m_select
SELECT_LEX * m_select
The SELECT the window is on.
Definition: window.h:101
Window::FBC_LAST_BUFFERED_ROW
@ FBC_LAST_BUFFERED_ROW
The last row cached in the frame buffer; needed to resurrect input row.
Definition: window.h:359
Window_evaluation_requirements::needs_peerset
bool needs_peerset
Set to true if we need peerset for evaluation (e.g.
Definition: window.h:1452
Window::m_rowno_in_frame
int64 m_rowno_in_frame
Execution state: the row number of the current row within a frame, cf.
Definition: window.h:475
Window::def_pos
uint def_pos() const
Definition: window.h:691
Window::set_frame_buffer_param
void set_frame_buffer_param(Temp_table_param *p)
Setter for m_frame_buffer_param, q.v.
Definition: window.h:1069
Window::last_row_output
int64 last_row_output() const
See m_last_row_output.
Definition: window.h:1108
Window::m_order_by_items
List< Cached_item > m_order_by_items
items for the ORDER BY exprs.
Definition: window.h:236
Window::Reset_level
Reset_level
Definition: window.h:1338
Window::st_offset::operator<
bool operator<(const st_offset &a) const
Used for sorting offsets in ascending order for faster traversal of frame buffer tmp file.
Definition: window.h:201
Window::reset_order_by_peer_set
void reset_order_by_peer_set()
Reset the current row's ORDER BY expressions when starting a new peer set.
Definition: window.cc:494
Window::st_ll_offset
Definition: window.h:204
Window::Frame_buffer_position
Holds information about a position in the buffer frame as stored in a temporary file (cf.
Definition: window.h:256
Window::set_row_has_fields_in_out_table
void set_row_has_fields_in_out_table(int64 rowno)
See m_row_has_fields_in_out_table.
Definition: window.h:1297
Window::FBC_FIRST_KEY
@ FBC_FIRST_KEY
Definition: window.h:362
false
#define false
Definition: config_static.h:43
Window::m_tmp_pos
Frame_buffer_position m_tmp_pos
Sometimes we read one row too many, so that the saved position will be too far out because we subsequ...
Definition: window.h:308
Window::m_frame_buffer_positions
Mem_root_array_YY< Frame_buffer_position > m_frame_buffer_positions
Execution state: used iff m_needs_frame_buffering.
Definition: window.h:299