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