ArrayDesc inferSchema(std::vector< ArrayDesc> schemas, boost::shared_ptr< Query> query) { assert(schemas.size() == 1); ArrayDesc const& desc = schemas[0]; Dimensions const& dims = desc.getDimensions(); Attributes const& attrs = desc.getAttributes(); AttributeID aid = 0; if (_parameters.size() >= 1) { aid = ((boost::shared_ptr<OperatorParamReference>&)_parameters[0])->getObjectNo(); } AggregatePtr maxAggregate = AggregateLibrary::getInstance()->createAggregate("max", TypeLibrary::getType(attrs[aid].getType())); Attributes aggAttrs(1); aggAttrs[0] = AttributeDesc((AttributeID)0, attrs[aid].getName() + "_max", maxAggregate->getResultType().typeId(), AttributeDesc::IS_NULLABLE, 0); if (_parameters.size() <= 1) { Dimensions aggDims(1); aggDims[0] = DimensionDesc("i", 0, 0, 0, 0, 1, 0); return ArrayDesc(desc.getName(), aggAttrs, aggDims); } else { vector<int> groupBy(_parameters.size()-1); for (size_t i = 0; i < groupBy.size(); i++) { groupBy[i] = ((boost::shared_ptr<OperatorParamReference>&)_parameters[i + 1])->getObjectNo(); } Dimensions aggDims(groupBy.size()); for (size_t i = 0, n = aggDims.size(); i < n; i++) { DimensionDesc const& srcDim = dims[groupBy[i]]; aggDims[i] = DimensionDesc( srcDim.getBaseName(), srcDim.getStartMin(), srcDim.getCurrStart(), srcDim.getCurrEnd(), srcDim.getEndMax(), i == 0 && groupBy[i] == 0 ? srcDim.getChunkInterval() : srcDim.getCurrLength(), 0, srcDim.getType(), srcDim.getFlags(), srcDim.getMappingArrayName(), srcDim.getComment(), srcDim.getFuncMapOffset(), srcDim.getFuncMapScale()); } return ArrayDesc(desc.getName(), aggAttrs, aggDims); } }
QxSqlQuery & QxSqlQuery::groupBy(const QString & col1, const QString & col2, const QString & col3, const QString & col4, const QString & col5, const QString & col6, const QString & col7, const QString & col8, const QString & col9) { return groupBy(QStringList() << col1 << col2 << col3 << col4 << col5 << col6 << col7 << col8 << col9); }
QxSqlQuery & QxSqlQuery::groupBy(const QString & col1, const QString & col2, const QString & col3, const QString & col4, const QString & col5) { return groupBy(QStringList() << col1 << col2 << col3 << col4 << col5); }
QxSqlQuery & QxSqlQuery::groupBy(const QString & col1, const QString & col2) { return groupBy(QStringList() << col1 << col2); }
void ASTSelectQuery::formatImpl(const FormatSettings & s, FormatState & state, FormatStateStacked frame) const { frame.current_select = this; frame.need_parens = false; std::string indent_str = s.one_line ? "" : std::string(4 * frame.indent, ' '); if (with()) { s.ostr << (s.hilite ? hilite_keyword : "") << indent_str << "WITH " << (s.hilite ? hilite_none : ""); s.one_line ? with()->formatImpl(s, state, frame) : with()->as<ASTExpressionList &>().formatImplMultiline(s, state, frame); s.ostr << s.nl_or_ws; } s.ostr << (s.hilite ? hilite_keyword : "") << indent_str << "SELECT " << (distinct ? "DISTINCT " : "") << (s.hilite ? hilite_none : ""); s.one_line ? select()->formatImpl(s, state, frame) : select()->as<ASTExpressionList &>().formatImplMultiline(s, state, frame); if (tables()) { s.ostr << (s.hilite ? hilite_keyword : "") << s.nl_or_ws << indent_str << "FROM " << (s.hilite ? hilite_none : ""); tables()->formatImpl(s, state, frame); } if (prewhere()) { s.ostr << (s.hilite ? hilite_keyword : "") << s.nl_or_ws << indent_str << "PREWHERE " << (s.hilite ? hilite_none : ""); prewhere()->formatImpl(s, state, frame); } if (where()) { s.ostr << (s.hilite ? hilite_keyword : "") << s.nl_or_ws << indent_str << "WHERE " << (s.hilite ? hilite_none : ""); where()->formatImpl(s, state, frame); } if (groupBy()) { s.ostr << (s.hilite ? hilite_keyword : "") << s.nl_or_ws << indent_str << "GROUP BY " << (s.hilite ? hilite_none : ""); s.one_line ? groupBy()->formatImpl(s, state, frame) : groupBy()->as<ASTExpressionList &>().formatImplMultiline(s, state, frame); } if (group_by_with_rollup) s.ostr << (s.hilite ? hilite_keyword : "") << s.nl_or_ws << indent_str << (s.one_line ? "" : " ") << "WITH ROLLUP" << (s.hilite ? hilite_none : ""); if (group_by_with_cube) s.ostr << (s.hilite ? hilite_keyword : "") << s.nl_or_ws << indent_str << (s.one_line ? "" : " ") << "WITH CUBE" << (s.hilite ? hilite_none : ""); if (group_by_with_totals) s.ostr << (s.hilite ? hilite_keyword : "") << s.nl_or_ws << indent_str << (s.one_line ? "" : " ") << "WITH TOTALS" << (s.hilite ? hilite_none : ""); if (having()) { s.ostr << (s.hilite ? hilite_keyword : "") << s.nl_or_ws << indent_str << "HAVING " << (s.hilite ? hilite_none : ""); having()->formatImpl(s, state, frame); } if (orderBy()) { s.ostr << (s.hilite ? hilite_keyword : "") << s.nl_or_ws << indent_str << "ORDER BY " << (s.hilite ? hilite_none : ""); s.one_line ? orderBy()->formatImpl(s, state, frame) : orderBy()->as<ASTExpressionList &>().formatImplMultiline(s, state, frame); } if (limitByValue()) { s.ostr << (s.hilite ? hilite_keyword : "") << s.nl_or_ws << indent_str << "LIMIT " << (s.hilite ? hilite_none : ""); limitByValue()->formatImpl(s, state, frame); s.ostr << (s.hilite ? hilite_keyword : "") << " BY " << (s.hilite ? hilite_none : ""); s.one_line ? limitBy()->formatImpl(s, state, frame) : limitBy()->as<ASTExpressionList &>().formatImplMultiline(s, state, frame); } if (limitLength()) { s.ostr << (s.hilite ? hilite_keyword : "") << s.nl_or_ws << indent_str << "LIMIT " << (s.hilite ? hilite_none : ""); if (limitOffset()) { limitOffset()->formatImpl(s, state, frame); s.ostr << ", "; } limitLength()->formatImpl(s, state, frame); } if (settings()) { s.ostr << (s.hilite ? hilite_keyword : "") << s.nl_or_ws << indent_str << "SETTINGS " << (s.hilite ? hilite_none : ""); settings()->formatImpl(s, state, frame); } }
int main() { std::vector<T> v{ { T{ 1, 1.1f, 'a' }, T{ 2, 2.2f, 'b' }, T{ 2, 2.2f, 'c' }, T{ 3, 3.3f, 'd' }, T{ 3, 3.3f, 'e' }, T{ 3, 3.3f, 'f' } } }; { std::map< int, std::vector< T > > const actual = groupBy( v.begin(), v.end(), & get_i ); std::map< int, std::vector< T > > const expected { { { 1, { T{ 1, 1.1f, 'a' } } }, { 2, { T{ 2, 2.2f, 'b' }, T{ 2, 2.2f, 'c' } } }, { 3, { T{ 3, 3.3f, 'd' }, T{ 3, 3.3f, 'e' }, T{ 3, 3.3f, 'f' } } } } }; assert( actual == expected ); } { std::map< int, std::vector< T > > const actual = groupBy( v.begin(), v.end(), & get_cir ); std::map< int, std::vector< T > > const expected { { { 1, { T{ 1, 1.1f, 'a' } } }, { 2, { T{ 2, 2.2f, 'b' }, T{ 2, 2.2f, 'c' } } }, { 3, { T{ 3, 3.3f, 'd' }, T{ 3, 3.3f, 'e' }, T{ 3, 3.3f, 'f' } } } } }; assert( actual == expected ); } { std::map< int, std::map< float, std::vector< T > > > const actual = groupBy( v.begin(), v.end(), & get_i, Get_f()); std::map< int, std::map< float, std::vector< T > > > const expected{ { { 1, { { 1.1f, { T{ 1, 1.1f, 'a' } } } } }, { 2, { { 2.2f, { T{ 2, 2.2f, 'b' }, T{ 2, 2.2f, 'c' } } } } }, { 3, { { 3.3f, { T{ 3, 3.3f, 'd' }, T{ 3, 3.3f, 'e' }, T{ 3, 3.3f, 'f' } } } } } } }; assert( actual == expected ); } { std::map< int, std::map<float, std::map<char, std::vector<T> > > > const actual = groupBy( v.begin(), v.end(), & get_i, Get_f(), get_c ); std::map< int, std::map< float, std::map< char, std::vector< T > > > > const expected { { { 1, { { 1.1f, { { 'a', { T{ 1, 1.1f, 'a' } } } } } } }, { 2, { { 2.2f, { { 'b', { T{ 2, 2.2f, 'b' } } }, { 'c', { T{ 2, 2.2f, 'c' } } } } } } }, { 3, { { 3.3f, { { 'd', { T{ 3, 3.3f, 'd' } } }, { 'e', { T{ 3, 3.3f, 'e' } } }, { 'f', { T{ 3, 3.3f, 'f' } } } } } } } } }; assert(actual == expected); } }