Line data Source code
1 : /* 2 : * SPDX-License-Identifier: MPL-2.0 3 : * 4 : * This Source Code Form is subject to the terms of the Mozilla Public 5 : * License, v. 2.0. If a copy of the MPL was not distributed with this 6 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 : * 8 : * Copyright 2024 MonetDB Foundation; 9 : * Copyright August 2008 - 2023 MonetDB B.V.; 10 : * Copyright 1997 - July 2008 CWI. 11 : */ 12 : 13 : #include "monetdb_config.h" 14 : #include "rel_physical.h" 15 : #include "rel_optimizer_private.h" 16 : #include "rel_rewriter.h" 17 : #include "rel_exp.h" 18 : #include "rel_rel.h" 19 : 20 : #define IS_ORDER_BASED_AGGR(name) (strcmp((name), "quantile") == 0 || strcmp((name), "quantile_avg") == 0 || \ 21 : strcmp((name), "median") == 0 || strcmp((name), "median_avg") == 0) 22 : 23 : static sql_rel * 24 1358809 : rel_add_orderby(visitor *v, sql_rel *rel) 25 : { 26 1358809 : if (is_groupby(rel->op)) { 27 16876 : if (rel->exps && !rel->r) { /* find quantiles */ 28 4321 : sql_exp *obe = NULL, *oberef = NULL; 29 9251 : for(node *n = rel->exps->h; n; n = n->next) { 30 4930 : sql_exp *e = n->data; 31 : 32 4930 : if (is_aggr(e->type)) { 33 4919 : sql_subfunc *af = e->f; 34 4919 : list *aa = e->l; 35 : 36 : /* for now we only handle one sort order */ 37 4919 : if (IS_ORDER_BASED_AGGR(af->func->base.name) && aa && list_length(aa) == 2) { 38 28 : sql_exp *nobe = aa->h->data; 39 28 : if (nobe && !obe) { 40 21 : sql_rel *l = rel->l = rel_project(v->sql->sa, rel->l, rel_projections(v->sql, rel->l, NULL, 1, 1)); 41 21 : obe = nobe; 42 21 : oberef = nobe; 43 21 : if (l) { 44 21 : if (!is_alias(nobe->type)) { 45 0 : oberef = nobe = exp_label(v->sql->sa, exp_copy(v->sql, nobe), ++v->sql->label); 46 0 : append(l->exps, nobe); 47 : } 48 21 : set_nulls_first(nobe); 49 21 : set_ascending(nobe); 50 21 : aa->h->data = exp_ref(v->sql, nobe); 51 21 : list *o = l->r = sa_list(v->sql->sa); 52 21 : if (o) 53 21 : append(o, nobe); 54 : } 55 7 : } else if (exp_match_exp(nobe, obe)) { 56 3 : aa->h->data = exp_ref(v->sql, oberef); 57 : } 58 : } 59 : } 60 : } 61 : return rel; 62 : } 63 : } 64 : return rel; 65 : } 66 : 67 : sql_rel * 68 544067 : rel_physical(mvc *sql, sql_rel *rel) 69 : { 70 544067 : visitor v = { .sql = sql }; 71 : 72 544067 : rel = rel_visitor_bottomup(&v, rel, &rel_add_orderby); 73 544054 : return rel; 74 : }