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 1678139 : query_processed(sql_query *query )
19 : {
20 1678139 : query -> last_rel = NULL;
21 1678139 : query -> last_exp = NULL;
22 1678139 : query -> last_state = 0;
23 1678139 : query -> last_card = 0;
24 1678139 : }
25 :
26 : static stacked_query *
27 34873 : sq_create( allocator *sa, sql_rel *rel, sql_exp *exp, sql_exp *prev, int sql_state, int card)
28 : {
29 34873 : stacked_query *q = SA_NEW(sa, stacked_query);
30 :
31 34873 : assert(rel);
32 34873 : *q = (stacked_query) {
33 : .rel = rel,
34 : .last_used = exp,
35 : .sql_state = sql_state,
36 : .prev = prev,
37 : .used_card = card,
38 34873 : .grouped = is_groupby(rel->op)|rel->grouped,
39 : .groupby = 0, /* not used for groupby of inner */
40 : };
41 34873 : return q;
42 : }
43 :
44 : sql_query *
45 771390 : query_create( mvc *sql)
46 : {
47 771390 : sql_query *q = SA_ZNEW(sql->sa, sql_query);
48 :
49 771362 : q->sql = sql;
50 771362 : q->outer = sql_stack_new(sql->sa, 32);
51 771453 : return q;
52 : }
53 :
54 : void
55 34873 : query_push_outer(sql_query *q, sql_rel *r, int sql_state)
56 : {
57 34873 : if (!q->last_rel)
58 12332 : q->last_rel = r;
59 34873 : if (r != q->last_rel) {
60 33 : r->grouped = is_groupby(q->last_rel->op);
61 33 : q->last_rel = r;
62 33 : q->last_exp = q->prev = NULL;
63 33 : q->last_state = 0;
64 33 : q->last_card = 0;
65 : }
66 34873 : assert(r== q->last_rel);
67 34873 : 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 34873 : assert(sq);
69 34873 : sql_stack_push(q->outer, sq);
70 34873 : }
71 :
72 : sql_rel *
73 34873 : query_pop_outer(sql_query *q)
74 : {
75 34873 : stacked_query *sq = sql_stack_pop(q->outer);
76 34873 : sql_rel *r = sq->rel;
77 :
78 34873 : q->last_rel = r;
79 34873 : q->last_exp = sq->last_used;
80 34873 : q->last_state = sq->sql_state;
81 34873 : q->last_card = sq->used_card;
82 34873 : return r;
83 : }
84 :
85 : sql_rel *
86 13318 : query_fetch_outer(sql_query *q, int i)
87 : {
88 13318 : stacked_query *sq = sql_stack_fetch(q->outer, i);
89 13318 : if (!sq)
90 : return NULL;
91 13299 : return sq->rel;
92 : }
93 :
94 : int
95 12596 : query_fetch_outer_state(sql_query *q, int i)
96 : {
97 12596 : stacked_query *sq = sql_stack_fetch(q->outer, i);
98 12596 : if (!sq)
99 : return 0;
100 12596 : return sq->sql_state;
101 : }
102 :
103 : void
104 251 : query_update_outer(sql_query *q, sql_rel *r, int i)
105 : {
106 251 : stacked_query *sq = sql_stack_fetch(q->outer, i);
107 251 : sq->rel = r;
108 251 : sq->last_used = NULL;
109 251 : sq->used_card = 0;
110 251 : sq->grouped = is_groupby(r->op);
111 251 : }
112 :
113 : unsigned int
114 677658 : query_has_outer(sql_query *q)
115 : {
116 677658 : return sql_stack_top(q->outer);
117 : }
118 :
119 : int
120 11607 : query_outer_used_exp(sql_query *q, int i, sql_exp *e, int f)
121 : {
122 11607 : stacked_query *sq = sql_stack_fetch(q->outer, i);
123 :
124 11607 : if (sq->last_used == NULL) {
125 2241 : sq->last_used = e;
126 2241 : sq->used_card = sq->rel->card;
127 2241 : return 0;
128 : }
129 9366 : if (is_sql_aggr(f) && !is_sql_farg(f) && sq->groupby) /* cannot user outer both for inner groupby and aggregation */
130 : return -1;
131 9366 : if (is_sql_groupby(f))
132 15 : sq->groupby = 1;
133 :
134 9366 : 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 9366 : if (!is_sql_aggr(f) && sq->grouped && e->card > CARD_AGGR)
137 : return -1;
138 :
139 9366 : sq->last_used = e;
140 9366 : sq->used_card = sq->rel->card;
141 9366 : 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 9 : query_outer_pop_last_used(sql_query *q, int i)
152 : {
153 9 : stacked_query *sq = sql_stack_fetch(q->outer, i);
154 :
155 9 : sq->last_used = NULL;
156 9 : sq->used_card = 0;
157 9 : sq->sql_state = 0;
158 9 : }
159 :
160 : int
161 251 : query_outer_aggregated(sql_query *q, int i, sql_exp *e)
162 : {
163 251 : stacked_query *sq = sql_stack_fetch(q->outer, i);
164 :
165 251 : assert(sq->grouped);
166 251 : sq->last_used = e;
167 251 : sq->used_card = sq->rel->card;
168 251 : return 0;
169 : }
170 :
171 : int
172 296 : query_outer_used_card(sql_query *q, int i)
173 : {
174 296 : stacked_query *sq = sql_stack_fetch(q->outer, i);
175 :
176 296 : return sq->used_card;
177 : }
178 :
179 : sql_exp *
180 115 : query_outer_last_used(sql_query *q, int i)
181 : {
182 115 : stacked_query *sq = sql_stack_fetch(q->outer, i);
183 :
184 115 : return sq->last_used;
185 : }
|