├── .gitignore ├── LICENSE ├── Makefile ├── NOTICE ├── README.md ├── arduino └── sketch.ino ├── doc └── doxygen │ └── Doxyfile └── src ├── arduinodebug.cpp ├── arduinodebug.h ├── db_ctconf.h ├── db_types.h ├── dberror.h ├── dbindex ├── dbindex.c ├── dbindex.h └── dbindex_types.h ├── dblogic ├── compare_tuple.c ├── compare_tuple.h ├── db_aggr_func_codes.h ├── eet.c └── eet.h ├── dbmacros.h ├── dbmm ├── db_query_mm.c └── db_query_mm.h ├── dbobjects ├── relation.c ├── relation.h ├── tuple.c └── tuple.h ├── dbops ├── aggregate.c ├── aggregate.h ├── db_ops.c ├── db_ops.h ├── db_ops_types.h ├── ntjoin.c ├── ntjoin.h ├── osijoin.c ├── osijoin.h ├── project.c ├── project.h ├── scan.c ├── scan.h ├── select.c ├── select.h ├── sort.c └── sort.h ├── dboutput ├── query_output.c └── query_output.h ├── dbparser ├── dbcreate.c ├── dbcreate.h ├── dbinsert.c ├── dbinsert.h ├── dblexer.c ├── dblexer.h ├── dbparseexpr.c ├── dbparseexpr.h ├── dbparser.c └── dbparser.h ├── dbstorage ├── SD_c_iface.cpp ├── SD_c_iface.h ├── dbstorage.c └── dbstorage.h ├── include └── debug.h ├── mainpage.h ├── pstdint.h ├── ref.h ├── unit_tests ├── CuTest.c ├── CuTest.h ├── aggregate │ ├── aggregate_ut.c │ └── run_aggregate_ut.c ├── db_query_mm │ ├── db_query_mm_ut.c │ └── run_db_query_mm_ut.c ├── dbcreate │ ├── dbcreate_ut.c │ └── run_dbcreate_ut.c ├── dbinsert │ ├── dbinsert_ut.c │ └── run_dbinsert_ut.c ├── dblexer │ ├── dblexer_ut.c │ └── run_dblexer_ut.c ├── dbparseexpr │ ├── dbparseexpr_ut.c │ └── run_dbparseexpr_ut.c ├── dbparser │ ├── dbparser_ut.c │ └── run_dbparser_ut.c ├── eet │ ├── eet_ut.c │ └── run_eet_ut.c ├── ntjoin │ ├── ntjoin_ut.c │ └── run_ntjoin_ut.c ├── osijoin │ ├── osijoin_ut.c │ └── run_osijoin_ut.c ├── project │ ├── project_ut.c │ └── run_project_ut.c ├── runalltests.c ├── scan │ ├── run_scan_ut.c │ └── scan_ut.c ├── select │ ├── run_select_ut.c │ └── select_ut.c └── sort │ ├── run_sort_ut.c │ └── sort_ut.c └── utils ├── cfs_init_test_relations.c ├── cfs_init_test_relations.h ├── gen_bench_relations.c ├── gen_bench_relations.h ├── gen_test_indexes.c └── gen_test_relations.c /.gitignore: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Author: Graeme Douglas 3 | # Things for git to ignore. 4 | # 5 | ############################################################################### 6 | 7 | ## All binary directories 8 | bin/ 9 | 10 | ## In general, ignore html/latex folders in doxygen directory. 11 | doc/doxygen/html 12 | doc/doxygen/latex 13 | 14 | ## Ignore contikified directory. 15 | contikify 16 | 17 | ## Ignore annoying eclipse files for those of us that use such software. 18 | .settings 19 | .project 20 | 21 | ## Ignore contiki example dir, except what I force add. 22 | contiki_ex 23 | 24 | ## General Files 25 | # Compiled files 26 | *~ 27 | *.com 28 | *class 29 | *.dll 30 | *.exe 31 | *.so 32 | *.o 33 | 34 | # Annoying OS files 35 | .DS_Store* 36 | Icon? 37 | ethumbs.db 38 | Thumbs.db 39 | *bak 40 | 41 | # Annoying vim files 42 | *.swp 43 | *.swo 44 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Copyright 2013 Graeme Douglas 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | 15 | Files provided under other licenses: 16 | -pstdint.h is written by Paul Hsieh and is licensed under the three-clause 17 | BSD license. See src/pstdint.h for the license. 18 | -CuTest.h and CuTest.c are written by Asim Jalis and are provided 19 | under the ZLib-Libpng license, and is provided at 20 | http://zlib.net/zlib_license.html 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | LittleD 2 | ======= 3 | 4 | Hi there! You may be interested in a sister project, [IonDB - A key-value store for embedded devices](https://github.com/iondbproject/iondb). 5 | 6 | "What is this?" 7 | --------------- 8 | 9 | LittleD is a relational database for microprocessor devices, using as little 10 | as 1kB of RAM for most queries. LittleD supports 11 | SELECT-FROM-WHERE syntax, including inner joins, projections, and selections 12 | over arbitrary expressions. LittleD also has support for CREATE TABLE and 13 | INSERT statements. Only integers and fixed-width strings are supported 14 | at this time. In the future, query pre-compilation, network transmission, 15 | network relational operators, aggregation, and improved indexing 16 | are hoped to be implemented. 17 | 18 | If you are interested in the design of LittleD, you might want to check out 19 | my published research: [here](http://dl.acm.org/citation.cfm?id=2554891) or 20 | [here](https://people.ok.ubc.ca/rlawrenc/research/Papers/LittleD.pdf). 21 | 22 | Show me some code! 23 | ------------------ 24 | 25 | Sure! 26 | 27 | ```c 28 | #include "Littled/dbparser/dbparser.h" 29 | 30 | #define BYTES_LEN 400 31 | 32 | int main(void) 33 | { 34 | char memseg[BYTES_LEN]; 35 | db_query_mm_t mm; 36 | db_op_base_t* root; 37 | db_tuple_t tuple; 38 | 39 | init_query_mm(&mm, memseg, BYTES_LEN); 40 | parse("CREATE TABLE sensors (id int, temp int);", &mm); 41 | 42 | init_query_mm(&mm, memseg, BYTES_LEN); 43 | parse("INSERT INTO sensors VALUES (1, 221);", &mm); 44 | init_query_mm(&mm, memseg, BYTES_LEN); 45 | parse("INSERT INTO sensors VALUES (2, 89884);", &mm); 46 | init_query_mm(&mm, memseg, BYTES_LEN); 47 | parse("INSERT INTO sensors VALUES (3, 112);", &mm); 48 | init_query_mm(&mm, memseg, BYTES_LEN); 49 | parse("INSERT INTO sensors VALUES (4, 455);", &mm); 50 | init_query_mm(&mm, memseg, BYTES_LEN); 51 | parse("INSERT INTO sensors VALUES (5, 3313);", &mm); 52 | init_query_mm(&mm, memseg, BYTES_LEN); 53 | parse("INSERT INTO sensors VALUES (6, 11);", &mm); 54 | init_query_mm(&mm, memseg, BYTES_LEN); 55 | parse("INSERT INTO sensors VALUES (7, 99996);", &mm); 56 | init_query_mm(&mm, memseg, BYTES_LEN); 57 | parse("INSERT INTO sensors VALUES (8, 6565);", &mm); 58 | init_query_mm(&mm, memseg, BYTES_LEN); 59 | parse("INSERT INTO sensors VALUES (9, 6565);", &mm); 60 | 61 | init_query_mm(&mm, memseg, BYTES_LEN); 62 | root = parse("SELECT * FROM sensors;", &mm); 63 | if (root == NULL) 64 | { 65 | printf("NULL root\n"); 66 | } 67 | else 68 | { 69 | init_tuple(&tuple, root->header->tuple_size, root->header->num_attr, &mm); 70 | 71 | while (next(root, &tuple, &mm) == 1) 72 | { 73 | int id = getintbyname(&tuple, "id", root->header); 74 | int sensor_val = getintbyname(&tuple, "temp", root->header);; 75 | printf("sensor val: %i (%i)\n", sensor_val, id); 76 | } 77 | } 78 | 79 | return 0; 80 | } 81 | ``` 82 | 83 | Detailed Summary 84 | ---------------- 85 | 86 | LittleD provides a SQL frontend to manage data under the relational model. 87 | This project targets devices of about the same capabilities as the Arduino 88 | Mega2560. In a nutshell, the system supports the creation of tables, 89 | data insertion, and SELECT-FROM-WHERE syntax. Error messages are 90 | supported but not mandatory. A simple configuration header file dictates 91 | which features are compiled in so the database's codespace footprint 92 | can be controlled according to application needs. All code except 93 | that needed to interface with Arduinos is written in C. 94 | 95 | This project is part of ongoing research being conducted at the 96 | University of British Columbia's Okanagan Campus under the direction 97 | of Dr. Ramon Lawrence. The work has been supported by Dr. Lawrence's 98 | Distributed Data Lab, the Irving K. Barber School of Arts and Sciences, 99 | the Natural Sciences and Engineering Research Council of Canada, 100 | along with a list of people too numerous to name. 101 | 102 | Building Instructions 103 | --------------------- 104 | 105 | To simply build the database locally, in your shell of choice navigate 106 | to the repository root and execute the command 107 | 108 | make 109 | 110 | To build the unit tests, issue the command 111 | 112 | make tests 113 | 114 | and navigate to the _bin/tests_ directory within the repository's root 115 | directory. You may run all tests by 116 | 117 | ./runalltests 118 | 119 | Single tests are included in the same directory. The documentation 120 | can be generated using 121 | 122 | make docs 123 | 124 | and reside in the _doc/doxygen_ directory. Note that doxygen must be installed 125 | for the documentation to be generated. Finally, 126 | 127 | make clean 128 | 129 | deletes all files created at compile time. 130 | 131 | Eclipse Setup 132 | ------------- 133 | 134 | LittleD can be managed using an Eclipse Makefile project. 135 | Either the packaged C/C++ Eclipse IDE or the installable CDT package 136 | must be used. 137 | 138 | First make sure that the repository is cloned. 139 | In Eclipse click **File** -> **Import...**. Within the **Select** window, choose 140 | under **C/C++** the **Existing Code as Makefile Project** option and click 141 | **Next**. Give your Eclipse Project a name and browse to the root of the 142 | project repository to use the code. Choose the correct compiler for your 143 | system and then click **Finish**. 144 | 145 | As noted above, there are a small number of make targets that can be used 146 | with the project's Makefile. By right clicking the project in the 147 | **Package Explorer** and selecting **Make Targets** -> **Create...**. Leaving 148 | all options at the their default, enter the name of the target to add 149 | (for instance, _tests_) and then click **OK**. You can then run the Make target 150 | by right clicking on the project in the **Project Explorer** and choosing 151 | **Make Targets** -> **Build...**. Select the target from the list that appears 152 | and click **Build**. Finally, you can run individual files with main methods 153 | by opening them and click the green **Run** button at the top. 154 | 155 | Can I contribute? 156 | ----------------- 157 | 158 | Absolutely! Contributions are welcome! Please make pull requests off the master 159 | branch. 160 | -------------------------------------------------------------------------------- /arduino/sketch.ino: -------------------------------------------------------------------------------- 1 | /** 2 | @author Graeme Douglas 3 | @brief 4 | @details 5 | @copyright Copyright 2013 Graeme Douglas 6 | @license Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | @par 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 15 | either express or implied. See the License for the specific 16 | language governing permissions and limitations under the 17 | License. 18 | */ 19 | 20 | #include "SD.h" 21 | #include "littled/arduinodebug.h" 22 | #include "littled/dbparser/dbparser.h" 23 | #include "littled/dbstorage/SD_c_iface.h" 24 | #include "littled/dboutput/query_output.h" 25 | #include "littled/utils/gen_bench_relations.h" 26 | 27 | //File myFile; 28 | 29 | int my_putc( char c, FILE *t) { 30 | Serial.write( c ); 31 | } 32 | 33 | int printfilechars(char *relationname) 34 | { 35 | Serial.println("PRINT FILE CONTENTS\n"); 36 | Serial.flush(); 37 | db_fileref_t toPrint; 38 | unsigned char buffer = 0; 39 | 40 | if (toPrint = db_openreadfile(relationname)) 41 | { 42 | int readsize = 1*sizeof(char); 43 | while (db_fileread(toPrint, &buffer, readsize) == readsize) 44 | { 45 | Serial.println(buffer, HEX); 46 | //printf("0x%x : %c\n", (int)(buffer), (char)buffer); 47 | buffer = 0; 48 | } 49 | db_fileclose(toPrint); 50 | return 0; 51 | } 52 | return -1; 53 | } 54 | 55 | void setup() 56 | { 57 | Serial.begin(9600); 58 | Serial.flush(); 59 | while (!Serial) { 60 | ; 61 | } 62 | // Use pin 10 for Uno, 53 for mega 63 | //pinMode(10, OUTPUT); 64 | pinMode(53, OUTPUT); 65 | if (!SD.begin(4)) 66 | { 67 | Serial.println("sd init failed!"); 68 | Serial.flush(); 69 | return; 70 | } 71 | //fdevopen(&my_putc, 0); // Uncomment this for printf! 72 | Serial.println("initialization done."); 73 | Serial.flush(); 74 | 75 | Serial.println("BEGIN\n"); 76 | Serial.flush(); 77 | 78 | /* 79 | db_fileref_t tempf = db_openwritefile("t"); 80 | unsigned char buf = 1; 81 | while (buf < 10) 82 | { 83 | db_filewrite(tempf, &buf, 1); 84 | buf++; 85 | } 86 | db_fileclose(tempf); 87 | printfilechars("t"); 88 | db_fileremove("t"); 89 | 90 | ad_printstr("asdfghj"); 91 | ad_printint(10); 92 | ad_printint_hex(15); 93 | ad_printint_bin(3); 94 | ad_printchar('g'); 95 | */ 96 | 97 | Serial.println("Init relation"); 98 | Serial.flush(); 99 | // name, numattr, numtuples, bound, seed, type. 100 | gen_bench_relation("r", 2, 5, 30, 2003, 1); 101 | //printfilechars("r"); 102 | 103 | Serial.println("Init query data"); 104 | Serial.flush(); 105 | int size = 1000; 106 | unsigned char memseg[size]; 107 | db_query_mm_t mm; 108 | init_query_mm(&mm, memseg, size); 109 | char command[] = "SELECT * FROM r;"; 110 | Serial.println("Parse query"); 111 | Serial.flush(); 112 | db_op_base_t *rootp = parse(command, &mm); 113 | Serial.println("Init tuple"); 114 | Serial.flush(); 115 | db_tuple_t tuple; 116 | init_tuple(&tuple, rootp->header->tuple_size, rootp->header->num_attr, &mm); 117 | int count = 0; 118 | Serial.println("Execute query"); 119 | Serial.flush(); 120 | #if 1 121 | while(1==next(rootp, &tuple, &mm)) 122 | { 123 | count++; 124 | Serial.flush(); 125 | } 126 | #endif 127 | #if 0 128 | char *output = formatQuery(rootp, &mm); 129 | Serial.println(output); 130 | Serial.flush(); 131 | free(output); 132 | #endif 133 | Serial.println(count); 134 | 135 | /* 136 | //printQuery(rootp, &mm); 137 | */ 138 | 139 | Serial.println("\nEND"); 140 | Serial.flush(); 141 | 142 | 143 | 144 | 145 | /* 146 | 147 | if (SD.exists("example.txt")) { 148 | Serial.println("example.txt exists."); 149 | } 150 | else { 151 | Serial.println("example.txt doesn't exist."); 152 | } 153 | 154 | // open a new file and immediately close it: 155 | Serial.println("Creating example.txt..."); 156 | myFile = SD.open("example.txt", FILE_WRITE); 157 | myFile.close(); 158 | 159 | // Check to see if the file exists: 160 | if (SD.exists("example.txt")) { 161 | Serial.println("example.txt exists."); 162 | } 163 | else { 164 | Serial.println("example.txt doesn't exist."); 165 | } 166 | 167 | // delete the file: 168 | Serial.println("Removing example.txt..."); 169 | SD.remove("example.txt"); 170 | 171 | if (SD.exists("example.txt")){ 172 | Serial.println("example.txt exists."); 173 | } 174 | else { 175 | Serial.println("example.txt doesn't exist."); 176 | } 177 | */ 178 | } 179 | 180 | void loop() 181 | { 182 | /* 183 | while (1) { 184 | ; 185 | } 186 | */ 187 | } 188 | -------------------------------------------------------------------------------- /src/arduinodebug.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @file arduinodebug.cpp 4 | @author Graeme Douglas 5 | @brief C++ code for debug messages on Arduino platform. 6 | @see For more information, please refer to @ref arduinodebug.h 7 | @copyright Copyright 2013 Graeme Douglas 8 | @license Licensed under the Apache License, Version 2.0 (the "License"); 9 | you may not use this file except in compliance with the License. 10 | You may obtain a copy of the License at 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | @par 14 | Unless required by applicable law or agreed to in writing, 15 | software distributed under the License is distributed on an 16 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 17 | either express or implied. See the License for the specific 18 | language governing permissions and limitations under the 19 | License. 20 | */ 21 | /******************************************************************************/ 22 | 23 | #include "arduinodebug.h" 24 | 25 | void ad_printstr(char *str) 26 | { 27 | Serial.println(str); 28 | Serial.flush(); 29 | } 30 | 31 | void ad_printint(int i) 32 | { 33 | Serial.println(i); 34 | Serial.flush(); 35 | } 36 | 37 | void ad_printint_hex(int i) 38 | { 39 | Serial.println(i, HEX); 40 | Serial.flush(); 41 | } 42 | 43 | void ad_printint_bin(int i) 44 | { 45 | Serial.println(i, BIN); 46 | Serial.flush(); 47 | } 48 | 49 | void ad_printchar(char c) 50 | { 51 | Serial.println(c); 52 | Serial.flush(); 53 | } 54 | -------------------------------------------------------------------------------- /src/arduinodebug.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @file arduinodebug.h 4 | @author Graeme Douglas 5 | @brief Header containing arduino debug message code. 6 | @details 7 | @copyright Copyright 2013 Graeme Douglas 8 | @license Licensed under the Apache License, Version 2.0 (the "License"); 9 | you may not use this file except in compliance with the License. 10 | You may obtain a copy of the License at 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | @par 14 | Unless required by applicable law or agreed to in writing, 15 | software distributed under the License is distributed on an 16 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 17 | either express or implied. See the License for the specific 18 | language governing permissions and limitations under the 19 | License. 20 | */ 21 | /******************************************************************************/ 22 | #ifndef ARDUINODEBUG_H 23 | #define ARDUINODEBUG_H 24 | 25 | #include 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | /** 32 | @brief Print a string. 33 | @param str The array of characters to be printed. 34 | */ 35 | void ad_printstr(char *str); 36 | 37 | /** 38 | @brief Print an int in decimal format. 39 | @param i The integer to be printed. 40 | */ 41 | void ad_printint(int i); 42 | 43 | /** 44 | @brief Print an int in hexadecimal format. 45 | @param i The integer to be printed. 46 | */ 47 | void ad_printint_hex(int i); 48 | 49 | /** 50 | @brief Print an int in binary format. 51 | @param i The integer to be printed. 52 | */ 53 | void ad_printint_bin(int i); 54 | 55 | /** 56 | @brief Print a character. 57 | @param i The integer to be printed. 58 | */ 59 | void ad_printchar(char c); 60 | 61 | #ifdef __cplusplus 62 | } 63 | #endif 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /src/db_ctconf.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @file db_ctconf.h 4 | @author Graeme Douglas 5 | @brief Compile time options for the database. 6 | @details Certain features for the database need to be "mixed in" at 7 | compile time. For instance, it would be beneficial to only 8 | use features that are needed for a given platform or 9 | application, to reduce binary size, and make includes a whole 10 | bunch cleaner. This is the file that controls all of that, and 11 | must be configured _BEFORE_ compiling the database. 12 | @copyright Copyright 2013 Graeme Douglas 13 | @license Licensed under the Apache License, Version 2.0 (the "License"); 14 | you may not use this file except in compliance with the License. 15 | You may obtain a copy of the License at 16 | http://www.apache.org/licenses/LICENSE-2.0 17 | 18 | @par 19 | Unless required by applicable law or agreed to in writing, 20 | software distributed under the License is distributed on an 21 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 22 | either express or implied. See the License for the specific 23 | language governing permissions and limitations under the 24 | License. 25 | */ 26 | /******************************************************************************/ 27 | 28 | #ifndef DB_CTCONF_H 29 | #define DB_CTCONF_H 30 | 31 | /**** Configuration Options. ****/ 32 | /******************************************************************************/ 33 | /*** Options for target platform. ***/ 34 | /* Option to compile for standard platform (average PC). */ 35 | /** 36 | @def DB_CTCONF_OPTION_TARGET_STD 37 | @brief Standard build target platform. 38 | @details The standard target platform. Should be used for compiling on 39 | the average workstation/PC. 40 | */ 41 | #ifndef DB_CTCONF_OPTION_TARGET_STD 42 | #define DB_CTCONF_OPTION_TARGET_STD 0 43 | #endif 44 | 45 | /* Option to compile for CONTIKI OS. */ 46 | /** 47 | @def DB_CTCONF_OPTION_TARGET_CONTIKI 48 | @brief Build target is Contiki OS. 49 | @details Build the database to run on Contiki OS. This mostly means 50 | using CFS-based scan operator instead of binary-file scan. 51 | */ 52 | #ifndef DB_CTCONF_OPTION_TARGET_CONTIKI 53 | #define DB_CTCONF_OPTION_TARGET_CONTIKI 1 54 | #endif 55 | 56 | /* Option to compile for ARDUINO. */ 57 | /** 58 | @def DB_CTCONF_OPTION_TARGET_ARDUINO 59 | @brief Build target is Arduino. 60 | @details Build the database to run on Arduino. This means linking 61 | into the SD.h library to manipulate files. 62 | */ 63 | #ifndef DB_CTCONF_OPTION_TARGET_ARDUINO 64 | #define DB_CTCONF_OPTION_TARGET_ARDUINO 2 65 | #endif 66 | /******************************************************************************/ 67 | 68 | /**** Configuration Settings. ****/ 69 | /******************************************************************************/ 70 | /*** Target Setting. ***/ 71 | /** 72 | @def DB_CTCONF_SETTING_TARGET 73 | @brief Setting determining which platform to compile for. 74 | @details This setting must be set to one of the options under the 75 | namespace DB_CTCONF_OPTION_TARGET_. 76 | */ 77 | #ifndef DB_CTCONF_SETTING_TARGET 78 | #define DB_CTCONF_SETTING_TARGET DB_CTCONF_OPTION_TARGET_STD 79 | #endif 80 | 81 | /*** Feature settings. ***/ 82 | /* Option to enable aggregates. */ 83 | /** 84 | @def DB_CTCONF_SETTING_FEATURE_AGGREGATION 85 | @brief If @c 1, include aggregates in the database. Otherwise, don't. 86 | @details Use this flag to remove the aggregation feature from the 87 | database. 88 | */ 89 | #ifndef DB_CTCONF_SETTING_FEATURE_AGGREGATION 90 | #define DB_CTCONF_SETTING_FEATURE_AGGREGATION 0 91 | #endif 92 | 93 | /* Option to enable aggregates. */ 94 | /** 95 | @def DB_CTCONF_SETTING_FEATURE_SORT 96 | @brief If @c 1, include aggregates in the database. Otherwise, don't. 97 | @details Use this flag to remove the aggregation feature from the 98 | database. 99 | */ 100 | #ifndef DB_CTCONF_SETTING_FEATURE_SORT 101 | #define DB_CTCONF_SETTING_FEATURE_SORT 0 102 | #endif 103 | 104 | /** 105 | @brief If @c 1, support CREATE TABLE statements. 106 | */ 107 | #ifndef DB_CTCONF_SETTING_FEATURE_CREATE_TABLE 108 | #define DB_CTCONF_SETTING_FEATURE_CREATE_TABLE 1 109 | #endif 110 | 111 | /** 112 | @brief If this is equal to @c 1, error messages will be displayed 113 | appropriately. 114 | */ 115 | #ifndef DB_CTCONF_SETTING_FEATURE_ERROR_MESSAGES 116 | #define DB_CTCONF_SETTING_FEATURE_ERROR_MESSAGES 1 117 | #endif 118 | 119 | /** 120 | @brief If this is equal to @c 1, maximum amount of memory used during 121 | a query will be profiled. 122 | */ 123 | #ifndef DB_CTCONF_PROFILE_MAXMEM 124 | #define DB_CTCONF_PROFILE_MAXMEM 1 125 | #endif 126 | 127 | /** 128 | @brief The maximum length of a string atttibute (not including the 129 | null-byte). 130 | */ 131 | #ifndef DB_CTCONF_SETTING_MAXSTRINGLENGTH 132 | #define DB_CTCONF_SETTING_MAXSTRINGLENGTH 200 133 | #endif 134 | /******************************************************************************/ 135 | 136 | #endif 137 | -------------------------------------------------------------------------------- /src/db_types.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @file db_types.h 4 | @author Graeme Douglas 5 | @brief Header file containing type information to be used throughout 6 | the database. 7 | @details This file relies on pstdint.h for definitions of 8, 16, and 8 | 32 bit integers, except for certain target platforms. 9 | @copyright Copyright 2013 Graeme Douglas 10 | @license Licensed under the Apache License, Version 2.0 (the "License"); 11 | you may not use this file except in compliance with the License. 12 | You may obtain a copy of the License at 13 | http://www.apache.org/licenses/LICENSE-2.0 14 | 15 | @par 16 | Unless required by applicable law or agreed to in writing, 17 | software distributed under the License is distributed on an 18 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 19 | either express or implied. See the License for the specific 20 | language governing permissions and limitations under the 21 | License. 22 | */ 23 | /******************************************************************************/ 24 | 25 | #ifndef DB_TYPES_H 26 | #define DB_TYPES_H 27 | 28 | #include "db_ctconf.h" 29 | #ifdef DB_CTCONF_SETTING_TARGET 30 | #if DB_CTCONF_SETTING_TARGET == DB_CTCONF_OPTION_TARGET_CONTIKI 31 | #include 32 | #elif DB_CTCONF_SETTING_TARGET == DB_CTCONF_OPTION_TARGET_ARDUINO 33 | #include 34 | #elif defined GNUC || defined __llvm__ || defined __clang__ 35 | #include 36 | #else 37 | #include "pstdint.h" 38 | #endif 39 | #else 40 | #error "CONFIGURATION FILE MUST HAVE DB_CTCONF_SETTING_TARGET DEFINED!" 41 | #endif 42 | 43 | /*** Fixed sized integers. ***/ 44 | /* 1 byte signed integers. */ 45 | /** 46 | @brief One byte signed integer. 47 | */ 48 | typedef int8_t db_int8; 49 | 50 | /** 51 | @brief Maxmimum value for a one-byte signed integer. 52 | */ 53 | #ifndef DB_INT8_MAX 54 | #define DB_INT8_MAX 0x7F 55 | #endif 56 | 57 | /** 58 | @brief Minimum value for a one-byte signed integer. 59 | */ 60 | #ifndef DB_INT8_MIN 61 | #define DB_INT8_MIN 0x80 62 | #endif 63 | 64 | 65 | /* 2 byte signed integers. */ 66 | /** 67 | @brief Two byte signed integer. 68 | */ 69 | typedef int16_t db_int16; 70 | 71 | /** 72 | @brief Maxmimum value for a two-byte signed integer. 73 | */ 74 | #ifndef DB_INT16_MAX 75 | #define DB_INT16_MAX 0x7FFF 76 | #endif 77 | 78 | /** 79 | @brief Minimum value for a two-byte signed integer. 80 | */ 81 | #ifndef DB_INT16_MIN 82 | #define DB_INT16_MIN 0x8000 83 | #endif 84 | 85 | 86 | /* 4 byte signed integers. */ 87 | /** 88 | @brief Four byte signed integer. 89 | */ 90 | typedef int32_t db_int32; 91 | 92 | /** 93 | @brief Maxmimum value for a four-byte signed integer. 94 | */ 95 | #ifndef DB_INT32_MAX 96 | #define DB_INT32_MAX 0x7FFFFFFF 97 | #endif 98 | 99 | /** 100 | @brief Minimum value for a four-byte signed integer. 101 | */ 102 | #ifndef DB_INT32_MIN 103 | #define DB_INT32_MIN 0x80000000 104 | #endif 105 | 106 | 107 | /* 1 byte unsgined integers. */ 108 | /** 109 | @brief One byte unsigned integer. 110 | */ 111 | typedef uint8_t db_uint8; 112 | 113 | /** 114 | @brief Maxmimum value for a one-byte unsigned integer. 115 | */ 116 | #ifndef DB_UINT8_MAX 117 | #define DB_UINT8_MAX 0xFF 118 | #endif 119 | 120 | /** 121 | @brief Minimum value for a one-byte unsigned integer. 122 | */ 123 | #ifndef DB_UINT8_MIN 124 | #define DB_UINT8_MIN 0x00 125 | #endif 126 | 127 | 128 | /* 2 byte unsgined integers. */ 129 | /** 130 | @brief Two byte unsigned integer. 131 | */ 132 | typedef uint16_t db_uint16; 133 | 134 | /** 135 | @brief Maxmimum value for a two-byte unsigned integer. 136 | */ 137 | #ifndef DB_UINT16_MAX 138 | #define DB_UINT16_MAX 0xFFFF 139 | #endif 140 | 141 | /** 142 | @brief Minimum value for a two-byte unsigned integer. 143 | */ 144 | #ifndef DB_UINT16_MIN 145 | #define DB_UINT16_MIN 0x0000 146 | #endif 147 | 148 | 149 | /* 4 byte unsgined integers. */ 150 | /** 151 | @brief Four byte unsigned integer. 152 | */ 153 | typedef uint32_t db_uint32; 154 | 155 | /** 156 | @brief Maxmimum value for a four-byte unsigned integer. 157 | */ 158 | #ifndef DB_UINT32_MAX 159 | #define DB_UINT32_MAX 0xFFFFFFFF 160 | #endif 161 | 162 | /** 163 | @brief Minimum value for a two-byte unsigned integer. 164 | */ 165 | #ifndef DB_UINT32_MIN 166 | #define DB_UINT32_MIN 0x00000000 167 | #endif 168 | 169 | 170 | /*** Variable sized integers. ***/ 171 | /* The general db_int type. The size of this type is allowed to change with 172 | * the size of integers on the target system. */ 173 | /** 174 | @brief Variably sized signed integer. 175 | */ 176 | typedef int db_int; 177 | 178 | /** 179 | @brief Maximum value for platform specific integer. 180 | */ 181 | #ifndef DB_INT_MAX 182 | #if INT_MAX == 0x7F 183 | # define DB_INT_MAX 0x7F 184 | #elif INT_MAX == 0x7FFF 185 | # define DB_INT_MAX 0x7FFF 186 | #elif INT_MAX == 0x7FFFFFFF 187 | # define DB_INT_MAX 0x7FFFFFFF 188 | #else 189 | #ifdef _PSTDINT_H_INCLUDED 190 | # error "Integer size unsupported" 191 | #else 192 | # define DB_INT_MAX INT_MAX 193 | #endif 194 | #endif 195 | #endif 196 | 197 | /** 198 | @brief Minimum value for platform-specific integer. 199 | */ 200 | #ifndef DB_INT_MIN 201 | #if INT_MAX == 0x7F 202 | # define DB_INT_MIN 0x80 203 | #elif INT_MAX == 0x7FFF 204 | # define DB_INT_MIN 0x8000 205 | #elif INT_MAX == 0x7FFFFFFF 206 | # define DB_INT_MIN 0x80000000 207 | #else 208 | #ifdef _PSTDINT_H_INCLUDED 209 | # error "Integer size unsupported" 210 | #else 211 | # define DB_INT_MIN INT_MIN 212 | #endif 213 | #endif 214 | #endif 215 | /* A note about database strings 216 | ** I find it totally unecessary to define database strings on several grounds. 217 | ** char's are entirely universal. Secondly, strings in C are really character 218 | ** arrays / pointers, so typedef'ing any string will inevitably lead to 219 | ** array size confusion. 220 | */ 221 | 222 | #endif 223 | -------------------------------------------------------------------------------- /src/dberror.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @author Graeme Douglas 4 | @file dberror.h 5 | @brief A file containing macro definitions for error reporting. 6 | @details 7 | @copyright Copyright 2013 Graeme Douglas 8 | @license Licensed under the Apache License, Version 2.0 (the "License"); 9 | you may not use this file except in compliance with the License. 10 | You may obtain a copy of the License at 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | @par 14 | Unless required by applicable law or agreed to in writing, 15 | software distributed under the License is distributed on an 16 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 17 | either express or implied. See the License for the specific 18 | language governing permissions and limitations under the 19 | License. 20 | */ 21 | /******************************************************************************/ 22 | 23 | #ifndef DBERROR_H 24 | #define DBERROR_H 25 | 26 | #include "db_ctconf.h" 27 | 28 | /** 29 | @brief Print error message. 30 | @param message The error to print. 31 | @param offset The offset of the token or character that lead 32 | to the error. 33 | @param command The command that caused the error. 34 | */ 35 | #ifndef DB_ERROR_MESSAGE 36 | #if defined(DB_CTCONF_SETTING_FEATURE_ERROR_MESSAGES) && 0!=DB_CTCONF_SETTING_FEATURE_ERROR_MESSAGES 37 | #define DB_ERROR_MESSAGE(message, offset, command) \ 38 | do { \ 39 | printf("ERROR AT COLUMN %d OF \"%s\":\n\t%s\n", (offset), (command), (message)); \ 40 | } while(0) 41 | #else 42 | #define DB_ERROR_MESSAGE(message, offset, command) 43 | #endif 44 | #else 45 | #error "MACRO NAME CLASH ON DB_ERROR_MESSAGE!" 46 | #endif 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /src/dbindex/dbindex.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @file dbindex.c 4 | @author Graeme Douglas 5 | @brief A generic relation index interface. 6 | @see For more information, please refer to @ref dbindex.h and 7 | @ref dbindex_types.h. 8 | @details 9 | @copyright Copyright 2013 Graeme Douglas 10 | @license Licensed under the Apache License, Version 2.0 (the "License"); 11 | you may not use this file except in compliance with the License. 12 | You may obtain a copy of the License at 13 | http://www.apache.org/licenses/LICENSE-2.0 14 | 15 | @par 16 | Unless required by applicable law or agreed to in writing, 17 | software distributed under the License is distributed on an 18 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 19 | either express or implied. See the License for the specific 20 | language governing permissions and limitations under the 21 | License. 22 | */ 23 | /******************************************************************************/ 24 | 25 | #include "dbindex.h" 26 | 27 | db_int init_index(db_index_t *indexp, char *name) 28 | { 29 | /* Prepare for ugly. */ 30 | char realname[8 + strlen(name)]; 31 | sprintf(realname, "DB_IDX_%s", name); 32 | 33 | indexp->indexref = db_openreadfile(realname); 34 | if (DB_STORAGE_NOFILE == indexp->indexref || 1!=db_fileread(indexp->indexref, &(indexp->type), 1)) 35 | { 36 | return 0; 37 | } 38 | 39 | return 1; 40 | } 41 | 42 | db_int close_index(db_index_t *indexp) 43 | { 44 | return db_fileclose(indexp->indexref); 45 | } 46 | 47 | db_int scan_find(scan_t *sp, db_uint8 indexon, db_eet_t *searchfor, 48 | db_tuple_t *comparator_tp, relation_header_t *comparator_hp, 49 | db_query_mm_t *mmp) 50 | { 51 | db_index_offset_t offset = 52 | db_index_getoffset(sp, indexon, 53 | searchfor, 54 | comparator_tp, 55 | comparator_hp, 56 | mmp); 57 | 58 | if (-1 >= offset) 59 | { 60 | return 0; 61 | } 62 | else 63 | { 64 | db_filerewind(sp->relation); 65 | db_fileseek(sp->relation, offset); 66 | return 1; 67 | } 68 | } 69 | 70 | // FIXME: For now, this assumes equality for each of the expressions. 71 | db_index_offset_t db_index_getoffset(scan_t *sp, db_uint8 indexon, 72 | db_eet_t *searchfor, 73 | db_tuple_t *comparator_tp, 74 | relation_header_t *comparator_hp, 75 | db_query_mm_t *mmp) 76 | { 77 | if (sp->idx_meta_data.num_idx <= indexon) 78 | return -1; 79 | 80 | db_index_t index; 81 | if (1!=init_index(&index, sp->idx_meta_data.names[indexon])) 82 | { 83 | return -1; 84 | } 85 | 86 | if (DB_INDEX_TYPE_INLINE == index.type) 87 | { 88 | long first = sp->tuple_start; 89 | size_t total_size = sp->base.header->tuple_size + (sp->base.header->num_attr / 8); 90 | total_size += (sp->base.header->num_attr) % 8 > 0 ? 1 : 0; 91 | long last; 92 | if (sizeof(long)!=db_fileread(index.indexref, (unsigned char*)&(last), sizeof(long))) 93 | { 94 | return -1; 95 | } 96 | if (last > 0) 97 | last = first + (total_size * (last - 1)); 98 | else 99 | last = first; 100 | long imin = 0; 101 | long imax = (last - first) / total_size; 102 | long imid; 103 | 104 | db_uint8 order[sp->idx_meta_data.num_expr[indexon]]; 105 | int result; 106 | for (result = 0; result < sp->idx_meta_data.num_expr[indexon]; ++result) 107 | order[result] = DB_TUPLE_ORDER_ASC; 108 | 109 | db_tuple_t temp; 110 | init_tuple(&temp, sp->base.header->tuple_size, sp->base.header->num_attr, mmp); 111 | rewind_scan(sp, mmp); 112 | 113 | long i = -1; 114 | 115 | /* We binary search on expressions for first occurence. */ 116 | while (imin <= imax) 117 | { 118 | imid = imin + ((imax - imin) / 2); 119 | 120 | db_filerewind(sp->relation); 121 | db_fileseek(sp->relation, (imid*(total_size))+first); 122 | next_scan(sp, &temp, mmp); 123 | 124 | /* arr[imid], key */ 125 | if (NULL == comparator_hp) /* FIXME: quick hack to let indexed scans work. */ 126 | { 127 | result = getintbypos(&temp, ((db_int)searchfor), sp->base.header) - ((db_int)comparator_tp); 128 | } 129 | else 130 | result = cmp_tuple(&temp, comparator_tp, 131 | sp->base.header, comparator_hp, 132 | sp->idx_meta_data.exprs[indexon], 133 | searchfor, 134 | sp->idx_meta_data.num_expr[indexon], 135 | order, 1, mmp); 136 | 137 | if (result < 0) 138 | imin = imid + 1; 139 | else if (result > 0) 140 | imax = imid - 1; 141 | else if (imin != imid) 142 | imax = imid; 143 | else 144 | { 145 | i = imid; 146 | break; 147 | } 148 | 149 | } 150 | 151 | if (i <= -1) i = imin; 152 | i = (first + (i*total_size)); 153 | 154 | db_filerewind(sp->relation); 155 | db_fileseek(sp->relation, i); 156 | next_scan(sp, &temp, mmp); 157 | 158 | /* FIXME: quick hack to let indexed scans work. (first part of the condition) */ 159 | if (NULL != comparator_hp && 0!=cmp_tuple(&temp, comparator_tp, 160 | sp->base.header, comparator_hp, 161 | sp->idx_meta_data.exprs[indexon], 162 | searchfor, 163 | sp->idx_meta_data.num_expr[indexon], 164 | order, 1, mmp)) 165 | i = -1; 166 | 167 | close_tuple(&temp, mmp); 168 | close_index(&index); 169 | 170 | return i; 171 | } 172 | 173 | return -1; 174 | } 175 | -------------------------------------------------------------------------------- /src/dbindex/dbindex.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @file dbindex.h 4 | @author Graeme Douglas 5 | @brief A generic relation index interface. 6 | @details 7 | @copyright Copyright 2013 Graeme Douglas 8 | @license Licensed under the Apache License, Version 2.0 (the "License"); 9 | you may not use this file except in compliance with the License. 10 | You may obtain a copy of the License at 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | @par 14 | Unless required by applicable law or agreed to in writing, 15 | software distributed under the License is distributed on an 16 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 17 | either express or implied. See the License for the specific 18 | language governing permissions and limitations under the 19 | License. 20 | */ 21 | /******************************************************************************/ 22 | 23 | #ifndef DBINDEX_H 24 | #define DBINDEX_H 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | #include "../ref.h" 31 | #include "../dblogic/eet.h" 32 | #include "../dblogic/compare_tuple.h" 33 | #include "dbindex_types.h" 34 | #include "../dbops/db_ops_types.h" 35 | 36 | /** 37 | @brief Database index search modes. 38 | @details Since search routines usually only need to be slightly 39 | modified for various structure operations, we will 40 | maximize code reuse by leveraging search modes. 41 | */ 42 | typedef enum 43 | { 44 | DB_INDEX_SEARCHMODE_EXACT = 0, /**< Find an exact match. */ 45 | DB_INDEX_SEARCHMODE_PREVIOUS = 1, /**< If no exact match can 46 | be found, then we return 47 | the closest predecessor. 48 | */ 49 | DB_INDEX_SEARCHMODE_COUNT /**< The number of elements 50 | in this enumerated type. 51 | */ 52 | } db_index_searchmode_t; 53 | 54 | /** 55 | @brief Database relation index types. 56 | */ 57 | typedef enum 58 | { 59 | DB_INDEX_TYPE_NONE = 0, /**< No index. */ 60 | DB_INDEX_TYPE_INLINE = 1, /**< Inline index (sorted as it comes in). */ 61 | DB_INDEX_TYPE_SKIPLIST, /**< Skip list index. */ 62 | DB_INDEX_TYPE_COUNT /**< Count of all index types. */ 63 | } db_index_type_t; 64 | 65 | /** 66 | @brief The generic index type. 67 | */ 68 | typedef struct db_index 69 | { 70 | db_uint8 type; /**< Type of the index. */ 71 | db_fileref_t indexref; /**< Reference to the file containing 72 | index data. */ 73 | } db_index_t; 74 | 75 | /** 76 | @brief An index offset type. 77 | */ 78 | typedef long db_index_offset_t; 79 | 80 | /** 81 | @brief Find the next tuple from an indexed scan based on another 82 | tuple. 83 | @param sp The indexed scan operator to search. 84 | @param indexon Which index to use. 85 | @param searchfor The expression to search against. 86 | @param comparator_tp A pointer to the tuple to evaluate the 87 | expression over. 88 | @param comparator_hp A pointer to the relation header info for 89 | the relation the tuple pointed at by 90 | @p comparator_tp. 91 | @param mmp A pointer to the memory manager instance being 92 | used to allocate memory for this query. 93 | @returns @c 1 if a tuple is found, @c 0 otherwise. 94 | */ 95 | db_int scan_find(scan_t *sp, 96 | db_uint8 indexon, 97 | db_eet_t *searchfor, 98 | db_tuple_t *comparator_tp, 99 | relation_header_t *comparator_hp, 100 | db_query_mm_t *mmp); 101 | 102 | /** 103 | @brief Find the offset of a tuple in an indexed relation matching the 104 | search criterion. 105 | @param sp The indexed scan operator to search. 106 | @param indexon Which index to use. 107 | @param searchfor The expression to search against. 108 | @param comparator_tp A pointer to the tuple to evaluate the 109 | expression over. 110 | @param comparator_hp A pointer to the relation header info for 111 | the relation the tuple pointed at by 112 | @p comparator_tp. 113 | @param mmp A pointer to the memory manager instance being 114 | used to allocate memory for this query. 115 | @returns @c -1 if no index found, otherwise an integral offset greater 116 | than or equal to @c 0. 117 | */ 118 | db_index_offset_t db_index_getoffset(scan_t *sp, 119 | db_uint8 indexon, 120 | db_eet_t *searchfor, 121 | db_tuple_t *comparator_tp, 122 | relation_header_t *comparator_hp, 123 | db_query_mm_t *mmp); 124 | 125 | #ifdef __cplusplus 126 | } 127 | #endif 128 | 129 | #endif 130 | -------------------------------------------------------------------------------- /src/dbindex/dbindex_types.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @file dbindex_types.h 4 | @author Graeme Douglas 5 | @brief A file storing index types that need to be referenced 6 | in ways that may lead to circular dependencies. 7 | @details 8 | @copyright Copyright 2013 Graeme Douglas 9 | @license Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | 14 | @par 15 | Unless required by applicable law or agreed to in writing, 16 | software distributed under the License is distributed on an 17 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 18 | either express or implied. See the License for the specific 19 | language governing permissions and limitations under the 20 | License. 21 | */ 22 | /******************************************************************************/ 23 | 24 | #ifndef DBINDEX_TYPES_H 25 | #define DBINDEX_TYPES_H 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | /** 32 | @brief In-memory metadata for all indexing information of a 33 | relation. 34 | */ 35 | typedef struct db_index_meta 36 | { 37 | db_uint8 num_idx; /**< Number of indexes belonging to 38 | a relation. */ 39 | db_uint8 *len_names; /**< Length of each index name. */ 40 | char **names; /**< The names of each index. */ 41 | db_uint8 *num_expr; /**< The number of expressions in 42 | each index. */ 43 | db_eet_t **exprs; /**< Array of expressions for each 44 | index. */ 45 | } db_index_meta_t; 46 | 47 | #ifdef __cplusplus 48 | } 49 | #endif 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /src/dblogic/compare_tuple.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @file compare_tuple.h 4 | @author Graeme Douglas 5 | @brief Code to compare and sort tuples absolutely. 6 | @details This code allows us to compare two tuples to determine their 7 | order, assuming they belong to the same relation. It also 8 | provides code needed to do a tuple-at-a-time sort (read: 9 | insertion sort). 10 | @copyright Copyright 2013 Graeme Douglas 11 | @license Licensed under the Apache License, Version 2.0 (the "License"); 12 | you may not use this file except in compliance with the License. 13 | You may obtain a copy of the License at 14 | http://www.apache.org/licenses/LICENSE-2.0 15 | 16 | @par 17 | Unless required by applicable law or agreed to in writing, 18 | software distributed under the License is distributed on an 19 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 20 | either express or implied. See the License for the specific 21 | language governing permissions and limitations under the 22 | License. 23 | @todo Implement better sorting algorithm, perhaps Tyler C's. 24 | */ 25 | /******************************************************************************/ 26 | 27 | #ifndef COMPARE_TUPLE_H 28 | #define COMPARE_TUPLE_H 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | #include 35 | #include "../ref.h" 36 | #include "../dbobjects/relation.h" 37 | #include "../dbobjects/tuple.h" 38 | #include "../dbops/db_ops_types.h" 39 | #include "../dbops/db_ops.h" 40 | #include "eet.h" 41 | 42 | /* Used to determine whether to sort tuples by max or minimum first. */ 43 | /** 44 | @enum db_tupler_order_t 45 | @brief Enumerated values for values for tuple order. 46 | */ 47 | typedef enum 48 | { 49 | DB_TUPLE_ORDER_ASC = 0, /**< The tuples are to be compared 50 | and/or sorted in ascending order. 51 | */ 52 | DB_TUPLE_ORDER_DESC, /**< The tuples are to be compared 53 | and/or sorted in descending order. 54 | */ 55 | DB_TUPLE_ORDER_COUNT /**< The number of values for this 56 | type. */ 57 | } db_tuple_order_t; 58 | 59 | /* Compares two tuples _FROM THE SAME RELATION_ to determine which comes 60 | before the other, in either minimum or maximum order. */ 61 | /** 62 | @brief Compares two tuples of the same relation to determine their 63 | order. 64 | @details This comparison first compares the tuples based on the order 65 | expressions. Then, if the order expressions do not determine 66 | the order of the tuples and strictComp != 1, the tuples' 67 | attributes are used to determine the order, so as to give a 68 | "total ordering". 69 | @param a Pointer to the first tuple to be compared. 70 | @param b Pointer to the second tuple to be compared. 71 | @param hp_a The relation header (schema) for the relation 72 | @p a belongs to. 73 | @param hp_b The relation header (schema) for the relation 74 | @p a belongs to. Set pointer to @p hp_a if 75 | @p b is from the same relation as @p a. 76 | @param order_exprs_a Array of order-determining expressions for 77 | @p a. 78 | @param order_exprs_b Array of order-determining expressions for 79 | @p b. Set pointer to @p order_exprs_a if 80 | @p b is from the same relation as @p a. 81 | @param num_expr The number of elements in @p order_exprs 82 | and @p order. 83 | @param order Array where each element's value is either 84 | @c DB_TUPLE_ORDER_ASC or @c DB_TUPLE_ORDER_DESC. 85 | Element i of this array determines the order 86 | which element i in @p order_exprs is compared 87 | and/or sorted on. 88 | @param strictComp If this value is 1, @p a and @p b are not 89 | compared based on their attributes, but 90 | insttead ONLY compared on @p order_exprs. 91 | Otherwise, @p a and @p b are compared 92 | on their attributes to break a tie. 93 | @param mmp A pointer to the memory manager pointer 94 | used to make memory allocations. 95 | @returns @c -1 if @p a comes before @p b, 0 if @p a is equivalent 96 | to @p b, and @c 1 if @p a comes after @p b. 97 | */ 98 | db_int8 cmp_tuple(db_tuple_t* a, 99 | db_tuple_t* b, 100 | relation_header_t *hp_a, 101 | relation_header_t *hp_b, 102 | db_eet_t *order_exprs_a, 103 | db_eet_t *order_exprs_b, 104 | db_int num_expr, 105 | db_uint8 *order, 106 | db_uint8 strictComp, 107 | db_query_mm_t *mmp); 108 | 109 | /* Return the next tuple in sorted order. */ 110 | /** 111 | @brief Given a previously selected tuple, returns the next sorted 112 | tuple. 113 | @param next_tp Pointer to the tuple variable to place the next 114 | tuple in. 115 | @param previous_tp Pointer to the last tuple returned. If it is 116 | desired to retrieve the first in-order tuple, 117 | this parameter should be set to @c NULL. 118 | @param next_count A pointer to the variable in which to store the 119 | number of tuples that are identical to 120 | @p next_tp. 121 | @param order_exprs Array of order-determining expressions. 122 | @param src_op Pointer to operator that will be providing 123 | tuples to be sorted. It can be thought of 124 | as the relation that is to be sorted. 125 | @param num_expr The number of elements in @p order_exprs 126 | and @p order. 127 | @param order Array where each element's value is either 128 | @c DB_TUPLE_ORDER_ASC or @c DB_TUPLE_ORDER_DESC. 129 | Element i of this array determines the order 130 | which element i in @p order_exprs is compared 131 | and/or sorted on. 132 | @param mmp A pointer to the memory manager pointer 133 | used to make memory allocations. 134 | @returns @c -1 if an error occurs, @c 0 if there are no more tuples 135 | to return, and @c 1 otherwise. 136 | */ 137 | db_int next_inorder_tuple(db_tuple_t *next_tp, 138 | db_tuple_t *previous_tp, 139 | db_int *next_count, 140 | db_op_base_t *src_op, 141 | db_eet_t *order_exprs, 142 | db_uint8 num_expr, 143 | db_uint8 *order, 144 | db_query_mm_t *mmp); 145 | 146 | #ifdef __cplusplus 147 | } 148 | #endif 149 | 150 | #endif 151 | -------------------------------------------------------------------------------- /src/dblogic/db_aggr_func_codes.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @file db_aggr_func_codes.h 4 | @author Graeme Douglas 5 | @brief This file defines aggregate function codes. 6 | @details 7 | @copyright Copyright 2013 Graeme Douglas 8 | @license Licensed under the Apache License, Version 2.0 (the "License"); 9 | you may not use this file except in compliance with the License. 10 | You may obtain a copy of the License at 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | @par 14 | Unless required by applicable law or agreed to in writing, 15 | software distributed under the License is distributed on an 16 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 17 | either express or implied. See the License for the specific 18 | language governing permissions and limitations under the 19 | License. 20 | */ 21 | /******************************************************************************/ 22 | 23 | #ifndef DB_AGGR_FUNC_CODES_H 24 | #define DB_AGGR_FUNC_CODES_H 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* Enumerated type for aggregate function codes. Aggregate functions on the 31 | same type should be kept together (all aggregate values on ints should be 32 | kept together, etc. 33 | -Important note: Make sure you properly differentiate between COUNTROWS 34 | (the aggregate function COUNT) and COUNT (the number of enumerated types 35 | in this file). 36 | */ 37 | /** 38 | @enum db_aggr_func_code_t 39 | @brief Enumerated type for database aggregate function code. 40 | */ 41 | typedef enum 42 | { 43 | DB_AGGR_COUNTROWS = 0, /**< @c COUNT(...) aggregate function code. */ 44 | DB_AGGR_BAND, /**< Bitwise @c AND aggregate function code. */ 45 | DB_AGGR_BOR, /**< Bitwise @c OR aggregate function code. */ 46 | DB_AGGR_BXOR, /**< Bitwise @c XOR aggregate function code. */ 47 | DB_AGGR_SUM, /**< @c SUM(...) aggregate function code. */ 48 | DB_AGGR_MAX, /**< @c MAX(...) aggregate function code. */ 49 | DB_AGGR_MIN, /**< @c MIN(...) aggregate function code. */ 50 | DB_AGGR_FIRST, /**< @c FIRST(...) aggregate function code. */ 51 | DB_AGGR_LAST, /**< @c LAST(...) aggregate function code. */ 52 | DB_AGGR_AVG_DBINT, /**< @c AVG(...) aggregate function code. */ 53 | DB_AGGR_STDDEVPOP, /**< @c STDDEVPOP(...) (population standard 54 | deviation) aggregate function code. */ 55 | DB_AGGR_STDDEVSAM, /**< @c STDDEVSAM(...) (sample standard 56 | deviation) aggregate function code. */ 57 | DB_AGGR_VARPOP, /**< @c VARPOP(...) (population variance) 58 | aggregate function code. */ 59 | DB_AGGR_VARSAM, /**< @c VARSAM(...) (sample variance) aggregate 60 | function code. */ 61 | DB_AGGR_COUNT /**< @c The number of enumerated values. */ 62 | } db_aggr_func_code_t; 63 | 64 | #ifdef __cplusplus 65 | } 66 | #endif 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /src/dbmacros.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @author Graeme Douglas 4 | @file dbmacros.h 5 | @brief A place for various macros to reside. 6 | @details 7 | @copyright Copyright 2013 Graeme Douglas 8 | @license Licensed under the Apache License, Version 2.0 (the "License"); 9 | you may not use this file except in compliance with the License. 10 | You may obtain a copy of the License at 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | @par 14 | Unless required by applicable law or agreed to in writing, 15 | software distributed under the License is distributed on an 16 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 17 | either express or implied. See the License for the specific 18 | language governing permissions and limitations under the 19 | License. 20 | */ 21 | /******************************************************************************/ 22 | 23 | #ifndef DBMACROS_H 24 | #define DBMACROS_H 25 | 26 | /** 27 | @brief Macro for moving any pointer some number of bytes cleanly. 28 | @param d The destination pointer. This is the pointer that is 29 | to be set. 30 | @param s The source pointer. This is the pointer that is to be 31 | moved. IT WILL _NOT_ BE SET! 32 | @param n The integral number of bytes to move. May be negative. 33 | @param t The pointer type to cast back to. _Do not include 34 | include brackets for the type._ 35 | @todo Make it so all calls to this macro actualy use 36 | @ref POINTERATNBYTES. 37 | */ 38 | #ifndef MOVEPOINTERNBYTES 39 | #define MOVEPOINTERNBYTES(d, s, n, t) (d) = (t)(((unsigned char*)((s)))+(n)) 40 | #else 41 | #error "MACRO NAME CLASH ON MOVEPOINTERNBYTES!" 42 | #endif 43 | 44 | /** 45 | @brief Macro for accessing any pointer some number of bytes away 46 | cleanly. 47 | @param s The source pointer. This is the pointer that is to be 48 | moved. IT WILL _NOT_ BE SET! 49 | @param n The integral number of bytes to move. May be negative. 50 | @param t The pointer type to cast back to. _Do not include 51 | include brackets for the type._ 52 | */ 53 | #ifndef POINTERATNBYTES 54 | #define POINTERATNBYTES(s, n, t) ((t)(((unsigned char*)((s)))+(n))) 55 | #else 56 | #error "MACRO NAME CLASH ON POINTERATNBYTES!" 57 | #endif 58 | 59 | /** 60 | @brief Macro for measuring the distance between the two pointers. 61 | @details Calculates the distance in bytes between p1 and p2. 62 | If p1 comes after p2, the result shall be positive. 63 | Keep in mind, this only works within the same array (same 64 | rules as normal in C). 65 | @param p1 The pointer to be subtracted from. 66 | @param p2 The pointer to be subtracted. 67 | */ 68 | #ifndef POINTERBYTEDIST 69 | #define POINTERBYTEDIST(p1, p2) (((unsigned char*)(p1)) - ((unsigned char*)(p2))) 70 | #else 71 | #error "MACRO NAME CLASH ON POINTERBYTEDIST!" 72 | #endif 73 | 74 | /** 75 | Macro for moving any pointer @a s by @a n units cleanly by casting it 76 | to type source pointer type @a ts then casting it back to destination 77 | pointer type @td. 78 | @brief Move a pointer exactly a number of units cleanly. 79 | @param d The destination pointer. This is the pointer that is 80 | to be set. 81 | @param s The source pointer. This is the pointer that is to be 82 | moved. IT WILL _NOT_ BE SET! 83 | @param n The integral number of units (_not_ bytes) to move. 84 | May be negative. 85 | @param ts The pointer type to cast the source to before moving. 86 | _Do not include include brackets for the type._ 87 | @param td The pointer type to cast the result to before assigning. 88 | _Do not include include brackets for the type._ 89 | */ 90 | #ifndef MOVEPOINTERNUNITS 91 | #define MOVEPOINTERNUNITS(d, s, n, td, ts) (d) = (td)(((ts)((s)))+(n)) 92 | #else 93 | #error "MACRO NAME CLASH ON MOVEPOINTERUNITS!" 94 | #endif 95 | 96 | #endif 97 | -------------------------------------------------------------------------------- /src/dbobjects/relation.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @file relation.c 4 | @author Graeme Douglas 5 | @brief Implementation of in-memory relation handling. 6 | @see For more information, refer to relation.h 7 | @details 8 | @copyright Copyright 2013 Graeme Douglas 9 | @license Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | 14 | @par 15 | Unless required by applicable law or agreed to in writing, 16 | software distributed under the License is distributed on an 17 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 18 | either express or implied. See the License for the specific 19 | language governing permissions and limitations under the 20 | License. 21 | */ 22 | /******************************************************************************/ 23 | 24 | #include "relation.h" 25 | 26 | /*** Methods for retrieving positions and offsets of a relations attributes */ 27 | /* Returns the position of a relation's attribute by searching using name. */ 28 | db_int getposbyname(relation_header_t *hp, char* attr_name) 29 | { 30 | db_int toRet = -1; /* By default, return an error code. */ 31 | 32 | db_int i = 0; 33 | /* Find the position by linear search. */ 34 | for (i = 0; i < (db_int)hp->num_attr; ++i) 35 | { 36 | if (strcmp(hp->names[i], attr_name)==0) 37 | { 38 | toRet = i; 39 | break; 40 | } 41 | } 42 | return toRet; 43 | } 44 | 45 | /* Returns offset of an attribute based on its position in the record. */ 46 | db_uint8 getoffsetbypos(relation_header_t *hp, db_int pos) 47 | { 48 | if (pos < 0 || pos >= (db_int)hp->num_attr) 49 | return -1; /* Return error condition */ 50 | else 51 | return hp->offsets[pos]; 52 | } 53 | 54 | /* Returns the offset of a relation's attribute by searching using name. */ 55 | db_uint8 getoffsetbyname(relation_header_t *hp, char* attr_name) 56 | { 57 | db_int pos = getposbyname(hp, attr_name); 58 | return getoffsetbypos(hp, pos); 59 | } 60 | 61 | /* Return the type of an attribute given its position in tuple. */ 62 | db_uint8 gettypebypos(relation_header_t *hp, db_int pos) 63 | { 64 | return hp->types[pos]; 65 | } 66 | 67 | db_int getrelationheader(relation_header_t **hpp, char *relationname, db_query_mm_t *mmp) 68 | { 69 | db_fileref_t relation = db_openreadfile(relationname); 70 | 71 | db_filerewind(relation); 72 | 73 | *hpp = DB_QMM_BALLOC(mmp, sizeof(relation_header_t)); 74 | 75 | /** Read away header info and store appropriately. ***/ 76 | db_fileread(relation, &((*hpp)->num_attr), 1); 77 | 78 | /* Allocate all the appropriate memory space */ 79 | (*hpp)->size_name = DB_QMM_BALLOC(mmp, (*hpp)->num_attr * sizeof(db_uint8)); 80 | (*hpp)->names = DB_QMM_BALLOC(mmp, (*hpp)->num_attr * sizeof(char*)); 81 | (*hpp)->types = DB_QMM_BALLOC(mmp, (*hpp)->num_attr * sizeof(db_uint8)); 82 | (*hpp)->offsets = DB_QMM_BALLOC(mmp, (*hpp)->num_attr * sizeof(db_uint8)); 83 | (*hpp)->sizes = DB_QMM_BALLOC(mmp, (*hpp)->num_attr * sizeof(db_uint8)); 84 | 85 | db_int i; /* Looping variable */ 86 | (*hpp)->tuple_size = 0; 87 | for (i = 0; i < (db_int)((*hpp)->num_attr); i++) 88 | { 89 | /* Read in the size of the ith name. */ 90 | db_fileread(relation, &((*hpp)->size_name[i]), sizeof(db_uint8)); 91 | 92 | /* Read in the attribute name for the ith attribute */ 93 | (*hpp)->names[i] = DB_QMM_BALLOC(mmp, (*hpp)->size_name[i]*sizeof(char)); 94 | db_fileread(relation, (unsigned char*)(*hpp)->names[i], (db_int)((*hpp)->size_name[i])); 95 | 96 | /* Read in the attribute type for the ith attribute */ 97 | db_fileread(relation, &((*hpp)->types[i]), sizeof(db_uint8)); 98 | 99 | /* Read in the attribute offset for the ith attribute */ 100 | db_fileread(relation, &((*hpp)->offsets[i]), sizeof(db_uint8)); 101 | 102 | /* Read in the attribute size for the ith attribute */ 103 | db_fileread(relation, &((*hpp)->sizes[i]), sizeof(db_uint8)); 104 | 105 | (*hpp)->tuple_size += (*hpp)->sizes[i]; 106 | } 107 | 108 | db_fileclose(relation); 109 | 110 | return 1; 111 | } 112 | 113 | db_int freerelationheader(relation_header_t *hp, db_query_mm_t *mmp) 114 | { 115 | /** Free all the previously allocated memory. */ 116 | /* Free size_name array */ 117 | DB_QMM_BFREE(mmp, hp->size_name); 118 | 119 | /* Free all the individual name arrays */ 120 | int i; 121 | for (i = 0; i < (db_int)(hp->num_attr); i++) 122 | { 123 | DB_QMM_BFREE(mmp, hp->names[i]); 124 | } 125 | 126 | /* Free the name array itself */ 127 | DB_QMM_BFREE(mmp, hp->names); 128 | 129 | DB_QMM_BFREE(mmp, hp->types); 130 | 131 | DB_QMM_BFREE(mmp, hp->offsets); 132 | 133 | DB_QMM_BFREE(mmp, hp->sizes); 134 | 135 | DB_QMM_BFREE(mmp, hp); 136 | 137 | return 1; 138 | } 139 | -------------------------------------------------------------------------------- /src/dbobjects/relation.h: -------------------------------------------------------------------------------- 1 | //***************************************************************************** 2 | /** 3 | @file relation.h 4 | @author Graeme Douglas 5 | @brief Method prototype and structure definitions for managing 6 | relations. 7 | @details Conceptually, relations can be files or tables on stable 8 | stable storage, or they could also be the result of some 9 | operator, despite the fact all operators work in a "tuple 10 | at a time" fashion. Some operators, such as projections, 11 | aggregates, and joins, will even create there own new schemas 12 | (headers). 13 | 14 | Some strong assumptions are made. Memory footprint of any 15 | tuple must not exceed 255 bytes. There cannot be more than 255 16 | attributes. The size of an attribute cannot exceed 255 bytes. 17 | An attributes name cannot be longer than 255 bytes (including 18 | terminator). 19 | @copyright Copyright 2013 Graeme Douglas 20 | @license Licensed under the Apache License, Version 2.0 (the "License"); 21 | you may not use this file except in compliance with the License. 22 | You may obtain a copy of the License at 23 | http://www.apache.org/licenses/LICENSE-2.0 24 | 25 | @par 26 | Unless required by applicable law or agreed to in writing, 27 | software distributed under the License is distributed on an 28 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 29 | either express or implied. See the License for the specific 30 | language governing permissions and limitations under the 31 | License. 32 | */ 33 | //***************************************************************************** 34 | 35 | #ifndef RELATION_H 36 | #define RELATION_H 37 | 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | #include 43 | #include "../ref.h" 44 | #include "../dbstorage/dbstorage.h" 45 | #include "../dbmm/db_query_mm.h" 46 | 47 | /* Relation header (AKA schema information). */ 48 | /** 49 | @struct relation_header_t 50 | @brief Referable representation of a relation's schema. 51 | */ 52 | typedef struct 53 | { 54 | /*@{*/ 55 | db_uint8 num_attr; /**< The number of attributes in relation. */ 56 | db_uint8 *size_name; /**< Size of the attribute's name in bytes, 57 | including the terminator. */ 58 | char **names; /**< Array of attribute names. */ 59 | db_uint8 *types; /**< Array of attribute types. */ 60 | db_uint8 *offsets; /**< Array of attribute offsets, in bytes. @todo remove this, do calculation instead. */ 61 | db_uint8 *sizes; /**< Array of attribute sizes, in bytes. */ 62 | db_uint8 tuple_size; /**< Size of a tuple, in bytes. */ 63 | /*@}*/ 64 | } relation_header_t; 65 | 66 | /*** Methods for retrieving positions/offsets of a relations attributes ***/ 67 | /* Returns the position of a relation's attribute given its ordered name. */ 68 | /** 69 | @brief Returns the position of a relation's attribute given the 70 | attributes name. 71 | @details This function will return a position to an attribute given 72 | the attribute name. This is not preferable, since it is 73 | possible for an attribute to have no name. 74 | @param hp Pointer to schema information for the relation 75 | of the attribute to find the position of. 76 | @param attr_name String name of the attribute whose position is 77 | desired. 78 | @return The position of the attribute whose name is @c attr_name. 79 | */ 80 | db_int getposbyname(relation_header_t *hp, /* Pointer to relation header 81 | structure. */ 82 | char* attr_name); /* Name of attribute to return 83 | position of. */ 84 | 85 | /* Returns the offset of a relation's attribute given its ordered position. */ 86 | /** 87 | @brief Returns offset of an attribute based on its ordered position in 88 | the relations schema. 89 | @param hp Pointer to the schema of the relation. 90 | @param pos Position of the attribute whose offset we 91 | desire. Should not be less than @c 0 or 92 | greater than @c hp->num_attr. 93 | @return Byte-based offset of the attribute at ordered position @c pos. 94 | @todo Change this to use sums instead of storing offsets. 95 | */ 96 | db_uint8 getoffsetbypos(relation_header_t *hp, /* Pointer to relation header 97 | structure. */ 98 | db_int pos); /* Position of attribute to get 99 | byte offset of. */ 100 | 101 | /* Returns the offset of a relation's attribute given its name. */ 102 | /** 103 | @brief Retrieves offset of an attribute based on its name in. 104 | @param hp Pointer to the schema of the relation. 105 | @param attr_name String name of the attribute whose offset is 106 | desired. 107 | @return Byte-based offset of the attribute at ordered position @c pos. 108 | @todo Change this to use sums instead of storing offsets. 109 | */ 110 | db_uint8 getoffsetbyname(relation_header_t *hp,/* Pointer to relation header 111 | structure. */ 112 | char* attr_name); /* Name of attribute to return 113 | position of. */ 114 | 115 | /* Return the type of an attribute given its position in tuple. */ 116 | /** 117 | @brief Retrieves type of an attribute based on its name in. 118 | @param hp Pointer to the schema of the relation. 119 | @param pos Position of the attribute whose offset is 120 | desired. Position should be no less than @c 0 121 | and no more than @c hp->num_attr. 122 | @return Type of attribute at ordered position @c pos in relation. 123 | */ 124 | db_uint8 gettypebypos(relation_header_t *hp, /* Pointer to relaiton header 125 | structure. */ 126 | db_int pos); /* Position of attribute to 127 | return the type of. */ 128 | 129 | /* Get relation header information for a relation. */ 130 | /** 131 | @brief Create in memory copy of relation meta data information. 132 | @param hpp Pointer to a relation schema pointer. 133 | The pointer being pointed to is that which 134 | should be set to point to the newly created 135 | schema information. 136 | @param relationname The name of the relation to generate 137 | schema information for. 138 | @param mmp A pointer to the per-query memory manager 139 | instance that will be used to allocate 140 | memory from. 141 | @returns @c 1 if the schema information was generated correctly, 142 | @c 0 otherwise. 143 | */ 144 | db_int getrelationheader(relation_header_t **hpp, 145 | char *relationame, 146 | db_query_mm_t *mmp); 147 | 148 | /* Remove relation header information from memory. */ 149 | /** 150 | @brief Remove the relation header information from memory. 151 | @param hp The pointer to the schema information 152 | to be freed. 153 | @param mmp The per-query memory manager used to allocated 154 | memory for the schema data. 155 | @returns @c 1 if the schema information was removed correctly, 156 | @c 0 otherwise. 157 | */ 158 | db_int freerelationheader(relation_header_t *hp, 159 | db_query_mm_t *mmp); 160 | 161 | #ifdef __cplusplus 162 | } 163 | #endif 164 | 165 | #endif 166 | -------------------------------------------------------------------------------- /src/dbobjects/tuple.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @file tuple.c 4 | @author Graeme Douglas 5 | @brief Implementation of in memory tuple handling. 6 | @see For more information, refer to @ref tuple.h. 7 | @details 8 | @copyright Copyright 2013 Graeme Douglas 9 | @license Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | 14 | @par 15 | Unless required by applicable law or agreed to in writing, 16 | software distributed under the License is distributed on an 17 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 18 | either express or implied. See the License for the specific 19 | language governing permissions and limitations under the 20 | License. 21 | */ 22 | /******************************************************************************/ 23 | 24 | #include "tuple.h" 25 | 26 | /*** Methods for retrieving information from a tuple. */ 27 | /* Retrieve an db_int from a tuple given its attribute name. */ 28 | db_int getintbyname(db_tuple_t *tp, char *attr_name, relation_header_t *hp) 29 | { 30 | db_uint8 offset = getoffsetbyname(hp, attr_name); 31 | /* Convert char pointer to db_int pointer so we can return db_int 32 | value. */ 33 | return *((db_int*)(&(tp->bytes[offset]))); 34 | } 35 | 36 | /* Retrieve an db_int from a tuple given its attribute position. */ 37 | db_int getintbypos(db_tuple_t *tp, db_int pos, relation_header_t *hp) 38 | { 39 | db_uint8 offset = getoffsetbypos(hp, pos); 40 | 41 | /* Convert char pointer to db_int pointer so we can return 42 | db_int value. */ 43 | return *((db_int*)(&(tp->bytes[(db_int)offset]))); 44 | } 45 | 46 | /* Retrieve a string from a tuple given its attribute name. */ 47 | char* getstringbyname(db_tuple_t *tp, char *attr_name, relation_header_t *hp) 48 | { 49 | db_uint8 offset = getoffsetbyname(hp, attr_name); 50 | 51 | /* Convert and return correct pointer types. */ 52 | return (char*)(&(tp->bytes[(db_int)offset])); 53 | } 54 | 55 | /* Retrieve a string from a tuple given its attribute position */ 56 | char* getstringbypos(db_tuple_t *tp, db_int pos, relation_header_t *hp) 57 | { 58 | db_uint8 offset = getoffsetbypos(hp, pos); 59 | /* Convert char pointer to db_int pointer so we can return db_int 60 | value. */ 61 | return (char*)(&(tp->bytes[(db_int)offset])); 62 | } 63 | 64 | /* Retrieve a void pointer from attribute at position pos. */ 65 | void* getvoidpbypos(db_tuple_t *tp, db_int pos, relation_header_t *hp) 66 | { 67 | db_uint8 offset = getoffsetbypos(hp, pos); 68 | 69 | /* Convert and return void pointer. */ 70 | return (void*)(&(tp->bytes[(db_int)offset])); 71 | } 72 | 73 | void copytuplebytes(db_tuple_t *to, db_tuple_t *from, int tstart, int fstart, 74 | int howmany) 75 | { 76 | howmany += tstart; 77 | for (; tstart < howmany; ++tstart, ++fstart) 78 | { 79 | to->bytes[tstart] = from->bytes[fstart]; 80 | } 81 | } 82 | void copytupleisnull(db_tuple_t *to, db_tuple_t *from, int tstart, int fstart, 83 | int howmany) 84 | { 85 | howmany += tstart; 86 | for (; tstart < howmany; ++tstart, ++fstart) 87 | { 88 | to->isnull[tstart] = from->isnull[fstart]; 89 | } 90 | } 91 | 92 | /* Create a tuple */ 93 | db_int init_tuple(db_tuple_t *tp, db_uint8 tuple_size, db_uint8 num_attr, 94 | db_query_mm_t *mmp) 95 | { 96 | /* Determine minimum number of bytes needed to create a bit vector 97 | num_attr bits. */ 98 | db_int toalloc = ((db_int)num_attr) / 8; 99 | if (((db_int)num_attr) % 8 > 0) 100 | toalloc++; 101 | 102 | tp->bytes = DB_QMM_BALLOC(mmp, SIZE_BYTE*((size_t)tuple_size)); 103 | tp->isnull = DB_QMM_BALLOC(mmp, SIZE_BYTE*((size_t)toalloc)); 104 | 105 | /* Write 0's in bit array to avoid confusion with garbage. */ 106 | db_int i = 0; 107 | for (; i < toalloc; i++) 108 | { 109 | tp->isnull[i] = 0; 110 | } 111 | 112 | //printf("tp->bytes (after malloc): %p\n", tp->bytes); 113 | return 0; 114 | } 115 | 116 | /* Destroy a tuple, specifically its bytes */ 117 | db_int close_tuple(db_tuple_t *tp, db_query_mm_t *mmp) 118 | { 119 | DB_QMM_BFREE(mmp, tp->bytes); 120 | DB_QMM_BFREE(mmp, tp->isnull); 121 | 122 | tp->bytes = NULL; 123 | tp->isnull = NULL; 124 | 125 | return 0; 126 | } 127 | -------------------------------------------------------------------------------- /src/dbobjects/tuple.h: -------------------------------------------------------------------------------- 1 | //***************************************************************************** 2 | /** 3 | @file tuple.h 4 | @author Graeme Douglas 5 | @brief Method prototype and structure definitions for managing 6 | tuples. 7 | @details Notes: 8 | 9 | -See relation.h and relation.c 10 | 11 | -A tuple is an array of consecutive bytes. 12 | 13 | -To interpret the array of bytes, we must have the header 14 | information. 15 | 16 | -Assumption is made that no two attributes in a relation have 17 | the same name. 18 | 19 | -All positions start from 0, NOT 1. 20 | @copyright Copyright 2013 Graeme Douglas 21 | @license Licensed under the Apache License, Version 2.0 (the "License"); 22 | you may not use this file except in compliance with the License. 23 | You may obtain a copy of the License at 24 | http://www.apache.org/licenses/LICENSE-2.0 25 | 26 | @par 27 | Unless required by applicable law or agreed to in writing, 28 | software distributed under the License is distributed on an 29 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 30 | either express or implied. See the License for the specific 31 | language governing permissions and limitations under the 32 | License. 33 | */ 34 | //***************************************************************************** 35 | 36 | #ifndef TUPLE_H 37 | #define TUPLE_H 38 | 39 | #ifdef __cplusplus 40 | extern "C" { 41 | #endif 42 | 43 | #include 44 | #include 45 | #include "../dbmm/db_query_mm.h" 46 | #include "../ref.h" 47 | #include "relation.h" 48 | 49 | /* Tuple structure. */ 50 | /** 51 | @struct db_tuple_t 52 | @brief In-memory representation of a tuple. 53 | @details A tuple is just a sequence of bytes that stores information, 54 | in addition to a bit-array signalling which attributes are 55 | actually NULL. This bit-array is actually a byte array as 56 | well, rounded up to accomodate for the number of bits required. 57 | */ 58 | typedef struct 59 | { 60 | /*@{*/ 61 | char *isnull; /**< Bit array (rounded up to nearest 62 | byte) where bit @c i indicates 63 | whether or not the @c i'th 64 | attribute is NULL or not (@c 1 65 | indicates a NULL value, @c 0 66 | otherwise). */ 67 | char *bytes; /**< Array of bytes that represents all 68 | the values for the tuple. 69 | */ 70 | /*@}*/ 71 | } db_tuple_t; 72 | 73 | /*** Methods for retrieving information from a tuple. */ 74 | /* Retrieve a db_int from a tuple given its attribute name. */ 75 | /** 76 | @brief Retrieves an integer stored in a tuple from a relation 77 | given the attribute's name. 78 | @param tp Pointer to the tuple from which to retrieve 79 | integer from. 80 | @param attr_name String name of the attribute. 81 | @param hp Pointer to schema information for the relation. 82 | @return The value of the attribute whose name is @c attr_name. 83 | */ 84 | db_int getintbyname(db_tuple_t *tp, /* Pointer to tuple structure. */ 85 | char *attr_name, /* Name of attribute to return value 86 | of. */ 87 | relation_header_t *hp); /* Pointer to relation header 88 | structure. */ 89 | 90 | /* Retrieve an db_int from a tuple given its attribute position. */ 91 | /** 92 | @brief Retrieves an integer stored in a tuple given its ordered 93 | position in the tuple. 94 | @param tp Pointer to the tuple from which to retrieve 95 | integer from. 96 | @param hp Pointer to schema information for the relation. 97 | @param pos Integer position of the attribute. 98 | @return The integer value of the attribute whose ordered position is 99 | @c pos. 100 | */ 101 | db_int getintbypos(db_tuple_t *tp, /* Pointer to tuple structure. */ 102 | db_int pos, /* The position of the attribute 103 | to return the value of. */ 104 | relation_header_t *hp); /* Pointer to relation header 105 | structure. */ 106 | 107 | /* Retrieve a string from a tuple given its attribute name. */ 108 | /** 109 | @brief Retrieves a string stored in a tuple given the string name 110 | of the attribute which contains the value. 111 | @param tp Pointer to the tuple from which to retrieve 112 | string from. 113 | @param attr_name String name of the attribute. 114 | @param hp Pointer to schema information for the relation. 115 | @return The string value of the attribute whose name is @c attr_name. 116 | */ 117 | char* getstringbyname(db_tuple_t *tp, /* Pointer to tuple structure. */ 118 | char *attr_name, /* Name of attribute to return value 119 | of. */ 120 | relation_header_t *hp); /* Pointer of relation header 121 | structure. */ 122 | 123 | /* Retrieve a string from a tuple given its attribute position */ 124 | /** 125 | @brief Retrieves a string stored in an attribute from a relation 126 | given its ordered position within the tuple. 127 | @param tp Pointer to the tuple from which to retrieve 128 | string from. 129 | @param pos Integer position of the attribute. 130 | @param hp Pointer to schema information for the relation. 131 | @return The string value of the attribute whose name is @c pos. 132 | */ 133 | char* getstringbypos(db_tuple_t *tp, /* Pointer to tuple structure. */ 134 | db_int pos, /* position of the attribute to return 135 | the value of. */ 136 | relation_header_t *hp); /* Pointer to relation header 137 | structure. */ 138 | 139 | /* Retrieve a void pointer from attribute at position pos. */ 140 | /** 141 | @brief Retrieves the type of an attribute in a tuple given its ordered 142 | position within the tuple. 143 | @param tp Pointer to the tuple from which to retrieve 144 | string from. 145 | @param pos Integer position of the attribute. 146 | @param hp Pointer to schema information for the relation. 147 | @return The string value of the attribute whose name is @c pos. 148 | */ 149 | void* getvoidpbypos(db_tuple_t *tp, /* Pointer to tuple structure. */ 150 | db_int pos, /* Position of the attribute to 151 | get the pointer of. */ 152 | relation_header_t *hp); /* Pointer of relation header 153 | structure. */ 154 | 155 | /** 156 | @brief Copy bytes from one tuple to another. 157 | @param to Pointer to the tuple to copy the bytes to. 158 | @param from Pointer to the tuple to copy the bytes from. 159 | @param tstart The first byte to overwrite. 160 | @param fstart The first byte to read. 161 | @param howmany How many bytes to copy. 162 | */ 163 | void copytuplebytes(db_tuple_t *to, 164 | db_tuple_t *from, 165 | int tstart, 166 | int fstart, 167 | int howmany); 168 | 169 | /** 170 | @brief Copy isnull bytes from one tuple to another. 171 | @param to Pointer to the tuple to copy the bytes to. 172 | @param from Pointer to the tuple to copy the bytes from. 173 | @param tstart The first byte to overwrite. 174 | @param fstart The first byte to read. 175 | @param howmany How many bytes to copy. 176 | */ 177 | void copytupleisnull(db_tuple_t *to, 178 | db_tuple_t *from, 179 | int tstart, 180 | int fstart, 181 | int howmany); 182 | 183 | /* Create a tuple */ 184 | /** 185 | @brief Initializes a tuple. 186 | @details Initilization of a tuple involves allocating dynamic memory 187 | for the byte array and the bit-array. Since memory must be 188 | allocated for a tuple, a tuple cannot be used before it is 189 | initialized, and must be closed after it is initialized. 190 | @param tp Pointer to the tuple to initialize 191 | @param tuple_size The size, in bytes, of the tuple. This size 192 | does NOT included the size of the bit array 193 | for NULL signalling. 194 | @param num_attr The number of attributes in the relation. 195 | @param mmp A pointer to the memory manager that will be 196 | used to allocate memory. Pass NULL to use 197 | @c malloc(..). 198 | @return 1 on success, -1 otherwise. 199 | */ 200 | db_int init_tuple(db_tuple_t *tp, /* Pointer to tuple structure. */ 201 | db_uint8 tuple_size, /* The number of bytes to make the 202 | tuple. */ 203 | db_uint8 num_attr, /* The number of attributes in the 204 | relation. */ 205 | db_query_mm_t *mmp); 206 | 207 | /* Destroy a tuple, specifically its bytes */ 208 | /** 209 | @brief Closes a tuple. 210 | @details De-allocates memory previously allocated for a tuple. 211 | @param tp Pointer to the tuple to initialize 212 | @param mmp A pointer to the memory manager that will be 213 | used to de-allocate memory. Pass NULL 214 | to use @c free(..). 215 | @return 1 on success, -1 otherwise. 216 | */ 217 | db_int close_tuple(db_tuple_t *tp, db_query_mm_t *mmp); 218 | 219 | #ifdef __cplusplus 220 | } 221 | #endif 222 | 223 | #endif 224 | -------------------------------------------------------------------------------- /src/dbops/aggregate.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @file aggregate.h 4 | @author Graeme Douglas 5 | @brief The relational aggregate (GROUP BY) operator. 6 | @details The projecting expressions are those that are parsed from the 7 | SELECT clause. Some assumptions are made. The most important 8 | of these is that we assume that expressions are never larger 9 | than DB_INT8_MAX. We also assume that no expressions can have 10 | non-grouping or non-aggregated expressions. 11 | @copyright Copyright 2013 Graeme Douglas 12 | @license Licensed under the Apache License, Version 2.0 (the "License"); 13 | you may not use this file except in compliance with the License. 14 | You may obtain a copy of the License at 15 | http://www.apache.org/licenses/LICENSE-2.0 16 | 17 | @par 18 | Unless required by applicable law or agreed to in writing, 19 | software distributed under the License is distributed on an 20 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 21 | either express or implied. See the License for the specific 22 | language governing permissions and limitations under the 23 | License. 24 | */ 25 | /******************************************************************************/ 26 | 27 | #ifndef AGGREGATE_H 28 | #define AGGREGATE_H 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | #include "db_ops.h" 35 | #include "../dbobjects/relation.h" 36 | #include "../dblogic/eet.h" 37 | #include "../dblogic/compare_tuple.h" 38 | #include 39 | 40 | #ifdef DB_CTCONF_SETTING_FEATURE_AGGREGATION 41 | #if DB_CTCONF_SETTING_FEATURE_AGGREGATION == 1 42 | 43 | /* Initialize the aggregate operator. */ 44 | /** 45 | @brief Initialize an aggregate operator. 46 | @param ap Pointer to the aggregate operator that 47 | is to be initialized. 48 | @param child Pointer to the operator immediately 49 | below @p ap in the execution tree. That 50 | is, the child. 51 | @param exprs Array of bytecode projecting 52 | expressions. 53 | @param num_expr The num of elements in @p exprs. 54 | @param groupby_exprs The set of expressions that determines 55 | how the tuples are grouped during 56 | aggregation. 57 | @param num_groupby_exprs The number of elements in 58 | @p groupby_exprs. 59 | @param having_expr The bytecode expression generated 60 | from the HAVING clause. 61 | @param mmp The per-query memory manager being used 62 | to allocate memory for this query. 63 | @returns @c 1 if the operator was initialized, @c -1 if an error occured, 64 | @c 0 otherwise. 65 | */ 66 | db_int init_aggregate(aggregate_t *ap, 67 | db_op_base_t *child, 68 | db_eet_t *exprs, 69 | db_uint8 num_expr, 70 | db_eet_t *groupby_exprs, 71 | db_uint8 num_groupby_expr, 72 | db_eet_t *having_expr, 73 | db_query_mm_t *mmp); 74 | 75 | /* Rewind the aggregate operator. */ 76 | /** 77 | @brief Rewind the aggregate operator. 78 | @see rewind_dbop 79 | */ 80 | db_int rewind_aggregate(aggregate_t *ap, db_query_mm_t *mmp); 81 | 82 | /* Return the next tuple from the aggregate operator. */ 83 | /** 84 | @brief Get the next tuple from an aggregate operator. 85 | @see next 86 | */ 87 | db_int next_aggregate(aggregate_t *ap, db_tuple_t *tp, db_query_mm_t *mmp); 88 | 89 | /* Close the aggregate operator. */ 90 | /** 91 | @brief Safely deconstruct the aggregate operator. 92 | */ 93 | db_int close_aggregate(aggregate_t *ap, db_query_mm_t *mmp); 94 | 95 | #endif 96 | #endif 97 | 98 | #ifdef __cplusplus 99 | } 100 | #endif 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /src/dbops/db_ops.c: -------------------------------------------------------------------------------- 1 | /***** 2 | ****************************************************************************** 3 | Author: Graeme Douglas 4 | 5 | Implementation of db_ops.h interface. See db_ops.h for documentation, 6 | notes. 7 | ****************************************************************************** 8 | */ 9 | 10 | #include "db_ops.h" 11 | #include "../db_ctconf.h" 12 | 13 | db_int8 findindexon(scan_t *sp, db_eetnode_attr_t *attrp) 14 | { 15 | db_int8 i = 0; 16 | db_uint8 found = 1; 17 | for (; i < sp->idx_meta_data.num_idx; ++i) 18 | { 19 | if (sizeof(db_eetnode_attr_t) != sp->idx_meta_data.exprs[i]->size) 20 | continue; 21 | 22 | // FIXME: This only works for attribute to attribute indexing. 23 | if (attrp->pos != ((db_eetnode_attr_t*)(sp->idx_meta_data.exprs[i]->nodes))->pos) 24 | { 25 | found = 0; 26 | } 27 | if (found) 28 | return i; 29 | else 30 | found = 1; 31 | } 32 | 33 | return -1; 34 | } 35 | 36 | /* A generic next method that can be called on any operator. */ 37 | db_int next(db_op_base_t *op, db_tuple_t *next_tp, db_query_mm_t *mmp) 38 | { 39 | if (op->type == DB_SCAN) 40 | { 41 | return next_scan((scan_t*)op, next_tp, mmp); 42 | } 43 | else if (op->type == DB_PROJECT) 44 | { 45 | return next_project((project_t*)op, next_tp, mmp); 46 | } 47 | else if (op->type == DB_SELECT) 48 | { 49 | return next_select((select_t*)op, next_tp, mmp); 50 | } 51 | else if (op->type == DB_NTJOIN) 52 | { 53 | return next_ntjoin((ntjoin_t*)op, next_tp, mmp); 54 | } 55 | else if (op->type == DB_OSIJOIN) 56 | { 57 | return next_osijoin((osijoin_t*)op, next_tp, mmp); 58 | } 59 | else if (op->type == DB_SORT) 60 | { 61 | return next_sort((sort_t*)op, next_tp, mmp); 62 | } 63 | #ifdef DB_CTCONF_SETTING_FEATURE_AGGREGATION 64 | #if DB_CTCONF_SETTING_FEATURE_AGGREGATION == 1 65 | else if (op->type == DB_AGGREGATE) 66 | { 67 | return next_aggregate((aggregate_t*)op, next_tp, mmp); 68 | } 69 | #endif 70 | #endif 71 | else 72 | return -1; 73 | } 74 | 75 | /* A generic rewind method. */ 76 | db_int rewind_dbop(db_op_base_t *op, db_query_mm_t *mmp) 77 | { 78 | if (op->type == DB_SCAN) 79 | { 80 | return rewind_scan((scan_t*)op, mmp); 81 | } 82 | else if (op->type == DB_PROJECT) 83 | { 84 | return rewind_project((project_t*)op, mmp); 85 | } 86 | else if (op->type == DB_SELECT) 87 | { 88 | return rewind_select((select_t*)op, mmp); 89 | } 90 | else if (op->type == DB_NTJOIN) 91 | { 92 | return rewind_ntjoin((ntjoin_t*)op, mmp); 93 | } 94 | else if (op->type == DB_OSIJOIN) 95 | { 96 | return rewind_osijoin((osijoin_t*)op, mmp); 97 | } 98 | else if (op->type == DB_SORT) 99 | { 100 | return rewind_sort((sort_t*)op, mmp); 101 | } 102 | #ifdef DB_CTCONF_SETTING_FEATURE_AGGREGATION 103 | #if DB_CTCONF_SETTING_FEATURE_AGGREGATION == 1 104 | else if (op->type == DB_AGGREGATE) 105 | { 106 | return rewind_aggregate((aggregate_t*)op, mmp); 107 | } 108 | #endif 109 | #endif 110 | else 111 | return -1; 112 | } 113 | 114 | /* A generic close method. */ 115 | void close(db_op_base_t *op, db_query_mm_t *mmp) 116 | { 117 | /* TODO In the future, some sort of check on types would be good. */ 118 | if (op->type == DB_SCAN) 119 | { 120 | close_scan((scan_t*)op, mmp); 121 | } 122 | else if (op->type == DB_PROJECT) 123 | { 124 | close_project((project_t*)op, mmp); 125 | } 126 | else if (op->type == DB_SELECT) 127 | { 128 | close_select((select_t*)op, mmp); 129 | } 130 | else if (op->type == DB_NTJOIN) 131 | { 132 | close_ntjoin((ntjoin_t*)op, mmp); 133 | } 134 | else if (op->type == DB_OSIJOIN) 135 | { 136 | close_osijoin((osijoin_t*)op, mmp); 137 | } 138 | else if (op->type == DB_SORT) 139 | { 140 | close_sort((sort_t*)op, mmp); 141 | } 142 | #ifdef DB_CTCONF_SETTING_FEATURE_AGGREGATION 143 | #if DB_CTCONF_SETTING_FEATURE_AGGREGATION == 1 144 | else if (op->type == DB_AGGREGATE) 145 | { 146 | close_aggregate((aggregate_t*)op, mmp); 147 | } 148 | #endif 149 | #endif 150 | } 151 | 152 | /* Get the number of childrem an operator has. */ 153 | db_int numopchildren(db_op_base_t *op) 154 | { 155 | if (op->type == DB_SCAN) 156 | { 157 | return 0; 158 | } 159 | else if (DB_PROJECT == op->type || 160 | DB_SELECT == op->type || 161 | DB_SORT == op->type || 162 | DB_AGGREGATE == op->type) 163 | { 164 | return 1; 165 | } 166 | else if (DB_NTJOIN == op->type || DB_OSIJOIN == op->type) 167 | { 168 | return 2; 169 | } 170 | else 171 | { 172 | return -1; 173 | } 174 | } 175 | 176 | /* Close an entire execution tree recursively. */ 177 | db_int closeexecutiontree(db_op_base_t *op, db_query_mm_t *mmp) 178 | { 179 | if (NULL == op) 180 | { 181 | return 1; 182 | } 183 | else if (DB_NTJOIN == op->type || DB_OSIJOIN == op->type) 184 | { 185 | switch (closeexecutiontree(((ntjoin_t*)op)->lchild, mmp)) { 186 | case 1: 187 | break; 188 | default: 189 | return -1; 190 | } 191 | switch (closeexecutiontree(((ntjoin_t*)op)->rchild, mmp)) { 192 | case 1: 193 | break; 194 | default: 195 | return -1; 196 | } 197 | } 198 | else if (1 == numopchildren(op)) 199 | { 200 | switch (closeexecutiontree(((db_op_onechild_t*)op)->child, mmp)) { 201 | case 1: 202 | break; 203 | default: 204 | return -1; 205 | } 206 | } 207 | else if (0 == numopchildren(op)) 208 | {} 209 | else 210 | { 211 | return -1; 212 | } 213 | close(op, mmp); 214 | return 1; 215 | } 216 | -------------------------------------------------------------------------------- /src/dbops/db_ops.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @author Graeme Douglas 4 | @file db_ops.h 5 | @brief Interface for generic database operators. 6 | @details This is a file that contains database operator related methods. 7 | The main goal of this file is to help achieve an object-oriented 8 | style to all operators by simulating inheritence/polymorphism 9 | with structs. 10 | 11 | Notes: 12 | -Assumption is made that the first parameter passed 13 | to all functions below is a pointer to the _GENERIC_ 14 | operator. Beyond that, no assumptions are made. 15 | @copyright Copyright 2013 Graeme Douglas 16 | @license Licensed under the Apache License, Version 2.0 (the "License"); 17 | you may not use this file except in compliance with the License. 18 | You may obtain a copy of the License at 19 | http://www.apache.org/licenses/LICENSE-2.0 20 | 21 | @par 22 | Unless required by applicable law or agreed to in writing, 23 | software distributed under the License is distributed on an 24 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 25 | either express or implied. See the License for the specific 26 | language governing permissions and limitations under the 27 | License. 28 | */ 29 | /******************************************************************************/ 30 | 31 | #ifndef DB_OP_H 32 | #define DB_OP_H 33 | 34 | #ifdef __cplusplus 35 | extern "C" { 36 | #endif 37 | 38 | #include "db_ops_types.h" 39 | #include "../dbmm/db_query_mm.h" 40 | #include "../dbobjects/tuple.h" 41 | #include "scan.h" 42 | #include "project.h" 43 | #include "select.h" 44 | #include "ntjoin.h" 45 | #include "osijoin.h" 46 | #include "sort.h" 47 | #include "aggregate.h" 48 | 49 | /** 50 | @brief Find the index that uses this attribute. 51 | @param sp The scan operator that is indexed. 52 | @param attrp The attribute that needs to be indexed. 53 | @returns Which index to use, or else @c -1. 54 | */ 55 | db_int8 findindexon(scan_t *sp, db_eetnode_attr_t *attrp); 56 | 57 | /* 58 | A generic next method that can be called on any operator. 59 | -It is assumed that next always returns 1 on success, 60 | 0 on no more tuples, and any other number on failure. 61 | */ 62 | /** 63 | @brief Get the next tuple from the operator. 64 | @param op Pointer to the operator. 65 | @param next_tp Pointer to the initialized tuple 66 | to place ther result in. 67 | @param mmp A pointer to the memory manager pointer 68 | that will allocate memory for the operator. 69 | @returns @c 0 if no more tuples to return, @c -1 if an error occurs, 70 | @c 1 otherwise. 71 | */ 72 | db_int next(db_op_base_t *op, db_tuple_t *next_tp, db_query_mm_t *mmp); 73 | 74 | /* A generic rewind method. */ 75 | /** 76 | @brief Allow the operator to be re-used. Rewind is recursive. 77 | @param op Pointer to the operator to be re-initialized. 78 | @param mmp A pointer to the memory manager pointer 79 | that will allocate memory for the operator. 80 | @returns @c 1 if the operator (and its children) were rewound, @c -1 81 | if an error occurs, @c 0 otherwise. 82 | */ 83 | db_int rewind_dbop(db_op_base_t *op, db_query_mm_t *mmp); 84 | 85 | /* A generic close method. */ 86 | /** 87 | @brief Cleanly, non-recursively destroy an operator. 88 | @param op Pointer to the operator to be closed. 89 | @param mmp A pointer to the memory manager pointer 90 | that will allocate memory for the operator. 91 | @returns @c 1 if the operator (and its children) were closed, @c -1 92 | if an error occurs, @c 0 otherwise. 93 | */ 94 | void close(db_op_base_t *op, db_query_mm_t *mmp); 95 | 96 | /* Get the number of childrem an operator has. */ 97 | /** 98 | @brief Get the number of children an operator has. 99 | @param op Pointer to the operator. 100 | @returns The number of children the operator has. 101 | */ 102 | db_int numopchildren(db_op_base_t *op); 103 | 104 | /* Close an entire execution tree recursively. */ 105 | /** 106 | @brief Close the entire execution tree. 107 | @param op Pointer to the root operator in the execution 108 | tree. 109 | @param mmp A pointer to the memory manager pointer 110 | that will allocate memory for the operator. 111 | @returns @c 1 if the execution tree was cleanly dstroyed, @c -1 112 | otherwise. 113 | */ 114 | db_int closeexecutiontree(db_op_base_t *op, db_query_mm_t *mmp); 115 | 116 | #ifdef __cplusplus 117 | } 118 | #endif 119 | 120 | #endif 121 | -------------------------------------------------------------------------------- /src/dbops/ntjoin.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @file ntjoin.c 4 | @author Graeme Douglas 5 | @brief Implementation of the ensted-tuple join oeprator. 6 | @see For more information, reference @ref ntjoin.h. 7 | @details 8 | @copyright Copyright 2013 Graeme Douglas 9 | @license Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | 14 | @par 15 | Unless required by applicable law or agreed to in writing, 16 | software distributed under the License is distributed on an 17 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 18 | either express or implied. See the License for the specific 19 | language governing permissions and limitations under the 20 | License. 21 | */ 22 | /******************************************************************************/ 23 | 24 | #include "db_ops_types.h" 25 | #include "ntjoin.h" 26 | #include "db_ops.h" 27 | #include "../dblogic/eet.h" 28 | 29 | /* Initialize the selection operator. */ 30 | db_int init_ntjoin(ntjoin_t *jp, db_eet_t *ep, db_op_base_t *lchild, db_op_base_t *rchild, db_query_mm_t *mmp) 31 | { 32 | /*** Construct new header. ***/ 33 | jp->base.header = DB_QMM_BALLOC(mmp, sizeof(relation_header_t)); 34 | 35 | /* Number of attributes / tuple size for joined tuple is sum of 36 | * children's number of attributes / tuple size. */ 37 | jp->base.header->num_attr = lchild->header->num_attr + rchild->header->num_attr; 38 | jp->base.header->tuple_size = lchild->header->tuple_size + rchild->header->tuple_size; 39 | 40 | /* Allocate all necessary memory for the header. */ 41 | jp->base.header->size_name = DB_QMM_BALLOC(mmp, sizeof(db_uint8)*(jp->base.header->num_attr)); 42 | jp->base.header->names = DB_QMM_BALLOC(mmp, sizeof(char*)*(jp->base.header->num_attr)); 43 | jp->base.header->types = DB_QMM_BALLOC(mmp, sizeof(db_uint8)*(jp->base.header->num_attr)); 44 | jp->base.header->offsets = DB_QMM_BALLOC(mmp, sizeof(db_uint8)*(jp->base.header->num_attr)); 45 | jp->base.header->sizes = DB_QMM_BALLOC(mmp, sizeof(db_uint8)*(jp->base.header->num_attr)); 46 | 47 | /* Write out left child's header properties into new header. */ 48 | db_int i; 49 | for (i = 0; i < (db_int)(lchild->header->num_attr); i++) 50 | { 51 | *((jp->base.header->size_name)+i) = *((lchild->header->size_name)+i); 52 | *((jp->base.header->names)+i) = *((lchild->header->names)+i); 53 | *((jp->base.header->types)+i) = *((lchild->header->types)+i); 54 | *((jp->base.header->offsets)+i) = *((lchild->header->offsets)+i); 55 | *((jp->base.header->sizes)+i) = *((lchild->header->sizes)+i); 56 | } 57 | db_uint8 first_roffset = lchild->header->offsets[i-1] + lchild->header->sizes[i-1]; 58 | 59 | /* Write out right child's header properties new header.*/ 60 | for (i = 0; i < (db_int)(rchild->header->num_attr); i++) 61 | { 62 | *(((jp->base.header->size_name)+i)+lchild->header->num_attr) = *((rchild->header->size_name)+i); 63 | *(((jp->base.header->names)+i)+lchild->header->num_attr) = *((rchild->header->names)+i); 64 | *(((jp->base.header->types)+i)+lchild->header->num_attr) = *((rchild->header->types)+i); 65 | *(((jp->base.header->offsets)+i)+lchild->header->num_attr) = first_roffset + *((rchild->header->offsets)+i); 66 | *(((jp->base.header->sizes)+i)+lchild->header->num_attr) = *((rchild->header->sizes)+i); 67 | } 68 | 69 | jp->base.type = DB_NTJOIN; 70 | jp->tree = ep; 71 | jp->lchild = lchild; 72 | jp->rchild = rchild; 73 | init_tuple(&(jp->lt), jp->lchild->header->tuple_size, jp->lchild->header->num_attr, mmp); 74 | 75 | /* Get the first tuple from left relation, store the result. */ 76 | jp->lvalid = (db_uint8)next(jp->lchild, &(jp->lt), mmp); 77 | return 1; 78 | } 79 | 80 | /* Re-start the operator from the beginning. This assumes the operator has 81 | * been initialized. */ 82 | db_int rewind_ntjoin(ntjoin_t *jp, db_query_mm_t *mmp) 83 | { 84 | rewind_dbop(jp->lchild, mmp); 85 | rewind_dbop(jp->rchild, mmp); 86 | jp->lvalid = (db_uint8)next(jp->lchild, &(jp->lt), mmp); 87 | return 1; 88 | } 89 | 90 | /* Find next tuple that passes the join condition. 91 | -This assumes that the evaluation tree will always reduce to either 0 or 1 92 | for all tuples. 93 | -The algorithm used is the following: 94 | while lt is a valid tuple from lchild 95 | for each tuple rt remaining in rchild 96 | if rt joins lt 97 | return joined tuple 98 | lt <- next tuple from lchild 99 | rewind rchild 100 | */ 101 | db_int next_ntjoin(ntjoin_t *jp, db_tuple_t *next_tp, db_query_mm_t *mmp) 102 | { 103 | /* Create necessary result variable. */ 104 | db_int result = 0, retval; 105 | db_tuple_t rt; 106 | init_tuple(&rt, jp->rchild->header->tuple_size, jp->rchild->header->num_attr, mmp); 107 | 108 | /* Build arrays to be passed to eet evaluation engine. */ 109 | relation_header_t *hpa[2]; 110 | hpa[0] = jp->lchild->header; 111 | hpa[1] = jp->rchild->header; 112 | db_tuple_t *tpa[2]; 113 | tpa[0] = &(jp->lt); 114 | tpa[1] = &rt; 115 | db_int looper; 116 | 117 | while (1 == jp->lvalid) 118 | { 119 | looper = next(jp->rchild, &rt, mmp); 120 | while (looper) 121 | { 122 | /* Evaluate join condition eet on this tuple, if it 123 | exists. If its NULL, all tuples pass (cross prod). 124 | */ 125 | if (jp->tree != NULL && jp->tree->nodes != NULL) 126 | { 127 | retval = evaluate_eet(jp->tree, &result, tpa, hpa, 0, mmp); 128 | } 129 | else 130 | { 131 | /* If there is no join condition, allow all 132 | tuples to pass. */ 133 | retval = 1; 134 | result = 1; 135 | } 136 | 137 | if (1 == result && 1 == retval) 138 | { 139 | /*** Do the join by combining the tuples 140 | * together. ***/ 141 | /* Write out left tuples bytes into new tuple. 142 | * */ 143 | /* Write out left tuples isnull into new tuple. 144 | * */ 145 | db_int l_isnullsize = (db_int)(jp->lchild->header->num_attr) % 8 > 0 146 | ? ((db_int)(jp->lchild->header->num_attr) / 8) + 1 147 | : ((db_int)(jp->lchild->header->num_attr) / 8); 148 | 149 | copytuplebytes(next_tp, &(jp->lt), 0, 0, jp->lchild->header->tuple_size); 150 | 151 | copytupleisnull(next_tp, &(jp->lt), 0, 0, l_isnullsize); 152 | 153 | /* Write out right tuples bytes directly after 154 | * left tuples bytes. */ 155 | copytuplebytes(next_tp, &rt, jp->lchild->header->tuple_size, 0, jp->rchild->header->tuple_size); 156 | 157 | /* Write out right tuples isnull into new tuple. 158 | * */ 159 | db_int i; 160 | db_int j = (db_int)(jp->lchild->header->num_attr); 161 | for (i = 0; i < (db_int)(jp->rchild->header->num_attr); ++i) 162 | { 163 | /* If this bit is 0 ... */ 164 | if (0 == (rt.isnull[i/8] & (1 << (i % 8)))) 165 | { 166 | next_tp->isnull[j/8] &= ~(1 << (j % 8)); 167 | } 168 | else 169 | { 170 | next_tp->isnull[j/8] |= (1 << (j % 8)); 171 | } 172 | j++; 173 | } 174 | close_tuple(&rt, mmp); 175 | return 1; 176 | } 177 | looper = next(jp->rchild, &rt, mmp); 178 | } 179 | if (0 != looper) /* Cannot be 1 at this point. */ 180 | { 181 | close_tuple(&rt, mmp); 182 | return next(jp->rchild, &rt, mmp); /* Return error */ 183 | } 184 | 185 | /* Get next tuple from operator below. */ 186 | jp->lvalid = next(jp->lchild, &(jp->lt), mmp); 187 | 188 | if (jp->lvalid != 1 && jp->lvalid != 0) 189 | { 190 | close_tuple(&rt, mmp); 191 | return jp->lvalid; 192 | } 193 | else 194 | { 195 | rewind_dbop(jp->rchild, mmp); 196 | } 197 | } 198 | close_tuple(&rt, mmp); 199 | return jp->lvalid; 200 | } 201 | 202 | /* Close the selection operator. */ 203 | db_int close_ntjoin(ntjoin_t *jp, db_query_mm_t *mmp) 204 | { 205 | close_tuple(&(jp->lt), mmp); 206 | /* Free all header properties that were allocated */ 207 | DB_QMM_BFREE(mmp, jp->base.header->size_name); 208 | DB_QMM_BFREE(mmp, jp->base.header->names); 209 | DB_QMM_BFREE(mmp, jp->base.header->types); 210 | DB_QMM_BFREE(mmp, jp->base.header->offsets); 211 | DB_QMM_BFREE(mmp, jp->base.header->sizes); 212 | 213 | /* Free the header itself. */ 214 | DB_QMM_BFREE(mmp, jp->base.header); 215 | 216 | /* For the time being, do nothing! */ 217 | return 1; 218 | } 219 | -------------------------------------------------------------------------------- /src/dbops/ntjoin.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @file ntjoin.h 4 | @author Graeme Douglas 5 | @brief The relational join, specfically a binary nested-tuple join. 6 | @details 7 | @copyright Copyright 2013 Graeme Douglas 8 | @license Licensed under the Apache License, Version 2.0 (the "License"); 9 | you may not use this file except in compliance with the License. 10 | You may obtain a copy of the License at 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | @par 14 | Unless required by applicable law or agreed to in writing, 15 | software distributed under the License is distributed on an 16 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 17 | either express or implied. See the License for the specific 18 | language governing permissions and limitations under the 19 | License. 20 | */ 21 | /******************************************************************************/ 22 | 23 | #ifndef NTJOIN_H 24 | #define NTJOIN_H 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | #include "db_ops_types.h" 31 | #include "../dbobjects/relation.h" 32 | #include "../dbobjects/tuple.h" 33 | #include 34 | 35 | /* Initialize the selection operator. */ 36 | /** 37 | @brief Initialize a nested-tuple join oeprator. 38 | @param jp A pointer to the nested-tuple join that is 39 | to be initialized. 40 | @param ep A pointer to the bytecode expression to be used 41 | to filter results by, or @c NULL if no filtering 42 | is to occur. 43 | @param lchild A pointer to the operator that is passing tuples 44 | to the left side of the join. 45 | @param rchild A pointer to the operator that is passing tuples 46 | to the right side of the join. 47 | @param mmp A pointer to the per-query memory manager that 48 | is allocating space for this query. 49 | */ 50 | db_int init_ntjoin(ntjoin_t *jp, 51 | db_eet_t *ep, 52 | db_op_base_t *lchild, 53 | db_op_base_t *rchild, 54 | db_query_mm_t *mmp); 55 | 56 | /* Re-start the operator from the beginning. This assumes the operator has 57 | been initialized. */ 58 | /** 59 | @brief Rewind a nested-tuple join operator. 60 | @see For more information, please reference @ref rewind_dbop. 61 | */ 62 | db_int rewind_ntjoin(ntjoin_t *jp, db_query_mm_t *mmp); 63 | 64 | /* Find next tuple that passes the join condition. */ 65 | /** 66 | @brief Produce the next tuple from a nested-tuple join operator. 67 | @see For more information, please reference @ref next. 68 | */ 69 | db_int next_ntjoin(ntjoin_t *jp, db_tuple_t *next_tp, db_query_mm_t *mmp); 70 | 71 | /* Close the selection operator. */ 72 | /** 73 | @brief Cleanly deconstruct a nested-tuple join operator. 74 | @see For more information, please reference @ref close. 75 | */ 76 | db_int close_ntjoin(ntjoin_t *jp, db_query_mm_t *mmp); 77 | 78 | #ifdef __cplusplus 79 | } 80 | #endif 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /src/dbops/osijoin.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @file osijoin.h 4 | @author Graeme Douglas 5 | @brief One-sided index join. 6 | @details A join that requires one of the two input relations 7 | be indexed. 8 | @copyright Copyright 2013 Graeme Douglas 9 | @license Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | 14 | @par 15 | Unless required by applicable law or agreed to in writing, 16 | software distributed under the License is distributed on an 17 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 18 | either express or implied. See the License for the specific 19 | language governing permissions and limitations under the 20 | License. 21 | */ 22 | /******************************************************************************/ 23 | 24 | #ifndef OSIJOIN_H 25 | #define OSIJOIN_H 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | #include "../dbindex/dbindex.h" 32 | #include "db_ops_types.h" 33 | #include "osijoin.h" 34 | #include "db_ops.h" 35 | #include "../dblogic/eet.h" 36 | 37 | /** 38 | @brief Check if the right child is indexed. 39 | */ 40 | #ifndef DB_OSIJOIN_RINDEXED 41 | #define DB_OSIJOIN_RINDEXED(bitinfo) \ 42 | ((bitinfo) & (1)) 43 | #else 44 | #error "MACRO NAME CLASH ON DB_OSI_RINDEXED" 45 | #endif 46 | 47 | /** 48 | @brief Update if there are more tuples in the unindexed relation. 49 | */ 50 | #ifndef DB_OSIJOIN_UPDATE_UMORE 51 | #define DB_OSIJOIN_UPDATE_UMORE(bitinfo, updater) \ 52 | if (1==(updater)){ \ 53 | ((bitinfo) |= (1 << 1)); \ 54 | } else { \ 55 | ((bitinfo) &= ~(1 << 1)); \ 56 | } 57 | #else 58 | #error "MACRO NAME CLASH ON DB_OSI_UPDATE_UMORE" 59 | #endif 60 | 61 | /** 62 | @brief Check if the last call to next(..) on the unindexed tuple 63 | was successful. 64 | */ 65 | #ifndef DB_OSIJOIN_UMORE 66 | #define DB_OSIJOIN_UMORE(bitinfo) \ 67 | (((bitinfo) & (1 << 1)) >> 1) 68 | #else 69 | #error "MACRO NAME CLASH ON DB_OSI_UMORE" 70 | #endif 71 | 72 | /** 73 | @brief Update if an indexed value was found. 74 | */ 75 | #ifndef DB_OSIJOIN_UPDATE_IVALID 76 | #define DB_OSIJOIN_UPDATE_IVALID(bitinfo, updater) \ 77 | if (-1!=(updater)){ \ 78 | ((bitinfo) |= (1 << 2)); \ 79 | } else { \ 80 | ((bitinfo) &= ~(1 << 2)); \ 81 | } 82 | #else 83 | #error "MACRO NAME CLASH ON DB_OSI_UPDATE_UMORE" 84 | #endif 85 | 86 | /** 87 | @brief Check if an indexed value was found. 88 | */ 89 | #ifndef DB_OSIJOIN_IVALID 90 | #define DB_OSIJOIN_IVALID(bitinfo) \ 91 | (((bitinfo) & (1 << 2)) >> 2) 92 | #else 93 | #error "MACRO NAME CLASH ON DB_OSI_UMORE" 94 | #endif 95 | 96 | /* Initialize the operator. */ 97 | /** 98 | @brief Attempt to initialize an osijoin. 99 | @details Its not really a good idea to use this method as it first 100 | attempts to initialize an @ref ntjoin_t object, then tries 101 | to convert it to an @ref osijoin_t object. If this method 102 | returns @c 0, either the initialization or the conversion 103 | could have failed, and you will not not know which. 104 | The author used it for testing, and for that purpose it 105 | worked well. You are better off to call @ref init_ntjoin 106 | followed by @ref setup_osijoin to handle the errors 107 | yourself. 108 | @param jp A pointer to the join object to initialize. 109 | @param ep A pointer to the join expression to initalize on. 110 | @param lchild A pointer to the left child of the join operator. 111 | @param rchild A pointer to the right child of the join operator. 112 | @param mmp A pointer to the memory manager instance variable 113 | used to allocate memory for this query. 114 | @returns @c 1 if a one-sided join was properly initialized, @c 0 115 | otherwise. 116 | @see For more information on things to be wary of, reference 117 | @ref setup_osijoin. 118 | */ 119 | db_int init_osijoin(osijoin_t *jp, 120 | db_eet_t *ep, 121 | db_op_base_t *lchild, 122 | db_op_base_t *rchild, 123 | db_query_mm_t *mmp); 124 | 125 | /* Setup a one-sided index-based join from a nested tuple. */ 126 | /** 127 | @brief Convert an nested-tuple join into a one-sided 128 | index join. 129 | @param jp A pointer to an already initialized instance 130 | of an @ref ntjoin_t object. If this method 131 | returns @c 0, it is fine to assume that 132 | the object will still function as an @ref ntjoin_t 133 | operator. 134 | @param mmp A pointer to the memory manager instance variable 135 | that will be used for allocating memory in this 136 | query. 137 | @returns @c 1 if @c jp was converted, @c 0 otherwise. 138 | */ 139 | db_int setup_osijoin(osijoin_t *jp, db_query_mm_t *mmp); 140 | 141 | /* Re-start the operator from the beginning. This assumes the operator has 142 | been initialized. */ 143 | /** 144 | @brief Rewind an instance of an @ref osijoin_t. 145 | @param jp The join operator to be rewound. 146 | @param mmp The memory manager being used to allocate memory 147 | for this query. 148 | @returns @c 1 if the operator was rewound, @c 0 otherwise. 149 | */ 150 | db_int rewind_osijoin(osijoin_t *jp, db_query_mm_t *mmp); 151 | 152 | /** 153 | @brief Rewind an instance of an @ref osijoin_t. 154 | @param jp The join operator to be rewound. 155 | @param next_tp A pointer to the initiazlized tuple that will 156 | store the next result of this operator. 157 | @param mmp A pointer to the per-query memory manager being 158 | used to allocate memory for this query. 159 | @returns @c 1 if a tuple is computed, @c 0 otherwise. 160 | */ 161 | db_int next_osijoin(osijoin_t *jp, db_tuple_t *next_tp, db_query_mm_t *mmp); 162 | 163 | /* Close the selection operator. */ 164 | /** 165 | @brief Cleanly destroy an instance of an @ref osijoin_t object. 166 | @param jp A pointer to the one-sided index join operator 167 | to destroy. 168 | @param mmp A pointer to the per-query memory manager being 169 | used to allocate memory for this query. 170 | @returns @c 1 if successful, @c 0 otherwise. 171 | */ 172 | db_int close_osijoin(osijoin_t *jp, db_query_mm_t *mmp); 173 | 174 | #ifdef __cplusplus 175 | } 176 | #endif 177 | 178 | #endif 179 | -------------------------------------------------------------------------------- /src/dbops/project.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @file project.c 4 | @author Graeme Douglas 5 | @brief Implementation of the projection operator. 6 | @see For external method documentation, @ref project.h. 7 | @details 8 | @copyright Copyright 2013 Graeme Douglas 9 | @license Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | 14 | @par 15 | Unless required by applicable law or agreed to in writing, 16 | software distributed under the License is distributed on an 17 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 18 | either express or implied. See the License for the specific 19 | language governing permissions and limitations under the 20 | License. 21 | */ 22 | /******************************************************************************/ 23 | 24 | #include "db_ops_types.h" 25 | #include "project.h" 26 | #include "db_ops.h" 27 | 28 | /* Initialize the projection operator. */ 29 | db_int init_project(project_t *pp, db_op_base_t *childop_p, db_eet_t* exprs, 30 | db_uint8 num_exprs, db_query_mm_t *mmp) 31 | { 32 | pp->base.type = DB_PROJECT; 33 | pp->exprs = exprs; 34 | pp->num_exprs = num_exprs; 35 | 36 | pp->base.header = DB_QMM_BALLOC(mmp, sizeof(relation_header_t)); 37 | db_int result = createnewheader(pp->base.header, 38 | childop_p->header, exprs, num_exprs, mmp); 39 | pp->child = childop_p; 40 | return result; 41 | } 42 | 43 | /* This method assumes the scan is already initialized */ 44 | db_int rewind_project(project_t *pp, db_query_mm_t *mmp) 45 | { 46 | rewind_dbop(pp->child, mmp); 47 | return 1; 48 | } 49 | 50 | /* Retrieve next tuple. 51 | This assumes a properly initialized tuple with apropriate number of bytes 52 | is passed in. 53 | */ 54 | db_int next_project(project_t *pp, db_tuple_t *next_tp, db_query_mm_t *mmp) 55 | { 56 | db_tuple_t temp_t; 57 | init_tuple(&temp_t, pp->child->header->tuple_size, pp->child->header->num_attr, mmp); 58 | 59 | /* Get the next tuple from the child */ 60 | db_int result = next(pp->child, &temp_t, mmp); 61 | if (1 != result) 62 | { 63 | close_tuple(&temp_t, mmp); 64 | return result; 65 | } 66 | else 67 | { 68 | /* For each byte in the old tuple, if it belongs to an 69 | * attribute in the new tuple, copy it. 70 | */ 71 | db_int i = 0, k = 0; /* k for attributes, i for expressions. */ 72 | for (; i < (db_int)(pp->num_exprs); ++k, ++i) 73 | { 74 | if (NULL == pp->exprs[i].nodes) 75 | { 76 | db_int j_a, j_bytes; 77 | for (j_a = pp->exprs[i].stack_size; j_a < pp->exprs[i].stack_size + pp->exprs[i].size; ++j_a) 78 | { 79 | for (j_bytes = 0; j_bytes < (db_int)(pp->base.header->sizes[k]); ++j_bytes) 80 | { 81 | next_tp->bytes[pp->base.header->offsets[k] + j_bytes] = 82 | temp_t.bytes[(db_int)(pp->child->header->offsets[j_a]) + j_bytes]; 83 | } 84 | 85 | if (1==(((temp_t.isnull[j_a/8]) & (1 << (j_a % 8))) >> (j_a % 8))) 86 | { 87 | next_tp->isnull[(k / 8)] |= (1 << (k % 8)); 88 | } 89 | else 90 | { 91 | next_tp->isnull[(k / 8)] &= ~(1 << (k % 8)); 92 | } 93 | ++k; 94 | } 95 | 96 | /* Since we increment k below, must decrement now. */ 97 | k--; 98 | 99 | } 100 | else if (pp->base.header->types[k] == DB_INT) 101 | { 102 | db_int value; 103 | db_tuple_t *temp_tp = &temp_t; 104 | switch (evaluate_eet(&(pp->exprs[i]), &value, &temp_tp, 105 | &(pp->child->header), 0, mmp)) 106 | { 107 | case 2: 108 | /* Set this attributes isnull bit to 1. */ 109 | next_tp->isnull[(k / 8)] |= (1 << (k % 8)); 110 | break; 111 | case 1: 112 | /* Make sure this attributes isnull bit is 0. */ 113 | next_tp->isnull[(k / 8)] &= ~(1 << (k % 8)); 114 | *((db_int*)(&next_tp->bytes[pp->base.header->offsets[k]])) = 115 | value; 116 | break; 117 | case -1: 118 | default: 119 | close_tuple(&temp_t, mmp); 120 | return -1; 121 | } 122 | } 123 | else if (pp->base.header->types[k] == DB_STRING) 124 | { 125 | db_int j; 126 | char *value; 127 | db_tuple_t *temp_tp = &temp_t; 128 | switch (evaluate_eet(&(pp->exprs[i]), &value, &temp_tp, 129 | &(pp->child->header), 0, mmp)) 130 | { 131 | case 2: 132 | /* Set this attributes isnull bit to 1. */ 133 | next_tp->isnull[(k / 8)] |= (1 << (k % 8)); 134 | break; 135 | case 1: 136 | /* Make sure this attributes isnull bit is 0. */ 137 | next_tp->isnull[(k / 8)] &= ~(1 << (k % 8)); 138 | for (j = 0; j < strlen(value); j++) 139 | { 140 | next_tp->bytes[pp->base.header->offsets[k] + j] = (value[j]); 141 | } 142 | next_tp->bytes[pp->base.header->offsets[k] + strlen(value)] = '\0'; 143 | break; 144 | case -1: 145 | default: 146 | close_tuple(&temp_t, mmp); 147 | return -1; 148 | } 149 | } 150 | /* TODO: Implement future types here. */ 151 | } 152 | close_tuple(&temp_t, mmp); 153 | return 1; 154 | } 155 | } 156 | 157 | /* Close the projection operator. */ 158 | void close_project(project_t *pp, db_query_mm_t *mmp) 159 | { 160 | /* Free up header's properties */ 161 | DB_QMM_BFREE(mmp, pp->base.header->size_name); 162 | DB_QMM_BFREE(mmp, pp->base.header->names); 163 | DB_QMM_BFREE(mmp, pp->base.header->types); 164 | DB_QMM_BFREE(mmp, pp->base.header->offsets); 165 | DB_QMM_BFREE(mmp, pp->base.header->sizes); 166 | 167 | /* Free up header */ 168 | DB_QMM_BFREE(mmp, pp->base.header); 169 | } 170 | -------------------------------------------------------------------------------- /src/dbops/project.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @file project.h 4 | @author Graeme Douglas 5 | @brief The relational projection operator. 6 | @details This assumes a tuple at a time approach. 7 | @copyright Copyright 2013 Graeme Douglas 8 | @license Licensed under the Apache License, Version 2.0 (the "License"); 9 | you may not use this file except in compliance with the License. 10 | You may obtain a copy of the License at 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | @par 14 | Unless required by applicable law or agreed to in writing, 15 | software distributed under the License is distributed on an 16 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 17 | either express or implied. See the License for the specific 18 | language governing permissions and limitations under the 19 | License. 20 | */ 21 | /******************************************************************************/ 22 | 23 | #ifndef PROJECT_H 24 | #define PROJECT_H 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | #include "db_ops_types.h" 31 | #include "../dbobjects/relation.h" 32 | #include "../dbobjects/tuple.h" 33 | #include "../dblogic/eet.h" 34 | #include 35 | #include 36 | 37 | /* Initialize the projection operator. */ 38 | /** 39 | @brief Initialize a projection operator. 40 | @param pp A pointer to a projection operator to be 41 | intialized. 42 | @param childop_p A pointer to the operator that will pass 43 | tuples into the projection operator. 44 | @param exprs The array of projecting bytecode expressions. 45 | @param num_exprs The number of expressions in @p exprs. 46 | @param mmp Pointer to the per-query memory manager that is 47 | being used to allocate memory for the query. 48 | */ 49 | db_int init_project(project_t *pp, 50 | db_op_base_t *childop_p, 51 | db_eet_t *exprs, 52 | db_uint8 num_exprs, 53 | db_query_mm_t *mmp); 54 | 55 | /* This method assumes the scan is already initialized */ 56 | /** 57 | @brief Rewind the projection operator. 58 | @see Reference @ref rewind_dbop for documentation. 59 | */ 60 | db_int rewind_project(project_t *pp, db_query_mm_t *mmp); 61 | 62 | /* Retrieve next tuple. */ 63 | /** 64 | @brief Retrieve the next tuple from the projection operator. 65 | @see Reference @ref next for documentation. 66 | */ 67 | db_int next_project(project_t *pp, db_tuple_t *next_tp, db_query_mm_t *mmp); 68 | 69 | /* Close the projection operator. */ 70 | /** 71 | @brief Safely destroy a projection operator. 72 | @see Reference @ref close for documentation. 73 | */ 74 | void close_project(project_t *pp, db_query_mm_t *mmp); 75 | 76 | #ifdef __cplusplus 77 | } 78 | #endif 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /src/dbops/scan.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @file scan.c 4 | @author Graeme Douglas 5 | @brief The scan operator implementation. 6 | @see For all external function definitions, reference 7 | @ref scan.h. 8 | @details 9 | @copyright Copyright 2013 Graeme Douglas 10 | @license Licensed under the Apache License, Version 2.0 (the "License"); 11 | you may not use this file except in compliance with the License. 12 | You may obtain a copy of the License at 13 | http://www.apache.org/licenses/LICENSE-2.0 14 | 15 | @par 16 | Unless required by applicable law or agreed to in writing, 17 | software distributed under the License is distributed on an 18 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 19 | either express or implied. See the License for the specific 20 | language governing permissions and limitations under the 21 | License. 22 | */ 23 | /******************************************************************************/ 24 | 25 | #include "../dbstorage/dbstorage.h" 26 | #include "scan.h" 27 | #include "db_ops.h" 28 | 29 | /* Initialize the scan operator. */ 30 | db_int init_scan(scan_t *sp, char* relationName, db_query_mm_t *mmp) 31 | { 32 | if (sp == NULL || 1 != getrelationheader(&(sp->base.header), relationName, mmp)) 33 | return -1; 34 | 35 | sp->base.type = DB_SCAN; 36 | 37 | sp->indexon = -1; 38 | 39 | sp->tuple_start = 1; 40 | int i; 41 | for (i = 0; i < (db_int)sp->base.header->num_attr; ++i) 42 | { 43 | sp->tuple_start += 4; /* constant sized info */ 44 | sp->tuple_start += (long)(sp->base.header->size_name[i]); 45 | } 46 | 47 | sp->relation = db_openreadfile(relationName); 48 | rewind_scan(sp, mmp); 49 | 50 | /* Build up index info. */ 51 | char metaname[9+strlen(relationName)]; 52 | sprintf(metaname, "DB_IDXM_%s", relationName); 53 | db_fileref_t idxmetafile = db_openreadfile(metaname); 54 | 55 | if (DB_STORAGE_NOFILE == idxmetafile) 56 | { 57 | sp->idx_meta_data.num_idx = 0; 58 | return 1; 59 | } 60 | 61 | db_fileread(idxmetafile, &(sp->idx_meta_data.num_idx), sizeof(db_uint8)); 62 | sp->idx_meta_data.len_names = DB_QMM_BALLOC(mmp, sizeof(db_uint8)*(sp->idx_meta_data.num_idx)); 63 | sp->idx_meta_data.names = DB_QMM_BALLOC(mmp, sizeof(char*)*(sp->idx_meta_data.num_idx)); 64 | sp->idx_meta_data.num_expr = DB_QMM_BALLOC(mmp, sizeof(db_uint8)*(sp->idx_meta_data.num_idx)); 65 | sp->idx_meta_data.exprs = DB_QMM_BALLOC(mmp, sizeof(db_eet_t*)*(sp->idx_meta_data.num_idx)); 66 | 67 | int j; 68 | for (i = 0; i < sp->idx_meta_data.num_idx; ++i) 69 | { 70 | // TODO: Make sure all pointers passed to read function make sense. 71 | db_fileread(idxmetafile, &(sp->idx_meta_data.len_names[i]), sizeof(db_uint8)); 72 | sp->idx_meta_data.names[i] = DB_QMM_BALLOC(mmp, sp->idx_meta_data.len_names[i]); 73 | db_fileread(idxmetafile, (unsigned char*)(sp->idx_meta_data.names[i]), sp->idx_meta_data.len_names[i]); 74 | db_fileread(idxmetafile, &(sp->idx_meta_data.num_expr[i]), sizeof(db_uint8)); 75 | sp->idx_meta_data.exprs[i] = DB_QMM_BALLOC(mmp, sizeof(db_eet_t)*(sp->idx_meta_data.num_expr[i])); 76 | db_fileread(idxmetafile, (unsigned char*)(sp->idx_meta_data.exprs[i]), sizeof(db_eet_t)*(sp->idx_meta_data.num_expr[i])); 77 | 78 | for (j = 0; j < sp->idx_meta_data.num_expr[i]; ++j) 79 | { 80 | sp->idx_meta_data.exprs[i][j].nodes = DB_QMM_BALLOC(mmp, (sp->idx_meta_data.exprs[i][j].size)); 81 | db_fileread(idxmetafile, (unsigned char*)(sp->idx_meta_data.exprs[i][j].nodes), (sp->idx_meta_data.exprs[i][j].size)); 82 | } 83 | } 84 | 85 | db_fileclose(idxmetafile); 86 | 87 | return 1; 88 | } 89 | 90 | /* This method assumes the scan is already initialized */ 91 | db_int rewind_scan(scan_t *sp, db_query_mm_t *mmp) 92 | { 93 | /* Go to beginning, skip over header information. */ 94 | db_filerewind(sp->relation); 95 | db_fileseek(sp->relation, sp->tuple_start); 96 | return 1; 97 | } 98 | 99 | /* Retrieve the next tuple from the relation. */ 100 | db_int next_scan(scan_t *sp, db_tuple_t *next_tp, db_query_mm_t *mmp) 101 | { 102 | db_int bit_arr_size = ((db_int)(sp->base.header->num_attr)) / 8; 103 | if (((db_int)(sp->base.header->num_attr)) % 8 > 0) 104 | { 105 | bit_arr_size++; 106 | } 107 | if (bit_arr_size == db_fileread(sp->relation, (unsigned char*)next_tp->isnull, SIZE_BYTE * bit_arr_size)) 108 | { 109 | if ((size_t)(sp->base.header->tuple_size) == db_fileread(sp->relation, (unsigned char*)next_tp->bytes, SIZE_BYTE * (db_int)(sp->base.header->tuple_size))) 110 | { 111 | // TODO: Right now, this assumes we only use ints for index. 112 | /* Only check stop condition if it exists. */ 113 | if (sp->indexon > -1) 114 | { 115 | db_int val; 116 | val = getintbypos(next_tp, sp->indexon, sp->base.header); 117 | if (val >= sp->stopat) return 0; 118 | } 119 | #if 0 120 | #endif 121 | 122 | return 1; 123 | } 124 | else 125 | { 126 | return 0; 127 | } 128 | } 129 | else 130 | { 131 | return 0; 132 | } 133 | } 134 | 135 | /* Close the operator. */ 136 | void close_scan(scan_t *sp, db_query_mm_t *mmp) 137 | { 138 | /* Close the file stream. */ 139 | db_fileclose(sp->relation); 140 | 141 | freerelationheader(sp->base.header, mmp); 142 | 143 | /* Free indexing information, if necessary. */ 144 | if (sp->idx_meta_data.num_idx > 0) 145 | { 146 | int i, j; 147 | for (i = 0; i < (db_int)sp->idx_meta_data.num_idx; i++) 148 | { 149 | DB_QMM_BFREE(mmp, sp->idx_meta_data.names[i]); 150 | for (j = 0; j < (db_int)sp->idx_meta_data.num_expr[i]; j++) 151 | DB_QMM_BFREE(mmp, sp->idx_meta_data.exprs[i][j].nodes); 152 | DB_QMM_BFREE(mmp, sp->idx_meta_data.exprs[i]); 153 | } 154 | DB_QMM_BFREE(mmp, sp->idx_meta_data.len_names); 155 | DB_QMM_BFREE(mmp, sp->idx_meta_data.names); 156 | DB_QMM_BFREE(mmp, sp->idx_meta_data.num_expr); 157 | DB_QMM_BFREE(mmp, sp->idx_meta_data.exprs); 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /src/dbops/scan.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @file scan.h 4 | @author Graeme Douglas 5 | @brief The scan operator. 6 | @details 7 | @copyright Copyright 2013 Graeme Douglas 8 | @license Licensed under the Apache License, Version 2.0 (the "License"); 9 | you may not use this file except in compliance with the License. 10 | You may obtain a copy of the License at 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | @par 14 | Unless required by applicable law or agreed to in writing, 15 | software distributed under the License is distributed on an 16 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 17 | either express or implied. See the License for the specific 18 | language governing permissions and limitations under the 19 | License. 20 | */ 21 | /******************************************************************************/ 22 | 23 | #ifndef SCAN_H 24 | #define SCAN_H 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | #include "../db_ctconf.h" 31 | #include "../ref.h" 32 | #include "db_ops_types.h" 33 | #include "../dbobjects/relation.h" 34 | #include "../dbobjects/tuple.h" 35 | #include "../dbindex/dbindex_types.h" 36 | #include "../db_ctconf.h" 37 | #if defined(DB_CTCONF_SETTING_TARGET) && DB_CTCONF_SETTING_TARGET == DB_CTCONF_OPTION_TARGET_ARDUINO 38 | #include "../arduinodebug.h" 39 | #endif 40 | #include 41 | #include 42 | 43 | /* Initialize the scan operator. */ 44 | /** 45 | @brief Initialize a scan operator. 46 | @param sp A pointer to the scan operator to be intialized. 47 | @param relationName The name of the relation to be scanned. 48 | @param mmp A pointer to the per-query memory manager that 49 | will be allocate memory for this query. 50 | @returns @c 1 if the operator was successfully initialized, @c -1 if an 51 | error occurred. 52 | */ 53 | db_int init_scan(scan_t *sp, 54 | char* relationName, 55 | db_query_mm_t *mmp); 56 | 57 | /* Rewind a scan operator. */ 58 | /** 59 | @brief Rewind the scan operator. 60 | @see Reference @ref rewind_dbop for more information. 61 | */ 62 | db_int rewind_scan(scan_t *sp, db_query_mm_t *mmp); 63 | 64 | /* Retrieve the next tuple from the relation. */ 65 | /** 66 | @brief Retrieve the next tuple from storage mechanism. 67 | @see Reference @ref next for more information. 68 | */ 69 | db_int next_scan(scan_t *sp, db_tuple_t *next_tp, db_query_mm_t *mmp); 70 | 71 | /* Close scan. */ 72 | /** 73 | @brief Safely deconstruct the scan operator. 74 | @see Reference @ref close for more inforamtion. 75 | */ 76 | void close_scan(scan_t *sp, db_query_mm_t *mmp); 77 | 78 | #ifdef __cplusplus 79 | } 80 | #endif 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /src/dbops/select.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @file select.c 4 | @author Graeme Douglas 5 | @brief The implementation of the relation selection operator. 6 | @see For more information, refer to @ref select.h. 7 | @details 8 | @copyright Copyright 2013 Graeme Douglas 9 | @license Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | 14 | @par 15 | Unless required by applicable law or agreed to in writing, 16 | software distributed under the License is distributed on an 17 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 18 | either express or implied. See the License for the specific 19 | language governing permissions and limitations under the 20 | License. 21 | */ 22 | /******************************************************************************/ 23 | 24 | #include "db_ops_types.h" 25 | #include "select.h" 26 | #include "db_ops.h" 27 | #include "../dblogic/eet.h" 28 | 29 | /* Initialize the selection operator. */ 30 | db_int init_select(select_t *sp, db_eet_t *ep, db_op_base_t *child, db_query_mm_t *mmp) 31 | { 32 | sp->base.type = DB_SELECT; 33 | sp->base.header = child->header; 34 | sp->tree = ep; 35 | sp->child = child; 36 | return 1; 37 | } 38 | 39 | /* This method assumes the scan is already initialized */ 40 | db_int rewind_select(select_t *sp, db_query_mm_t *mmp) 41 | { 42 | rewind_dbop(sp->child, mmp); 43 | return 1; 44 | } 45 | 46 | /* Find next tuple that passes the selection condition. 47 | -This assumes that the evaluation tree will alway s reduce to either 0 or 1 48 | all tuples. */ 49 | db_int next_select(select_t *sp, db_tuple_t *next_tp, db_query_mm_t *mmp) 50 | { 51 | /* Create necessary result variable. */ 52 | db_int result, retval = 0; 53 | while(1) 54 | { 55 | /* Get next tuple from operator below. */ 56 | result = next(sp->child, next_tp, mmp); 57 | /* Evaluate select eet on this tuple. 58 | -Note that we can make the assumption that the header and 59 | tuple arrays will be only one attribute big, hence why 60 | the following code works. */ 61 | if (1==result) 62 | { 63 | retval = evaluate_eet(sp->tree, &result, &next_tp, &(sp->base.header), 0, mmp); 64 | if (1 == result && 1 == retval) 65 | { 66 | break; 67 | } 68 | } 69 | else 70 | { 71 | break; 72 | } 73 | } 74 | return result; 75 | } 76 | 77 | /* Close the selection operator. */ 78 | db_int close_select(select_t *sp, db_query_mm_t *mmp) 79 | { 80 | /* For the time being, do nothing! */ 81 | return 1; 82 | } 83 | -------------------------------------------------------------------------------- /src/dbops/select.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @file select.h 4 | @author Graeme Douglas 5 | @brief The relational selection operator. 6 | @details Selection (WHERE) is the part of the query that filters results 7 | that do not involve any form of aggregation/grouping. 8 | In other words, we choose tuples that meet some condition. 9 | @copyright Copyright 2013 Graeme Douglas 10 | @license Licensed under the Apache License, Version 2.0 (the "License"); 11 | you may not use this file except in compliance with the License. 12 | You may obtain a copy of the License at 13 | http://www.apache.org/licenses/LICENSE-2.0 14 | 15 | @par 16 | Unless required by applicable law or agreed to in writing, 17 | software distributed under the License is distributed on an 18 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 19 | either express or implied. See the License for the specific 20 | language governing permissions and limitations under the 21 | License. 22 | */ 23 | /******************************************************************************/ 24 | 25 | #ifndef SELECT_H 26 | #define SELECT_H 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | #include "db_ops_types.h" 33 | #include "../dbobjects/relation.h" 34 | #include "../dbobjects/tuple.h" 35 | 36 | /* Initialize the selection operator. */ 37 | /** 38 | @brief Intialize a selection operator. 39 | @param sp A pointer to the selection operator that is to 40 | be initialized. 41 | @param ep A pointer to the bytecode expression that will 42 | be used to filter results. 43 | @param child A pointer to the relational operator that will 44 | be passing tuples into the selection. 45 | @param mmp A pointer to the per-query memory manager that 46 | will be used to allocate memory for this query. 47 | */ 48 | db_int init_select(select_t *sp, 49 | db_eet_t *ep, 50 | db_op_base_t *child, 51 | db_query_mm_t *mmp); 52 | 53 | /* Find next tuple that passes the selection condition. */ 54 | /** 55 | @brief Retrieve the next tuple from a selection operator. 56 | @details This assumes that the filtering expression will always 57 | reduce to either @c 0 or @c 1 (@c false / @c true). 58 | @see For more information, reference @ref next. 59 | */ 60 | db_int next_select(select_t *sp, db_tuple_t *next_tp, db_query_mm_t *mmp); 61 | 62 | /* Rewind the selection operator. */ 63 | /** 64 | @brief Rewind the selection operator. 65 | @see For more information, reference @ref rewind_dbop. 66 | */ 67 | db_int rewind_select(select_t *sp, db_query_mm_t *mmp); 68 | 69 | /* Cclose the selection operator. */ 70 | /** 71 | @brief Safely deconstruct the selection operator. 72 | @see For more information, reference @ref close. 73 | */ 74 | db_int close_select(select_t *sp, db_query_mm_t *mmp); 75 | 76 | #ifdef __cplusplus 77 | } 78 | #endif 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /src/dbops/sort.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @file sort.c 4 | @author Graeme Douglas 5 | @brief The implementation for the sort operator. 6 | @see For more information, see @ref sort.h. 7 | @details 8 | @copyright Copyright 2013 Graeme Douglas 9 | @license Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | 14 | @par 15 | Unless required by applicable law or agreed to in writing, 16 | software distributed under the License is distributed on an 17 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 18 | either express or implied. See the License for the specific 19 | language governing permissions and limitations under the 20 | License. 21 | */ 22 | /******************************************************************************/ 23 | 24 | #include "sort.h" 25 | #include "db_ops.h" 26 | #include "../dblogic/compare_tuple.h" 27 | 28 | /* Initialize the sort operator. */ 29 | db_int init_sort(sort_t *sp, db_op_base_t *child, db_eet_t *sort_exprs, 30 | db_uint8 num_expr, db_uint8 *order, db_query_mm_t *mmp) 31 | { 32 | sp->base.type = DB_SORT; 33 | sp->base.header = child->header; 34 | 35 | /* Allocate memory for the previous tuple. */ 36 | sp->previous_tp = NULL; 37 | 38 | sp->next_count = 0; 39 | sp->child = child; 40 | sp->sort_exprs = sort_exprs; 41 | sp->num_expr = num_expr; 42 | sp->order = order; 43 | return 1; 44 | } 45 | 46 | /* Rewind the sort operator. */ 47 | db_int rewind_sort(sort_t *sp, db_query_mm_t *mmp) 48 | { 49 | switch (rewind_dbop(sp->child, mmp)) 50 | { 51 | case 1: 52 | if (sp->previous_tp != NULL) 53 | { 54 | close_tuple(sp->previous_tp, mmp); 55 | DB_QMM_BFREE(mmp, sp->previous_tp); 56 | } 57 | sp->previous_tp = NULL; 58 | return 1; 59 | case 0: 60 | return 0; 61 | default: 62 | return -1; /* Error out. */ 63 | } 64 | } 65 | 66 | /* Return the next tuple from the sort operator. */ 67 | db_int next_sort(sort_t *sp, db_tuple_t *tp, db_query_mm_t *mmp) 68 | { 69 | if (sp == NULL) 70 | return -1; 71 | if (tp == NULL) 72 | return -1; 73 | if (tp->bytes == NULL) 74 | return -1; 75 | 76 | db_int i; 77 | if (sp->next_count > 0) 78 | { 79 | if (sp->previous_tp == NULL) 80 | return -1; 81 | if (sp->previous_tp->bytes == NULL) 82 | return -1; 83 | 84 | /* Copy out previous's bytes to next. */ 85 | for (i = 0; i < (db_int)(sp->base.header->tuple_size); ++i) 86 | { 87 | tp->bytes[i] = sp->previous_tp->bytes[i]; 88 | } 89 | for (i = 0; i < (db_int)(sp->base.header->num_attr); ++i) 90 | { 91 | tp->isnull[i/8] = sp->previous_tp->isnull[i/8]; 92 | } 93 | sp->next_count--; 94 | return 1; 95 | } 96 | switch (next_inorder_tuple(tp, sp->previous_tp, &(sp->next_count), 97 | sp->child, (sp->sort_exprs), sp->num_expr, sp->order, mmp)) 98 | { 99 | case 1: 100 | if (sp->previous_tp == NULL) 101 | { 102 | sp->previous_tp = DB_QMM_BALLOC(mmp, sizeof(db_tuple_t)); 103 | init_tuple(sp->previous_tp, 104 | sp->base.header->tuple_size, 105 | sp->base.header->num_attr, mmp); 106 | } 107 | /* Decrement the count by 1. */ 108 | (sp->next_count)--; 109 | /* Copy out next's bytes to previous. */ 110 | for (i = 0; i < (db_int)sp->base.header->tuple_size; ++i) 111 | { 112 | sp->previous_tp->bytes[i] = tp->bytes[i]; 113 | } 114 | for (i = 0; i < (db_int)(sp->base.header->num_attr); ++i) 115 | { 116 | sp->previous_tp->isnull[i/8] = tp->isnull[i/8]; 117 | } 118 | return 1; 119 | case 0: 120 | /* Decrement the count by 1. */ 121 | (sp->next_count)--; 122 | return 0; 123 | default: 124 | /* Decrement the count by 1. */ 125 | (sp->next_count)--; 126 | return -1; /* Error out. */ 127 | } 128 | } 129 | 130 | /* Close the sort operator. */ 131 | db_int close_sort(sort_t *sp, db_query_mm_t *mmp) 132 | { 133 | /* Free memory used by previous tuple, if it was initialized. */ 134 | if (sp->previous_tp != NULL) 135 | { 136 | close_tuple(sp->previous_tp, mmp); 137 | DB_QMM_BFREE(mmp, sp->previous_tp); 138 | } 139 | return 1; 140 | } 141 | -------------------------------------------------------------------------------- /src/dbops/sort.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @file sort.h 4 | @author Graeme Douglas 5 | @brief The relational sort operator. 6 | @details This is the relational operator behind the ORDER BY clause. 7 | @copyright Copyright 2013 Graeme Douglas 8 | @license Licensed under the Apache License, Version 2.0 (the "License"); 9 | you may not use this file except in compliance with the License. 10 | You may obtain a copy of the License at 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | @par 14 | Unless required by applicable law or agreed to in writing, 15 | software distributed under the License is distributed on an 16 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 17 | either express or implied. See the License for the specific 18 | language governing permissions and limitations under the 19 | License. 20 | */ 21 | /******************************************************************************/ 22 | 23 | #ifndef SORT_H 24 | #define SORT_H 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | #include 31 | #include "../dbobjects/relation.h" 32 | #include "../dbobjects/tuple.h" 33 | #include "../ref.h" 34 | #include "db_ops_types.h" 35 | 36 | /* Initialize the sort operator. */ 37 | /** 38 | @brief Initialize a relational sort operator. 39 | @param sp A pointer to the sort operator to be 40 | initialized. 41 | @param child A pointer to the operator that will 42 | pass tuples into the sort operator. 43 | @param sort_exprs An array of bytecode expressions that 44 | determine how to order the tuples. 45 | @param num_expr The number of expressions in @p sort_exprs. 46 | @param order An array of integers determining what order to 47 | sort the tuples for each expression. This 48 | should have exactly @p num_expr integers. 49 | @param mmp A pointer to the memory manager pointer to be 50 | used to allocate memory for this query. 51 | */ 52 | db_int init_sort(sort_t *sp, 53 | db_op_base_t *child, 54 | db_eet_t *sort_exprs, 55 | db_uint8 num_expr, 56 | db_uint8 *order, 57 | db_query_mm_t *mmp); 58 | 59 | /* Rewind the sort operator. */ 60 | /** 61 | @brief Rewind a sort operator. 62 | @see For more information, reference @ref rewind_dbop. 63 | */ 64 | db_int rewind_sort(sort_t *sp, db_query_mm_t *mmp); 65 | 66 | /* Return the next tuple from the sort operator. */ 67 | /** 68 | @brief Retrieve the next sorted tuple from a sort operator. 69 | @see For more information, reference @ref next. 70 | */ 71 | db_int next_sort(sort_t *sp, db_tuple_t *tp, db_query_mm_t *mmp); 72 | 73 | /* Close the sort operator. */ 74 | /** 75 | @brief Cleanly deconstruct a sort operator. 76 | @see For more information, reference @ref close. 77 | */ 78 | db_int close_sort(sort_t *sp, db_query_mm_t *mmp); 79 | 80 | #ifdef __cplusplus 81 | } 82 | #endif 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /src/dboutput/query_output.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @file query_output.h 4 | @author Graeme Douglas 5 | @brief Output queries to string or standard output. 6 | @details 7 | @copyright Copyright 2013 Graeme Douglas 8 | @license Licensed under the Apache License, Version 2.0 (the "License"); 9 | you may not use this file except in compliance with the License. 10 | You may obtain a copy of the License at 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | @par 14 | Unless required by applicable law or agreed to in writing, 15 | software distributed under the License is distributed on an 16 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 17 | either express or implied. See the License for the specific 18 | language governing permissions and limitations under the 19 | License. 20 | */ 21 | /******************************************************************************/ 22 | 23 | #ifndef QUERY_OUTPUT_H 24 | #define QUERY_OUTPUT_H 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | #include "../dbmm/db_query_mm.h" 31 | #include "../dbobjects/relation.h" 32 | #include "../dbobjects/tuple.h" 33 | #include "../dbops/db_ops.h" 34 | #include "../ref.h" 35 | #include 36 | #include 37 | 38 | /** 39 | @brief Print a query to standard out. 40 | @details The query will be formatted into a string and then printed 41 | out via the standard output. If the target system does 42 | not have a large enough section of memory to stringize the 43 | results, don't call the method. 44 | @param op A pointer to the root operator for the query's 45 | execution tree. 46 | @param mmp A pointer to the per-query memory manager used 47 | to allocate memory for the query. 48 | */ 49 | void printQuery(db_op_base_t *op, 50 | db_query_mm_t *mmp); 51 | 52 | /** 53 | @brief Format the query results into a stirng. 54 | @details If your system does not have enough memory to format the 55 | results into a string, do not call this method. The result 56 | must be freed! 57 | @param op A pointer to the root operator for the query's 58 | execution tree. 59 | @param mmp A pointer to the per-query memory manager used 60 | to allocate memory for the query. 61 | @returns The formatted query. 62 | */ 63 | char* formatQuery(db_op_base_t *op, 64 | db_query_mm_t *mmp); 65 | 66 | /** 67 | @brief Print a query to standard out. 68 | @param op A pointer to the root operator for the query's 69 | execution tree. 70 | @param next_t A pointer to an initialized tuple corresponding 71 | to @p op. 72 | @param mmp A pointer to the per-query memory manager used 73 | to allocate memory for the query. 74 | @returns The size of the string representing the query. 75 | */ 76 | db_int sizeQuery(db_op_base_t *op, 77 | db_tuple_t *next_t, 78 | db_query_mm_t *mmp); 79 | 80 | /** 81 | @brief Format a tuple. 82 | @details The result must be free! 83 | @param toprint The tuple to be formatted. 84 | @param op A pointer to the root operator for the query's 85 | execution tree. 86 | @param widths The width of each formatted column in the 87 | query results. 88 | @returns The formatted tuple. 89 | */ 90 | char* formatTuple(db_tuple_t *toprint, 91 | db_op_base_t *op, 92 | db_int *widths); 93 | 94 | /** 95 | @brief Print a tuple. 96 | @param toprint The tuple to be printed. 97 | @param op A pointer to the root operator for the query's 98 | execution tree. 99 | @param widths The width of each formatted column in the 100 | query results. 101 | */ 102 | void printTuple(db_tuple_t *toprint, 103 | db_op_base_t *op, 104 | db_int *widths); 105 | 106 | /** 107 | @brief Print a row separator. 108 | @param op A pointer to the root operator in the query 109 | execution tree. 110 | @param widths The widths of each formatted column in the 111 | query results. 112 | */ 113 | void printRowSeparator(db_op_base_t *op, 114 | db_int *widths); 115 | 116 | /** 117 | @brief Format a row separator. 118 | @details This must be freed! 119 | @param op A pointer to the root operator in the query 120 | execution tree. 121 | @param widths The widths of each formatted column in the 122 | query results. 123 | @returns A formatted row separator for the query results. 124 | */ 125 | char* formatRowSeparator(db_op_base_t *op, 126 | db_int *widths); 127 | 128 | /** 129 | @brief Get the size of the string representation of a row 130 | in the query results. 131 | @param op A pointer to the root operator in the query 132 | execution tree. 133 | @param widths The widths of each formatted column in the 134 | query results. 135 | @returns The size of the string representation of a row in 136 | the query results. 137 | */ 138 | db_int sizeOfRow(db_op_base_t *op, 139 | db_int *widths); 140 | 141 | /** 142 | @brief Compute the widths of each column in the formatted 143 | query results. 144 | @details Allocated space for @p widths must be freed! 145 | @param op A pointer to the root operator in the query 146 | execution tree. 147 | @param widths A pointer that will be set to an array 148 | of @c db_int values, one for each 149 | column in the query output. 150 | */ 151 | void computeWidths(db_op_base_t *op, 152 | db_int *widths); 153 | 154 | #ifdef __cplusplus 155 | } 156 | #endif 157 | 158 | #endif 159 | -------------------------------------------------------------------------------- /src/dbparser/dbcreate.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @file dbcreate.c 4 | @author Graeme Douglas 5 | @brief Implementation of databases create functions. 6 | @see For more information, refer to @ref dbcreate.h. 7 | @details 8 | @copyright Copyright 2013 Graeme Douglas 9 | @license Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | 14 | @par 15 | Unless required by applicable law or agreed to in writing, 16 | software distributed under the License is distributed on an 17 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 18 | either express or implied. See the License for the specific 19 | language governing permissions and limitations under the 20 | License. 21 | */ 22 | /******************************************************************************/ 23 | 24 | #include "dbcreate.h" 25 | #include "../db_ctconf.h" 26 | 27 | #if defined(DB_CTCONF_SETTING_FEATURE_CREATE_TABLE) && 1==DB_CTCONF_SETTING_FEATURE_CREATE_TABLE 28 | /** 29 | @brief Create a table. 30 | @details This function creates a table from a simplified CREATE TABLE 31 | statement. This function assumes that the 'CREATE' and 32 | 'TABLE' tokens have been thrown away; that is, the next token 33 | to process is the table's name. 34 | @param lexerp A pointer to the lexer instance variable that 35 | is generating the token stream. 36 | @param end The index of the first character in the command 37 | being lexed that is not part of the CREATE 38 | statement. 39 | @param mmp A pointer to the per-query memory manager being 40 | used to process this query. 41 | @returns @c 1 if the table was created successfully, @c -1 if an error 42 | occurred, @c 0 otherwise. 43 | */ 44 | db_int createTable(db_lexer_t *lexerp, db_int end, db_query_mm_t *mmp) 45 | { 46 | db_fileref_t newtable; 47 | char *tablename; 48 | 49 | /* Create a file with table name. */ 50 | if (1==lexer_next(lexerp) && (db_uint8)DB_LEXER_TT_IDENT == lexerp->token.type) 51 | { 52 | tablename = db_qmm_falloc(mmp, gettokenlength(&(lexerp->token))+1); 53 | gettokenstring(&(lexerp->token), tablename, lexerp); 54 | 55 | if (db_fileexists(tablename)) 56 | { 57 | DB_ERROR_MESSAGE("duplicate table name", lexerp->token.start, lexerp->command); 58 | db_qmm_ffree(mmp, tablename); 59 | return -1; 60 | } 61 | 62 | newtable = db_openwritefile(tablename); 63 | } 64 | 65 | /* Throw away the bracket. */ 66 | if (1!=lexer_next(lexerp) || DB_LEXER_TT_LPAREN != lexerp->token.type) 67 | { 68 | DB_ERROR_MESSAGE("missing '('", lexerp->offset, lexerp->command); 69 | db_fileclose(newtable); 70 | db_fileremove(tablename); 71 | db_qmm_ffree(mmp, tablename); 72 | return -1; 73 | } 74 | 75 | db_uint8 attrcount = 0; 76 | int i; 77 | db_lexer_token_t *arr = db_qmm_balloc(mmp, 0); 78 | 79 | while (1==lexer_next(lexerp) && DB_LEXER_TT_RPAREN != lexerp->token.type) 80 | { 81 | if (attrcount > 0 && DB_LEXER_TT_COMMA != lexerp->token.type) 82 | { 83 | DB_ERROR_MESSAGE("duplicate attr name", lexerp->token.start, lexerp->command); 84 | db_qmm_bfree(mmp, arr); 85 | db_fileclose(newtable); 86 | db_fileremove(tablename); 87 | db_qmm_ffree(mmp, tablename); 88 | return -1; 89 | } 90 | else if (attrcount > 0 && 1!=lexer_next(lexerp)) 91 | { 92 | DB_ERROR_MESSAGE("dangling comma", lexerp->offset, lexerp->command); 93 | db_qmm_bfree(mmp, arr); 94 | db_fileclose(newtable); 95 | db_fileremove(tablename); 96 | db_qmm_ffree(mmp, tablename); 97 | return -1; 98 | } 99 | 100 | if (DB_LEXER_TT_IDENT == lexerp->token.type) 101 | { 102 | int length = gettokenlength(&(lexerp->token)); 103 | char attrname[length+1]; 104 | gettokenstring(&(lexerp->token), attrname, lexerp); 105 | 106 | /* Validate unique attribute name. */ 107 | for (i = 0; i < (int)attrcount; ++i) 108 | { 109 | if (1==token_stringequal(arr+i, attrname, length, lexerp, 0)) 110 | { 111 | DB_ERROR_MESSAGE("duplicate attr name", lexerp->token.start, lexerp->command); 112 | db_qmm_bfree(mmp, arr); 113 | db_fileclose(newtable); 114 | db_fileremove(tablename); 115 | db_qmm_ffree(mmp, tablename); 116 | return -1; 117 | } 118 | } 119 | 120 | /* Add current token to set to check in future. */ 121 | arr=db_qmm_bextend(mmp, sizeof(db_lexer_token_t)); 122 | arr[0] = lexerp->token; 123 | 124 | /* We will perform some hackiness here. Since we need 125 | to know the number of attributes before we write, 126 | we will simply store the values of the types, and 127 | if necessary, lengths, in the tokens. */ 128 | if (1==lexer_next(lexerp) && DB_LEXER_TOKENINFO_TYPE_DBINT == lexerp->token.info) 129 | { 130 | arr[0].type = DB_INT; 131 | arr[0].bcode = sizeof(db_int); 132 | } 133 | /* Extract size of the string. */ 134 | else if (DB_LEXER_TOKENINFO_TYPE_DBSTRING == lexerp->token.info && 135 | 1==lexer_next(lexerp) && DB_LEXER_TT_LPAREN == lexerp->token.type && 136 | 1==lexer_next(lexerp) && DB_LEXER_TT_INT == lexerp->token.type && 137 | (length=getintegerfromtoken(&(lexerp->token), lexerp)) > 0 && 138 | length <= DB_CTCONF_SETTING_MAXSTRINGLENGTH && 139 | 1==lexer_next(lexerp) && DB_LEXER_TT_RPAREN == lexerp->token.type) 140 | { 141 | arr[0].type = DB_STRING; 142 | arr[0].bcode = length; 143 | } 144 | /* TODO: Implement future types here. */ 145 | else 146 | { 147 | DB_ERROR_MESSAGE("bad attribute type", lexerp->token.start, lexerp->command); 148 | db_qmm_bfree(mmp, arr); 149 | db_fileclose(newtable); 150 | db_fileremove(tablename); 151 | db_qmm_ffree(mmp, tablename); 152 | return -1; 153 | } 154 | } 155 | else 156 | { 157 | DB_ERROR_MESSAGE("bad attribute declaration", lexerp->token.start, lexerp->command); 158 | db_qmm_bfree(mmp, arr); 159 | db_fileclose(newtable); 160 | db_fileremove(tablename); 161 | db_qmm_ffree(mmp, tablename); 162 | return -1; 163 | } 164 | 165 | attrcount++; 166 | } 167 | 168 | /* Build out the new relation file. */ 169 | db_filewrite(newtable, &attrcount, sizeof(db_uint8)); 170 | db_uint8 offset = 0; 171 | db_uint8 temp; 172 | 173 | while (attrcount > 0) 174 | { 175 | /* Write out the length of the attribute name. */ 176 | db_uint8 length = (db_uint8)gettokenlength(&(arr[((int)attrcount)-1]))+1; 177 | char attrname[(int)length]; 178 | gettokenstring(&(arr[((int)attrcount)-1]), attrname, lexerp); 179 | 180 | /* Write out the attribute name. */ 181 | db_filewrite(newtable, &length, sizeof(db_uint8)); 182 | db_filewrite(newtable, attrname, (size_t)length); 183 | 184 | /* Write out the attribute type. */ 185 | temp = (db_uint8)(arr[((int)attrcount)-1].type); 186 | db_filewrite(newtable, &temp, sizeof(db_uint8)); 187 | 188 | /* Write out the offset and size. */ 189 | temp = (db_uint8)arr[((int)attrcount)-1].bcode; 190 | db_filewrite(newtable, &offset, sizeof(db_uint8)); 191 | db_filewrite(newtable, &temp, sizeof(db_uint8)); 192 | offset += temp; 193 | 194 | attrcount--; 195 | } 196 | 197 | db_qmm_bfree(mmp, arr); 198 | db_fileclose(newtable); 199 | 200 | /* Throw away the bracket. */ 201 | if (DB_LEXER_TT_RPAREN != lexerp->token.type) 202 | { 203 | DB_ERROR_MESSAGE("missing ')'", lexerp->offset, lexerp->command); 204 | db_fileremove(tablename); 205 | db_qmm_ffree(mmp, tablename); 206 | return -1; 207 | } 208 | 209 | if (end < lexerp->offset) 210 | { 211 | DB_ERROR_MESSAGE("malformed statement", 0, lexerp->command); 212 | db_fileremove(tablename); 213 | db_qmm_ffree(mmp, tablename); 214 | return -1; 215 | } 216 | 217 | db_qmm_ffree(mmp, tablename); 218 | return 1; 219 | } 220 | #endif 221 | 222 | db_int processCreate(db_lexer_t *lexerp, db_int end, db_query_mm_t *mmp) 223 | { 224 | lexer_next(lexerp); 225 | switch (lexerp->token.info) { 226 | case DB_LEXER_TOKENINFO_LITERAL_TABLE: 227 | #if defined(DB_CTCONF_SETTING_FEATURE_CREATE_TABLE) && 1==DB_CTCONF_SETTING_FEATURE_CREATE_TABLE 228 | return createTable(lexerp, end, mmp); 229 | #else 230 | return -1; 231 | #endif 232 | default: 233 | return -1; 234 | } 235 | } 236 | -------------------------------------------------------------------------------- /src/dbparser/dbcreate.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @file dbcreate.h 4 | @author Graeme Douglas 5 | @brief The databases create functions. 6 | @details 7 | @copyright Copyright 2013 Graeme Douglas 8 | @license Licensed under the Apache License, Version 2.0 (the "License"); 9 | you may not use this file except in compliance with the License. 10 | You may obtain a copy of the License at 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | @par 14 | Unless required by applicable law or agreed to in writing, 15 | software distributed under the License is distributed on an 16 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 17 | either express or implied. See the License for the specific 18 | language governing permissions and limitations under the 19 | License. 20 | */ 21 | /******************************************************************************/ 22 | 23 | #ifndef DBCREATE_H 24 | #define DBCREATE_H 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | #include "../ref.h" 31 | #include "../db_ctconf.h" 32 | #include "dblexer.h" 33 | 34 | /** 35 | @brief Process the different CREATE statements for the database. 36 | @param lexerp A pointer to the lexer instance variable 37 | that is generating the token stream. 38 | @param end The first index of a character in the 39 | command being lexed not in this statement. 40 | @param mmp The per-query memory manager being used 41 | to allocate memory for this statement. 42 | @returns @c 1 if the statement was successful, @c -1 if an error occured, 43 | @c 0 otherwise. 44 | */ 45 | db_int processCreate(db_lexer_t *lexerp, db_int end, db_query_mm_t *mmp); 46 | 47 | #ifdef __cplusplus 48 | } 49 | #endif 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /src/dbparser/dbinsert.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @file dbinsert.h 4 | @author Graeme Douglas 5 | @brief Header for @c INSERT statement processing. 6 | @details 7 | @copyright Copyright 2013 Graeme Douglas 8 | @license Licensed under the Apache License, Version 2.0 (the "License"); 9 | you may not use this file except in compliance with the License. 10 | You may obtain a copy of the License at 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | @par 14 | Unless required by applicable law or agreed to in writing, 15 | software distributed under the License is distributed on an 16 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 17 | either express or implied. See the License for the specific 18 | language governing permissions and limitations under the 19 | License. 20 | */ 21 | /******************************************************************************/ 22 | #ifndef DBINSERT_H 23 | #define DBINSERT_H 24 | 25 | #include "../ref.h" 26 | #include "../dbmm/db_query_mm.h" 27 | #include "dblexer.h" 28 | #include "../dbstorage/dbstorage.h" 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | /** 35 | @brief Processes an @c INSERT statement. 36 | @details Expects that the token the lexer is pointed at is the one 37 | directly after the @c INSERT token. 38 | @param lexerp A pointer to the lexer being used to 39 | parse the statement. 40 | @param end The offset immediately after the last 41 | character in the statement. 42 | @param mmp A pointer to the memory manager that 43 | is being used to execute this statement. 44 | @returns @c 1 if the statement was successful, @c 0 otherwise. 45 | */ 46 | db_int insert_command(db_lexer_t *lexerp, db_int end, db_query_mm_t *mmp); 47 | 48 | #ifdef __cplusplus 49 | } 50 | #endif 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /src/dbparser/dbparseexpr.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @author Graeme Douglas 4 | @file dbparseexpr.h 5 | @brief Portion of parser that converts SQL expressions to executable 6 | bytecode. 7 | @details 8 | @copyright Copyright 2013 Graeme Douglas 9 | @license Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | 14 | @par 15 | Unless required by applicable law or agreed to in writing, 16 | software distributed under the License is distributed on an 17 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 18 | either express or implied. See the License for the specific 19 | language governing permissions and limitations under the 20 | License. 21 | */ 22 | /******************************************************************************/ 23 | 24 | #ifndef DBPARSEEXPR_H 25 | #define DBPARSEEXPR_H 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | #include "dblexer.h" 32 | #include "../dbobjects/relation.h" 33 | #include "../dbops/db_ops.h" 34 | #include "../dbmm/db_query_mm.h" 35 | #include "../dblogic/eet.h" 36 | 37 | /* Parse an expression into evaluable form. */ 38 | /** 39 | @brief Convert an SQL expression to bytecode. 40 | @details This method completely translates an expression, expressed in 41 | SQL, to executable bytecode. This method will fail if 42 | their is not enough memory to parse the expression out. 43 | @param exprp A pointer which, after successful execution 44 | of the method, will point to the first node 45 | of the converted expression, on the back stack. 46 | @param lexerp A pointer to the lexer which will be used to 47 | parse the expression. 48 | @param start The position of the first character that is 49 | a part of the expression, in the query string. 50 | @param end The position of the first character _AFTER_ 51 | @p start that should _NOT_ included in the 52 | expression. 53 | @param mmp A pointer to the per-query memory manager that 54 | is being used for this query. 55 | @param jointolast A Boolean flag indicating if this expression 56 | is to be joined to the top most section 57 | of memory on the back stack. Set to @c 1 if 58 | that is desired, @c 0 otherwise. 59 | @returns @c -1 if any error occured, @c 1 otherwise. 60 | */ 61 | db_int parseexpression(db_eetnode_t **exprp, 62 | db_lexer_t *lexerp, 63 | db_int start, 64 | db_int end, 65 | db_query_mm_t *mmp, 66 | db_uint8 jointolast); 67 | 68 | 69 | /** 70 | @brief Verify and properly setup attributes in an expression. 71 | @details This method will look for attributes in the expression 72 | and translate their identifiers into an executable form. 73 | @param eetp A pointer to the expression to be processed. 74 | @param lexerp A pointer to the lexer currently in use. 75 | @param evalpoint A pointer to the operator where the expression 76 | is being evaluated from. 77 | @param scans Pointer to the array of table scan operators. 78 | @param numscans The number of scans in the array. 79 | @param startdepth The intended depth of the evaluation point. 80 | Set to @c 0 if the expression is actually 81 | evaluated at this point. Essentially, 82 | if the root evaluation point is a join and 83 | this is set to @c 1 or bigger, pretend 84 | the evaluation point is _NOT_ a join. 85 | @returns @c 1 if all attributes verified and processed successfully, 86 | @c -1 if an error occured, @c 0 otherwise. 87 | */ 88 | db_int verifysetupattributes(db_eet_t *eetp, 89 | db_lexer_t *lexerp, 90 | db_op_base_t *evalpoint, 91 | scan_t *scans, 92 | db_uint8 numscans, 93 | int startdepth); 94 | 95 | #ifdef __cplusplus 96 | } 97 | #endif 98 | 99 | #endif 100 | -------------------------------------------------------------------------------- /src/dbparser/dbparser.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @author Graeme Douglas 4 | @file dbparser.h 5 | @brief The databases SQL parser interface. 6 | @details The goal of the parser is to take a SQL query string and use it 7 | to determine how to build up the query execution tree. 8 | @copyright Copyright 2013 Graeme Douglas 9 | @license Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | 14 | @par 15 | Unless required by applicable law or agreed to in writing, 16 | software distributed under the License is distributed on an 17 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 18 | either express or implied. See the License for the specific 19 | language governing permissions and limitations under the 20 | License. 21 | */ 22 | /******************************************************************************/ 23 | 24 | #ifndef DBPARSER_H 25 | #define DBPARSER_H 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | #include "../dbops/db_ops.h" 32 | #include "../dbmm/db_query_mm.h" 33 | #include "dblexer.h" 34 | #include "dbparseexpr.h" 35 | #include "dbcreate.h" 36 | #include "dbinsert.h" 37 | #include "../db_ctconf.h" 38 | #if defined(DB_CTCONF_SETTING_TARGET) && DB_CTCONF_SETTING_TARGET == DB_CTCONF_OPTION_TARGET_ARDUINO 39 | #include "../arduinodebug.h" 40 | #endif 41 | 42 | #ifndef DB_PARSER_OP_NONE 43 | #define DB_PARSER_OP_NONE (db_op_base_t*)1 44 | #else 45 | #error "MACRO NAME CLASH ON DB_PARSER_OP_NONE" 46 | #endif 47 | 48 | /** 49 | @brief Print a string representaiton of an execution tree. 50 | @details This will allocate memory to print the string. The caller 51 | is responsible for freeing it. 52 | @param root A pointer to the root operator of the 53 | tree. 54 | @param strp A pointer to a character pointer. Allocated 55 | memory will be pointed to by this pointer. 56 | */ 57 | void queryTreeToString(db_op_base_t *root, char **strp); 58 | 59 | /* Returns the root operator in the parse tree. */ 60 | /** 61 | @brief Build an executable query tree from an SQL command. 62 | @param command A pointer to the character array that describes 63 | the query to execute. 64 | @param mmp A pointer to an initialized per-query memory 65 | manager that is to allocate memory for this 66 | query. 67 | @returns A pointer to the root operator of the execution tree, or 68 | @c NULL if an error occurs. 69 | */ 70 | db_op_base_t* parse(char* command, db_query_mm_t* mmp); 71 | 72 | #ifdef __cplusplus 73 | } 74 | #endif 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /src/dbstorage/SD_c_iface.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @file SD_c_iface.cpp 4 | @author Graeme Douglas 5 | @brief Wrapper code for Arduino SD file handling. 6 | @details 7 | @see Reference @ref SD_c_iface.h for more information. 8 | @copyright Copyright 2013 Graeme Douglas 9 | @license Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | 14 | @par 15 | Unless required by applicable law or agreed to in writing, 16 | software distributed under the License is distributed on an 17 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 18 | either express or implied. See the License for the specific 19 | language governing permissions and limitations under the 20 | License. 21 | */ 22 | /******************************************************************************/ 23 | #include "SD_c_iface.h" 24 | 25 | #include "SD.h" 26 | 27 | /** 28 | @brief A structure that translates a file object to a C-compatible 29 | struct. 30 | */ 31 | struct _SD_File 32 | { 33 | File f; /**< The Arduino SD File object we to use. */ 34 | }; 35 | 36 | int SD_File_Exists(char *filepath) 37 | { 38 | return (int)(SD.exists(filepath)); 39 | } 40 | 41 | int SD_File_Open(SD_File **file, char *filepath, unsigned char mode) 42 | { 43 | if (!file) return 0; 44 | if (SD_FILE_MODE_READ == mode) 45 | mode = FILE_READ; 46 | else if (SD_FILE_MODE_WRITE == mode) 47 | mode = FILE_WRITE; 48 | *file = new struct _SD_File(); 49 | (*file)->f = SD.open(filepath, mode); 50 | if (!((*file)->f)) 51 | { 52 | return 0; 53 | } 54 | return 1; 55 | } 56 | 57 | size_t SD_File_Write(SD_File *file, const uint8_t *buf, size_t size) 58 | { 59 | return (file) ? file->f.write(buf, size) : 0; 60 | } 61 | 62 | int SD_File_Read(SD_File *file, void *buf, uint16_t nbytes) 63 | { 64 | return (file) ? file->f.read(buf, nbytes) : -1; 65 | } 66 | 67 | int SD_File_Seek(SD_File *file, unsigned long pos) 68 | { 69 | return (file) ? file->f.seek(pos) : 0; 70 | } 71 | 72 | // TODO: How do we signal an error here? 73 | unsigned long SD_File_Position(SD_File *file) 74 | { 75 | return (file) ? file->f.position() : 0; 76 | } 77 | 78 | void SD_File_Close(SD_File *file) 79 | { 80 | if (file) file->f.close(); 81 | delete file; 82 | } 83 | 84 | int SD_File_Remove(char *filepath) 85 | { 86 | return SD.remove(filepath); 87 | } 88 | 89 | int SD_File_Begin(uint8_t csPin) 90 | { 91 | SD.begin(csPin); 92 | } 93 | -------------------------------------------------------------------------------- /src/dbstorage/SD_c_iface.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @file SD_c_iface.h 4 | @author Graeme Douglas 5 | @brief A wrapper around Arduino SD file handling so C code can call 6 | it. 7 | @details Since Arduino code is all C++ and this database is written in 8 | C, we must use a wrapper to use SD files on Arduinos. 9 | @copyright Copyright 2013 Graeme Douglas 10 | @license Licensed under the Apache License, Version 2.0 (the "License"); 11 | you may not use this file except in compliance with the License. 12 | You may obtain a copy of the License at 13 | http://www.apache.org/licenses/LICENSE-2.0 14 | 15 | @par 16 | Unless required by applicable law or agreed to in writing, 17 | software distributed under the License is distributed on an 18 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 19 | either express or implied. See the License for the specific 20 | language governing permissions and limitations under the 21 | License. 22 | */ 23 | /******************************************************************************/ 24 | #ifndef SD_C_IFACE_H 25 | #define SD_C_IFACE_H 26 | 27 | #include 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | /** 34 | @brief Wrapper around Arduino File type. 35 | */ 36 | typedef struct _SD_File SD_File; 37 | 38 | /** 39 | @brief Arduino SD File write modes. 40 | */ 41 | typedef enum 42 | { 43 | SD_FILE_MODE_READ = 0, /**< Open a file for reading (from start). */ 44 | SD_FILE_MODE_WRITE = 1, /**< Open a file for reading and writing 45 | (from end). */ 46 | SD_FILE_MODE_COUNT /**< Number of elements in enum. */ 47 | } SD_File_Mode_t; 48 | 49 | /** 50 | @brief Check to see if an Arduino SD File exists. 51 | @param filepath String containing path to file (basic filename). 52 | @returns @c 1 if the file exists, @c 0 otherwise. 53 | */ 54 | int SD_File_Exists(char *filepath); 55 | 56 | /** 57 | @brief Wrapper around Arduino SD file write method. 58 | @param file Pointer to a pointer of the C file structure 59 | type associated with the C++ SD file object. 60 | The pointer pointed to by this pointer 61 | will be set to the newly allocated object. 62 | @param filepath String containing path to file (basic filename). 63 | @param mode What mode to open the file under. 64 | @returns A file for reading, or @c NULL if an error occurred. 65 | */ 66 | int SD_File_Open(SD_File **file, char *filepath, unsigned char mode); 67 | 68 | /** 69 | @brief Wrapper around Arduino SD file write method. 70 | @param file Pointer to C file struct type associated with an SD 71 | file object. 72 | @param buf Pointer to the data that is to be written. 73 | @param size The number of bytes to be written. 74 | @returns The number of bytes written. 75 | */ 76 | size_t SD_File_Write(SD_File *file, const uint8_t *buf, size_t size); 77 | 78 | /** 79 | @brief Wrapper around Arduino SD file read method. 80 | @param file Pointer to C file struct type associated with an SD 81 | file object. 82 | @param buf Pointer to the memory segment to be read into. 83 | @param nbytes The number of bytes to be read. 84 | @returns A read status. 85 | (?) 86 | */ 87 | int SD_File_Read(SD_File *file, void *buf, uint16_t nbytes); 88 | 89 | /** 90 | @brief Wrapper around Arduino SD file read method. 91 | @param file Pointer to C file struct type associated with an SD 92 | file object. 93 | @param pos The position in the file to seek to. 94 | (from the beginning?) 95 | @returns @c 1 for success, @c 0 for failure. 96 | */ 97 | int SD_File_Seek(SD_File *file, unsigned long pos); 98 | 99 | /** 100 | @brief Wrapper around Arduino SD file position method. 101 | @param file Pointer to C file struct type associated with an SD 102 | file object. 103 | @returns The position of the cursor within the file. 104 | */ 105 | unsigned long SD_File_Position(SD_File *file); 106 | 107 | /** 108 | @brief Wrapper around Arduino SD file close method. 109 | @param file Pointer to C file struct type associated with an SD 110 | file object. 111 | */ 112 | void SD_File_Close(SD_File *file); 113 | 114 | /** 115 | @brief Wrapper around Arduino SD file remove method. 116 | @param filepath The string containing the path to the file. 117 | @returns @c 1 if the file was removed successfully, @c 0 otherwise. 118 | */ 119 | int SD_File_Remove(char *filepath); 120 | 121 | /** 122 | @brief Wrapper around Arduino SD file begin method. 123 | @param csPin The pin connected to the chip select line of the SD 124 | card. 125 | @todo Is there a safe number to use as a signal to use default 126 | pin? 127 | */ 128 | int SD_File_Begin(uint8_t csPin); 129 | 130 | #ifdef __cplusplus 131 | } 132 | #endif 133 | 134 | #endif 135 | -------------------------------------------------------------------------------- /src/dbstorage/dbstorage.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @file dbstorage.c 4 | @author Graeme Douglas 5 | @brief The databases storage layer. 6 | @details 7 | @see For more information, refer to @ref dbstorage.h 8 | @copyright Copyright 2013 Graeme Douglas 9 | @license Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | 14 | @par 15 | Unless required by applicable law or agreed to in writing, 16 | software distributed under the License is distributed on an 17 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 18 | either express or implied. See the License for the specific 19 | language governing permissions and limitations under the 20 | License. 21 | */ 22 | /******************************************************************************/ 23 | 24 | #include "dbstorage.h" 25 | #include "../db_ctconf.h" 26 | 27 | db_int db_fileexists(char *filename) 28 | { 29 | #if DB_CTCONF_SETTING_TARGET == DB_CTCONF_OPTION_TARGET_CONTIKI 30 | int check = cfs_open(filename, CFS_READ); 31 | if (-1 == check) 32 | return 0; 33 | 34 | cfs_close(check); 35 | return 1; 36 | #elif DB_CTCONF_SETTING_TARGET == DB_CTCONF_OPTION_TARGET_ARDUINO 37 | return SD_File_Exists(filename); 38 | #else 39 | FILE* check = fopen(filename, "rb"); 40 | if (NULL == check) 41 | return 0; 42 | 43 | fclose(check); 44 | return 1; 45 | #endif 46 | } 47 | 48 | db_fileref_t db_openreadfile(char *filename) 49 | { 50 | #if DB_CTCONF_SETTING_TARGET == DB_CTCONF_OPTION_TARGET_CONTIKI 51 | return cfs_open(filename, CFS_READ); 52 | #elif DB_CTCONF_SETTING_TARGET == DB_CTCONF_OPTION_TARGET_ARDUINO 53 | db_fileref_t toret; 54 | if (1 != SD_File_Open(&toret, filename, SD_FILE_MODE_READ)) 55 | return DB_STORAGE_NOFILE; 56 | return toret; 57 | #else 58 | return fopen(filename, "rb"); 59 | #endif 60 | } 61 | 62 | db_fileref_t db_openwritefile(char *filename) 63 | { 64 | #if DB_CTCONF_SETTING_TARGET == DB_CTCONF_OPTION_TARGET_CONTIKI 65 | return cfs_open(filename, CFS_READ|CFS_WRITE); 66 | #elif DB_CTCONF_SETTING_TARGET == DB_CTCONF_OPTION_TARGET_ARDUINO 67 | SD_File_Remove(filename); 68 | db_fileref_t toret; 69 | if (1 != SD_File_Open(&toret, filename, SD_FILE_MODE_WRITE)) 70 | return DB_STORAGE_NOFILE; 71 | return toret; 72 | #else 73 | return fopen(filename, "wb"); 74 | #endif 75 | } 76 | 77 | db_fileref_t db_openappendfile(char *filename) 78 | { 79 | #if DB_CTCONF_SETTING_TARGET == DB_CTCONF_OPTION_TARGET_CONTIKI 80 | return cfs_open(filename, CFS_READ|CFS_WRITE|CFS_APPEND); 81 | #elif DB_CTCONF_SETTING_TARGET == DB_CTCONF_OPTION_TARGET_ARDUINO 82 | db_fileref_t toret; 83 | if (1 != SD_File_Open(&toret, filename, SD_FILE_MODE_WRITE)) 84 | return DB_STORAGE_NOFILE; 85 | return toret; 86 | #else 87 | return fopen(filename, "ab"); 88 | #endif 89 | } 90 | 91 | size_t db_fileread(db_fileref_t f, unsigned char *dest, size_t numbytes) 92 | { 93 | #if DB_CTCONF_SETTING_TARGET == DB_CTCONF_OPTION_TARGET_CONTIKI 94 | return (size_t)cfs_read(f, dest, numbytes); 95 | #elif DB_CTCONF_SETTING_TARGET == DB_CTCONF_OPTION_TARGET_ARDUINO 96 | return SD_File_Read(f, dest, numbytes); 97 | #else 98 | return numbytes*fread(dest, numbytes, 1, f); 99 | #endif 100 | } 101 | 102 | size_t db_filewrite(db_fileref_t f, void *towrite, size_t numbytes) 103 | { 104 | #if DB_CTCONF_SETTING_TARGET == DB_CTCONF_OPTION_TARGET_CONTIKI 105 | return (size_t)cfs_write(f, towrite, numbytes); 106 | #elif DB_CTCONF_SETTING_TARGET == DB_CTCONF_OPTION_TARGET_ARDUINO 107 | return SD_File_Write(f, towrite, numbytes); 108 | #else 109 | return numbytes*fwrite(towrite, numbytes, 1, f); 110 | #endif 111 | } 112 | 113 | db_int db_filerewind(db_fileref_t f) 114 | { 115 | #if DB_CTCONF_SETTING_TARGET == DB_CTCONF_OPTION_TARGET_CONTIKI 116 | return cfs_seek(f, 0, CFS_SEEK_SET); 117 | #elif DB_CTCONF_SETTING_TARGET == DB_CTCONF_OPTION_TARGET_ARDUINO 118 | return SD_File_Seek(f, 0); 119 | #else 120 | rewind(f); 121 | return 1; 122 | #endif 123 | } 124 | 125 | db_int db_fileseek(db_fileref_t f, size_t size) 126 | { 127 | #if DB_CTCONF_SETTING_TARGET == DB_CTCONF_OPTION_TARGET_CONTIKI 128 | return cfs_seek(f, size, CFS_SEEK_CUR); 129 | #elif DB_CTCONF_SETTING_TARGET == DB_CTCONF_OPTION_TARGET_ARDUINO 130 | size_t pos = SD_File_Position(f); 131 | return SD_File_Seek(f, pos+size); 132 | #else 133 | return fseek(f, size, SEEK_CUR); 134 | #endif 135 | } 136 | 137 | db_int db_fileclose(db_fileref_t f) 138 | { 139 | #if DB_CTCONF_SETTING_TARGET == DB_CTCONF_OPTION_TARGET_CONTIKI 140 | cfs_close(f); 141 | return 1; 142 | #elif DB_CTCONF_SETTING_TARGET == DB_CTCONF_OPTION_TARGET_ARDUINO 143 | SD_File_Close(f); 144 | return 1; 145 | #else 146 | return fclose(f); 147 | #endif 148 | } 149 | 150 | db_int db_fileremove(char *filename) 151 | { 152 | #if DB_CTCONF_SETTING_TARGET == DB_CTCONF_OPTION_TARGET_CONTIKI 153 | return (0==cfs_remove(filename)); 154 | #elif DB_CTCONF_SETTING_TARGET == DB_CTCONF_OPTION_TARGET_ARDUINO 155 | return SD_File_Remove(filename); 156 | #else 157 | return (0==remove(filename)); 158 | #endif 159 | } 160 | -------------------------------------------------------------------------------- /src/dbstorage/dbstorage.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @file dbstorage.h 4 | @author Graeme Douglas 5 | @brief The databases storage layer. 6 | @details Provides an abstract API for interacting with various storage 7 | backends. 8 | @copyright Copyright 2013 Graeme Douglas 9 | @license Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | 14 | @par 15 | Unless required by applicable law or agreed to in writing, 16 | software distributed under the License is distributed on an 17 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 18 | either express or implied. See the License for the specific 19 | language governing permissions and limitations under the 20 | License. 21 | */ 22 | /******************************************************************************/ 23 | 24 | #ifndef DBSTORAGE_H 25 | #define DBSTORAGE_H 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | #include "../db_ctconf.h" 32 | #include "../ref.h" 33 | #include 34 | #include 35 | 36 | #if DB_CTCONF_SETTING_TARGET == DB_CTCONF_OPTION_TARGET_CONTIKI 37 | 38 | #include "contiki.h" 39 | #include "cfs/cfs.h" 40 | 41 | typedef int db_fileref_t; 42 | 43 | #ifndef DB_STORAGE_NOFILE 44 | #define DB_STORAGE_NOFILE -1 45 | #else 46 | #error "NAME CLASH ON DB_STORAGE_NOFILE!" 47 | #endif 48 | 49 | #elif DB_CTCONF_SETTING_TARGET == DB_CTCONF_OPTION_TARGET_ARDUINO 50 | 51 | #include "SD_c_iface.h" 52 | 53 | typedef SD_File* db_fileref_t; 54 | 55 | #ifndef DB_STORAGE_NOFILE 56 | #define DB_STORAGE_NOFILE NULL 57 | #else 58 | #error "NAME CLASH ON DB_STORAGE_NOFILE!" 59 | #endif 60 | 61 | #else 62 | 63 | typedef FILE* db_fileref_t; 64 | 65 | #ifndef DB_STORAGE_NOFILE 66 | #define DB_STORAGE_NOFILE NULL 67 | #else 68 | #error "NAME CLASH ON DB_STORAGE_NOFILE!" 69 | #endif 70 | 71 | #endif 72 | 73 | /** 74 | @typedef db_fileref_t 75 | @brief An abstract reference to a file. 76 | @details As an example, @c FILE* is used for standard systems, and 77 | @c int is used for ContikiOS. In general, this should 78 | almost always be a pointer type or some sort of integral 79 | reference number type. 80 | */ 81 | 82 | /** 83 | @brief Check to see if a file exists. 84 | @param filename The name of the file. 85 | @returns @c 1 if the file exists, @c 0 if it does not. 86 | */ 87 | db_int db_fileexists(char *filename); 88 | 89 | /** 90 | @brief Open a file for reading. 91 | @param filename The name of the file to open. 92 | @returns A reference to the file to be read. 93 | */ 94 | db_fileref_t db_openreadfile(char *filename); 95 | 96 | /** 97 | @brief Open a file for (reading and?) writing. 98 | @param filename The name of the file to open. 99 | @returns A reference to the file to read/write. 100 | */ 101 | db_fileref_t db_openwritefile(char *filename); 102 | 103 | /** 104 | @brief Open a file for appending to. 105 | @param filename The name of the file to open. 106 | @returns A reference to the file to write to. 107 | */ 108 | db_fileref_t db_openappendfile(char *filename); 109 | 110 | /** 111 | @brief Read from the current position in the file. 112 | @param f A reference to the file to read 113 | from. 114 | @param dest The memory location to place 115 | the read data in. 116 | @param numbytes The number of bytes to read. 117 | @returns The number of bytes successfully read. 118 | */ 119 | size_t db_fileread(db_fileref_t f, 120 | unsigned char *dest, 121 | size_t numbytes); 122 | 123 | /** 124 | @brief Write to the current position in the file. 125 | @param f A reference to the file to write 126 | to. 127 | @param towrite The memory location to read data 128 | from. 129 | @param numbytes The number of bytes to write. 130 | @returns The number of bytes successfully written. 131 | */ 132 | size_t db_filewrite(db_fileref_t f, 133 | void *towrite, 134 | size_t numbytes); 135 | 136 | /** 137 | @brief Set the files internal position back to the beginning. 138 | @param f A reference to the file to rewound. 139 | @returns @c 1 if the file was rewound, @c 0 otherwise. 140 | */ 141 | db_int db_filerewind(db_fileref_t f); 142 | 143 | /** 144 | @brief Move the files internal position based on where it currently is. 145 | @param f A reference to the file whose position is to be changed. 146 | @param size The number of bytes to move the position by. 147 | @returns @c 1 if the position was successfully modified, @c 0 otherwise. 148 | */ 149 | db_int db_fileseek(db_fileref_t f, 150 | size_t size); 151 | 152 | /** 153 | @brief Close a file. 154 | @param f A reference to the file to close. 155 | @return @c 1 if the file was closed successfully, @c 0 otherwise. 156 | */ 157 | db_int db_fileclose(db_fileref_t f); 158 | 159 | /** 160 | @brief Delete a file given its name. 161 | @param filename The name of the file to delete. 162 | @return @c 1 if the file was removed, @c 0 otherwise. 163 | */ 164 | db_int db_fileremove(char *filename); 165 | 166 | #ifdef __cplusplus 167 | } 168 | #endif 169 | 170 | #endif 171 | -------------------------------------------------------------------------------- /src/include/debug.h: -------------------------------------------------------------------------------- 1 | //***************************************************************************** 2 | /** 3 | @file debug.h 4 | @author Andrii Kuplevakhskyi 5 | @brief Debug utlities (printf() etc.). The utilities can be 6 | enabled or disabled 7 | 8 | @details 9 | @copyright Copyright 2016 Andrii Kuplevakhskyi 10 | @license Licensed under the Apache License, Version 2.0 (the "License"); 11 | you may not use this file except in compliance with the License. 12 | You may obtain a copy of the License at 13 | http://www.apache.org/licenses/LICENSE-2.0 14 | @par 15 | Unless required by applicable law or agreed to in writing, 16 | software distributed under the License is distributed on an 17 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 18 | either express or implied. See the License for the specific 19 | language governing permissions and limitations under the 20 | License. 21 | */ 22 | //***************************************************************************** 23 | 24 | #include 25 | 26 | #ifndef DEBUG_H 27 | #define DEBUG_H 28 | 29 | #ifdef ENABLE_DEBUG 30 | #define DEBUG_ENABLED (1) 31 | #else // ENABLE_DEBUG 32 | #define DEBUG_ENABLED (0) 33 | #endif //ENABLE_DEBUG 34 | 35 | 36 | #define PRINTF(...) \ 37 | do \ 38 | { \ 39 | if (0 != DEBUG_ENABLED) \ 40 | { \ 41 | printf(__VA_ARGS__); \ 42 | } \ 43 | } while (1 == 0) 44 | 45 | 46 | #endif // DEBUG_H 47 | 48 | -------------------------------------------------------------------------------- /src/mainpage.h: -------------------------------------------------------------------------------- 1 | /** 2 | @file mainpage.h 3 | @brief Doxygen mainpage. 4 | @details 5 | @mainpage Manual and Documentation for @systemname 6 | @copyright Copyright 2013 Graeme Douglas 7 | @license Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | @par 13 | Unless required by applicable law or agreed to in writing, 14 | software distributed under the License is distributed on an 15 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 16 | either express or implied. See the License for the specific 17 | language governing permissions and limitations under the 18 | License. 19 | @todo Create style guide. 20 | 21 | @section Introduction 22 | 23 | This document will provide information for developers attempting to use 24 | the system in a production enviroment. 25 | 26 | @section Features 27 | 28 | - SQL Parser and Execution Engine: 29 | - @c SELECT clause projections excluding aggregation 30 | - @c FROM clause scans and joins excluding @c OUTER/NATURAL 31 | joins 32 | - @c WHERE clause filtering 33 | - @c NULL handling 34 | - Support for common types 35 | - Integers (size depends on target platform) 36 | - Fixed-length strings 37 | - Common operators and functions supported 38 | - @c AND, @c OR, @c XOR, @c !, @c ^, @c &, @c |, 39 | @c +, @c -, @c *, @c /, @c %, @c ISNULL, @c LENGTH 40 | - Aribitrary expressions in supported clauses 41 | - Designed for sensor nodes and embedded devices with constrained 42 | resources 43 | - Query execution can occur with as little as 1 kB of RAM! 44 | - Compile time configurable options; pick the fetures you 45 | require for your application 46 | - Efficient stack-based per-query memory manager 47 | - Device and system freedom; easily portable, just write your 48 | own storage layer 49 | - ContikiOS ready (for devices support CFS file storage layer) 50 | */ 51 | -------------------------------------------------------------------------------- /src/ref.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @file ref.h 4 | @author Graeme Douglas 5 | @brief Header file containing definitions used throughout the database. 6 | @details 7 | @copyright Copyright 2013 Graeme Douglas 8 | @license Licensed under the Apache License, Version 2.0 (the "License"); 9 | you may not use this file except in compliance with the License. 10 | You may obtain a copy of the License at 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | @par 14 | Unless required by applicable law or agreed to in writing, 15 | software distributed under the License is distributed on an 16 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 17 | either express or implied. See the License for the specific 18 | language governing permissions and limitations under the 19 | License. 20 | */ 21 | /******************************************************************************/ 22 | 23 | #ifndef REF_H 24 | #define REF_H 25 | 26 | #include "db_types.h" 27 | #include "dbmacros.h" 28 | 29 | /* This is used to determine the attribute types. */ 30 | /** 31 | @enum attr_type 32 | @brief Enumerated type for database types. 33 | */ 34 | typedef enum 35 | { 36 | DB_INT = 0, /**< The database's integer type. */ 37 | DB_STRING = 1, /**< The database's ASCII string / char type. */ 38 | DB_NULL, /**< The database's NULL type. */ 39 | DB_TYPES_COUNT /**< The number of database types. */ 40 | } attr_type; 41 | 42 | /* Type size references */ 43 | /** 44 | @brief The size of a single byte. @todo Maybe get rid of this? 45 | */ 46 | static const db_int SIZE_BYTE = sizeof(char); 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /src/unit_tests/CuTest.h: -------------------------------------------------------------------------------- 1 | #ifndef CU_TEST_H 2 | #define CU_TEST_H 3 | 4 | #include 5 | #include 6 | 7 | #define CUTEST_VERSION "CuTest 1.5" 8 | 9 | /* CuString */ 10 | 11 | char* CuStrAlloc(int size); 12 | char* CuStrCopy(const char* old); 13 | 14 | #define CU_ALLOC(TYPE) ((TYPE*) malloc(sizeof(TYPE))) 15 | 16 | #define HUGE_STRING_LEN 8192 17 | #define STRING_MAX 256 18 | #define STRING_INC 256 19 | 20 | typedef struct 21 | { 22 | int length; 23 | int size; 24 | char* buffer; 25 | } CuString; 26 | 27 | void CuStringInit(CuString* str); 28 | CuString* CuStringNew(void); 29 | void CuStringRead(CuString* str, const char* path); 30 | void CuStringAppend(CuString* str, const char* text); 31 | void CuStringAppendChar(CuString* str, char ch); 32 | void CuStringAppendFormat(CuString* str, const char* format, ...); 33 | void CuStringInsert(CuString* str, const char* text, int pos); 34 | void CuStringResize(CuString* str, int newSize); 35 | void CuStringDelete(CuString* str); 36 | 37 | /* CuTest */ 38 | 39 | typedef struct CuTest CuTest; 40 | 41 | typedef void (*TestFunction)(CuTest *); 42 | 43 | struct CuTest 44 | { 45 | char* name; 46 | TestFunction function; 47 | int failed; 48 | int ran; 49 | const char* message; 50 | jmp_buf *jumpBuf; 51 | }; 52 | 53 | void CuTestInit(CuTest* t, const char* name, TestFunction function); 54 | CuTest* CuTestNew(const char* name, TestFunction function); 55 | void CuTestRun(CuTest* tc); 56 | void CuTestDelete(CuTest *t); 57 | 58 | /* Internal versions of assert functions -- use the public versions */ 59 | void CuFail_Line(CuTest* tc, const char* file, int line, const char* message2, const char* message); 60 | void CuAssert_Line(CuTest* tc, const char* file, int line, const char* message, int condition); 61 | void CuAssertStrEquals_LineMsg(CuTest* tc, 62 | const char* file, int line, const char* message, 63 | const char* expected, const char* actual); 64 | void CuAssertIntEquals_LineMsg(CuTest* tc, 65 | const char* file, int line, const char* message, 66 | int expected, int actual); 67 | void CuAssertDblEquals_LineMsg(CuTest* tc, 68 | const char* file, int line, const char* message, 69 | double expected, double actual, double delta); 70 | void CuAssertPtrEquals_LineMsg(CuTest* tc, 71 | const char* file, int line, const char* message, 72 | void* expected, void* actual); 73 | 74 | /* public assert functions */ 75 | 76 | #define CuFail(tc, ms) CuFail_Line( (tc), __FILE__, __LINE__, NULL, (ms)) 77 | #define CuAssert(tc, ms, cond) CuAssert_Line((tc), __FILE__, __LINE__, (ms), (cond)) 78 | #define CuAssertTrue(tc, cond) CuAssert_Line((tc), __FILE__, __LINE__, "assert failed", (cond)) 79 | 80 | #define CuAssertStrEquals(tc,ex,ac) CuAssertStrEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac)) 81 | #define CuAssertStrEquals_Msg(tc,ms,ex,ac) CuAssertStrEquals_LineMsg((tc),__FILE__,__LINE__,(ms),(ex),(ac)) 82 | #define CuAssertIntEquals(tc,ex,ac) CuAssertIntEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac)) 83 | #define CuAssertIntEquals_Msg(tc,ms,ex,ac) CuAssertIntEquals_LineMsg((tc),__FILE__,__LINE__,(ms),(ex),(ac)) 84 | #define CuAssertDblEquals(tc,ex,ac,dl) CuAssertDblEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac),(dl)) 85 | #define CuAssertDblEquals_Msg(tc,ms,ex,ac,dl) CuAssertDblEquals_LineMsg((tc),__FILE__,__LINE__,(ms),(ex),(ac),(dl)) 86 | #define CuAssertPtrEquals(tc,ex,ac) CuAssertPtrEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac)) 87 | #define CuAssertPtrEquals_Msg(tc,ms,ex,ac) CuAssertPtrEquals_LineMsg((tc),__FILE__,__LINE__,(ms),(ex),(ac)) 88 | 89 | #define CuAssertPtrNotNull(tc,p) CuAssert_Line((tc),__FILE__,__LINE__,"null pointer unexpected",(p != NULL)) 90 | #define CuAssertPtrNotNullMsg(tc,msg,p) CuAssert_Line((tc),__FILE__,__LINE__,(msg),(p != NULL)) 91 | 92 | /* CuSuite */ 93 | 94 | #define MAX_TEST_CASES 1024 95 | 96 | #define SUITE_ADD_TEST(SUITE,TEST) CuSuiteAdd(SUITE, CuTestNew(#TEST, TEST)) 97 | 98 | typedef struct 99 | { 100 | int count; 101 | CuTest* list[MAX_TEST_CASES]; 102 | int failCount; 103 | 104 | } CuSuite; 105 | 106 | 107 | void CuSuiteInit(CuSuite* testSuite); 108 | CuSuite* CuSuiteNew(void); 109 | void CuSuiteDelete(CuSuite *testSuite); 110 | void CuSuiteAdd(CuSuite* testSuite, CuTest *testCase); 111 | void CuSuiteAddSuite(CuSuite* testSuite, CuSuite* testSuite2); 112 | void CuSuiteRun(CuSuite* testSuite); 113 | void CuSuiteSummary(CuSuite* testSuite, CuString* summary); 114 | void CuSuiteDetails(CuSuite* testSuite, CuString* details); 115 | 116 | #endif /* CU_TEST_H */ 117 | -------------------------------------------------------------------------------- /src/unit_tests/aggregate/run_aggregate_ut.c: -------------------------------------------------------------------------------- 1 | /** 2 | @author Graeme Douglas 3 | @brief 4 | @details 5 | @copyright Copyright 2013 Graeme Douglas 6 | @license Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | @par 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 15 | either express or implied. See the License for the specific 16 | language governing permissions and limitations under the 17 | License. 18 | */ 19 | 20 | void runAllTests_aggregate(); 21 | 22 | int main(void) 23 | { 24 | runAllTests_aggregate(); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /src/unit_tests/db_query_mm/run_db_query_mm_ut.c: -------------------------------------------------------------------------------- 1 | /** 2 | @author Graeme Douglas 3 | @brief 4 | @details 5 | @copyright Copyright 2013 Graeme Douglas 6 | @license Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | @par 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 15 | either express or implied. See the License for the specific 16 | language governing permissions and limitations under the 17 | License. 18 | */ 19 | 20 | void runAllTests_dbqmm(); 21 | 22 | int main(void) 23 | { 24 | runAllTests_dbqmm(); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /src/unit_tests/dbcreate/run_dbcreate_ut.c: -------------------------------------------------------------------------------- 1 | /** 2 | @author Graeme Douglas 3 | @brief 4 | @details 5 | @copyright Copyright 2013 Graeme Douglas 6 | @license Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | @par 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 15 | either express or implied. See the License for the specific 16 | language governing permissions and limitations under the 17 | License. 18 | */ 19 | 20 | void runAllTests_dbcreate(); 21 | 22 | int main(void) 23 | { 24 | runAllTests_dbcreate(); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /src/unit_tests/dbinsert/run_dbinsert_ut.c: -------------------------------------------------------------------------------- 1 | /** 2 | @author Graeme Douglas 3 | @brief 4 | @details 5 | @copyright Copyright 2013 Graeme Douglas 6 | @license Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | @par 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 15 | either express or implied. See the License for the specific 16 | language governing permissions and limitations under the 17 | License. 18 | */ 19 | 20 | void runAllTests_dbinsert(); 21 | 22 | int main(void) 23 | { 24 | runAllTests_dbinsert(); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /src/unit_tests/dblexer/run_dblexer_ut.c: -------------------------------------------------------------------------------- 1 | /** 2 | @author Graeme Douglas 3 | @brief 4 | @details 5 | @copyright Copyright 2013 Graeme Douglas 6 | @license Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | @par 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 15 | either express or implied. See the License for the specific 16 | language governing permissions and limitations under the 17 | License. 18 | */ 19 | 20 | void runAllTests_dblexer(); 21 | 22 | int main(void) 23 | { 24 | runAllTests_dblexer(); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /src/unit_tests/dbparseexpr/run_dbparseexpr_ut.c: -------------------------------------------------------------------------------- 1 | /** 2 | @author Graeme Douglas 3 | @brief 4 | @details 5 | @copyright Copyright 2013 Graeme Douglas 6 | @license Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | @par 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 15 | either express or implied. See the License for the specific 16 | language governing permissions and limitations under the 17 | License. 18 | */ 19 | 20 | void runAllTests_dbparseexpr(); 21 | 22 | int main(void) 23 | { 24 | runAllTests_dbparseexpr(); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /src/unit_tests/dbparser/run_dbparser_ut.c: -------------------------------------------------------------------------------- 1 | /** 2 | @author Graeme Douglas 3 | @brief 4 | @details 5 | @copyright Copyright 2013 Graeme Douglas 6 | @license Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | @par 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 15 | either express or implied. See the License for the specific 16 | language governing permissions and limitations under the 17 | License. 18 | */ 19 | 20 | void runAllTests_dbparser(); 21 | 22 | int main(void) 23 | { 24 | runAllTests_dbparser(); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /src/unit_tests/eet/run_eet_ut.c: -------------------------------------------------------------------------------- 1 | /** 2 | @author Graeme Douglas 3 | @brief 4 | @details 5 | @copyright Copyright 2013 Graeme Douglas 6 | @license Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | @par 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 15 | either express or implied. See the License for the specific 16 | language governing permissions and limitations under the 17 | License. 18 | */ 19 | 20 | void runAllTests_eet(); 21 | 22 | int main(void) 23 | { 24 | runAllTests_eet(); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /src/unit_tests/ntjoin/run_ntjoin_ut.c: -------------------------------------------------------------------------------- 1 | /** 2 | @author Graeme Douglas 3 | @brief 4 | @details 5 | @copyright Copyright 2013 Graeme Douglas 6 | @license Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | @par 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 15 | either express or implied. See the License for the specific 16 | language governing permissions and limitations under the 17 | License. 18 | */ 19 | 20 | void runAllTests_ntjoin(); 21 | 22 | int main(void) 23 | { 24 | runAllTests_ntjoin(); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /src/unit_tests/osijoin/run_osijoin_ut.c: -------------------------------------------------------------------------------- 1 | /** 2 | @author Graeme Douglas 3 | @brief 4 | @details 5 | @copyright Copyright 2013 Graeme Douglas 6 | @license Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | @par 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 15 | either express or implied. See the License for the specific 16 | language governing permissions and limitations under the 17 | License. 18 | */ 19 | 20 | void runAllTests_osijoin(); 21 | 22 | int main(void) 23 | { 24 | runAllTests_osijoin(); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /src/unit_tests/project/run_project_ut.c: -------------------------------------------------------------------------------- 1 | /** 2 | @author Graeme Douglas 3 | @brief 4 | @details 5 | @copyright Copyright 2013 Graeme Douglas 6 | @license Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | @par 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 15 | either express or implied. See the License for the specific 16 | language governing permissions and limitations under the 17 | License. 18 | */ 19 | 20 | void runAllTests_project(); 21 | 22 | int main(void) 23 | { 24 | runAllTests_project(); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /src/unit_tests/runalltests.c: -------------------------------------------------------------------------------- 1 | /** 2 | @author Graeme Douglas 3 | @brief 4 | @details 5 | @copyright Copyright 2013 Graeme Douglas 6 | @license Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | @par 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 15 | either express or implied. See the License for the specific 16 | language governing permissions and limitations under the 17 | License. 18 | */ 19 | 20 | #include 21 | #include 22 | #include "CuTest.h" 23 | 24 | CuSuite *DBAggregateGetSuite(); 25 | CuSuite *DBQueryMMGetSuite(); 26 | CuSuite* LexerGetSuite(); 27 | CuSuite* DBParseExprGetSuite(); 28 | CuSuite *DBEETGetSuite(); 29 | CuSuite *DBNTJoinGetSuite(); 30 | CuSuite *DBOSIJoinGetSuite(); 31 | CuSuite *DBProjectGetSuite(); 32 | CuSuite *DBScanGetSuite(); 33 | CuSuite *DBSelectGetSuite(); 34 | CuSuite *DBSortGetSuite(); 35 | 36 | void runAllTests(void) 37 | { 38 | CuString *output = CuStringNew(); 39 | CuSuite* suite = CuSuiteNew(); 40 | 41 | /* Create suites from other tests. */ 42 | //CuSuite *agg_suite = DBAggregateGetSuite(); 43 | CuSuite *dbqmm_suite = DBQueryMMGetSuite(); 44 | CuSuite *lex_suite = LexerGetSuite(); 45 | CuSuite *dbparseexpr_suite = DBParseExprGetSuite(); 46 | CuSuite *eet_suite = DBEETGetSuite(); 47 | CuSuite *ntjoin_suite = DBNTJoinGetSuite(); 48 | CuSuite *osijoin_suite = DBOSIJoinGetSuite(); 49 | CuSuite *project_suite = DBProjectGetSuite(); 50 | CuSuite *scan_suite = DBScanGetSuite(); 51 | CuSuite *select_suite = DBSelectGetSuite(); 52 | CuSuite *sort_suite = DBSortGetSuite(); 53 | 54 | //CuSuiteAddSuite(suite, agg_suite); 55 | CuSuiteAddSuite(suite, dbqmm_suite); 56 | CuSuiteAddSuite(suite, lex_suite); 57 | CuSuiteAddSuite(suite, dbparseexpr_suite); 58 | CuSuiteAddSuite(suite, eet_suite); 59 | CuSuiteAddSuite(suite, ntjoin_suite); 60 | CuSuiteAddSuite(suite, osijoin_suite); 61 | CuSuiteAddSuite(suite, project_suite); 62 | CuSuiteAddSuite(suite, scan_suite); 63 | CuSuiteAddSuite(suite, select_suite); 64 | CuSuiteAddSuite(suite, sort_suite); 65 | 66 | CuSuiteRun(suite); 67 | CuSuiteSummary(suite, output); 68 | CuSuiteDetails(suite, output); 69 | printf("%s\n", output->buffer); 70 | 71 | //CuSuiteDelete(agg_suite); 72 | CuSuiteDelete(dbqmm_suite); 73 | CuSuiteDelete(lex_suite); 74 | CuSuiteDelete(dbparseexpr_suite); 75 | CuSuiteDelete(eet_suite); 76 | CuSuiteDelete(ntjoin_suite); 77 | CuSuiteDelete(osijoin_suite); 78 | CuSuiteDelete(project_suite); 79 | CuSuiteDelete(scan_suite); 80 | CuSuiteDelete(select_suite); 81 | CuSuiteDelete(sort_suite); 82 | free(suite); 83 | CuStringDelete(output); 84 | } 85 | 86 | int main(void) 87 | { 88 | runAllTests(); 89 | return 0; 90 | } 91 | -------------------------------------------------------------------------------- /src/unit_tests/scan/run_scan_ut.c: -------------------------------------------------------------------------------- 1 | /** 2 | @author Graeme Douglas 3 | @brief 4 | @details 5 | @copyright Copyright 2013 Graeme Douglas 6 | @license Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | @par 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 15 | either express or implied. See the License for the specific 16 | language governing permissions and limitations under the 17 | License. 18 | */ 19 | 20 | void runAllTests_scan(); 21 | 22 | int main(void) 23 | { 24 | runAllTests_scan(); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /src/unit_tests/select/run_select_ut.c: -------------------------------------------------------------------------------- 1 | /** 2 | @author Graeme Douglas 3 | @brief 4 | @details 5 | @copyright Copyright 2013 Graeme Douglas 6 | @license Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | @par 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 15 | either express or implied. See the License for the specific 16 | language governing permissions and limitations under the 17 | License. 18 | */ 19 | 20 | void runAllTests_select(); 21 | 22 | int main(void) 23 | { 24 | runAllTests_select(); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /src/unit_tests/sort/run_sort_ut.c: -------------------------------------------------------------------------------- 1 | /** 2 | @author Graeme Douglas 3 | @brief 4 | @details 5 | @copyright Copyright 2013 Graeme Douglas 6 | @license Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | @par 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 15 | either express or implied. See the License for the specific 16 | language governing permissions and limitations under the 17 | License. 18 | */ 19 | 20 | void runAllTests_sort(); 21 | 22 | int main(void) 23 | { 24 | runAllTests_sort(); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /src/utils/cfs_init_test_relations.h: -------------------------------------------------------------------------------- 1 | //***************************************************************************** 2 | /** 3 | @file cfs_init_test_relations.h 4 | @author Graeme Douglas 5 | @brief A quick and dirty program for creating test relations for 6 | benchmarking the database. 7 | @details 8 | @copyright Copyright 2013 Graeme Douglas 9 | @license Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | 14 | @par 15 | Unless required by applicable law or agreed to in writing, 16 | software distributed under the License is distributed on an 17 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 18 | either express or implied. See the License for the specific 19 | language governing permissions and limitations under the 20 | License. 21 | */ 22 | //***************************************************************************** 23 | 24 | #ifndef CFS_INIT_TEST_RELATIONS_H 25 | #define CFS_INIT_TEST_RELATIONS_H 26 | #include "ref.h" 27 | #include 28 | #include 29 | #include 30 | #include "dbstorage.h" 31 | #include "eet.h" 32 | #include "dbindex.h" 33 | #include "db_ctconf.h" 34 | 35 | #ifdef DB_CTCONF_SETTING_TARGET 36 | #if DB_CTCONF_SETTING_TARGET == DB_CTCONF_OPTION_TARGET_STD 37 | #include 38 | 39 | /* Initialize a test relation, USING THE C FILE HANDLING. THESE RELATIONS 40 | PERSIST! */ 41 | /** 42 | @brief Build a test relation using C file handling. 43 | @details This is more of a "proof of concept" method. The purpose is to 44 | debug the code problems here before moving to CFS. 45 | */ 46 | db_int init_fs_test_relation(char *relationname, db_int numattr, 47 | db_int numtuples, db_int bound, db_int seed); 48 | #endif 49 | #endif 50 | 51 | #ifdef DB_CTCONF_SETTING_TARGET 52 | #if DB_CTCONF_SETTING_TARGET == DB_CTCONF_OPTION_TARGET_CONTIKI 53 | #include "contiki.h" 54 | #include "cfs/cfs.h" 55 | #include "cfs/cfs-coffee.h" 56 | #include "lib/random.h" 57 | 58 | /* Initialize a test relation using Contiki Filesystem interface (CFS). */ 59 | /** 60 | @brief Build a test relation using Contiki Filesystem interface. 61 | @details This builds a randomized relation relation to use during 62 | testing on devices using CFS. IF USED IN A SIMULATOR, ANY 63 | RELATION CREATED WITH THIS METHOD WILL VANISH! 64 | */ 65 | db_int init_cfs_test_relation(char *relationname, db_int numattr, 66 | db_int numtuples, db_int bound, db_int seed); 67 | #endif 68 | #endif 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /src/utils/gen_bench_relations.c: -------------------------------------------------------------------------------- 1 | /*****************************************************************************/ 2 | /** 3 | @file gen_bench_relations.c 4 | @author Graeme Douglas 5 | @brief A quick and dirty program for creating test relations for 6 | benchmarking the database. 7 | @details 8 | @see Reference @ref gen_bench_relations.h for more information. 9 | @copyright Copyright 2013 Graeme Douglas 10 | @license Licensed under the Apache License, Version 2.0 (the "License"); 11 | you may not use this file except in compliance with the License. 12 | You may obtain a copy of the License at 13 | http://www.apache.org/licenses/LICENSE-2.0 14 | 15 | @par 16 | Unless required by applicable law or agreed to in writing, 17 | software distributed under the License is distributed on an 18 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 19 | either express or implied. See the License for the specific 20 | language governing permissions and limitations under the 21 | License. 22 | */ 23 | /*****************************************************************************/ 24 | 25 | #include "gen_bench_relations.h" 26 | #include "debug.h" 27 | 28 | db_int integerlength(db_int value) 29 | { 30 | db_int length = 0; 31 | if (0 == value) 32 | length = 1; 33 | while (value) 34 | { 35 | length++; 36 | value/=10; 37 | } 38 | return length; 39 | } 40 | 41 | /* Initialize a test relation using Contiki Filesystem interface. */ 42 | db_int gen_bench_relation(char *relationname, db_int numattr, 43 | db_int numtuples, db_int bound, db_int seed, db_int type) 44 | { 45 | /* General variable declarations. */ 46 | char charWrite; 47 | db_int intWrite; 48 | char offset = 0; 49 | char size = 0; 50 | db_fileref_t myfile; 51 | db_fileremove(relationname); 52 | db_int i, j; 53 | // Allocate enough room for any integer. 54 | char attrname[5 + integerlength((db_int)DB_INT_MAX)]; 55 | 56 | /* Seed the random number generator to always generate the same 57 | relation. */ 58 | //random_init(seed); // TODO: FIX THIS!!! 59 | srand(seed); // time(NULL); 60 | 61 | /**** Create the new relation. ****/ 62 | size = 0; 63 | offset = 0; 64 | myfile = db_openwritefile(relationname); 65 | if (0 > myfile) 66 | { 67 | PRINTF("Could not open file for writing.\n"); 68 | return -1; 69 | } 70 | 71 | /* Write out the number of attributes into the relation. */ 72 | charWrite = numattr; 73 | db_filewrite(myfile, &charWrite, 1*sizeof(char)); 74 | 75 | /** Header information for all attributes. **/ 76 | for (i = 0; i < numattr; ++i) 77 | { 78 | /* Size of name. */ 79 | charWrite = 5 + integerlength(i); 80 | db_filewrite(myfile, &charWrite, 1*sizeof(char)); 81 | 82 | sprintf(attrname, "attr%d", i); 83 | /* Attribute name. */ 84 | db_filewrite(myfile, attrname, (strlen(attrname)+1)*sizeof(char)); 85 | 86 | /* Attribute type. */ 87 | charWrite = 0; 88 | db_filewrite(myfile, &charWrite, 1*sizeof(char)); 89 | 90 | /* Attribute offset. */ 91 | offset += size; 92 | db_filewrite(myfile, &offset, 1*sizeof(char)); 93 | 94 | /* Attribute size. */ 95 | size = (char)sizeof(db_int); 96 | db_filewrite(myfile, &size, 1*sizeof(char)); 97 | } 98 | 99 | db_int autoid = 0; 100 | /*** Write out tuples. ***/ 101 | for (i = 0; i < numtuples; ++i) 102 | { 103 | /* Determine size of isnull array. */ 104 | db_int isnull_size = numattr / 8; 105 | if (0 < numattr % 8) 106 | isnull_size++; 107 | /* Write out isnull bit array. */ 108 | for (j = 0; j < isnull_size; ++j) 109 | { 110 | charWrite = 0x0; 111 | db_filewrite(myfile, &charWrite, 1*sizeof(char)); 112 | } 113 | 114 | /* Write out attributes. */ 115 | for (j = 0; j < numattr; ++j) 116 | { 117 | if (1 == type && 0==j) 118 | { 119 | intWrite = autoid; 120 | autoid++; 121 | } 122 | else 123 | { 124 | //intWrite = (db_int)((random_rand()) % bound); 125 | intWrite = (db_int)((rand()) % bound); 126 | } 127 | db_filewrite(myfile, &intWrite, 1*sizeof(db_int)); 128 | } 129 | } 130 | 131 | db_fileclose(myfile); 132 | /* Write out index data, if necessary. */ 133 | if (1==type) 134 | { 135 | /* General variable declaration. */ 136 | long longWrite; 137 | db_fileref_t file; 138 | db_eet_t eet; 139 | db_eetnode_attr_t attr; 140 | char *tempname[100]; 141 | 142 | sprintf(tempname, "DB_IDXM_%s", relationname); 143 | file = db_openwritefile(tempname); 144 | 145 | if (file == DB_STORAGE_NOFILE) 146 | { 147 | puts("CAN'T OPEN IDXM FILE!"); 148 | return -1; 149 | } 150 | 151 | /* Write out the number of indexes for this relation. */ 152 | charWrite = 1; 153 | db_filewrite(file, &charWrite, sizeof(char)); 154 | 155 | /* Write out the length (including \0) of index name. */ 156 | charWrite = 2+strlen(relationname); 157 | db_filewrite(file, &charWrite, sizeof(char)); 158 | 159 | sprintf(tempname, "i%s", relationname); 160 | 161 | /* Index name.*/ 162 | db_filewrite(file, tempname, charWrite); 163 | 164 | /* Write out the number of expressions for this index. */ 165 | charWrite = 1; 166 | db_filewrite(file, &charWrite, sizeof(char)); 167 | 168 | /* Write out the expression. */ 169 | eet.size = sizeof(db_eetnode_attr_t); 170 | eet.stack_size = sizeof(db_eetnode_dbint_t); 171 | db_filewrite(file, (unsigned char*)(&eet), sizeof(db_eet_t)); 172 | attr.base.type = DB_EETNODE_ATTR; 173 | attr.pos = 0; 174 | attr.tuple_pos = 0; 175 | db_filewrite(file, (unsigned char*)(&attr), sizeof(db_eetnode_attr_t)); 176 | 177 | db_fileclose(file); 178 | 179 | sprintf(tempname, "DB_IDX_i%s", relationname); 180 | file = db_openwritefile(tempname); 181 | 182 | if (file == DB_STORAGE_NOFILE) 183 | { 184 | puts("CAN'T OPEN IDX FILE!"); 185 | return -1; 186 | } 187 | 188 | /* Write out index type. */ 189 | charWrite = DB_INDEX_TYPE_INLINE; 190 | db_filewrite(file, (unsigned char*)&charWrite, sizeof(char)); 191 | 192 | /* Write out number of records. */ 193 | longWrite = numtuples; 194 | db_filewrite(file, (unsigned char*)&longWrite, sizeof(long)); 195 | 196 | db_fileclose(file); 197 | } 198 | return 0; 199 | } 200 | -------------------------------------------------------------------------------- /src/utils/gen_bench_relations.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /** 3 | @file gen_bench_relations.h 4 | @author Graeme Douglas 5 | @brief A quick and dirty program for creating test relations for 6 | benchmarking the database. 7 | @details 8 | @copyright Copyright 2013 Graeme Douglas 9 | @license Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | 14 | @par 15 | Unless required by applicable law or agreed to in writing, 16 | software distributed under the License is distributed on an 17 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 18 | either express or implied. See the License for the specific 19 | language governing permissions and limitations under the 20 | License. 21 | */ 22 | /******************************************************************************/ 23 | 24 | #ifndef GEN_BENCH_RELATIONS_H 25 | #define GEN_BENCH_RELATIONS_H 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | #include "../ref.h" 32 | #include 33 | #include 34 | #include 35 | #include "../dbstorage/dbstorage.h" 36 | #include "../dblogic/eet.h" 37 | #include "../dbindex/dbindex.h" 38 | #include "../db_ctconf.h" 39 | #include 40 | 41 | /* Initialize a test relation using Contiki Filesystem interface (CFS). */ 42 | /** 43 | @brief Build a test relation for any system. 44 | */ 45 | db_int gen_bench_relation(char *relationname, db_int numattr, 46 | db_int numtuples, db_int bound, db_int seed, db_int type); 47 | 48 | #ifdef __cplusplus 49 | } 50 | #endif 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /src/utils/gen_test_indexes.c: -------------------------------------------------------------------------------- 1 | /** 2 | @author Graeme Douglas 3 | @brief A quick and dirty program for creating a set of test 4 | relations on any platform. 5 | @details 6 | @copyright Copyright 2013 Graeme Douglas 7 | @license Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | @par 13 | Unless required by applicable law or agreed to in writing, 14 | software distributed under the License is distributed on an 15 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 16 | either express or implied. See the License for the specific 17 | language governing permissions and limitations under the 18 | License. 19 | */ 20 | 21 | //#include "../ref.h" 22 | //#include "../relation.h" 23 | //#include "../tuple.h" 24 | #include "../ref.h" 25 | #include "../dblogic/eet.h" 26 | #include "../dbstorage/dbstorage.h" 27 | #include "../dbindex/dbindex.h" 28 | #include 29 | #include 30 | #include 31 | 32 | db_int main(void) 33 | { 34 | /* General variable declaration. */ 35 | char charWrite; 36 | long longWrite; 37 | db_fileref_t file; 38 | db_eet_t eet; 39 | db_eetnode_attr_t attr; 40 | 41 | /**** Create DB_IDXM_test_rel3. ****/ 42 | db_fileremove("../tests/DB_IDXM_test_rel3"); 43 | file = db_openwritefile("../tests/DB_IDXM_test_rel3"); 44 | 45 | if (file == NULL) 46 | { 47 | perror("Failed to open file \"DB_IDXM_test_rel3\"."); 48 | return -1; 49 | } 50 | 51 | /* Write out the number of indexes for this relation. */ 52 | charWrite = 1; 53 | db_filewrite(file, &charWrite, sizeof(char)); 54 | 55 | /* Write out the length (including \0) of index name. */ 56 | charWrite = 7; 57 | db_filewrite(file, &charWrite, sizeof(char)); 58 | 59 | /* Index name.*/ 60 | db_filewrite(file, "tr3idx", charWrite); 61 | 62 | /* Write out the number of expressions for this index. */ 63 | charWrite = 1; 64 | db_filewrite(file, &charWrite, sizeof(char)); 65 | 66 | /* Write out the expression. */ 67 | eet.size = sizeof(db_eetnode_attr_t); 68 | eet.stack_size = sizeof(db_eetnode_dbint_t); 69 | db_filewrite(file, (unsigned char*)(&eet), sizeof(db_eet_t)); 70 | attr.base.type = DB_EETNODE_ATTR; 71 | attr.pos = 0; 72 | attr.tuple_pos = 0; 73 | db_filewrite(file, (unsigned char*)(&attr), sizeof(db_eetnode_attr_t)); 74 | 75 | fclose(file); 76 | 77 | /**** Create DB_IDX_tr3idx ****/ 78 | db_fileremove("../tests/DB_IDX_tr3idx"); 79 | file = db_openwritefile("../tests/DB_IDX_tr3idx"); 80 | 81 | if (file == NULL) 82 | { 83 | perror("Failed to open file \"DB_IDXM_tr3idx\"."); 84 | return -1; 85 | } 86 | 87 | /* Write out index type. */ 88 | charWrite = DB_INDEX_TYPE_INLINE; 89 | db_filewrite(file, (unsigned char*)&charWrite, sizeof(char)); 90 | 91 | /* Write out number of records. */ 92 | longWrite = 2; 93 | db_filewrite(file, (unsigned char*)&longWrite, sizeof(long)); 94 | 95 | fclose(file); 96 | 97 | /**** Create DB_IDXM_fruit_stock_1. ****/ 98 | db_fileremove("../tests/DB_IDXM_fruit_stock_1"); 99 | file = db_openwritefile("../tests/DB_IDXM_fruit_stock_1"); 100 | 101 | if (file == NULL) 102 | { 103 | perror("Failed to open file \"DB_IDXM_fruit_stock_1\"."); 104 | return -1; 105 | } 106 | 107 | /* Write out the number of indexes for this relation. */ 108 | charWrite = 1; 109 | db_filewrite(file, &charWrite, sizeof(char)); 110 | 111 | /* Write out the length (including \0) of index name. */ 112 | charWrite = 7; 113 | db_filewrite(file, &charWrite, sizeof(char)); 114 | 115 | /* Index name.*/ 116 | db_filewrite(file, "fs1idx", charWrite); 117 | 118 | /* Write out the number of expressions for this index. */ 119 | charWrite = 1; 120 | db_filewrite(file, &charWrite, sizeof(char)); 121 | 122 | /* Write out the expression. */ 123 | eet.size = sizeof(db_eetnode_attr_t); 124 | eet.stack_size = sizeof(db_eetnode_dbint_t); 125 | db_filewrite(file, (unsigned char*)(&eet), sizeof(db_eet_t)); 126 | attr.base.type = DB_EETNODE_ATTR; 127 | attr.pos = 0; 128 | attr.tuple_pos = 0; 129 | db_filewrite(file, (unsigned char*)(&attr), sizeof(db_eetnode_attr_t)); 130 | 131 | fclose(file); 132 | 133 | /**** Create DB_IDX_fs1idx ****/ 134 | db_fileremove("../tests/DB_IDX_fs1idx"); 135 | file = db_openwritefile("../tests/DB_IDX_fs1idx"); 136 | 137 | if (file == NULL) 138 | { 139 | perror("Failed to open file \"DB_IDX_fs1idx\"."); 140 | return -1; 141 | } 142 | 143 | /* Write out index type. */ 144 | charWrite = DB_INDEX_TYPE_INLINE; 145 | db_filewrite(file, (unsigned char*)&charWrite, sizeof(char)); 146 | 147 | /* Write out number of records. */ 148 | longWrite = 5; 149 | db_filewrite(file, (unsigned char*)&longWrite, sizeof(long)); 150 | 151 | fclose(file); 152 | 153 | return 0; 154 | } 155 | -------------------------------------------------------------------------------- /src/utils/gen_test_relations.c: -------------------------------------------------------------------------------- 1 | /** 2 | @author Graeme Douglas 3 | @brief A quick and dirty program for creating a set of test 4 | relations on any platform. 5 | @details 6 | @copyright Copyright 2013 Graeme Douglas 7 | @license Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | @par 13 | Unless required by applicable law or agreed to in writing, 14 | software distributed under the License is distributed on an 15 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 16 | either express or implied. See the License for the specific 17 | language governing permissions and limitations under the 18 | License. 19 | */ 20 | 21 | #include "../ref.h" 22 | #include "../dbstorage/dbstorage.h" 23 | #include "../dbmm/db_query_mm.h" 24 | #include "../dbparser/dbparser.h" 25 | #include 26 | #include 27 | #include 28 | 29 | db_int main(void) 30 | { 31 | /* General variable declaration. */ 32 | db_query_mm_t mm; 33 | int memsegsize = 700; /* In bytes. */ 34 | char memseg[memsegsize]; 35 | init_query_mm(&mm, memseg, memsegsize); 36 | 37 | int i; 38 | char size = 0; 39 | 40 | /**** Create test_rel1. ****/ 41 | db_fileremove("../tests/test_rel1"); 42 | db_fileremove("./test_rel1"); 43 | char *test_rel1_cquery = "CREATE TABLE test_rel1 (Apple INT)"; 44 | char *test_rel1_iqueries[] = { 45 | "INSERT INTO test_rel1 VALUES (1)", 46 | "INSERT INTO test_rel1 VALUES (2)", 47 | "INSERT INTO test_rel1 VALUES (3)", 48 | "INSERT INTO test_rel1 VALUES (9)", 49 | }; 50 | init_query_mm(&mm, memseg, memsegsize); 51 | parse(test_rel1_cquery, &mm); 52 | size = sizeof(test_rel1_iqueries)/sizeof(char*); 53 | for (i = 0; i < size; i++) 54 | { 55 | init_query_mm(&mm, memseg, memsegsize); 56 | parse(test_rel1_iqueries[i], &mm); 57 | } 58 | 59 | /**** Create test_rel2. ****/ 60 | db_fileremove("test_rel2"); 61 | db_fileremove("../tests/test_rel2"); 62 | char *test_rel2_cquery = "CREATE TABLE test_rel2 (A1 INT, a2 STRING(10), \"3\" INT)"; 63 | char *test_rel2_iqueries[] = { 64 | }; /* Empty relation. */ 65 | init_query_mm(&mm, memseg, memsegsize); 66 | parse(test_rel2_cquery, &mm); 67 | size = sizeof(test_rel2_iqueries)/sizeof(char*); 68 | for (i = 0; i < size; i++) 69 | { 70 | init_query_mm(&mm, memseg, memsegsize); 71 | parse(test_rel2_iqueries[i], &mm); 72 | } 73 | 74 | /**** Create test_rel3. ****/ 75 | db_fileremove("../tests/test_rel3"); 76 | db_fileremove("test_rel3"); 77 | char *test_rel3_cquery = "CREATE TABLE test_rel3 (A1 INT, a2 STRING(10), \"3\" INT)"; 78 | char *test_rel3_iqueries[] = { 79 | "INSERT INTO test_rel3 VALUES (1, 'Hi', 1)", 80 | "INSERT INTO test_rel3 VALUES (73, 'linux', 4023)", 81 | }; 82 | init_query_mm(&mm, memseg, memsegsize); 83 | parse(test_rel3_cquery, &mm); 84 | size = sizeof(test_rel3_iqueries)/sizeof(char*); 85 | for (i = 0; i < size; i++) 86 | { 87 | init_query_mm(&mm, memseg, memsegsize); 88 | parse(test_rel3_iqueries[i], &mm); 89 | } 90 | 91 | /**** Create fruit_stock_1. ****/ 92 | db_fileremove("fruit_stock_1"); 93 | db_fileremove("../tests/fruit_stock_1"); 94 | char *fruit_stock_1_cquery = "CREATE TABLE fruit_stock_1 (id INT, name STRING(10), qty INT, price INT)"; 95 | char *fruit_stock_1_iqueries[] = { 96 | "INSERT INTO fruit_stock_1 VALUES (1, 'Apple', 10, 2)", 97 | "INSERT INTO fruit_stock_1 VALUES (2, 'Orange', 29, 3)", 98 | "INSERT INTO fruit_stock_1 VALUES (3, 'Pear', 17, 1)", 99 | "INSERT INTO fruit_stock_1 VALUES (4, 'Lemon', 12, 4)", 100 | "INSERT INTO fruit_stock_1 VALUES (5, 'Lime', 10, 3)", 101 | }; 102 | init_query_mm(&mm, memseg, memsegsize); 103 | parse(fruit_stock_1_cquery, &mm); 104 | size = sizeof(fruit_stock_1_iqueries)/sizeof(char*); 105 | for (i = 0; i < size; i++) 106 | { 107 | init_query_mm(&mm, memseg, memsegsize); 108 | parse(fruit_stock_1_iqueries[i], &mm); 109 | } 110 | 111 | /**** Create fruit_stock_2. ****/ 112 | db_fileremove("fruit_stock_2"); 113 | db_fileremove("../tests/fruit_stock_2"); 114 | char *fruit_stock_2_cquery = "CREATE TABLE fruit_stock_2 (id INT, name STRING(10), qty INT, price INT)"; 115 | char *fruit_stock_2_iqueries[] = { 116 | "INSERT INTO fruit_stock_2 (price) VALUES (2)", 117 | "INSERT INTO fruit_stock_2 VALUES (2, 'Orange', 29, 3)", 118 | "INSERT INTO fruit_stock_2 (id, qty, price) VALUES (3, 17, 1)", 119 | "INSERT INTO fruit_stock_2 (name, qty, price) VALUES ('Lemon', 12, 4)", 120 | "INSERT INTO fruit_stock_2 (id, name, price) VALUES (5, 'Lime', 3)", 121 | "INSERT INTO fruit_stock_2 (qty, price) VALUES (1374, 9)", 122 | "INSERT INTO fruit_stock_2 (name, price) VALUES ('Peach', 6)", 123 | "INSERT INTO fruit_stock_2 (id, price) VALUES (8, 2)", 124 | }; 125 | init_query_mm(&mm, memseg, memsegsize); 126 | parse(fruit_stock_2_cquery, &mm); 127 | size = sizeof(fruit_stock_2_iqueries)/sizeof(char*); 128 | for (i = 0; i < size; i++) 129 | { 130 | init_query_mm(&mm, memseg, memsegsize); 131 | parse(fruit_stock_2_iqueries[i], &mm); 132 | } 133 | 134 | /**** Create tenattrtable. ****/ 135 | db_fileremove("tenattrtable"); 136 | db_fileremove("../tests/tenattrtable"); 137 | char *tenattrtable_cquery = "CREATE TABLE tenattrtable (a0 INT, a1 INT, a2 INT, a3 INT, a4 INT, a5 INT, a6 INT, a7 INT, a8 INT, a9 INT)"; 138 | char *tenattrtable_iqueries[] = { 139 | "INSERT INTO tenattrtable VALUES (0, 0, 0, 0, 0, 0, 0, 0, 0, 0)", 140 | "INSERT INTO tenattrtable (a1, a2, a3, a4, a5, a6, a7, a8) VALUES (1, 1, 1, 1, 1, 1, 1, 1)", 141 | }; 142 | init_query_mm(&mm, memseg, memsegsize); 143 | parse(tenattrtable_cquery, &mm); 144 | size = sizeof(tenattrtable_iqueries)/sizeof(char*); 145 | for (i = 0; i < size; i++) 146 | { 147 | init_query_mm(&mm, memseg, memsegsize); 148 | parse(tenattrtable_iqueries[i], &mm); 149 | } 150 | 151 | /**** Create db_dummy (To be used for queries that do not involve a scan). ****/ 152 | db_fileremove("db_dummy"); 153 | db_fileremove("../tests/db_dummy"); 154 | char *db_dummy_cquery = "CREATE TABLE db_dummy (a0 INT)"; 155 | char *db_dummy_iqueries[] = { 156 | "INSERT INTO db_dummy VALUES (0)" 157 | }; 158 | init_query_mm(&mm, memseg, memsegsize); 159 | parse(db_dummy_cquery, &mm); 160 | size = sizeof(db_dummy_iqueries)/sizeof(char*); 161 | for (i = 0; i < size; i++) 162 | { 163 | init_query_mm(&mm, memseg, memsegsize); 164 | parse(db_dummy_iqueries[i], &mm); 165 | } 166 | 167 | return 0; 168 | } 169 | --------------------------------------------------------------------------------