1/*
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 *
6 * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
7 */
8
9#include "monetdb_config.h"
10#include "sql_parser.h"
11#include "sql_symbol.h"
12#include "rel_semantic.h"
13#include "rel_select.h"
14#include "rel_updates.h"
15#include "rel_trans.h"
16#include "rel_schema.h"
17#include "rel_psm.h"
18#include "rel_sequence.h"
19#include "rel_exp.h"
20
21#include <unistd.h>
22#include <string.h>
23#include <ctype.h>
24
25
26sql_rel *
27rel_parse(mvc *m, sql_schema *s, char *query, char emode)
28{
29 mvc o = *m;
30 sql_rel *rel = NULL;
31 buffer *b;
32 bstream *bs;
33 stream *buf;
34 char *n;
35 size_t len = _strlen(query);
36 sql_schema *c = cur_schema(m);
37 sql_query *qc = NULL;
38
39 m->qc = NULL;
40
41 m->caching = 0;
42 m->emode = emode;
43 if (s)
44 m->session->schema = s;
45
46 b = (buffer*)GDKmalloc(sizeof(buffer));
47 if (!b) {
48 return NULL;
49 }
50 n = GDKmalloc(len + 1 + 1);
51 if (!n) {
52 GDKfree(b);
53 return NULL;
54 }
55 snprintf(n, len + 2, "%s\n", query);
56 query = n;
57 len++;
58 buffer_init(b, query, len);
59 buf = buffer_rastream(b, "sqlstatement");
60 if(buf == NULL) {
61 buffer_destroy(b);
62 return NULL;
63 }
64 bs = bstream_create(buf, b->len);
65 if(bs == NULL) {
66 buffer_destroy(b);
67 return NULL;
68 }
69 scanner_init( &m->scanner, bs, NULL);
70 m->scanner.mode = LINE_1;
71 bstream_next(m->scanner.rs);
72
73 m->params = NULL;
74 /*m->args = NULL;*/
75 m->argc = 0;
76 m->sym = NULL;
77 m->errstr[0] = '\0';
78 /* via views we give access to protected objects */
79 if (emode != m_instantiate)
80 m->user_id = USER_MONETDB;
81
82 (void) sqlparse(m); /* blindly ignore errors */
83 qc = query_create(m);
84 rel = rel_semantic(qc, m->sym);
85
86 GDKfree(query);
87 GDKfree(b);
88 bstream_destroy(m->scanner.rs);
89
90 m->sym = NULL;
91 o.vars = m->vars; /* may have been realloc'ed */
92 o.sizevars = m->sizevars;
93 o.query = m->query;
94 if (m->session->status || m->errstr[0]) {
95 int status = m->session->status;
96
97 memcpy(o.errstr, m->errstr, sizeof(o.errstr));
98 *m = o;
99 m->session->status = status;
100 } else {
101 int label = m->label;
102
103 while (m->topvars > o.topvars) {
104 if (m->vars[--m->topvars].name)
105 c_delete(m->vars[m->topvars].name);
106 }
107 *m = o;
108 m->label = label;
109 }
110 m->session->schema = c;
111 return rel;
112}
113
114sql_rel *
115rel_semantic(sql_query *query, symbol *s)
116{
117 mvc *sql = query->sql;
118 if (!s)
119 return NULL;
120
121 switch (s->token) {
122
123 case TR_COMMIT:
124 case TR_SAVEPOINT:
125 case TR_RELEASE:
126 case TR_ROLLBACK:
127 case TR_START:
128 case TR_MODE:
129 return rel_transactions(query, s);
130
131 case SQL_CREATE_SCHEMA:
132 case SQL_DROP_SCHEMA:
133
134 case SQL_DECLARE_TABLE:
135 case SQL_CREATE_TABLE:
136 case SQL_CREATE_VIEW:
137 case SQL_DROP_TABLE:
138 case SQL_DROP_VIEW:
139 case SQL_ALTER_TABLE:
140
141 case SQL_COMMENT:
142
143 case SQL_GRANT:
144 case SQL_REVOKE:
145 case SQL_GRANT_ROLES:
146 case SQL_REVOKE_ROLES:
147
148 case SQL_CREATE_ROLE:
149 case SQL_DROP_ROLE:
150
151 case SQL_CREATE_INDEX:
152 case SQL_DROP_INDEX:
153
154 case SQL_CREATE_USER:
155 case SQL_DROP_USER:
156 case SQL_ALTER_USER:
157
158 case SQL_RENAME_COLUMN:
159 case SQL_RENAME_SCHEMA:
160 case SQL_RENAME_TABLE:
161 case SQL_RENAME_USER:
162 case SQL_SET_TABLE_SCHEMA:
163
164 case SQL_CREATE_TYPE:
165 case SQL_DROP_TYPE:
166 return rel_schemas(query, s);
167
168 case SQL_CREATE_SEQ:
169 case SQL_ALTER_SEQ:
170 case SQL_DROP_SEQ:
171 return rel_sequences(query, s);
172
173 case SQL_CREATE_FUNC:
174 case SQL_DROP_FUNC:
175 case SQL_DECLARE:
176 case SQL_CALL:
177 case SQL_SET:
178
179 case SQL_CREATE_TABLE_LOADER:
180
181 case SQL_CREATE_TRIGGER:
182 case SQL_DROP_TRIGGER:
183
184 case SQL_ANALYZE:
185 return rel_psm(query, s);
186
187 case SQL_INSERT:
188 case SQL_UPDATE:
189 case SQL_DELETE:
190 case SQL_TRUNCATE:
191 case SQL_MERGE:
192 case SQL_COPYFROM:
193 case SQL_BINCOPYFROM:
194 case SQL_COPYLOADER:
195 case SQL_COPYTO:
196 return rel_updates(query, s);
197
198 case SQL_WITH:
199 return rel_with_query(query, s);
200
201 case SQL_MULSTMT: {
202 dnode *d;
203 sql_rel *r = NULL;
204
205 if(!stack_push_frame(sql, "MUL"))
206 return sql_error(sql, 02, SQLSTATE(HY001) MAL_MALLOC_FAIL);
207 for (d = s->data.lval->h; d; d = d->next) {
208 symbol *sym = d->data.sym;
209 sql_rel *nr = rel_semantic(query, sym);
210
211 if (!nr) {
212 stack_pop_frame(sql);
213 return NULL;
214 }
215 if (r)
216 r = rel_list(sql->sa, r, nr);
217 else
218 r = nr;
219 }
220 stack_pop_frame(sql);
221 return r;
222 }
223 case SQL_PREP:
224 {
225 dnode *d = s->data.lval->h;
226 symbol *sym = d->data.sym;
227 sql_rel *r = rel_semantic(query, sym);
228
229 if (!r)
230 return NULL;
231 return r;
232 }
233
234 case SQL_SELECT:
235 case SQL_JOIN:
236 case SQL_CROSS:
237 case SQL_UNION:
238 case SQL_EXCEPT:
239 case SQL_INTERSECT:
240 case SQL_VALUES:
241 return rel_selects(query, s);
242
243 default:
244 return sql_error(sql, 02, SQLSTATE(42000) "Symbol type not found");
245 }
246}
247