casacore
Loading...
Searching...
No Matches
TableParseGroupby.h
Go to the documentation of this file.
1// # TableParseGroupby.h: Class handling GROUPBY and aggregate functions
2// # Copyright (C) 1994-2022
3// # Associated Universities, Inc. Washington DC, USA.
4// #
5// # This library is free software; you can redistribute it and/or modify it
6// # under the terms of the GNU Library General Public License as published by
7// # the Free Software Foundation; either version 2 of the License, or (at your
8// # option) any later version.
9// #
10// # This library is distributed in the hope that it will be useful, but WITHOUT
11// # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12// # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13// # License for more details.
14// #
15// # You should have received a copy of the GNU Library General Public License
16// # along with this library; if not, write to the Free Software Foundation,
17// # Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18// #
19// # Correspondence concerning AIPS++ should be addressed as follows:
20// # Internet email: casa-feedback@nrao.edu.
21// # Postal address: AIPS++ Project Office
22// # National Radio Astronomy Observatory
23// # 520 Edgemont Road
24// # Charlottesville, VA 22903-2475 USA
25
26#ifndef TABLES_TABLEPARSEGROUPBY_H
27#define TABLES_TABLEPARSEGROUPBY_H
28
29// # Includes
30#include <casacore/casa/aips.h>
31#include <casacore/tables/TaQL/ExprNode.h>
32#include <casacore/tables/TaQL/ExprGroup.h>
33#include <vector>
34
35namespace casacore { // # NAMESPACE CASACORE - BEGIN
36
37// # Forward declarations
38class TableParseQuery;
39
40// <summary>
41// Class handling GROUPBY and aggregate functions
42// </summary>
43
44// <use visibility=local>
45
46// <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="">
47// </reviewed>
48
49// <synopsis>
50// This class is used by TableParseQuery to handle TaQL's GROUPBY and HAVING
51// clauses and to setup and evaluate aggregate functions.
52// It checks that the commands and functions are given in a valid way.
53// <br>Note that some hooks are present for the ROLLUP keyword, but it is not
54// possible to use it yet.
55// </synopsis>
56
58 public:
60
61 // Keep the groupby expressions.
62 // It checks if they are all scalar expressions and do not contain
63 // aggregate functions..
64 void handleGroupby(const std::vector<TableExprNode>&, Bool rollup);
65
66 // Keep the having expression.
67 // It checks if the node results in a bool scalar value.
69
70 // Find if groupby and/or aggregate functions are given.
71 // The column nodes can only contain aggregate functions if SELECT is used.
72 // Finally it checks that HAVING is only used if a column node contains
73 // an aggregate function (it makes no sense otherwise).
74 void findGroupAggr(const Block<TableExprNode>& columnNodes, Bool isSelect);
75
76 // Is GROUPBY and/or aggregation used?
77 Bool isUsed() const { return itsGroupAggrUsed != 0; }
78
79 // Is only aggregation used?
80 Bool isOnlyAggr() const { return itsGroupAggrUsed != 0 && (itsGroupAggrUsed & GROUPBY) == 0; }
81
82 // Get the number of aggregation ndes.
83 uInt size() const { return itsAggrNodes.size(); }
84
85 // Disable applySelection for the column nodes of aggregate functions.
87
88 // An exception is thrown if the node uses an aggregate function.
89 static void checkAggrFuncs(const TableExprNode& node);
90
91 // Execute the grouping and aggregation and return the results.
92 // The rownrs are adapted to the resulting rownrs consisting of the
93 // first row of each group.
94 std::shared_ptr<TableExprGroupResult> execGroupAggr(Vector<rownr_t>& rownrs) const;
95
96 // Execute the HAVING clause (if present).
97 // Return False in no HAVING.
98 Bool execHaving(Vector<rownr_t>& rownrs, const std::shared_ptr<TableExprGroupResult>& groups);
99
100 private:
101 // Do the grouping and aggregation and return the results.
102 // It distinguishes the immediate and lazy aggregate functions.
103 // The rownrs are adapted to the resulting rownrs consisting of the
104 // first row of each group.
105 std::shared_ptr<TableExprGroupResult> aggregate(Vector<rownr_t>& rownrs) const;
106
107 // Do the grouping and aggregation and return the results.
108 // It consists of a single COUNTALL operation.
109 // The rownrs are adapted to the resulting rownrs consisting of the
110 // first row of each group.
111 std::shared_ptr<TableExprGroupResult> countAll(Vector<rownr_t>& rownrs) const;
112
113 // Create the set of aggregate functions and groupby keys.
114 std::vector<std::shared_ptr<TableExprGroupFuncSet>> multiKey(
115 const std::vector<TableExprNodeRep*>&, const Vector<rownr_t>& rownrs) const;
116
117 // Create the set of aggregate functions and groupby keys in case
118 // a single groupby key is given.
119 // This offers much faster map access then the general multipleKeys.
120 template <typename T>
121 std::vector<std::shared_ptr<TableExprGroupFuncSet>> singleKey(
122 const std::vector<TableExprNodeRep*>& nodes, const Vector<rownr_t>& rownrs) const {
123 // We have to group the data according to the (possibly empty) groupby.
124 // We step through the table in the normal order which may not be the
125 // groupby order.
126 // A map<key,int> is used to keep track of the results where the int
127 // is the index in a vector of a set of aggregate function objects.
128 std::vector<std::shared_ptr<TableExprGroupFuncSet>> funcSets;
129 std::map<T, int> keyFuncMap;
130 T lastKey = std::numeric_limits<T>::max();
131 int groupnr = -1;
132 // Loop through all rows.
133 // For each row generate the key to get the right entry.
134 TableExprId rowid(0);
135 T key;
136 for (rownr_t i = 0; i < rownrs.size(); ++i) {
137 rowid.setRownr(rownrs[i]);
138 itsGroupbyNodes[0].get(rowid, key);
139 if (key != lastKey) {
140 typename std::map<T, int>::iterator iter = keyFuncMap.find(key);
141 if (iter == keyFuncMap.end()) {
142 groupnr = funcSets.size();
143 keyFuncMap[key] = groupnr;
144 funcSets.push_back(
145 std::shared_ptr<TableExprGroupFuncSet>(new TableExprGroupFuncSet(nodes)));
146 } else {
147 groupnr = iter->second;
148 }
149 }
150 rowid.setRownr(rownrs[i]);
151 funcSets[groupnr]->apply(rowid);
152 }
153 return funcSets;
154 }
155
156 // Get pointers to the aggregate nodes in the node expression.
157 void getAggrNodes(const TableExprNode& node, std::vector<TableExprNodeRep*>& aggrNodes) const;
158
159 // # Data members.
160 // The possible GROUPBY expressions.
161 std::vector<TableExprNode> itsGroupbyNodes;
162 Bool itsGroupbyRollup; // # use ROLLUP in GROUPBY?
163 // The possible HAVING expression.
165 // Pointers to the aggregate function nodes.
166 std::vector<TableExprNodeRep*> itsAggrNodes;
168};
169
170} // namespace casacore
171
172#endif
size_t size() const
Definition ArrayBase.h:99
Class containing the results of aggregated values in a group.
Definition ExprGroup.h:740
void setRownr(rownr_t rownr)
Set the row number.
std::shared_ptr< TableExprGroupResult > execGroupAggr(Vector< rownr_t > &rownrs) const
Execute the grouping and aggregation and return the results.
std::vector< std::shared_ptr< TableExprGroupFuncSet > > singleKey(const std::vector< TableExprNodeRep * > &nodes, const Vector< rownr_t > &rownrs) const
Create the set of aggregate functions and groupby keys in case a single groupby key is given.
TableExprNode itsHavingNode
The possible HAVING expression.
Bool execHaving(Vector< rownr_t > &rownrs, const std::shared_ptr< TableExprGroupResult > &groups)
Execute the HAVING clause (if present).
Bool isUsed() const
Is GROUPBY and/or aggregation used?
std::shared_ptr< TableExprGroupResult > countAll(Vector< rownr_t > &rownrs) const
Do the grouping and aggregation and return the results.
void getAggrNodes(const TableExprNode &node, std::vector< TableExprNodeRep * > &aggrNodes) const
Get pointers to the aggregate nodes in the node expression.
std::vector< std::shared_ptr< TableExprGroupFuncSet > > multiKey(const std::vector< TableExprNodeRep * > &, const Vector< rownr_t > &rownrs) const
Create the set of aggregate functions and groupby keys.
std::vector< TableExprNode > itsGroupbyNodes
The possible GROUPBY expressions.
void handleHaving(const TableExprNode &)
Keep the having expression.
uInt size() const
Get the number of aggregation ndes.
std::shared_ptr< TableExprGroupResult > aggregate(Vector< rownr_t > &rownrs) const
Do the grouping and aggregation and return the results.
Bool isOnlyAggr() const
Is only aggregation used?
void findGroupAggr(const Block< TableExprNode > &columnNodes, Bool isSelect)
Find if groupby and/or aggregate functions are given.
static void checkAggrFuncs(const TableExprNode &node)
An exception is thrown if the node uses an aggregate function.
void handleGroupby(const std::vector< TableExprNode > &, Bool rollup)
Keep the groupby expressions.
uInt disableApplySelection()
Disable applySelection for the column nodes of aggregate functions.
std::vector< TableExprNodeRep * > itsAggrNodes
Pointers to the aggregate function nodes.
For temporary backward namespace compatibility, use casa as alias for casacore.
Definition mainpage.dox:28
unsigned int uInt
Definition aipstype.h:49
int Int
Definition aipstype.h:48
bool Bool
Define the standard types used by Casacore.
Definition aipstype.h:40
uInt64 rownr_t
Define the type of a row number in a table.
Definition aipsxtype.h:44