44 #define DEBUG DEBUG_NONE
62 struct source_dest_map {
63 attribute_t *from_attr;
69 static struct source_dest_map attr_map[AQL_ATTRIBUTE_LIMIT];
78 unsigned char *from_ptr;
81 static struct source_map source_map[AQL_ATTRIBUTE_LIMIT];
84 static unsigned char row[DB_MAX_ATTRIBUTES_PER_RELATION * DB_MAX_ELEMENT_SIZE];
85 static unsigned char extra_row[DB_MAX_ATTRIBUTES_PER_RELATION * DB_MAX_ELEMENT_SIZE];
86 static unsigned char result_row[AQL_ATTRIBUTE_LIMIT * DB_MAX_ELEMENT_SIZE];
87 static unsigned char *
const left_row = row;
88 static unsigned char *
const right_row = extra_row;
89 static unsigned char *
const join_row = result_row;
92 MEMB(relations_memb, relation_t, DB_RELATION_POOL_SIZE);
93 MEMB(attributes_memb, attribute_t, DB_ATTRIBUTE_POOL_SIZE);
95 static relation_t *relation_find(
char *);
96 static attribute_t *attribute_find(relation_t *,
char *);
97 static int get_attribute_value_offset(relation_t *, attribute_t *);
98 static void attribute_free(relation_t *, attribute_t *);
99 static void purge_relations(
void);
100 static void relation_clear(relation_t *);
101 static relation_t *relation_allocate(
void);
102 static void relation_free(relation_t *);
105 relation_find(
char *name)
109 for(rel =
list_head(relations); rel !=
NULL; rel = rel->next) {
110 if(strcmp(rel->name, name) == 0) {
119 attribute_find(relation_t *rel,
char *name)
123 for(attr =
list_head(rel->attributes); attr !=
NULL; attr = attr->next) {
124 if(strcmp(attr->name, name) == 0) {
132 get_attribute_value_offset(relation_t *rel, attribute_t *attr)
137 for(offset = 0, ptr =
list_head(rel->attributes);
143 offset += ptr->element_size;
150 attribute_free(relation_t *rel, attribute_t *attr)
152 if(attr->index !=
NULL) {
153 index_release(attr->index);
156 rel->attribute_count--;
160 purge_relations(
void)
167 if(rel->references == 0) {
175 relation_clear(relation_t *rel)
177 memset(rel, 0,
sizeof(*rel));
178 rel->tuple_storage = -1;
179 rel->cardinality = INVALID_TUPLE;
180 rel->dir = DB_STORAGE;
185 relation_allocate(
void)
194 PRINTF(
"DB: Failed to allocate a relation\n");
204 relation_free(relation_t *rel)
209 attribute_free(rel, attr);
227 relation_load(
char *name)
231 rel = relation_find(name);
237 rel = relation_allocate();
242 if(DB_ERROR(storage_get_relation(rel, name))) {
247 memcpy(rel->name, name,
sizeof(rel->name));
248 rel->name[
sizeof(rel->name) - 1] =
'\0';
253 if(rel->dir == DB_STORAGE && DB_ERROR(storage_load(rel))) {
254 relation_release(rel);
262 relation_release(relation_t *rel)
264 if(rel->references > 0) {
268 if(rel->references == 0) {
276 relation_create(
char *name, db_direction_t dir)
282 relation_clear(&old_rel);
284 if(storage_get_relation(&old_rel, name) == DB_OK) {
286 PRINTF(
"DB: Attempted to create a relation that already exists (%s)\n",
291 rel = relation_allocate();
296 rel->cardinality = 0;
298 strncpy(rel->name, name,
sizeof(rel->name) - 1);
299 rel->name[
sizeof(rel->name) - 1] =
'\0';
302 if(dir == DB_STORAGE) {
303 storage_drop_relation(rel, 1);
305 if(storage_put_relation(rel) == DB_OK) {
319 #if DB_FEATURE_REMOVE
321 relation_rename(
char *old_name,
char *new_name)
323 if(DB_ERROR(relation_remove(new_name, 0)) ||
324 DB_ERROR(storage_rename_relation(old_name, new_name))) {
325 return DB_STORAGE_ERROR;
333 relation_attribute_add(relation_t *rel, db_direction_t dir,
char *name,
334 domain_t domain,
size_t element_size)
336 attribute_t *attribute;
337 tuple_id_t cardinality;
339 cardinality = relation_cardinality(rel);
340 if(cardinality != INVALID_TUPLE && cardinality > 0) {
341 PRINTF(
"DB: Attempt to create an attribute in a non-empty relation\n");
345 if(element_size == 0 || element_size > DB_MAX_ELEMENT_SIZE) {
346 PRINTF(
"DB: Unacceptable element size: %u\n", element_size);
351 if(attribute ==
NULL) {
352 PRINTF(
"DB: Failed to allocate attribute \"%s\"!\n", name);
356 strncpy(attribute->name, name,
sizeof(attribute->name) - 1);
357 attribute->name[
sizeof(attribute->name) - 1] =
'\0';
358 attribute->domain = domain;
359 attribute->element_size = element_size;
360 attribute->aggregator = 0;
361 attribute->index =
NULL;
362 attribute->flags = 0 ;
364 rel->row_length += element_size;
366 list_add(rel->attributes, attribute);
367 rel->attribute_count++;
369 if(dir == DB_STORAGE) {
370 if(DB_ERROR(storage_put_attribute(rel, attribute))) {
371 PRINTF(
"DB: Failed to store attribute %s\n", attribute->name);
376 index_load(rel, attribute);
383 relation_attribute_get(relation_t *rel,
char *name)
387 attr = attribute_find(rel, name);
388 if(attr !=
NULL && !(attr->flags & ATTRIBUTE_FLAG_INVALID)) {
396 relation_attribute_remove(relation_t *rel,
char *name)
399 return DB_IMPLEMENTATION_ERROR;
403 if(rel->references > 1) {
404 return DB_BUSY_ERROR;
407 attr = relation_attribute_get(rel, name);
409 return DB_NAME_ERROR;
413 attribute_free(rel, attr);
419 relation_get_value(relation_t *rel, attribute_t *attr,
420 unsigned char *row_ptr, attribute_value_t *value)
423 unsigned char *from_ptr;
425 offset = get_attribute_value_offset(rel, attr);
427 return DB_IMPLEMENTATION_ERROR;
429 from_ptr = row_ptr + offset;
431 return db_phy_to_value(value, attr, from_ptr);
435 relation_set_primary_key(relation_t *rel,
char *name)
437 attribute_t *attribute;
439 attribute = relation_attribute_get(rel, name);
440 if(attribute ==
NULL) {
441 return DB_NAME_ERROR;
444 attribute->flags = ATTRIBUTE_FLAG_PRIMARY_KEY;
445 PRINTF(
"DB: New primary key: %s\n", attribute->name);
451 relation_remove(
char *name,
int remove_tuples)
456 rel = relation_load(name);
466 if(rel->references > 1) {
467 return DB_BUSY_ERROR;
470 result = storage_drop_relation(rel, remove_tuples);
476 relation_insert(relation_t *rel, attribute_value_t *values)
479 unsigned char record[rel->row_length];
481 attribute_value_t *value;
486 PRINTF(
"DB: Relation %s has a record size of %u bytes\n",
487 rel->name, (
unsigned)rel->row_length);
490 PRINTF(
"DB: Insert (");
492 for(attr =
list_head(rel->attributes); attr !=
NULL; attr = attr->next, value++) {
495 if(attr->domain != value->domain &&
496 !(attr->domain == DOMAIN_LONG && value->domain == DOMAIN_INT)) {
497 PRINTF(
"DB: The value domain %d does not match the domain %d of attribute %s\n",
498 value->domain, attr->domain, attr->name);
499 return DB_RELATIONAL_ERROR;
503 if(attr->flags & ATTRIBUTE_FLAG_INVALID) {
504 memset(ptr, 0, attr->element_size);
505 ptr += attr->element_size;
509 result = db_value_to_phy((
unsigned char *)ptr, attr, value);
510 if(DB_ERROR(result)) {
515 switch(attr->domain) {
517 PRINTF(
"%s=%d", attr->name, VALUE_INT(value));
520 PRINTF(
"%s=%ld", attr->name, VALUE_LONG(value));
523 PRINTF(
"%s='%s", attr->name, VALUE_STRING(value));
526 PRINTF(
")\nDB: Unhandled attribute domain: %d\n", attr->domain);
527 return DB_TYPE_ERROR;
530 if(attr->next !=
NULL) {
535 ptr += attr->element_size;
536 if(attr->index !=
NULL) {
537 if(DB_ERROR(index_insert(attr->index, value, rel->next_row))) {
538 return DB_INDEX_ERROR;
547 return storage_put_row(rel, record);
551 aggregate(attribute_t *attr, attribute_value_t *value)
555 switch(value->domain) {
557 long_value = VALUE_INT(value);
560 long_value = VALUE_LONG(value);
566 switch(attr->aggregator) {
568 attr->aggregation_value++;
571 attr->aggregation_value += long_value;
578 if(long_value > attr->aggregation_value) {
579 attr->aggregation_value = long_value;
583 if(long_value < attr->aggregation_value) {
584 attr->aggregation_value = long_value;
593 generate_attribute_map(
struct source_dest_map *attr_map,
unsigned attribute_count,
594 relation_t *from_rel, relation_t *to_rel,
595 unsigned char *from_row,
unsigned char *to_row)
597 attribute_t *from_attr;
598 attribute_t *to_attr;
600 struct source_dest_map *attr_map_ptr;
603 attr_map_ptr = attr_map;
604 for(size_sum = 0, to_attr =
list_head(to_rel->attributes);
606 to_attr = to_attr->next) {
607 from_attr = attribute_find(from_rel, to_attr->name);
608 if(from_attr ==
NULL) {
609 PRINTF(
"DB: Invalid attribute in the result relation: %s\n",
611 return DB_NAME_ERROR;
614 attr_map_ptr->from_attr = from_attr;
615 attr_map_ptr->to_attr = to_attr;
616 offset = get_attribute_value_offset(from_rel, from_attr);
618 return DB_IMPLEMENTATION_ERROR;
620 attr_map_ptr->from_offset = offset;
621 attr_map_ptr->to_offset = size_sum;
623 size_sum += to_attr->element_size;
631 select_index(db_handle_t *handle, lvm_instance_t *lvm_instance)
637 attribute_value_t av_min;
638 attribute_value_t av_max;
640 unsigned long min_range;
643 min_range = ULONG_MAX;
647 for(attr =
list_head(handle->rel->attributes);
650 if(attr->index !=
NULL &&
651 !LVM_ERROR(lvm_get_derived_range(lvm_instance, attr->name, &min, &max))) {
652 range = (
unsigned long)max.l - (
unsigned long)min.l;
653 PRINTF(
"DB: The search range for attribute \"%s\" comprises %ld values\n",
654 attr->name, range + 1);
656 if(range <= min_range) {
658 av_min.domain = av_max.domain = DOMAIN_INT;
659 VALUE_LONG(&av_min) = min.l;
660 VALUE_LONG(&av_max) = max.l;
667 if(index_get_iterator(&handle->index_iterator, index,
668 &av_min, &av_max) == DB_OK) {
669 handle->flags |= DB_HANDLE_FLAG_SEARCH_INDEX;
675 generate_selection_result(db_handle_t *handle, relation_t *rel, aql_adt_t *adt)
677 relation_t *result_rel;
678 unsigned attribute_count;
681 result_rel = handle->result_rel;
683 handle->current_row = 0;
684 handle->ncolumns = 0;
685 handle->tuple_id = 0;
686 for(attr =
list_head(result_rel->attributes); attr !=
NULL; attr = attr->next) {
687 if(attr->flags & ATTRIBUTE_FLAG_NO_STORE) {
692 handle->tuple = (tuple_t)result_row;
694 attribute_count = result_rel->attribute_count;
695 if(DB_ERROR(generate_attribute_map(attr_map, attribute_count, rel, result_rel, row, result_row))) {
696 return DB_IMPLEMENTATION_ERROR;
699 if(adt->lvm_instance !=
NULL) {
701 if(!LVM_ERROR(lvm_derive(adt->lvm_instance))) {
702 select_index(handle, adt->lvm_instance);
706 handle->flags |= DB_HANDLE_FLAG_PROCESSING;
711 #if DB_FEATURE_REMOVE
713 relation_process_remove(
void *handle_ptr)
719 handle = (db_handle_t *)handle_ptr;
722 result = relation_process_select(handle_ptr);
723 if(result == DB_FINISHED) {
724 PRINTF(
"DB: Finished removing tuples. Overwriting relation %s with the result\n",
726 relation_release(handle->rel);
727 relation_rename(adt->relations[0], adt->relations[1]);
735 relation_process_select(
void *handle_ptr)
740 unsigned attribute_count;
741 struct source_dest_map *attr_map_ptr, *attr_map_end;
742 attribute_t *result_attr;
743 unsigned char *from_ptr;
744 unsigned char *to_ptr;
745 operand_value_t operand_value;
747 attribute_value_t value;
748 lvm_status_t wanted_result;
750 handle = (db_handle_t *)handle_ptr;
751 adt = (aql_adt_t *)handle->adt;
753 attribute_count = handle->result_rel->attribute_count;
754 attr_map_end = attr_map + attribute_count;
756 if(handle->flags & DB_HANDLE_FLAG_SEARCH_INDEX) {
757 handle->tuple_id = index_get_next(&handle->index_iterator);
758 if(handle->tuple_id == INVALID_TUPLE) {
759 PRINTF(
"DB: An attribute value could not be found in the index\n");
760 if(handle->index_iterator.next_item_no == 0) {
761 return DB_INDEX_ERROR;
764 if(adt->flags & AQL_FLAG_AGGREGATE) {
765 goto end_aggregation;
774 result = storage_get_row(handle->rel, &handle->tuple_id, row);
776 if(DB_ERROR(result)) {
777 PRINTF(
"DB: Failed to get a row in relation %s!\n", handle->rel->name);
779 }
else if(result == DB_FINISHED) {
780 if(AQL_GET_FLAGS(adt) & AQL_FLAG_AGGREGATE) {
781 goto end_aggregation;
787 for(attr_map_ptr = attr_map; attr_map_ptr < attr_map_end; attr_map_ptr++) {
788 from_ptr = row + attr_map_ptr->from_offset;
789 result_attr = attr_map_ptr->to_attr;
792 if(result_attr->domain == DOMAIN_INT) {
793 operand_value.l = from_ptr[0] << 8 | from_ptr[1];
794 lvm_set_variable_value(result_attr->name, operand_value);
795 }
else if(result_attr->domain == DOMAIN_LONG) {
796 operand_value.l = (uint32_t)from_ptr[0] << 24 |
797 (uint32_t)from_ptr[1] << 16 |
798 (uint32_t)from_ptr[2] << 8 |
800 lvm_set_variable_value(result_attr->name, operand_value);
803 if(result_attr->flags & ATTRIBUTE_FLAG_NO_STORE) {
809 if(!(AQL_GET_FLAGS(adt) & AQL_FLAG_AGGREGATE)) {
811 memcpy(result_row + attr_map_ptr->to_offset, from_ptr,
812 result_attr->element_size);
816 wanted_result =
TRUE;
817 if(AQL_GET_FLAGS(adt) & AQL_FLAG_INVERSE_LOGIC) {
818 wanted_result =
FALSE;
822 if(adt->lvm_instance ==
NULL ||
823 lvm_execute(adt->lvm_instance) == wanted_result) {
824 if(AQL_GET_FLAGS(adt) & AQL_FLAG_AGGREGATE) {
825 for(attr_map_ptr = attr_map; attr_map_ptr < attr_map_end; attr_map_ptr++) {
826 from_ptr = row + attr_map_ptr->from_offset;
827 result = db_phy_to_value(&value, attr_map_ptr->to_attr, from_ptr);
828 if(DB_ERROR(result)) {
831 aggregate(attr_map_ptr->to_attr, &value);
834 if(AQL_GET_FLAGS(adt) & AQL_FLAG_ASSIGN) {
835 if(DB_ERROR(storage_put_row(handle->result_rel, result_row))) {
836 PRINTF(
"DB: Failed to store a row in the result relation!\n");
837 return DB_STORAGE_ERROR;
840 handle->current_row++;
849 for(attr_map_ptr = attr_map; attr_map_ptr < attr_map_end; attr_map_ptr++) {
850 result_attr = attr_map_ptr->to_attr;
851 to_ptr = result_row + attr_map_ptr->to_offset;
853 intbuf[0] = result_attr->aggregation_value >> 8;
854 intbuf[1] = result_attr->aggregation_value & 0xff;
856 memcpy(to_ptr, from_ptr, result_attr->element_size);
859 if(AQL_GET_FLAGS(adt) & AQL_FLAG_ASSIGN) {
860 if(DB_ERROR(storage_put_row(handle->result_rel, result_row))) {
861 PRINTF(
"DB: Failed to store a row in the result relation!\n");
862 return DB_STORAGE_ERROR;
866 handle->current_row = 1;
867 AQL_GET_FLAGS(adt) &= ~AQL_FLAG_AGGREGATE;
873 relation_select(
void *handle_ptr, relation_t *rel,
void *adt_ptr)
879 char *attribute_name;
882 int normal_attributes;
884 adt = (aql_adt_t *)adt_ptr;
886 handle = (db_handle_t *)handle_ptr;
890 if(AQL_GET_FLAGS(adt) & AQL_FLAG_ASSIGN) {
891 name = adt->relations[0];
894 name = RESULT_RELATION;
897 relation_remove(name, 1);
898 relation_create(name, dir);
899 handle->result_rel = relation_load(name);
901 if(handle->result_rel ==
NULL) {
902 PRINTF(
"DB: Failed to load a relation for the query result\n");
903 return DB_ALLOCATION_ERROR;
906 for(i = normal_attributes = 0; i < AQL_ATTRIBUTE_COUNT(adt); i++) {
907 attribute_name = adt->attributes[i].name;
909 attr = relation_attribute_get(rel, attribute_name);
911 PRINTF(
"DB: Select for invalid attribute %s in relation %s!\n",
912 attribute_name, rel->name);
913 return DB_NAME_ERROR;
916 PRINTF(
"DB: Found attribute %s in relation %s\n",
917 attribute_name, rel->name);
919 attr = relation_attribute_add(handle->result_rel, dir,
921 adt->aggregators[i] ? DOMAIN_INT : attr->domain,
924 PRINTF(
"DB: Failed to add a result attribute\n");
925 relation_release(handle->result_rel);
926 return DB_ALLOCATION_ERROR;
929 attr->aggregator = adt->aggregators[i];
930 switch(attr->aggregator) {
932 if(!(adt->attributes[i].flags & ATTRIBUTE_FLAG_NO_STORE)) {
938 attr->aggregation_value = LONG_MIN;
941 attr->aggregation_value = LONG_MAX;
944 attr->aggregation_value = 0;
948 attr->flags = adt->attributes[i].flags;
953 if(normal_attributes > 0 &&
954 handle->result_rel->attribute_count > normal_attributes) {
955 return DB_RELATIONAL_ERROR;
958 return generate_selection_result(handle, rel, adt);
963 relation_process_join(
void *handle_ptr)
967 relation_t *left_rel;
968 relation_t *right_rel;
969 relation_t *join_rel;
970 unsigned char *join_next_attribute_ptr;
972 tuple_id_t right_tuple_id;
973 attribute_value_t value;
976 handle = (db_handle_t *)handle_ptr;
977 left_rel = handle->left_rel;
978 right_rel = handle->right_rel;
979 join_rel = handle->join_rel;
981 if(!(handle->flags & DB_HANDLE_FLAG_INDEX_STEP)) {
987 for(handle->tuple_id = 0;; handle->tuple_id++) {
988 result = storage_get_row(left_rel, &handle->tuple_id, left_row);
989 if(DB_ERROR(result)) {
990 PRINTF(
"DB: Failed to get a row in left relation %s!\n", left_rel->name);
992 }
else if(result == DB_FINISHED) {
996 if(DB_ERROR(relation_get_value(left_rel, handle->left_join_attr, left_row, &value))) {
997 PRINTF(
"DB: Failed to get a value of the attribute \"%s\" to join on\n",
998 handle->left_join_attr->name);
999 return DB_IMPLEMENTATION_ERROR;
1002 if(DB_ERROR(index_get_iterator(&handle->index_iterator,
1003 handle->right_join_attr->index,
1005 PRINTF(
"DB: Failed to get an index iterator\n");
1006 return DB_INDEX_ERROR;
1008 handle->flags &= ~DB_HANDLE_FLAG_INDEX_STEP;
1015 right_tuple_id = index_get_next(&handle->index_iterator);
1016 if(right_tuple_id == INVALID_TUPLE) {
1019 handle->flags |= DB_HANDLE_FLAG_INDEX_STEP;
1023 result = storage_get_row(right_rel, &right_tuple_id, right_row);
1024 if(DB_ERROR(result)) {
1025 PRINTF(
"DB: Failed to get a row in right relation %s!\n", right_rel->name);
1027 }
else if(result == DB_FINISHED) {
1028 PRINTF(
"DB: The index refers to an invalid row: %lu\n",
1029 (
unsigned long)right_tuple_id);
1030 return DB_IMPLEMENTATION_ERROR;
1035 join_next_attribute_ptr = join_row;
1037 for(i = 0; i < join_rel->attribute_count; i++) {
1038 element_size = source_map[i].attr->element_size;
1040 memcpy(join_next_attribute_ptr, source_map[i].from_ptr, element_size);
1041 join_next_attribute_ptr += element_size;
1044 if(((aql_adt_t *)handle->adt)->flags & AQL_FLAG_ASSIGN) {
1045 if(DB_ERROR(storage_put_row(join_rel, join_row))) {
1046 return DB_STORAGE_ERROR;
1050 handle->current_row++;
1059 generate_join_result(db_handle_t *handle)
1061 relation_t *left_rel;
1062 relation_t *right_rel;
1063 relation_t *join_rel;
1065 attribute_t *result_attr;
1066 struct source_map *source_pair;
1069 unsigned char *from_ptr;
1071 handle->tuple = (tuple_t)join_row;
1072 handle->tuple_id = 0;
1074 left_rel = handle->left_rel;
1075 right_rel = handle->right_rel;
1076 join_rel = handle->join_rel;
1080 for(i = 0, result_attr =
list_head(join_rel->attributes);
1081 result_attr !=
NULL;
1082 result_attr = result_attr->next, i++) {
1083 source_pair = &source_map[i];
1084 attr = attribute_find(left_rel, result_attr->name);
1086 offset = get_attribute_value_offset(left_rel, attr);
1087 from_ptr = left_row + offset;
1088 }
else if((attr = attribute_find(right_rel, result_attr->name)) !=
NULL) {
1089 offset = get_attribute_value_offset(right_rel, attr);
1090 from_ptr = right_row + offset;
1092 PRINTF(
"DB: The attribute %s could not be found\n", result_attr->name);
1093 return DB_NAME_ERROR;
1097 PRINTF(
"DB: Unable to retrieve attribute values for the JOIN result\n");
1098 return DB_IMPLEMENTATION_ERROR;
1101 source_pair->attr = attr;
1102 source_pair->from_ptr = from_ptr;
1105 handle->flags |= DB_HANDLE_FLAG_PROCESSING;
1111 relation_join(
void *query_result,
void *adt_ptr)
1114 db_handle_t *handle;
1115 relation_t *left_rel;
1116 relation_t *right_rel;
1117 relation_t *join_rel;
1121 char *attribute_name;
1124 adt = (aql_adt_t *)adt_ptr;
1126 handle = (db_handle_t *)query_result;
1127 handle->current_row = 0;
1128 handle->ncolumns = 0;
1130 handle->flags = DB_HANDLE_FLAG_INDEX_STEP;
1132 if(AQL_GET_FLAGS(adt) & AQL_FLAG_ASSIGN) {
1133 name = adt->relations[0];
1136 name = RESULT_RELATION;
1139 relation_remove(name, 1);
1140 relation_create(name, dir);
1141 join_rel = relation_load(name);
1142 handle->result_rel = join_rel;
1144 if(join_rel ==
NULL) {
1145 PRINTF(
"DB: Failed to create a join relation!\n");
1146 return DB_ALLOCATION_ERROR;
1149 handle->join_rel = handle->result_rel = join_rel;
1150 left_rel = handle->left_rel;
1151 right_rel = handle->right_rel;
1153 handle->left_join_attr = relation_attribute_get(left_rel, adt->attributes[0].name);
1154 handle->right_join_attr = relation_attribute_get(right_rel, adt->attributes[0].name);
1155 if(handle->left_join_attr ==
NULL || handle->right_join_attr ==
NULL) {
1156 PRINTF(
"DB: The attribute (\"%s\") to join on does not exist in both relations\n",
1157 adt->attributes[0].name);
1158 return DB_RELATIONAL_ERROR;
1161 if(!index_exists(handle->right_join_attr)) {
1162 PRINTF(
"DB: The attribute to join on is not indexed\n");
1163 return DB_INDEX_ERROR;
1171 for(i = 1; i < AQL_ATTRIBUTE_COUNT(adt); i++) {
1172 attribute_name = adt->attributes[i].name;
1173 attr = relation_attribute_get(left_rel, attribute_name);
1175 attr = relation_attribute_get(right_rel, attribute_name);
1177 PRINTF(
"DB: The projection attribute \"%s\" does not exist in any of the relations to join\n",
1179 return DB_RELATIONAL_ERROR;
1183 if(relation_attribute_add(join_rel, dir, attr->name, attr->domain,
1184 attr->element_size) ==
NULL) {
1185 PRINTF(
"DB: Failed to add an attribute to the join relation\n");
1186 return DB_ALLOCATION_ERROR;
1192 return generate_join_result(handle);
1197 relation_cardinality(relation_t *rel)
1199 tuple_id_t tuple_id;
1202 if(rel->cardinality != INVALID_TUPLE) {
1203 return rel->cardinality;
1206 if(!RELATION_HAS_TUPLES(rel)) {
1210 if(DB_ERROR(storage_get_row_amount(rel, &tuple_id))) {
1211 return INVALID_TUPLE;
1214 rel->cardinality = tuple_id;
1216 PRINTF(
"DB: Relation %s has cardinality %lu\n", rel->name,
1217 (
unsigned long)tuple_id);
void * list_pop(list_t list)
Remove the first object on a list.
Linked list manipulation routines.
void memb_init(struct memb *m)
Initialize a memory block that was declared with MEMB().
Definitions and declarations for AQL, the Antelope Query Language.
The storage interface used by the database.
Declarations for the result acquisition API.
char memb_free(struct memb *m, void *ptr)
Deallocate a memory block from a memory block previously declared with MEMB().
void * memb_alloc(struct memb *m)
Allocate a memory block from a block of memory declared with MEMB().
#define NULL
The null pointer.
void list_remove(list_t list, void *item)
Remove a specific element from a list.
Definitions and declarations for the Propositional Logic Engine.
#define TRUE
An alias for one, used for clarity.
Database configuration options.
void list_init(list_t list)
Initialize a list.
void * list_head(list_t list)
Get a pointer to the first element of a list.
#define MEMB(name, structure, num)
Declare a memory block.
void list_add(list_t list, void *item)
Add an item at the end of a list.
#define LIST(name)
Declare a linked list.
#define LIST_STRUCT_INIT(struct_ptr, name)
Initialize a linked list that is part of a structure.
#define FALSE
An alias for zero, used for clarity.
A set of debugging macros.
Memory block allocation routines.
Header file for the CRC16 calculcation