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