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 "sql_query.h"
15 : #include "rel_rel.h"
16 :
17 : void
18 1714897 : query_processed(sql_query *query )
19 : {
20 1714897 : query -> last_rel = NULL;
21 1714897 : query -> last_exp = NULL;
22 1714897 : query -> last_state = 0;
23 1714897 : query -> last_card = 0;
24 1714897 : }
25 :
26 : static stacked_query *
27 38617 : sq_create( allocator *sa, sql_rel *rel, sql_exp *exp, sql_exp *prev, int sql_state, int card)
28 : {
29 38617 : stacked_query *q = SA_NEW(sa, stacked_query);
30 :
31 38617 : assert(rel);
32 38617 : *q = (stacked_query) {
33 : .rel = rel,
34 : .last_used = exp,
35 : .sql_state = sql_state,
36 : .prev = prev,
37 : .used_card = card,
38 38617 : .grouped = is_groupby(rel->op)|rel->grouped,
39 : .groupby = 0, /* not used for groupby of inner */
40 : };
41 38617 : return q;
42 : }
43 :
44 : sql_query *
45 792872 : query_create( mvc *sql)
46 : {
47 792872 : sql_query *q = SA_ZNEW(sql->sa, sql_query);
48 :
49 792961 : q->sql = sql;
50 792961 : q->outer = sql_stack_new(sql->sa, 32);
51 792995 : return q;
52 : }
53 :
54 : void
55 38617 : query_push_outer(sql_query *q, sql_rel *r, int sql_state)
56 : {
57 38617 : if (!q->last_rel)
58 15736 : q->last_rel = r;
59 38617 : if (r != q->last_rel) {
60 29 : r->grouped = is_groupby(q->last_rel->op);
61 29 : q->last_rel = r;
62 29 : q->last_exp = q->prev = NULL;
63 29 : q->last_state = 0;
64 29 : q->last_card = 0;
65 : }
66 38617 : assert(r== q->last_rel);
67 38617 : stacked_query *sq = sq_create(q->sql->sa, q->last_rel, q->last_exp, q->prev, sql_state/*q->last_state*/, q->last_card);
68 38617 : assert(sq);
69 38617 : sql_stack_push(q->outer, sq);
70 38617 : }
71 :
72 : sql_rel *
73 38597 : query_pop_outer(sql_query *q)
74 : {
75 38597 : stacked_query *sq = sql_stack_pop(q->outer);
76 38597 : sql_rel *r = sq->rel;
77 :
78 38597 : q->last_rel = r;
79 38597 : q->last_exp = sq->last_used;
80 38597 : q->last_state = sq->sql_state;
81 38597 : q->last_card = sq->used_card;
82 38597 : return r;
83 : }
84 :
85 : sql_rel *
86 12603 : query_fetch_outer(sql_query *q, int i)
87 : {
88 12603 : stacked_query *sq = sql_stack_fetch(q->outer, i);
89 12603 : if (!sq)
90 : return NULL;
91 12592 : return sq->rel;
92 : }
93 :
94 : int
95 12138 : query_fetch_outer_state(sql_query *q, int i)
96 : {
97 12138 : stacked_query *sq = sql_stack_fetch(q->outer, i);
98 12138 : if (!sq)
99 : return 0;
100 12138 : return sq->sql_state;
101 : }
102 :
103 : void
104 136 : query_update_outer(sql_query *q, sql_rel *r, int i)
105 : {
106 136 : stacked_query *sq = sql_stack_fetch(q->outer, i);
107 136 : sq->rel = r;
108 136 : sq->last_used = NULL;
109 136 : sq->used_card = 0;
110 136 : sq->grouped = is_groupby(r->op);
111 136 : }
112 :
113 : unsigned int
114 687079 : query_has_outer(sql_query *q)
115 : {
116 687079 : return sql_stack_top(q->outer);
117 : }
118 :
119 : int
120 11465 : query_outer_used_exp(sql_query *q, int i, sql_exp *e, int f)
121 : {
122 11465 : stacked_query *sq = sql_stack_fetch(q->outer, i);
123 :
124 11465 : if (sq->last_used == NULL) {
125 2200 : sq->last_used = e;
126 2200 : sq->used_card = sq->rel->card;
127 2200 : return 0;
128 : }
129 9265 : if (is_sql_aggr(f) && !is_sql_farg(f) && sq->groupby) /* cannot user outer both for inner groupby and aggregation */
130 : return -1;
131 9265 : if (is_sql_groupby(f))
132 8 : sq->groupby = 1;
133 :
134 9265 : if (is_sql_aggr(f) && !is_sql_farg(f) && sq->groupby && sq->last_used && sq->used_card > CARD_AGGR) /* used full relation */
135 : return -1;
136 9265 : if (!is_sql_aggr(f) && sq->grouped && e->card > CARD_AGGR)
137 : return -1;
138 :
139 9265 : sq->last_used = e;
140 9265 : sq->used_card = sq->rel->card;
141 9265 : assert( (!is_sql_aggr(f) && sq->grouped == 0) || /* outer is a none grouped relation */
142 : (!is_sql_aggr(f) && sq->grouped == 1 && e->card <= CARD_AGGR) || /* outer is groupbed, ie only return aggregations or groupby cols */
143 : (is_sql_aggr(f) && !is_sql_farg(f) && !sq->grouped && e->card != CARD_AGGR) || /* a column/constant to be aggregated */
144 : (is_sql_aggr(f) && !is_sql_farg(f) && sq->grouped && e->card != CARD_AGGR) || /* a column/constant to be aggregated */
145 : (is_sql_aggr(f) && is_sql_farg(f) && sq->grouped && e->card <= CARD_AGGR) || /* groupby ( function (group by col)) */
146 : (is_sql_aggr(f) && sq->grouped && e->card <= CARD_AGGR) ); /* nested aggregations is handled later */
147 : return 0;
148 : }
149 :
150 : void
151 0 : query_outer_pop_last_used(sql_query *q, int i)
152 : {
153 0 : stacked_query *sq = sql_stack_fetch(q->outer, i);
154 :
155 0 : sq->last_used = NULL;
156 0 : sq->used_card = 0;
157 0 : sq->sql_state = 0;
158 0 : }
159 :
160 : int
161 136 : query_outer_aggregated(sql_query *q, int i, sql_exp *e)
162 : {
163 136 : stacked_query *sq = sql_stack_fetch(q->outer, i);
164 :
165 136 : assert(sq->grouped);
166 136 : sq->last_used = e;
167 136 : sq->used_card = sq->rel->card;
168 136 : return 0;
169 : }
170 :
171 : int
172 168 : query_outer_used_card(sql_query *q, int i)
173 : {
174 168 : stacked_query *sq = sql_stack_fetch(q->outer, i);
175 :
176 168 : return sq->used_card;
177 : }
178 :
179 : sql_exp *
180 57 : query_outer_last_used(sql_query *q, int i)
181 : {
182 57 : stacked_query *sq = sql_stack_fetch(q->outer, i);
183 :
184 57 : return sq->last_used;
185 : }
|