db_result_t relation_remove(char *name, int remove_tuples) { relation_t *rel; db_result_t result; rel = relation_load(name); if(rel == NULL) { /* * Attempt to remove an inexistent relation. To allow for this * operation to be used for setting up repeatable tests and * experiments, we do not signal an error. */ return DB_OK; } if(rel->references > 1) { return DB_BUSY_ERROR; } result = storage_drop_relation(rel, remove_tuples); relation_free(rel); return result; }
int main(int argc, char **argv) { cst_wave *w; cst_relation *r; cst_utterance *u; if (argc != 3) { fprintf(stderr, "usage: mimic_play_wave_sync WAVEFILE LABELFILE\n"); return 1; } w = new_wave(); if (cst_wave_load_riff(w, argv[1]) != CST_OK_FORMAT) return -1; u = new_utterance(); r = utt_relation_create(u, "FOO"); if (relation_load(r, argv[2]) != CST_OK_FORMAT) return -1; mimic_play_wave_sync(w, r, my_call_back); return 0; }
db_result_t relation_select(void *handle_ptr, relation_t *rel, void *adt_ptr) { aql_adt_t *adt; db_handle_t *handle; char *name; db_direction_t dir; char *attribute_name; attribute_t *attr; int i; int normal_attributes; adt = (aql_adt_t *)adt_ptr; handle = (db_handle_t *)handle_ptr; handle->rel = rel; handle->adt = adt; if(AQL_GET_FLAGS(adt) & AQL_FLAG_ASSIGN) { name = adt->relations[0]; dir = DB_STORAGE; } else { name = RESULT_RELATION; dir = DB_MEMORY; } relation_remove(name, 1); relation_create(name, dir); handle->result_rel = relation_load(name); if(handle->result_rel == NULL) { PRINTF("DB: Failed to load a relation for the query result\n"); return DB_ALLOCATION_ERROR; } for(i = normal_attributes = 0; i < AQL_ATTRIBUTE_COUNT(adt); i++) { attribute_name = adt->attributes[i].name; attr = relation_attribute_get(rel, attribute_name); if(attr == NULL) { PRINTF("DB: Select for invalid attribute %s in relation %s!\n", attribute_name, rel->name); return DB_NAME_ERROR; } PRINTF("DB: Found attribute %s in relation %s\n", attribute_name, rel->name); attr = relation_attribute_add(handle->result_rel, dir, attribute_name, adt->aggregators[i] ? DOMAIN_INT : attr->domain, attr->element_size); if(attr == NULL) { PRINTF("DB: Failed to add a result attribute\n"); relation_release(handle->result_rel); return DB_ALLOCATION_ERROR; } attr->aggregator = adt->aggregators[i]; switch(attr->aggregator) { case AQL_NONE: if(!(adt->attributes[i].flags & ATTRIBUTE_FLAG_NO_STORE)) { /* Only count attributes projected into the result set. */ normal_attributes++; } break; case AQL_MAX: attr->aggregation_value = LONG_MIN; break; case AQL_MIN: attr->aggregation_value = LONG_MAX; break; default: attr->aggregation_value = 0; break; } attr->flags = adt->attributes[i].flags; } /* Preclude mixes of normal attributes and aggregated ones in selection results. */ if(normal_attributes > 0 && handle->result_rel->attribute_count > normal_attributes) { return DB_RELATIONAL_ERROR; } return generate_selection_result(handle, rel, adt); }
db_result_t relation_join(void *query_result, void *adt_ptr) { aql_adt_t *adt; db_handle_t *handle; relation_t *left_rel; relation_t *right_rel; relation_t *join_rel; char *name; db_direction_t dir; int i; char *attribute_name; attribute_t *attr; adt = (aql_adt_t *)adt_ptr; handle = (db_handle_t *)query_result; handle->current_row = 0; handle->ncolumns = 0; handle->adt = adt; handle->flags = DB_HANDLE_FLAG_INDEX_STEP; if(AQL_GET_FLAGS(adt) & AQL_FLAG_ASSIGN) { name = adt->relations[0]; dir = DB_STORAGE; } else { name = RESULT_RELATION; dir = DB_MEMORY; } relation_remove(name, 1); relation_create(name, dir); join_rel = relation_load(name); handle->result_rel = join_rel; if(join_rel == NULL) { PRINTF("DB: Failed to create a join relation!\n"); return DB_ALLOCATION_ERROR; } handle->join_rel = handle->result_rel = join_rel; left_rel = handle->left_rel; right_rel = handle->right_rel; handle->left_join_attr = relation_attribute_get(left_rel, adt->attributes[0].name); handle->right_join_attr = relation_attribute_get(right_rel, adt->attributes[0].name); if(handle->left_join_attr == NULL || handle->right_join_attr == NULL) { PRINTF("DB: The attribute (\"%s\") to join on does not exist in both relations\n", adt->attributes[0].name); return DB_RELATIONAL_ERROR; } if(!index_exists(handle->right_join_attr)) { PRINTF("DB: The attribute to join on is not indexed\n"); return DB_INDEX_ERROR; } /* * Define the resulting relation. We start from 1 when counting attributes * because the first attribute is only the one to join, and is not included * by default in the projected attributes. */ for(i = 1; i < AQL_ATTRIBUTE_COUNT(adt); i++) { attribute_name = adt->attributes[i].name; attr = relation_attribute_get(left_rel, attribute_name); if(attr == NULL) { attr = relation_attribute_get(right_rel, attribute_name); if(attr == NULL) { PRINTF("DB: The projection attribute \"%s\" does not exist in any of the relations to join\n", attribute_name); return DB_RELATIONAL_ERROR; } } if(relation_attribute_add(join_rel, dir, attr->name, attr->domain, attr->element_size) == NULL) { PRINTF("DB: Failed to add an attribute to the join relation\n"); return DB_ALLOCATION_ERROR; } handle->ncolumns++; } return generate_join_result(handle); }
static db_result_t aql_execute(db_handle_t *handle, aql_adt_t *adt) { uint8_t optype; int first_rel_arg; db_result_t result; relation_t *rel; aql_attribute_t *attr; attribute_t *relattr; optype = AQL_GET_TYPE(adt); if(optype == AQL_TYPE_NONE) { /* No-ops always succeed. These can be generated by empty lines or comments in the query language. */ return DB_OK; } /* If the ASSIGN flag is set, the first relation in the array is the desired result relation. */ first_rel_arg = !!(adt->flags & AQL_FLAG_ASSIGN); if(optype != AQL_TYPE_CREATE_RELATION && optype != AQL_TYPE_REMOVE_RELATION && optype != AQL_TYPE_JOIN) { rel = relation_load(adt->relations[first_rel_arg]); if(rel == NULL) { return DB_NAME_ERROR; } } else { rel = NULL; } result = DB_RELATIONAL_ERROR; switch(optype) { case AQL_TYPE_CREATE_ATTRIBUTE: attr = &adt->attributes[0]; if(relation_attribute_add(rel, DB_STORAGE, attr->name, attr->domain, attr->element_size) != NULL) { result = DB_OK; } break; case AQL_TYPE_CREATE_INDEX: relattr = relation_attribute_get(rel, adt->attributes[0].name); if(relattr == NULL) { result = DB_NAME_ERROR; break; } result = index_create(AQL_GET_INDEX_TYPE(adt), rel, relattr); break; case AQL_TYPE_CREATE_RELATION: if(relation_create(adt->relations[0], DB_STORAGE) != NULL) { result = DB_OK; } break; case AQL_TYPE_REMOVE_ATTRIBUTE: result = relation_attribute_remove(rel, adt->attributes[0].name); break; case AQL_TYPE_REMOVE_INDEX: relattr = relation_attribute_get(rel, adt->attributes[0].name); if(relattr != NULL) { if(relattr->index != NULL) { result = index_destroy(relattr->index); } else { result = DB_OK; } } else { result = DB_NAME_ERROR; } break; case AQL_TYPE_REMOVE_RELATION: result = relation_remove(adt->relations[0], 1); break; #if DB_FEATURE_REMOVE case AQL_TYPE_REMOVE_TUPLES: /* Overwrite the attribute array with a full copy of the original relation's attributes. */ adt->attribute_count = 0; for(relattr = list_head(rel->attributes); relattr != NULL; relattr = relattr->next) { AQL_ADD_ATTRIBUTE(adt, relattr->name, DOMAIN_UNSPECIFIED, 0); } AQL_SET_FLAG(adt, AQL_FLAG_INVERSE_LOGIC); #endif /* DB_FEATURE_REMOVE */ case AQL_TYPE_SELECT: if(handle == NULL) { result = DB_ARGUMENT_ERROR; break; } result = relation_select(handle, rel, adt); break; case AQL_TYPE_INSERT: result = relation_insert(rel, adt->values); break; #if DB_FEATURE_JOIN case AQL_TYPE_JOIN: if(handle == NULL) { result = DB_ARGUMENT_ERROR; break; } handle->left_rel = relation_load(adt->relations[first_rel_arg]); if(handle->left_rel == NULL) { break; } handle->right_rel = relation_load(adt->relations[first_rel_arg + 1]); if(handle->right_rel == NULL) { relation_release(handle->left_rel); break; } result = relation_join(handle, adt); break; #endif /* DB_FEATURE_JOIN */ default: break; } if(rel != NULL) { if(handle == NULL || !(handle->flags & DB_HANDLE_FLAG_PROCESSING)) { relation_release(rel); } } return result; }