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)
165 for(rel =
list_head(relations); rel != NULL;) {
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)
208 while((attr =
list_pop(rel->attributes)) != NULL) {
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 = LVM_TRUE;
817 if(AQL_GET_FLAGS(adt) & AQL_FLAG_INVERSE_LOGIC) {
818 wanted_result = LVM_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);
#define LIST_STRUCT_INIT(struct_ptr, name)
Initialize a linked list that is part of a structure.
int memb_free(struct memb *m, void *ptr)
Deallocate a memory block from a memory block previously declared with MEMB().
Header file for the CRC16 calculcation
A set of debugging macros for the IP stack
Definitions and declarations for AQL, the Antelope Query Language.
Declarations for the result acquisition API.
Linked list manipulation routines.
void * list_head(list_t list)
Get a pointer to the first element of a list.
The storage interface used by the database.
Database configuration options.
Memory block allocation routines.
Definitions and declarations for the Propositional Logic Engine.
void list_add(list_t list, void *item)
Add an item at the end of a list.
void list_init(list_t list)
Initialize a list.
#define LIST(name)
Declare a linked list.
void * memb_alloc(struct memb *m)
Allocate a memory block from a block of memory declared with MEMB().
void * list_pop(list_t list)
Remove the first object on a list.
void memb_init(struct memb *m)
Initialize a memory block that was declared with MEMB().
void list_remove(list_t list, void *item)
Remove a specific element from a list.
#define MEMB(name, structure, num)
Declare a memory block.