Contiki-NG
aql-exec.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010, Swedish Institute of Computer Science
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the Institute nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * This file is part of the Contiki operating system.
30 *
31 */
32
33/**
34 * \file
35 * Query execution functions for AQL.
36 * \author
37 * Nicolas Tsiftes <nvt@sics.se>
38 */
39
40#include <stdarg.h>
41#include <stdio.h>
42#include <string.h>
43
44#define DEBUG DEBUG_NONE
45#include "net/ipv6/uip-debug.h"
46
47#include "index.h"
48#include "relation.h"
49#include "result.h"
50#include "aql.h"
51
52static aql_adt_t adt;
53
54static void
55clear_handle(db_handle_t *handle)
56{
57 memset(handle, 0, sizeof(*handle));
58
59 handle->result_rel = NULL;
60 handle->left_rel = NULL;
61 handle->right_rel = NULL;
62 handle->join_rel = NULL;
63}
64
65static db_result_t
66aql_execute(db_handle_t *handle, aql_adt_t *adt)
67{
68 uint8_t optype;
69 int first_rel_arg;
70 db_result_t result;
71 relation_t *rel;
72 aql_attribute_t *attr;
73 attribute_t *relattr;
74
75 optype = AQL_GET_TYPE(adt);
76 if(optype == AQL_TYPE_NONE) {
77 /* No-ops always succeed. These can be generated by
78 empty lines or comments in the query language. */
79 return DB_OK;
80 }
81
82 /* If the ASSIGN flag is set, the first relation in the array is
83 the desired result relation. */
84 first_rel_arg = !!(adt->flags & AQL_FLAG_ASSIGN);
85
86 if(optype != AQL_TYPE_CREATE_RELATION &&
87 optype != AQL_TYPE_REMOVE_RELATION &&
88 optype != AQL_TYPE_JOIN) {
89 rel = relation_load(adt->relations[first_rel_arg]);
90 if(rel == NULL) {
91 return DB_NAME_ERROR;
92 }
93 } else {
94 rel = NULL;
95 }
96
97 result = DB_RELATIONAL_ERROR;
98 switch(optype) {
99 case AQL_TYPE_CREATE_ATTRIBUTE:
100 attr = &adt->attributes[0];
101 if(relation_attribute_add(rel, DB_STORAGE, attr->name, attr->domain,
102 attr->element_size) != NULL) {
103 result = DB_OK;
104 }
105 break;
106 case AQL_TYPE_CREATE_INDEX:
107 relattr = relation_attribute_get(rel, adt->attributes[0].name);
108 if(relattr == NULL) {
109 result = DB_NAME_ERROR;
110 break;
111 }
112 result = index_create(AQL_GET_INDEX_TYPE(adt), rel, relattr);
113 break;
114 case AQL_TYPE_CREATE_RELATION:
115 if(relation_create(adt->relations[0], DB_STORAGE) != NULL) {
116 result = DB_OK;
117 }
118 break;
119 case AQL_TYPE_REMOVE_ATTRIBUTE:
120 result = relation_attribute_remove(rel, adt->attributes[0].name);
121 break;
122 case AQL_TYPE_REMOVE_INDEX:
123 relattr = relation_attribute_get(rel, adt->attributes[0].name);
124 if(relattr != NULL) {
125 if(relattr->index != NULL) {
126 result = index_destroy(relattr->index);
127 } else {
128 result = DB_OK;
129 }
130 } else {
131 result = DB_NAME_ERROR;
132 }
133 break;
134 case AQL_TYPE_REMOVE_RELATION:
135 result = relation_remove(adt->relations[0], 1);
136 break;
137#if DB_FEATURE_REMOVE
138 case AQL_TYPE_REMOVE_TUPLES:
139 /* Overwrite the attribute array with a full copy of the original
140 relation's attributes. */
141 adt->attribute_count = 0;
142 for(relattr = list_head(rel->attributes);
143 relattr != NULL;
144 relattr = relattr->next) {
145 AQL_ADD_ATTRIBUTE(adt, relattr->name, DOMAIN_UNSPECIFIED, 0);
146 }
147 AQL_SET_FLAG(adt, AQL_FLAG_INVERSE_LOGIC);
148#endif /* DB_FEATURE_REMOVE */
149 case AQL_TYPE_SELECT:
150 if(handle == NULL) {
151 result = DB_ARGUMENT_ERROR;
152 break;
153 }
154 result = relation_select(handle, rel, adt);
155 break;
156 case AQL_TYPE_INSERT:
157 result = relation_insert(rel, adt->values);
158 break;
159#if DB_FEATURE_JOIN
160 case AQL_TYPE_JOIN:
161 if(handle == NULL) {
162 result = DB_ARGUMENT_ERROR;
163 break;
164 }
165 handle->left_rel = relation_load(adt->relations[first_rel_arg]);
166 if(handle->left_rel == NULL) {
167 break;
168 }
169 handle->right_rel = relation_load(adt->relations[first_rel_arg + 1]);
170 if(handle->right_rel == NULL) {
171 relation_release(handle->left_rel);
172 break;
173 }
174 result = relation_join(handle, adt);
175 break;
176#endif /* DB_FEATURE_JOIN */
177 default:
178 break;
179 }
180
181 if(rel != NULL) {
182 if(handle == NULL || !(handle->flags & DB_HANDLE_FLAG_PROCESSING)) {
183 relation_release(rel);
184 }
185 }
186
187 return result;
188}
189
190db_result_t
191db_query(db_handle_t *handle, const char *format, ...)
192{
193 va_list ap;
194 char query_string[AQL_MAX_QUERY_LENGTH];
195
196 va_start(ap, format);
197 vsnprintf(query_string, sizeof(query_string), format, ap);
198 va_end(ap);
199
200 if(handle != NULL) {
201 clear_handle(handle);
202 }
203
204 if(AQL_ERROR(aql_parse(&adt, query_string))) {
205 return DB_PARSING_ERROR;
206 }
207
208 /*aql_optimize(&adt);*/
209
210 return aql_execute(handle, &adt);
211}
212
213db_result_t
214db_process(db_handle_t *handle)
215{
216 uint8_t optype;
217
218 optype = ((aql_adt_t *)handle->adt)->optype;
219
220 switch(optype) {
221#if DB_FEATURE_REMOVE
222 case AQL_TYPE_REMOVE_TUPLES:
223 return relation_process_remove(handle);
224 break;
225#endif
226 case AQL_TYPE_SELECT:
227 return relation_process_select(handle);
228 break;
229#if DB_FEATURE_JOIN
230 case AQL_TYPE_JOIN:
231 return relation_process_join(handle);
232#endif /* DB_FEATURE_JOIN */
233 default:
234 break;
235 }
236
237 PRINTF("DB: Invalid operation type: %d\n", optype);
238
239 return DB_INCONSISTENCY_ERROR;
240}
Definitions and declarations for AQL, the Antelope Query Language.
void * list_head(const_list_t list)
Get a pointer to the first element of a list.
Definition: list.c:63
Declarations for the result acquisition API.
A set of debugging macros for the IP stack.