├── .gitignore ├── LICENSE ├── README.md └── src ├── CMakeLists.txt ├── LICENSE ├── common ├── CMakeLists.txt ├── generated_common.h ├── global_include.h ├── test │ ├── CMakeLists.txt │ ├── generated_common_test.cc │ └── test_commons.h ├── utils.cc └── utils.h ├── example ├── CMakeLists.txt ├── common_test.py ├── example1.json ├── example1.proto ├── json_example_utils.h ├── json_generated_query1.cc ├── json_generated_query2.cc ├── json_generated_query3.cc ├── json_generated_query4.cc ├── json_generated_query5.cc ├── json_generated_query6.cc ├── json_generated_query7.cc ├── json_golden1.out ├── json_golden2.out ├── json_golden3.out ├── json_golden4.out ├── json_golden5.out ├── json_golden6.out ├── json_golden7.out ├── proto_example_utils.h ├── proto_generated_query1.cc ├── proto_generated_query2.cc ├── proto_generated_query3.cc ├── proto_generated_query4.cc ├── proto_generated_query5.cc ├── proto_generated_query6.cc ├── proto_generated_query7.cc ├── proto_generated_query8.cc ├── proto_golden1.out ├── proto_golden2.out ├── proto_golden3.out ├── proto_golden4.out ├── proto_golden5.out ├── proto_golden6.out ├── proto_golden7.out └── proto_golden8.out ├── json-query ├── CMakeLists.txt ├── json_generated_common.h ├── json_query_engine.cc ├── json_query_engine.h └── test │ ├── CMakeLists.txt │ └── json_generated_common_test.cc ├── main ├── CMakeLists.txt └── run_query.cc ├── protobuf-query ├── CMakeLists.txt ├── protobuf_generated_common.h ├── protobuf_query_engine.cc ├── protobuf_query_engine.h └── test │ ├── CMakeLists.txt │ └── protobuf_generated_common_test.cc ├── sql ├── BISON_FLEX_README ├── CMakeLists.txt ├── query_tree.h ├── query_tree.hpp ├── select_parts.h ├── select_query.cc ├── select_query.h ├── sql.ll ├── sql.yy ├── test │ ├── CMakeLists.txt │ └── select_query_test.cc └── yy │ ├── location.hh │ ├── position.hh │ ├── sql.lex.cc │ ├── sql.output │ ├── sql.tab.cc │ ├── sql.tab.hh │ └── stack.hh └── third-party ├── rapidjson └── rapidjson-1.1.0 ├── include └── rapidjson │ ├── allocators.h │ ├── document.h │ ├── encodedstream.h │ ├── encodings.h │ ├── error │ ├── en.h │ └── error.h │ ├── filereadstream.h │ ├── filewritestream.h │ ├── fwd.h │ ├── internal │ ├── biginteger.h │ ├── diyfp.h │ ├── dtoa.h │ ├── ieee754.h │ ├── itoa.h │ ├── meta.h │ ├── pow10.h │ ├── regex.h │ ├── stack.h │ ├── strfunc.h │ ├── strtod.h │ └── swap.h │ ├── istreamwrapper.h │ ├── memorybuffer.h │ ├── memorystream.h │ ├── msinttypes │ ├── inttypes.h │ └── stdint.h │ ├── ostreamwrapper.h │ ├── pointer.h │ ├── prettywriter.h │ ├── rapidjson.h │ ├── reader.h │ ├── schema.h │ ├── stream.h │ ├── stringbuffer.h │ └── writer.h └── license.txt /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | eclipse_build/ 3 | .DS_Store 4 | src/.idea 5 | src/cmake-build-debug 6 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.12) 2 | project("object-query") 3 | 4 | if (APPLE) 5 | cmake_policy(SET CMP0042 NEW) 6 | SET(CMAKE_SHARED_LIBRARY_SUFFIX ".so") 7 | endif() 8 | 9 | if (${CMAKE_EXTRA_GENERATOR} MATCHES "Eclipse CDT4") 10 | add_definitions (-D__cplusplus=201402L) 11 | endif() 12 | 13 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g --std=c++14 -Wall -Wextra") 14 | 15 | enable_testing() 16 | enable_language(CXX) 17 | 18 | include(FindProtobuf) 19 | find_package(gflags REQUIRED) 20 | 21 | add_subdirectory(common) 22 | add_subdirectory(sql) 23 | add_subdirectory(protobuf-query) 24 | add_subdirectory(json-query) 25 | add_subdirectory(example) 26 | add_subdirectory(main) 27 | -------------------------------------------------------------------------------- /src/common/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | add_library(Utils generated_common.h global_include.h utils.h utils.cc) 3 | 4 | add_subdirectory(test) 5 | -------------------------------------------------------------------------------- /src/common/global_include.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 https://github.com/na-ka-na 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain the License at http://www.apache.org/licenses/LICENSE-2.0 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | template 20 | using optional = std::experimental::optional; 21 | 22 | using namespace std; 23 | 24 | template 25 | ostream& operator<<(ostream& os, const optional& obj) { 26 | obj ? (os << *obj) : (os << "NULL"); 27 | return os; 28 | } 29 | 30 | namespace oq { 31 | 32 | class Assert { 33 | public: 34 | template 35 | static runtime_error CreateException( 36 | const string& expr, const string& function, 37 | const string& file, long line, Args... args) { 38 | std::stringstream ss; 39 | ss << "ASSERT " << expr << " at " << file << ":" 40 | << line << " " << function << " msg:"; 41 | FormatMsg(ss, args...); 42 | FetchBacktrace(ss); 43 | return runtime_error(ss.str()); 44 | } 45 | private: 46 | template 47 | static void FormatMsg(std::ostream& oss, Type inst, Args... args) { 48 | FormatMsg(oss, inst); 49 | FormatMsg(oss, args...); 50 | } 51 | template 52 | static void FormatMsg(std::ostream& oss, Type inst) { 53 | oss << " " << inst; 54 | } 55 | static void FetchBacktrace (std::stringstream& ss) { 56 | void* callstack[128]; 57 | int i, frames = backtrace(callstack, 128); 58 | char** strs = backtrace_symbols(callstack, frames); 59 | ss << "\nBackTrace::\n======================"; 60 | for (i = 0; i < frames; ++i) { 61 | ss << "\n" << strs[i]; 62 | } 63 | ss << "\n======================"; 64 | free(strs); 65 | } 66 | static void FormatMsg(std::ostream&) {} 67 | }; 68 | 69 | #ifndef ASSERT 70 | #define ASSERT(expr, ...) \ 71 | if (!(expr)) { \ 72 | throw Assert::CreateException(string(#expr), __func__, __FILE__, __LINE__, ##__VA_ARGS__); \ 73 | } 74 | #endif 75 | 76 | #ifndef THROW 77 | #define THROW(...) \ 78 | throw Assert::CreateException("thrown", __func__, __FILE__, __LINE__, ##__VA_ARGS__); 79 | #endif 80 | 81 | } // namespace oq 82 | 83 | -------------------------------------------------------------------------------- /src/common/test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include_directories( 2 | ${CMAKE_SOURCE_DIR}/common 3 | ${CMAKE_SOURCE_DIR}/common/test 4 | ) 5 | 6 | add_executable(GeneratedCommonTest generated_common_test.cc) 7 | target_link_libraries(GeneratedCommonTest) 8 | add_test(GeneratedCommonTest GeneratedCommonTest) 9 | -------------------------------------------------------------------------------- /src/common/test/generated_common_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 https://github.com/na-ka-na 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain the License at http://www.apache.org/licenses/LICENSE-2.0 7 | */ 8 | 9 | // Unit tests for generated_common.h 10 | 11 | #include 12 | #include 13 | #include "test_commons.h" 14 | #include "generated_common.h" 15 | 16 | using namespace oq; 17 | 18 | void TestArthimeticFunctions() { 19 | auto a = Uminus(optional(1.1)); 20 | EXPECT_EQ(-1.1, *a); 21 | 22 | auto b = optional(2); 23 | auto c = Plus(a, b); 24 | EXPECT_EQ(9, int((*c) * 10)); 25 | 26 | auto d = Minus(a, b); 27 | EXPECT_EQ(-31, int((*d) * 10)); 28 | 29 | auto e = Mult(a, b); 30 | EXPECT_EQ(-22, int((*e) * 10)); 31 | 32 | auto f = Divide(a, b); 33 | EXPECT_EQ(-55, int((*f) * 100)); 34 | } 35 | 36 | string randomString() { 37 | srand (time(NULL)); 38 | size_t size = rand() % 140; 39 | if (size % 10) size = 0; 40 | return string(size, 'a'); 41 | } 42 | 43 | void checkEq(const string& expected, const MyString& actual) { 44 | EXPECT_EQ(expected.size(), actual.size()); 45 | stringstream ss; 46 | ss << actual; 47 | EXPECT_EQ(expected, ss.str()); 48 | } 49 | 50 | void TestMyString_constructor() { 51 | { 52 | MyString mystr; 53 | checkEq("", mystr); 54 | } 55 | { 56 | string str = randomString(); 57 | MyString mystr(str.c_str(), str.size()); 58 | checkEq(str, mystr); 59 | } 60 | { 61 | string str = randomString(); 62 | MyString mystr(&str); 63 | checkEq(str, mystr); 64 | } 65 | { 66 | string str = randomString(); 67 | MyString mystr(str); 68 | checkEq(str, mystr); 69 | } 70 | { 71 | string str = randomString(); 72 | string copy = str; 73 | MyString mystr(move(copy)); 74 | checkEq(str, mystr); 75 | } 76 | } 77 | 78 | void TestMyString_copyConstructor() { 79 | { 80 | string str = randomString(); 81 | MyString mystr1(str.c_str(), str.size()); 82 | MyString mystr(mystr1); 83 | checkEq(str, mystr); 84 | } 85 | { 86 | string str = randomString(); 87 | MyString mystr1(&str); 88 | MyString mystr(mystr1); 89 | checkEq(str, mystr); 90 | } 91 | { 92 | string str = randomString(); 93 | MyString mystr1(str); 94 | MyString mystr(mystr1); 95 | checkEq(str, mystr); 96 | } 97 | { 98 | string str = randomString(); 99 | string copy = str; 100 | MyString mystr1(move(copy)); 101 | MyString mystr(mystr1); 102 | checkEq(str, mystr); 103 | } 104 | } 105 | 106 | void TestMyString_moveConstructor() { 107 | { 108 | string str = randomString(); 109 | MyString mystr1(str.c_str(), str.size()); 110 | MyString mystr(move(mystr1)); 111 | checkEq(str, mystr); 112 | } 113 | { 114 | string str = randomString(); 115 | MyString mystr1(&str); 116 | MyString mystr(move(mystr1)); 117 | checkEq(str, mystr); 118 | } 119 | { 120 | string str = randomString(); 121 | MyString mystr1(str); 122 | MyString mystr(move(mystr1)); 123 | checkEq(str, mystr); 124 | } 125 | { 126 | string str = randomString(); 127 | string copy = str; 128 | MyString mystr1(move(copy)); 129 | MyString mystr(move(mystr1)); 130 | checkEq(str, mystr); 131 | } 132 | } 133 | 134 | int main() { 135 | TestArthimeticFunctions(); 136 | TestMyString_constructor(); 137 | TestMyString_copyConstructor(); 138 | TestMyString_moveConstructor(); 139 | } 140 | -------------------------------------------------------------------------------- /src/common/test/test_commons.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 https://github.com/na-ka-na 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain the License at http://www.apache.org/licenses/LICENSE-2.0 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | #include "global_include.h" 13 | 14 | namespace oq { 15 | 16 | #ifndef EXPECT_EQ 17 | #define EXPECT_EQ(expected, actual, ...) \ 18 | ASSERT(expected == actual, "expected:", expected, "actual:", actual, ##__VA_ARGS__) 19 | #endif 20 | 21 | #ifndef EXPECT_NE 22 | #define EXPECT_NE(expected, actual, ...) \ 23 | ASSERT(expected != actual, "expected:", expected, "actual:", actual, ##__VA_ARGS__) 24 | #endif 25 | 26 | #ifndef EXPECT_TRUE 27 | #define EXPECT_TRUE(actual, ...) \ 28 | ASSERT(static_cast(actual), "actual not true:", actual, ##__VA_ARGS__) 29 | #endif 30 | 31 | #ifndef EXPECT_FALSE 32 | #define EXPECT_FALSE(actual, ...) \ 33 | ASSERT(!static_cast(actual), "actual not false:", actual, ##__VA_ARGS__) 34 | #endif 35 | 36 | } // namespace oq 37 | -------------------------------------------------------------------------------- /src/common/utils.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 https://github.com/na-ka-na 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain the License at http://www.apache.org/licenses/LICENSE-2.0 7 | */ 8 | 9 | #include "utils.h" 10 | #include "global_include.h" 11 | 12 | using namespace oq; 13 | 14 | const function Utils::string2str = [](const string& str) {return str;}; 15 | 16 | vector Utils::splitDotIdentifier(const string& identifier) { 17 | static regex notdot("([^.]+)"); 18 | auto partsBegin = sregex_iterator(identifier.begin(), identifier.end(), notdot); 19 | vector selectFieldParts; 20 | for (sregex_iterator it = partsBegin; it != sregex_iterator(); ++it) { 21 | selectFieldParts.push_back(it->str()); 22 | } 23 | return selectFieldParts; 24 | } 25 | 26 | string Utils::makePlural(const string& name) { 27 | ASSERT(!name.empty()); 28 | return name + "s"; 29 | } 30 | 31 | string Utils::makeSingular(const string& name) { 32 | ASSERT(!name.empty()); 33 | if ((name.size() > 1) && (name.substr(name.size()-1, 1) == "s")) { 34 | return name.substr(0, name.size()-1); 35 | } else { 36 | return "each_" + name; 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /src/common/utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 https://github.com/na-ka-na 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain the License at http://www.apache.org/licenses/LICENSE-2.0 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include "global_include.h" 16 | 17 | using namespace std; 18 | 19 | namespace oq { 20 | 21 | class Utils { 22 | public: 23 | template 24 | static string join(const string& delim, It begin, It end, 25 | const function& to_str) { 26 | string joined; 27 | if (begin != end) { 28 | joined += to_str(*begin); 29 | while ((++begin) != end) { 30 | joined += delim; 31 | joined += to_str(*begin); 32 | } 33 | } 34 | return joined; 35 | } 36 | 37 | template 38 | static string joinVec(const string& delim, const vector& ts, 39 | const function& to_str) { 40 | return join(delim, ts.cbegin(), ts.cend(), to_str); 41 | } 42 | 43 | static const function string2str; 44 | 45 | template 46 | static function strfn() {return [](const T& t) {return t.str();};} 47 | 48 | static vector splitDotIdentifier(const string& identifier); 49 | 50 | static string makePlural(const string& name); 51 | 52 | static string makeSingular(const string& name); 53 | }; 54 | 55 | struct CodeGenSpec { 56 | vector headerIncludes; 57 | }; 58 | 59 | } // namespace oq 60 | -------------------------------------------------------------------------------- /src/example/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include_directories( 2 | SYSTEM ${PROTOBUF_INCLUDE_DIRS} 3 | ${CMAKE_BINARY_DIR}/example 4 | ${CMAKE_SOURCE_DIR}/common 5 | ${CMAKE_SOURCE_DIR}/protobuf-query 6 | ${CMAKE_SOURCE_DIR}/json-query 7 | ${CMAKE_SOURCE_DIR}/third-party/rapidjson/include 8 | ) 9 | 10 | file(GLOB ProtoFiles "${CMAKE_CURRENT_SOURCE_DIR}/*.proto") 11 | PROTOBUF_GENERATE_CPP(ProtoSources ProtoHeaders ${ProtoFiles}) 12 | 13 | # protobuf 3.3 generates some code with -Wunused-parameter warnings. 14 | # I guess we can disable all warning checks for generated files, but only disabling one for now. 15 | set_source_files_properties(${ProtoSources} PROPERTIES COMPILE_FLAGS -Wno-unused-parameter) 16 | 17 | add_library(ExampleProtos SHARED ${ProtoSources} ${ProtoHeaders}) 18 | target_link_libraries(ExampleProtos ${PROTOBUF_LIBRARIES}) 19 | 20 | set(common_test_py "common_test.py") 21 | add_custom_command(OUTPUT ${common_test_py} 22 | COMMAND cp ${CMAKE_CURRENT_SOURCE_DIR}/${common_test_py} ${CMAKE_CURRENT_BINARY_DIR} 23 | DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${common_test_py}) 24 | 25 | string(REPLACE ";" "," CMAKE_PREFIX_PATHS "${CMAKE_PREFIX_PATH}") 26 | 27 | foreach(qtype IN ITEMS proto json) 28 | foreach(testnum RANGE 1 8) 29 | if((${qtype} STREQUAL "json") AND (${testnum} STREQUAL "8")) 30 | continue() 31 | endif() 32 | set(golden_out "${qtype}_golden${testnum}.out") 33 | add_custom_command(OUTPUT ${golden_out} 34 | COMMAND cp ${CMAKE_CURRENT_SOURCE_DIR}/${golden_out} ${CMAKE_CURRENT_BINARY_DIR} 35 | DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${golden_out}) 36 | add_custom_target(${qtype}Test${testnum} ALL DEPENDS ${common_test_py} ${golden_out} RunQuery) 37 | add_test(NAME ${qtype}Test${testnum} COMMAND python ${common_test_py} ${qtype} ${testnum} ${CMAKE_PREFIX_PATHS}) 38 | set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${qtype}"_actual${testnum}.out") 39 | set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${qtype}"_generated_query${testnum}") 40 | set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${qtype}"_generated_query${testnum}.dSYM") 41 | endforeach(testnum) 42 | endforeach(qtype) 43 | 44 | # This is just for IDEs 45 | file(GLOB GenFiles "${CMAKE_CURRENT_SOURCE_DIR}/*.cc") 46 | add_library(GenFilesLib ${GenFiles}) 47 | -------------------------------------------------------------------------------- /src/example/common_test.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import subprocess 3 | 4 | TEST_SQL_QUERIES = [ 5 | # 1 6 | "SELECT financial.quarterly_profits,financial.quarterly_revenues,all_employees.id,\ 7 | all_employees.name,all_employees.active,all_employees.active_direct_reports,\ 8 | all_employees.enumx, all_employees.enumy,founded,board_of_directors\ 9 | FROM Example1.Company", 10 | 11 | # 2 12 | "SELECT all_employees.id, all_employees.name\ 13 | FROM Example1.Company\ 14 | WHERE all_employees.id IS NOT NULL AND\ 15 | ((all_employees.name='def' AND all_employees.active=true) OR\ 16 | all_employees.name='abc') AND\ 17 | financial.quarterly_profits>0", 18 | 19 | # 3 20 | "SELECT all_employees.id, financial.quarterly_revenues/all_employees.active_direct_reports\ 21 | FROM Example1.Company\ 22 | WHERE all_employees.active_direct_reports > 0 AND\ 23 | financial.quarterly_revenues*2 > 1", 24 | 25 | # 4 26 | "SELECT financial.quarterly_profits,all_employees.name,all_employees.active\ 27 | FROM Example1.Company\ 28 | ORDER BY all_employees.active,financial.quarterly_profits DESC,all_employees.id ASC", 29 | 30 | # 5 31 | "SELECT STR(all_employees.id) + ': ' + all_employees.name + ' (' + STR(all_employees.active) + ')' AS employee,\ 32 | STR(all_employees.id) + ' ' + employee + ' ' + STR(founded) AS employee2\ 33 | FROM Example1.Company\ 34 | WHERE employee2 LIKE '.*true.*'", 35 | 36 | # 6 37 | "SELECT all_employees.name, all_employees.active_direct_reports\ 38 | FROM Example1.Company\ 39 | WHERE all_employees.active_direct_reports IS NOT NULL", 40 | 41 | # 7 42 | "SELECT EmployeeStr(all_employees.name, all_employees.id), STR(all_employees.id), STR(all_employees)\ 43 | FROM Example1.Company", 44 | 45 | # 8 46 | "SELECT *, all_employees.* AS emp\ 47 | FROM Example1.Company", 48 | ] 49 | 50 | def runTest(querytype, testnum, cmake_prefix_paths): 51 | SOURCE_DIR = '../../src' 52 | data_file = SOURCE_DIR + '/example/example1.json' 53 | golden_out = querytype + '_golden' + str(testnum) + '.out' 54 | actual_out = querytype + '_actual' + str(testnum) + '.out' 55 | 56 | cmd_parts = ['../main/RunQuery'] 57 | cmd_parts.append('--queryType=' + querytype) 58 | cmd_parts.append('--codeGenDir=' + SOURCE_DIR + '/example') 59 | cmd_parts.append('--codeGenPrefix=' + querytype + '_generated_query' + str(testnum)) 60 | cmd_parts.append('--codeCompileDir=.') 61 | if querytype == 'proto': 62 | cmd_parts.append('--cppProtoHeader=example1.pb.h') 63 | cmd_parts.append('--cppProtoLib=./libExampleProtos.so') 64 | cmd_parts.append('--cppExtraIncludes=proto_example_utils.h') 65 | elif querytype == 'json': 66 | cmd_parts.append('--cppExtraIncludes=json_example_utils.h') 67 | cppExtraIncludeDirs = [] 68 | cppExtraLinkLibDirs = [] 69 | if len(cmake_prefix_paths) > 0: 70 | cppExtraIncludeDirs.extend([p + '/include' for p in cmake_prefix_paths]) 71 | cppExtraLinkLibDirs.extend([p + '/lib' for p in cmake_prefix_paths]) 72 | if len(cppExtraIncludeDirs) > 0: 73 | cmd_parts.append('--cppExtraIncludeDirs=' + ','.join(cppExtraIncludeDirs)) 74 | if len(cppExtraLinkLibDirs) > 0: 75 | cmd_parts.append('--cppExtraLinkLibDirs=' + ','.join(cppExtraLinkLibDirs)) 76 | cmd_parts.append(TEST_SQL_QUERIES[testnum-1]) 77 | cmd_parts.append(data_file) 78 | 79 | # subprocess.check* will raise error if command fails 80 | sys.stderr.write('RUNNING ' + ' '.join(cmd_parts) + '\n') 81 | with open(actual_out, 'w') as acutal_hndl: 82 | subprocess.check_call(cmd_parts, stdout=acutal_hndl) 83 | 84 | # diff doesn't return non zero exit if files differ, so do it manually 85 | cmd_parts = ['diff', '--brief', golden_out, actual_out] 86 | sys.stderr.write('RUNNING ' + ' '.join(cmd_parts) + '\n') 87 | diff_res = subprocess.check_output(cmd_parts) 88 | if len(diff_res) > 0: 89 | sys.stderr.write(diff_res) 90 | exit(1) 91 | sys.stderr.write('Success\n') 92 | 93 | 94 | if __name__ == "__main__": 95 | if len(sys.argv) < 3: 96 | sys.stderr.write('Invalid num arguments, expected atleast 2, querytype, testnum\n') 97 | sys.exit(1) 98 | 99 | querytype = sys.argv[1] 100 | if querytype != 'proto' and querytype != 'json': 101 | sys.stderr.write('querytype should be either proto or json') 102 | sys.exit(1) 103 | 104 | testnum = int(sys.argv[2]) 105 | if (testnum < 1) or (testnum > len(TEST_SQL_QUERIES)): 106 | sys.stderr.write('Invalid testnum ' + str(testnum) + ' valid range: [1,' + 107 | str(len(TEST_SQL_QUERIES)) + ']') 108 | sys.exit(1) 109 | 110 | cmake_prefix_paths = [] 111 | if len(sys.argv) >= 4: 112 | cmake_prefix_paths = sys.argv[3].split(',') 113 | 114 | runTest(querytype, testnum, cmake_prefix_paths) 115 | -------------------------------------------------------------------------------- /src/example/example1.json: -------------------------------------------------------------------------------- 1 | { 2 | "all_employees": [ 3 | { 4 | "active": false, 5 | "enumx": "ENUMX_X1", 6 | "enumy": [ 7 | "ENUMY_Y1", 8 | "ENUMY_Y2" 9 | ], 10 | "id": 1, 11 | "name": "abc" 12 | }, 13 | { 14 | "active": true, 15 | "active_direct_reports": [ 16 | 1, 17 | 2 18 | ], 19 | "enumy": [ 20 | "ENUMY_Y1" 21 | ], 22 | "id": 2, 23 | "name": "def" 24 | } 25 | ], 26 | "board_of_directors": [ 27 | 1, 28 | 2 29 | ], 30 | "financial": { 31 | "quarterly_profits": [ 32 | 1.322423, 33 | 2.4324269 34 | ], 35 | "quarterly_revenues": [ 36 | 1.9892451, 37 | 2.274987 38 | ] 39 | }, 40 | "founded": 1 41 | } 42 | -------------------------------------------------------------------------------- /src/example/example1.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package Example1; 4 | 5 | message Company { 6 | optional int32 founded = 1; 7 | repeated int32 board_of_directors = 2; 8 | optional Financial financial = 11; 9 | repeated Employee all_employees = 12; 10 | } 11 | 12 | message Financial { 13 | repeated float quarterly_profits = 1; 14 | repeated float quarterly_revenues = 2; 15 | } 16 | 17 | message Employee { 18 | optional int32 id = 1; 19 | optional string name = 2; 20 | optional bool active = 3; 21 | repeated int32 active_direct_reports = 4; 22 | optional EnumX enumx = 5; 23 | repeated EnumY enumy = 6; 24 | } 25 | 26 | enum EnumX { 27 | ENUMX_UNKNOWN = 0; 28 | ENUMX_X1 = 1; 29 | ENUMX_X2 = 2; 30 | } 31 | 32 | enum EnumY { 33 | ENUMY_UNKNOWN = 0; 34 | ENUMY_Y1 = 1; 35 | ENUMY_Y2 = 2; 36 | } 37 | -------------------------------------------------------------------------------- /src/example/json_example_utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "json_generated_common.h" 5 | 6 | using namespace std; 7 | 8 | string EmployeeStr(const oq::JsonValue& name, const oq::JsonValue& id) { 9 | stringstream ss; 10 | ss << name << "(id=" << id << ")"; 11 | return ss.str(); 12 | } 13 | -------------------------------------------------------------------------------- /src/example/json_generated_query2.cc: -------------------------------------------------------------------------------- 1 | /* 2 | SELECT all_employees.id, all_employees.name FROM Example1.Company WHERE ((all_employees.id IS NOT NULL AND (((all_employees.name = 'def') AND (all_employees.active = TRUE)) OR (all_employees.name = 'abc'))) AND (financial.quarterly_profits > 0)) 3 | 4 | with (document = parseFromFile()) { 5 | for each all_employee in document.all_employees { 6 | for each each_active in all_employee.all_employees.active { 7 | for each each_id in all_employee.all_employees.id { 8 | if (!all_employees.id IS NOT NULL) { continue; } 9 | tuples.add(all_employees.id) 10 | for each each_name in all_employee.all_employees.name { 11 | if (!(((all_employees.name = 'def') AND (all_employees.active = TRUE)) OR (all_employees.name = 'abc'))) { continue; } 12 | tuples.add(all_employees.name) 13 | for each each_financial in document.financial { 14 | for each quarterly_profit in each_financial.financial.quarterly_profits { 15 | if (!(financial.quarterly_profits > 0)) { continue; } 16 | tuples.record() 17 | } //quarterly_profit 18 | } //each_financial 19 | } //each_name 20 | } //each_id 21 | } //each_active 22 | } //all_employee 23 | } //document 24 | tuples.print('all_employees.id', 'all_employees.name') 25 | */ 26 | #include "json_example_utils.h" 27 | #include "json_generated_common.h" 28 | 29 | using namespace std; 30 | using namespace oq; 31 | 32 | vector header = { 33 | "all_employees.id", 34 | "all_employees.name", 35 | }; 36 | 37 | string $c3 = "abc"; 38 | string $c1 = "def"; 39 | auto $c4 = 0; 40 | auto $c2 = true; 41 | 42 | using S0 = optional; /* all_employees.active */ 43 | using S1 = optional; /* all_employees.id */ 44 | using S2 = optional; /* all_employees.name */ 45 | using S3 = optional; /* financial.quarterly_profits */ 46 | using TupleType = tuple; 47 | 48 | void runSelect(const vector& documents, vector& tuples) { 49 | for (const auto* document : Iterators::mk_json_iterator(documents)) { 50 | for (const auto* all_employee : Iterators::mk_json_iterator("all_employees", document, "all_employees")) { 51 | for (const auto* each_active : Iterators::mk_json_iterator("all_employees.active", all_employee, "active")) { 52 | S0 s0 = each_active ? *each_active : S0(); 53 | for (const auto* each_id : Iterators::mk_json_iterator("all_employees.id", all_employee, "id")) { 54 | S1 s1 = each_id ? *each_id : S1(); 55 | if (!IsNotNull(s1)) { continue; } 56 | for (const auto* each_name : Iterators::mk_json_iterator("all_employees.name", all_employee, "name")) { 57 | S2 s2 = each_name ? *each_name : S2(); 58 | if (!((Eq(s2, &$c1) && Eq(s0, &$c2)) || Eq(s2, &$c3))) { continue; } 59 | for (const auto* each_financial : Iterators::mk_json_iterator("financial", document, "financial")) { 60 | for (const auto* quarterly_profit : Iterators::mk_json_iterator("financial.quarterly_profits", each_financial, "quarterly_profits")) { 61 | S3 s3 = quarterly_profit ? *quarterly_profit : S3(); 62 | if (!Gt(s3, &$c4)) { continue; } 63 | tuples.emplace_back(s1, s2); 64 | } 65 | } 66 | } 67 | } 68 | } 69 | } 70 | } 71 | } 72 | 73 | void printTuples(const vector& tuples) { 74 | vector sizes; 75 | for (size_t i=0; i(t))); 80 | sizes[1] = max(sizes[1], PrintSize(get<1>(t))); 81 | } 82 | cout << std::left; 83 | for (size_t i=0; i(t)); 93 | Print(cout << " | " << setw(sizes[1]), get<1>(t)); 94 | cout << endl; 95 | } 96 | } 97 | 98 | int main(int argc, char** argv) { 99 | vector documents; 100 | FROM(argc, argv, documents); 101 | vector tuples; 102 | runSelect(documents, tuples); 103 | printTuples(tuples); 104 | } 105 | -------------------------------------------------------------------------------- /src/example/json_generated_query3.cc: -------------------------------------------------------------------------------- 1 | /* 2 | SELECT all_employees.id, (financial.quarterly_revenues/all_employees.active_direct_reports) FROM Example1.Company WHERE ((all_employees.active_direct_reports > 0) AND ((financial.quarterly_revenues*2) > 1)) 3 | 4 | with (document = parseFromFile()) { 5 | for each all_employee in document.all_employees { 6 | for each active_direct_report in all_employee.all_employees.active_direct_reports { 7 | if (!(all_employees.active_direct_reports > 0)) { continue; } 8 | for each each_id in all_employee.all_employees.id { 9 | tuples.add(all_employees.id) 10 | for each each_financial in document.financial { 11 | for each quarterly_revenue in each_financial.financial.quarterly_revenues { 12 | if (!((financial.quarterly_revenues*2) > 1)) { continue; } 13 | tuples.add((financial.quarterly_revenues/all_employees.active_direct_reports)) 14 | tuples.record() 15 | } //quarterly_revenue 16 | } //each_financial 17 | } //each_id 18 | } //active_direct_report 19 | } //all_employee 20 | } //document 21 | tuples.print('all_employees.id', '(financial.quarterly_revenues/all_employees.active_direct_reports)') 22 | */ 23 | #include "json_example_utils.h" 24 | #include "json_generated_common.h" 25 | 26 | using namespace std; 27 | using namespace oq; 28 | 29 | vector header = { 30 | "all_employees.id", 31 | "(financial.quarterly_revenues/all_employees.active_direct_reports)", 32 | }; 33 | 34 | auto $c1 = 0; 35 | auto $c3 = 1; 36 | auto $c2 = 2; 37 | 38 | using S0 = optional; /* all_employees.active_direct_reports */ 39 | using S1 = optional; /* all_employees.id */ 40 | using S2 = optional; /* financial.quarterly_revenues */ 41 | using S3 = decltype(Divide(S2(), S0())); /* (financial.quarterly_revenues/all_employees.active_direct_reports) */ 42 | using TupleType = tuple; 43 | 44 | void runSelect(const vector& documents, vector& tuples) { 45 | for (const auto* document : Iterators::mk_json_iterator(documents)) { 46 | for (const auto* all_employee : Iterators::mk_json_iterator("all_employees", document, "all_employees")) { 47 | for (const auto* active_direct_report : Iterators::mk_json_iterator("all_employees.active_direct_reports", all_employee, "active_direct_reports")) { 48 | S0 s0 = active_direct_report ? *active_direct_report : S0(); 49 | if (!Gt(s0, &$c1)) { continue; } 50 | for (const auto* each_id : Iterators::mk_json_iterator("all_employees.id", all_employee, "id")) { 51 | S1 s1 = each_id ? *each_id : S1(); 52 | for (const auto* each_financial : Iterators::mk_json_iterator("financial", document, "financial")) { 53 | for (const auto* quarterly_revenue : Iterators::mk_json_iterator("financial.quarterly_revenues", each_financial, "quarterly_revenues")) { 54 | S2 s2 = quarterly_revenue ? *quarterly_revenue : S2(); 55 | if (!Gt(Mult(s2, &$c2), &$c3)) { continue; } 56 | S3 s3 = Divide(s2, s0); 57 | tuples.emplace_back(s1, s3); 58 | } 59 | } 60 | } 61 | } 62 | } 63 | } 64 | } 65 | 66 | void printTuples(const vector& tuples) { 67 | vector sizes; 68 | for (size_t i=0; i(t))); 73 | sizes[1] = max(sizes[1], PrintSize(get<1>(t))); 74 | } 75 | cout << std::left; 76 | for (size_t i=0; i(t)); 86 | Print(cout << " | " << setw(sizes[1]), get<1>(t)); 87 | cout << endl; 88 | } 89 | } 90 | 91 | int main(int argc, char** argv) { 92 | vector documents; 93 | FROM(argc, argv, documents); 94 | vector tuples; 95 | runSelect(documents, tuples); 96 | printTuples(tuples); 97 | } 98 | -------------------------------------------------------------------------------- /src/example/json_generated_query4.cc: -------------------------------------------------------------------------------- 1 | /* 2 | SELECT financial.quarterly_profits, all_employees.name, all_employees.active FROM Example1.Company ORDER BY all_employees.active, financial.quarterly_profits DESC, all_employees.id 3 | 4 | with (document = parseFromFile()) { 5 | for each all_employee in document.all_employees { 6 | for each each_active in all_employee.all_employees.active { 7 | tuples.add(all_employees.active) 8 | for each each_id in all_employee.all_employees.id { 9 | tuples.add(all_employees.id) 10 | for each each_name in all_employee.all_employees.name { 11 | tuples.add(all_employees.name) 12 | for each each_financial in document.financial { 13 | for each quarterly_profit in each_financial.financial.quarterly_profits { 14 | tuples.add(financial.quarterly_profits) 15 | tuples.record() 16 | } //quarterly_profit 17 | } //each_financial 18 | } //each_name 19 | } //each_id 20 | } //each_active 21 | } //all_employee 22 | } //document 23 | tuples.sortBy('all_employees.active', 'financial.quarterly_profits', 'all_employees.id') 24 | tuples.print('financial.quarterly_profits', 'all_employees.name', 'all_employees.active') 25 | */ 26 | #include "json_example_utils.h" 27 | #include "json_generated_common.h" 28 | 29 | using namespace std; 30 | using namespace oq; 31 | 32 | vector header = { 33 | "financial.quarterly_profits", 34 | "all_employees.name", 35 | "all_employees.active", 36 | }; 37 | 38 | using S0 = optional; /* all_employees.active */ 39 | using S1 = optional; /* all_employees.id */ 40 | using S2 = optional; /* all_employees.name */ 41 | using S3 = optional; /* financial.quarterly_profits */ 42 | using TupleType = tuple; 43 | 44 | void runSelect(const vector& documents, vector& tuples) { 45 | for (const auto* document : Iterators::mk_json_iterator(documents)) { 46 | for (const auto* all_employee : Iterators::mk_json_iterator("all_employees", document, "all_employees")) { 47 | for (const auto* each_active : Iterators::mk_json_iterator("all_employees.active", all_employee, "active")) { 48 | S0 s0 = each_active ? *each_active : S0(); 49 | for (const auto* each_id : Iterators::mk_json_iterator("all_employees.id", all_employee, "id")) { 50 | S1 s1 = each_id ? *each_id : S1(); 51 | for (const auto* each_name : Iterators::mk_json_iterator("all_employees.name", all_employee, "name")) { 52 | S2 s2 = each_name ? *each_name : S2(); 53 | for (const auto* each_financial : Iterators::mk_json_iterator("financial", document, "financial")) { 54 | for (const auto* quarterly_profit : Iterators::mk_json_iterator("financial.quarterly_profits", each_financial, "quarterly_profits")) { 55 | S3 s3 = quarterly_profit ? *quarterly_profit : S3(); 56 | tuples.emplace_back(s3, s2, s0, s1); 57 | } 58 | } 59 | } 60 | } 61 | } 62 | } 63 | } 64 | } 65 | 66 | bool compareTuples(const TupleType& t1, const TupleType& t2) { 67 | int c; 68 | c = Compare(get<2>(t1), get<2>(t2)); 69 | if (c < 0) {return true;} else if (c > 0) {return false;} 70 | c = -Compare(get<0>(t1), get<0>(t2)); 71 | if (c < 0) {return true;} else if (c > 0) {return false;} 72 | c = Compare(get<3>(t1), get<3>(t2)); 73 | if (c < 0) {return true;} else if (c > 0) {return false;} 74 | return false; 75 | } 76 | 77 | void printTuples(const vector& tuples) { 78 | vector sizes; 79 | for (size_t i=0; i(t))); 84 | sizes[1] = max(sizes[1], PrintSize(get<1>(t))); 85 | sizes[2] = max(sizes[2], PrintSize(get<2>(t))); 86 | } 87 | cout << std::left; 88 | for (size_t i=0; i(t)); 98 | Print(cout << " | " << setw(sizes[1]), get<1>(t)); 99 | Print(cout << " | " << setw(sizes[2]), get<2>(t)); 100 | cout << endl; 101 | } 102 | } 103 | 104 | int main(int argc, char** argv) { 105 | vector documents; 106 | FROM(argc, argv, documents); 107 | vector tuples; 108 | runSelect(documents, tuples); 109 | std::sort(tuples.begin(), tuples.end(), compareTuples); 110 | printTuples(tuples); 111 | } 112 | -------------------------------------------------------------------------------- /src/example/json_generated_query5.cc: -------------------------------------------------------------------------------- 1 | /* 2 | SELECT (((((STR(all_employees.id)+': ')+all_employees.name)+' (')+STR(all_employees.active))+')') AS employee, ((((STR(all_employees.id)+' ')+employee)+' ')+STR(founded)) AS employee2 FROM Example1.Company WHERE (employee2 LIKE '.*true.*') 3 | 4 | with (document = parseFromFile()) { 5 | for each all_employee in document.all_employees { 6 | for each each_active in all_employee.all_employees.active { 7 | for each each_id in all_employee.all_employees.id { 8 | for each each_name in all_employee.all_employees.name { 9 | tuples.add((((((STR(all_employees.id)+': ')+all_employees.name)+' (')+STR(all_employees.active))+')')) 10 | for each each_founded in document.founded { 11 | if (!(((((STR(all_employees.id)+' ')+(((((STR(all_employees.id)+': ')+all_employees.name)+' (')+STR(all_employees.active))+')'))+' ')+STR(founded)) LIKE '.*true.*')) { continue; } 12 | tuples.add(((((STR(all_employees.id)+' ')+(((((STR(all_employees.id)+': ')+all_employees.name)+' (')+STR(all_employees.active))+')'))+' ')+STR(founded))) 13 | tuples.record() 14 | } //each_founded 15 | } //each_name 16 | } //each_id 17 | } //each_active 18 | } //all_employee 19 | } //document 20 | tuples.print('(((((STR(all_employees.id)+': ')+all_employees.name)+' (')+STR(all_employees.active))+')')', '((((STR(all_employees.id)+' ')+(((((STR(all_employees.id)+': ')+all_employees.name)+' (')+STR(all_employees.active))+')'))+' ')+STR(founded))') 21 | */ 22 | #include "json_example_utils.h" 23 | #include "json_generated_common.h" 24 | 25 | using namespace std; 26 | using namespace oq; 27 | 28 | vector header = { 29 | "employee", 30 | "employee2", 31 | }; 32 | 33 | string $c4 = " "; 34 | string $c2 = " ("; 35 | string $c3 = ")"; 36 | regex $c5 = regex(".*true.*", regex::optimize); 37 | string $c1 = ": "; 38 | 39 | template 40 | optional $STR(const optional& arg0) { 41 | if (arg0) { 42 | return optional(STR(*arg0)); 43 | } else { 44 | return optional(); 45 | } 46 | } 47 | 48 | using S0 = optional; /* all_employees.active */ 49 | using S1 = optional; /* all_employees.id */ 50 | using S2 = optional; /* all_employees.name */ 51 | using S3 = optional; /* founded */ 52 | using S4 = decltype(Plus(Plus(Plus(Plus(Plus($STR(S1()), &$c1), S2()), &$c2), $STR(S0())), &$c3)); /* (((((STR(all_employees.id)+': ')+all_employees.name)+' (')+STR(all_employees.active))+')') */ 53 | using S5 = decltype(Plus(Plus(Plus(Plus($STR(S1()), &$c4), Plus(Plus(Plus(Plus(Plus($STR(S1()), &$c1), S2()), &$c2), $STR(S0())), &$c3)), &$c4), $STR(S3()))); /* ((((STR(all_employees.id)+' ')+(((((STR(all_employees.id)+': ')+all_employees.name)+' (')+STR(all_employees.active))+')'))+' ')+STR(founded)) */ 54 | using TupleType = tuple; 55 | 56 | void runSelect(const vector& documents, vector& tuples) { 57 | for (const auto* document : Iterators::mk_json_iterator(documents)) { 58 | for (const auto* all_employee : Iterators::mk_json_iterator("all_employees", document, "all_employees")) { 59 | for (const auto* each_active : Iterators::mk_json_iterator("all_employees.active", all_employee, "active")) { 60 | S0 s0 = each_active ? *each_active : S0(); 61 | for (const auto* each_id : Iterators::mk_json_iterator("all_employees.id", all_employee, "id")) { 62 | S1 s1 = each_id ? *each_id : S1(); 63 | for (const auto* each_name : Iterators::mk_json_iterator("all_employees.name", all_employee, "name")) { 64 | S2 s2 = each_name ? *each_name : S2(); 65 | S4 s4 = Plus(Plus(Plus(Plus(Plus($STR(s1), &$c1), s2), &$c2), $STR(s0)), &$c3); 66 | for (const auto* each_founded : Iterators::mk_json_iterator("founded", document, "founded")) { 67 | S3 s3 = each_founded ? *each_founded : S3(); 68 | if (!Like(Plus(Plus(Plus(Plus($STR(s1), &$c4), Plus(Plus(Plus(Plus(Plus($STR(s1), &$c1), s2), &$c2), $STR(s0)), &$c3)), &$c4), $STR(s3)), $c5)) { continue; } 69 | S5 s5 = Plus(Plus(Plus(Plus($STR(s1), &$c4), Plus(Plus(Plus(Plus(Plus($STR(s1), &$c1), s2), &$c2), $STR(s0)), &$c3)), &$c4), $STR(s3)); 70 | tuples.emplace_back(s4, s5); 71 | } 72 | } 73 | } 74 | } 75 | } 76 | } 77 | } 78 | 79 | void printTuples(const vector& tuples) { 80 | vector sizes; 81 | for (size_t i=0; i(t))); 86 | sizes[1] = max(sizes[1], PrintSize(get<1>(t))); 87 | } 88 | cout << std::left; 89 | for (size_t i=0; i(t)); 99 | Print(cout << " | " << setw(sizes[1]), get<1>(t)); 100 | cout << endl; 101 | } 102 | } 103 | 104 | int main(int argc, char** argv) { 105 | vector documents; 106 | FROM(argc, argv, documents); 107 | vector tuples; 108 | runSelect(documents, tuples); 109 | printTuples(tuples); 110 | } 111 | -------------------------------------------------------------------------------- /src/example/json_generated_query6.cc: -------------------------------------------------------------------------------- 1 | /* 2 | SELECT all_employees.name, all_employees.active_direct_reports FROM Example1.Company WHERE all_employees.active_direct_reports IS NOT NULL 3 | 4 | with (document = parseFromFile()) { 5 | for each all_employee in document.all_employees { 6 | for each active_direct_report in all_employee.all_employees.active_direct_reports { 7 | if (!all_employees.active_direct_reports IS NOT NULL) { continue; } 8 | tuples.add(all_employees.active_direct_reports) 9 | for each each_name in all_employee.all_employees.name { 10 | tuples.add(all_employees.name) 11 | tuples.record() 12 | } //each_name 13 | } //active_direct_report 14 | } //all_employee 15 | } //document 16 | tuples.print('all_employees.name', 'all_employees.active_direct_reports') 17 | */ 18 | #include "json_example_utils.h" 19 | #include "json_generated_common.h" 20 | 21 | using namespace std; 22 | using namespace oq; 23 | 24 | vector header = { 25 | "all_employees.name", 26 | "all_employees.active_direct_reports", 27 | }; 28 | 29 | using S0 = optional; /* all_employees.active_direct_reports */ 30 | using S1 = optional; /* all_employees.name */ 31 | using TupleType = tuple; 32 | 33 | void runSelect(const vector& documents, vector& tuples) { 34 | for (const auto* document : Iterators::mk_json_iterator(documents)) { 35 | for (const auto* all_employee : Iterators::mk_json_iterator("all_employees", document, "all_employees")) { 36 | for (const auto* active_direct_report : Iterators::mk_json_iterator("all_employees.active_direct_reports", all_employee, "active_direct_reports")) { 37 | S0 s0 = active_direct_report ? *active_direct_report : S0(); 38 | if (!IsNotNull(s0)) { continue; } 39 | for (const auto* each_name : Iterators::mk_json_iterator("all_employees.name", all_employee, "name")) { 40 | S1 s1 = each_name ? *each_name : S1(); 41 | tuples.emplace_back(s1, s0); 42 | } 43 | } 44 | } 45 | } 46 | } 47 | 48 | void printTuples(const vector& tuples) { 49 | vector sizes; 50 | for (size_t i=0; i(t))); 55 | sizes[1] = max(sizes[1], PrintSize(get<1>(t))); 56 | } 57 | cout << std::left; 58 | for (size_t i=0; i(t)); 68 | Print(cout << " | " << setw(sizes[1]), get<1>(t)); 69 | cout << endl; 70 | } 71 | } 72 | 73 | int main(int argc, char** argv) { 74 | vector documents; 75 | FROM(argc, argv, documents); 76 | vector tuples; 77 | runSelect(documents, tuples); 78 | printTuples(tuples); 79 | } 80 | -------------------------------------------------------------------------------- /src/example/json_generated_query7.cc: -------------------------------------------------------------------------------- 1 | /* 2 | SELECT EmployeeStr(all_employees.name,all_employees.id), STR(all_employees.id), STR(all_employees) FROM Example1.Company 3 | 4 | with (document = parseFromFile()) { 5 | for each all_employee in document.all_employees { 6 | tuples.add(STR(all_employees)) 7 | for each each_id in all_employee.all_employees.id { 8 | tuples.add(STR(all_employees.id)) 9 | for each each_name in all_employee.all_employees.name { 10 | tuples.add(EmployeeStr(all_employees.name,all_employees.id)) 11 | tuples.record() 12 | } //each_name 13 | } //each_id 14 | } //all_employee 15 | } //document 16 | tuples.print('EmployeeStr(all_employees.name,all_employees.id)', 'STR(all_employees.id)', 'STR(all_employees)') 17 | */ 18 | #include "json_example_utils.h" 19 | #include "json_generated_common.h" 20 | 21 | using namespace std; 22 | using namespace oq; 23 | 24 | vector header = { 25 | "EmployeeStr(all_employees.name,all_employees.id)", 26 | "STR(all_employees.id)", 27 | "STR(all_employees)", 28 | }; 29 | 30 | template 31 | optional $EmployeeStr(const optional& arg0, const optional& arg1) { 32 | if (arg0 && arg1) { 33 | return optional(EmployeeStr(*arg0, *arg1)); 34 | } else { 35 | return optional(); 36 | } 37 | } 38 | template 39 | optional $STR(const optional& arg0) { 40 | if (arg0) { 41 | return optional(STR(*arg0)); 42 | } else { 43 | return optional(); 44 | } 45 | } 46 | 47 | using S0 = optional; /* all_employees */ 48 | using S1 = optional; /* all_employees.id */ 49 | using S2 = optional; /* all_employees.name */ 50 | using S3 = decltype($EmployeeStr(S2(), S1())); /* EmployeeStr(all_employees.name,all_employees.id) */ 51 | using S4 = decltype($STR(S1())); /* STR(all_employees.id) */ 52 | using S5 = decltype($STR(S0())); /* STR(all_employees) */ 53 | using TupleType = tuple; 54 | 55 | void runSelect(const vector& documents, vector& tuples) { 56 | for (const auto* document : Iterators::mk_json_iterator(documents)) { 57 | for (const auto* all_employee : Iterators::mk_json_iterator("all_employees", document, "all_employees")) { 58 | S0 s0 = all_employee ? *all_employee : S0(); 59 | S5 s5 = $STR(s0); 60 | for (const auto* each_id : Iterators::mk_json_iterator("all_employees.id", all_employee, "id")) { 61 | S1 s1 = each_id ? *each_id : S1(); 62 | S4 s4 = $STR(s1); 63 | for (const auto* each_name : Iterators::mk_json_iterator("all_employees.name", all_employee, "name")) { 64 | S2 s2 = each_name ? *each_name : S2(); 65 | S3 s3 = $EmployeeStr(s2, s1); 66 | tuples.emplace_back(s3, s4, s5); 67 | } 68 | } 69 | } 70 | } 71 | } 72 | 73 | void printTuples(const vector& tuples) { 74 | vector sizes; 75 | for (size_t i=0; i(t))); 80 | sizes[1] = max(sizes[1], PrintSize(get<1>(t))); 81 | sizes[2] = max(sizes[2], PrintSize(get<2>(t))); 82 | } 83 | cout << std::left; 84 | for (size_t i=0; i(t)); 94 | Print(cout << " | " << setw(sizes[1]), get<1>(t)); 95 | Print(cout << " | " << setw(sizes[2]), get<2>(t)); 96 | cout << endl; 97 | } 98 | } 99 | 100 | int main(int argc, char** argv) { 101 | vector documents; 102 | FROM(argc, argv, documents); 103 | vector tuples; 104 | runSelect(documents, tuples); 105 | printTuples(tuples); 106 | } 107 | -------------------------------------------------------------------------------- /src/example/json_golden1.out: -------------------------------------------------------------------------------- 1 | financial.quarterly_profits | financial.quarterly_revenues | all_employees.id | all_employees.name | all_employees.active | all_employees.active_direct_reports | all_employees.enumx | all_employees.enumy | founded | board_of_directors 2 | --------------------------- | ---------------------------- | ---------------- | ------------------ | -------------------- | ----------------------------------- | ------------------- | ------------------- | ------- | ------------------ 3 | 1.32242 | 1.98925 | 1 | abc | false | NULL | ENUMX_X1 | ENUMY_Y1 | 1 | 1 4 | 1.32242 | 2.27499 | 1 | abc | false | NULL | ENUMX_X1 | ENUMY_Y1 | 1 | 1 5 | 2.43243 | 1.98925 | 1 | abc | false | NULL | ENUMX_X1 | ENUMY_Y1 | 1 | 1 6 | 2.43243 | 2.27499 | 1 | abc | false | NULL | ENUMX_X1 | ENUMY_Y1 | 1 | 1 7 | 1.32242 | 1.98925 | 1 | abc | false | NULL | ENUMX_X1 | ENUMY_Y1 | 1 | 2 8 | 1.32242 | 2.27499 | 1 | abc | false | NULL | ENUMX_X1 | ENUMY_Y1 | 1 | 2 9 | 2.43243 | 1.98925 | 1 | abc | false | NULL | ENUMX_X1 | ENUMY_Y1 | 1 | 2 10 | 2.43243 | 2.27499 | 1 | abc | false | NULL | ENUMX_X1 | ENUMY_Y1 | 1 | 2 11 | 1.32242 | 1.98925 | 1 | abc | false | NULL | ENUMX_X1 | ENUMY_Y2 | 1 | 1 12 | 1.32242 | 2.27499 | 1 | abc | false | NULL | ENUMX_X1 | ENUMY_Y2 | 1 | 1 13 | 2.43243 | 1.98925 | 1 | abc | false | NULL | ENUMX_X1 | ENUMY_Y2 | 1 | 1 14 | 2.43243 | 2.27499 | 1 | abc | false | NULL | ENUMX_X1 | ENUMY_Y2 | 1 | 1 15 | 1.32242 | 1.98925 | 1 | abc | false | NULL | ENUMX_X1 | ENUMY_Y2 | 1 | 2 16 | 1.32242 | 2.27499 | 1 | abc | false | NULL | ENUMX_X1 | ENUMY_Y2 | 1 | 2 17 | 2.43243 | 1.98925 | 1 | abc | false | NULL | ENUMX_X1 | ENUMY_Y2 | 1 | 2 18 | 2.43243 | 2.27499 | 1 | abc | false | NULL | ENUMX_X1 | ENUMY_Y2 | 1 | 2 19 | 1.32242 | 1.98925 | 2 | def | true | 1 | NULL | ENUMY_Y1 | 1 | 1 20 | 1.32242 | 2.27499 | 2 | def | true | 1 | NULL | ENUMY_Y1 | 1 | 1 21 | 2.43243 | 1.98925 | 2 | def | true | 1 | NULL | ENUMY_Y1 | 1 | 1 22 | 2.43243 | 2.27499 | 2 | def | true | 1 | NULL | ENUMY_Y1 | 1 | 1 23 | 1.32242 | 1.98925 | 2 | def | true | 1 | NULL | ENUMY_Y1 | 1 | 2 24 | 1.32242 | 2.27499 | 2 | def | true | 1 | NULL | ENUMY_Y1 | 1 | 2 25 | 2.43243 | 1.98925 | 2 | def | true | 1 | NULL | ENUMY_Y1 | 1 | 2 26 | 2.43243 | 2.27499 | 2 | def | true | 1 | NULL | ENUMY_Y1 | 1 | 2 27 | 1.32242 | 1.98925 | 2 | def | true | 2 | NULL | ENUMY_Y1 | 1 | 1 28 | 1.32242 | 2.27499 | 2 | def | true | 2 | NULL | ENUMY_Y1 | 1 | 1 29 | 2.43243 | 1.98925 | 2 | def | true | 2 | NULL | ENUMY_Y1 | 1 | 1 30 | 2.43243 | 2.27499 | 2 | def | true | 2 | NULL | ENUMY_Y1 | 1 | 1 31 | 1.32242 | 1.98925 | 2 | def | true | 2 | NULL | ENUMY_Y1 | 1 | 2 32 | 1.32242 | 2.27499 | 2 | def | true | 2 | NULL | ENUMY_Y1 | 1 | 2 33 | 2.43243 | 1.98925 | 2 | def | true | 2 | NULL | ENUMY_Y1 | 1 | 2 34 | 2.43243 | 2.27499 | 2 | def | true | 2 | NULL | ENUMY_Y1 | 1 | 2 35 | -------------------------------------------------------------------------------- /src/example/json_golden2.out: -------------------------------------------------------------------------------- 1 | all_employees.id | all_employees.name 2 | ---------------- | ------------------ 3 | 1 | abc 4 | 1 | abc 5 | 2 | def 6 | 2 | def 7 | -------------------------------------------------------------------------------- /src/example/json_golden3.out: -------------------------------------------------------------------------------- 1 | all_employees.id | (financial.quarterly_revenues/all_employees.active_direct_reports) 2 | ---------------- | ------------------------------------------------------------------ 3 | 2 | 1.98925 4 | 2 | 2.27499 5 | 2 | 0.994623 6 | 2 | 1.13749 7 | -------------------------------------------------------------------------------- /src/example/json_golden4.out: -------------------------------------------------------------------------------- 1 | financial.quarterly_profits | all_employees.name | all_employees.active 2 | --------------------------- | ------------------ | -------------------- 3 | 2.43243 | abc | false 4 | 1.32242 | abc | false 5 | 2.43243 | def | true 6 | 1.32242 | def | true 7 | -------------------------------------------------------------------------------- /src/example/json_golden5.out: -------------------------------------------------------------------------------- 1 | employee | employee2 2 | ------------- | ----------------- 3 | 2: def (true) | 2 2: def (true) 1 4 | -------------------------------------------------------------------------------- /src/example/json_golden6.out: -------------------------------------------------------------------------------- 1 | all_employees.name | all_employees.active_direct_reports 2 | ------------------ | ----------------------------------- 3 | def | 1 4 | def | 2 5 | -------------------------------------------------------------------------------- /src/example/json_golden7.out: -------------------------------------------------------------------------------- 1 | EmployeeStr(all_employees.name,all_employees.id) | STR(all_employees.id) | STR(all_employees) 2 | ------------------------------------------------ | --------------------- | --------------------------------------------------------------------------------------- 3 | abc(id=1) | 1 | {"active":false,"enumx":"ENUMX_X1","enumy":["ENUMY_Y1","ENUMY_Y2"],"id":1,"name":"abc"} 4 | def(id=2) | 2 | {"active":true,"active_direct_reports":[1,2],"enumy":["ENUMY_Y1"],"id":2,"name":"def"} 5 | -------------------------------------------------------------------------------- /src/example/proto_example_utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "generated_common.h" 4 | #include "example1.pb.h" 5 | 6 | string EmployeeStr(const oq::MyString& name, int id) { 7 | stringstream ss; 8 | ss << name << "(id=" << id << ")"; 9 | return ss.str(); 10 | } 11 | 12 | string STR(const Example1::Employee& t) { 13 | return EmployeeStr(oq::MyString(&t.name()), t.id()); 14 | } 15 | -------------------------------------------------------------------------------- /src/example/proto_generated_query1.cc: -------------------------------------------------------------------------------- 1 | /* 2 | SELECT financial.quarterly_profits, financial.quarterly_revenues, all_employees.id, all_employees.name, all_employees.active, all_employees.active_direct_reports, all_employees.enumx, all_employees.enumy, founded, board_of_directors FROM Example1.Company 3 | 4 | with (company = parseFromFile()) { 5 | tuples.add(founded) 6 | for each board_of_director in company.board_of_directors() { 7 | tuples.add(board_of_directors) 8 | for each quarterly_profit in company.financial().quarterly_profits() { 9 | tuples.add(financial.quarterly_profits) 10 | for each quarterly_revenue in company.financial().quarterly_revenues() { 11 | tuples.add(financial.quarterly_revenues) 12 | for each all_employee in company.all_employees() { 13 | tuples.add(all_employees.id) 14 | tuples.add(all_employees.name) 15 | tuples.add(all_employees.active) 16 | tuples.add(all_employees.enumx) 17 | for each active_direct_report in all_employee.active_direct_reports() { 18 | tuples.add(all_employees.active_direct_reports) 19 | for each each_enumy in all_employee.enumy() { 20 | tuples.add(all_employees.enumy) 21 | tuples.record() 22 | } //each_enumy 23 | } //active_direct_report 24 | } //all_employee 25 | } //quarterly_revenue 26 | } //quarterly_profit 27 | } //board_of_director 28 | } //company 29 | tuples.print('financial.quarterly_profits', 'financial.quarterly_revenues', 'all_employees.id', 'all_employees.name', 'all_employees.active', 'all_employees.active_direct_reports', 'all_employees.enumx', 'all_employees.enumy', 'founded', 'board_of_directors') 30 | */ 31 | #include "example1.pb.h" 32 | #include "proto_example_utils.h" 33 | #include "protobuf_generated_common.h" 34 | 35 | using namespace std; 36 | using namespace oq; 37 | 38 | vector header = { 39 | "financial.quarterly_profits", 40 | "financial.quarterly_revenues", 41 | "all_employees.id", 42 | "all_employees.name", 43 | "all_employees.active", 44 | "all_employees.active_direct_reports", 45 | "all_employees.enumx", 46 | "all_employees.enumy", 47 | "founded", 48 | "board_of_directors", 49 | }; 50 | 51 | using S0 = optional; /* active() */ 52 | using S1 = optional; /* active_direct_reports() */ 53 | using S2 = optional; /* enumx() */ 54 | using S3 = optional; /* enumy() */ 55 | using S4 = optional; /* id() */ 56 | using S5 = optional; /* name() */ 57 | using S6 = optional; /* board_of_directors() */ 58 | using S7 = optional; /* financial().quarterly_profits() */ 59 | using S8 = optional; /* financial().quarterly_revenues() */ 60 | using S9 = optional; /* founded() */ 61 | using TupleType = tuple; 62 | 63 | void runSelect(const vector& companys, vector& tuples) { 64 | for (const auto* company : Iterators::mk_vec_iterator(&companys)) { 65 | S9 s9 = S9(); 66 | if (company && company->has_founded()) { 67 | s9 = company->founded(); 68 | } 69 | for (const auto* board_of_director : Iterators::mk_pb_iterator(company ? &company->board_of_directors() : nullptr)) { 70 | S6 s6 = S6(); 71 | if (board_of_director) { 72 | s6 = *board_of_director; 73 | } 74 | for (const auto* quarterly_profit : Iterators::mk_pb_iterator(company ? &company->financial().quarterly_profits() : nullptr)) { 75 | S7 s7 = S7(); 76 | if (quarterly_profit) { 77 | s7 = *quarterly_profit; 78 | } 79 | for (const auto* quarterly_revenue : Iterators::mk_pb_iterator(company ? &company->financial().quarterly_revenues() : nullptr)) { 80 | S8 s8 = S8(); 81 | if (quarterly_revenue) { 82 | s8 = *quarterly_revenue; 83 | } 84 | for (const auto* all_employee : Iterators::mk_pb_iterator(company ? &company->all_employees() : nullptr)) { 85 | S4 s4 = S4(); 86 | if (all_employee && all_employee->has_id()) { 87 | s4 = all_employee->id(); 88 | } 89 | S5 s5 = S5(); 90 | if (all_employee && all_employee->has_name()) { 91 | s5 = MyString(&(all_employee->name())); 92 | } 93 | S0 s0 = S0(); 94 | if (all_employee && all_employee->has_active()) { 95 | s0 = all_employee->active(); 96 | } 97 | S2 s2 = S2(); 98 | if (all_employee && all_employee->has_enumx()) { 99 | s2 = MyString(&(Example1::EnumX_Name(static_cast(all_employee->enumx())))); 100 | } 101 | for (const auto* active_direct_report : Iterators::mk_pb_iterator(all_employee ? &all_employee->active_direct_reports() : nullptr)) { 102 | S1 s1 = S1(); 103 | if (active_direct_report) { 104 | s1 = *active_direct_report; 105 | } 106 | for (const auto* each_enumy : Iterators::mk_pb_iterator(all_employee ? &all_employee->enumy() : nullptr)) { 107 | S3 s3 = S3(); 108 | if (each_enumy) { 109 | s3 = MyString(&(Example1::EnumY_Name(static_cast(*each_enumy)))); 110 | } 111 | tuples.emplace_back(s7, s8, s4, s5, s0, s1, s2, s3, s9, s6); 112 | } 113 | } 114 | } 115 | } 116 | } 117 | } 118 | } 119 | } 120 | 121 | void printTuples(const vector& tuples) { 122 | vector sizes; 123 | for (size_t i=0; i(t))); 128 | sizes[1] = max(sizes[1], PrintSize(get<1>(t))); 129 | sizes[2] = max(sizes[2], PrintSize(get<2>(t))); 130 | sizes[3] = max(sizes[3], PrintSize(get<3>(t))); 131 | sizes[4] = max(sizes[4], PrintSize(get<4>(t))); 132 | sizes[5] = max(sizes[5], PrintSize(get<5>(t))); 133 | sizes[6] = max(sizes[6], PrintSize(get<6>(t))); 134 | sizes[7] = max(sizes[7], PrintSize(get<7>(t))); 135 | sizes[8] = max(sizes[8], PrintSize(get<8>(t))); 136 | sizes[9] = max(sizes[9], PrintSize(get<9>(t))); 137 | } 138 | cout << std::left; 139 | for (size_t i=0; i(t)); 149 | Print(cout << " | " << setw(sizes[1]), get<1>(t)); 150 | Print(cout << " | " << setw(sizes[2]), get<2>(t)); 151 | Print(cout << " | " << setw(sizes[3]), get<3>(t)); 152 | Print(cout << " | " << setw(sizes[4]), get<4>(t)); 153 | Print(cout << " | " << setw(sizes[5]), get<5>(t)); 154 | Print(cout << " | " << setw(sizes[6]), get<6>(t)); 155 | Print(cout << " | " << setw(sizes[7]), get<7>(t)); 156 | Print(cout << " | " << setw(sizes[8]), get<8>(t)); 157 | Print(cout << " | " << setw(sizes[9]), get<9>(t)); 158 | cout << endl; 159 | } 160 | } 161 | 162 | int main(int argc, char** argv) { 163 | vector companys; 164 | FROM(argc, argv, companys); 165 | vector tuples; 166 | runSelect(companys, tuples); 167 | printTuples(tuples); 168 | } 169 | -------------------------------------------------------------------------------- /src/example/proto_generated_query2.cc: -------------------------------------------------------------------------------- 1 | /* 2 | SELECT all_employees.id, all_employees.name FROM Example1.Company WHERE ((all_employees.id IS NOT NULL AND (((all_employees.name = 'def') AND (all_employees.active = TRUE)) OR (all_employees.name = 'abc'))) AND (financial.quarterly_profits > 0)) 3 | 4 | with (company = parseFromFile()) { 5 | for each quarterly_profit in company.financial().quarterly_profits() { 6 | if (!(financial.quarterly_profits > 0)) { continue; } 7 | for each all_employee in company.all_employees() { 8 | if (!all_employees.id IS NOT NULL) { continue; } 9 | if (!(((all_employees.name = 'def') AND (all_employees.active = TRUE)) OR (all_employees.name = 'abc'))) { continue; } 10 | tuples.add(all_employees.id) 11 | tuples.add(all_employees.name) 12 | tuples.record() 13 | } //all_employee 14 | } //quarterly_profit 15 | } //company 16 | tuples.print('all_employees.id', 'all_employees.name') 17 | */ 18 | #include "example1.pb.h" 19 | #include "proto_example_utils.h" 20 | #include "protobuf_generated_common.h" 21 | 22 | using namespace std; 23 | using namespace oq; 24 | 25 | vector header = { 26 | "all_employees.id", 27 | "all_employees.name", 28 | }; 29 | 30 | string $c3 = "abc"; 31 | string $c1 = "def"; 32 | auto $c4 = 0; 33 | auto $c2 = true; 34 | 35 | using S0 = optional; /* active() */ 36 | using S1 = optional; /* id() */ 37 | using S2 = optional; /* name() */ 38 | using S3 = optional; /* financial().quarterly_profits() */ 39 | using TupleType = tuple; 40 | 41 | void runSelect(const vector& companys, vector& tuples) { 42 | for (const auto* company : Iterators::mk_vec_iterator(&companys)) { 43 | for (const auto* quarterly_profit : Iterators::mk_pb_iterator(company ? &company->financial().quarterly_profits() : nullptr)) { 44 | S3 s3 = S3(); 45 | if (quarterly_profit) { 46 | s3 = *quarterly_profit; 47 | } 48 | if (!Gt(s3, &$c4)) { continue; } 49 | for (const auto* all_employee : Iterators::mk_pb_iterator(company ? &company->all_employees() : nullptr)) { 50 | S1 s1 = S1(); 51 | if (all_employee && all_employee->has_id()) { 52 | s1 = all_employee->id(); 53 | } 54 | S2 s2 = S2(); 55 | if (all_employee && all_employee->has_name()) { 56 | s2 = MyString(&(all_employee->name())); 57 | } 58 | S0 s0 = S0(); 59 | if (all_employee && all_employee->has_active()) { 60 | s0 = all_employee->active(); 61 | } 62 | if (!IsNotNull(s1)) { continue; } 63 | if (!((Eq(s2, &$c1) && Eq(s0, &$c2)) || Eq(s2, &$c3))) { continue; } 64 | tuples.emplace_back(s1, s2); 65 | } 66 | } 67 | } 68 | } 69 | 70 | void printTuples(const vector& tuples) { 71 | vector sizes; 72 | for (size_t i=0; i(t))); 77 | sizes[1] = max(sizes[1], PrintSize(get<1>(t))); 78 | } 79 | cout << std::left; 80 | for (size_t i=0; i(t)); 90 | Print(cout << " | " << setw(sizes[1]), get<1>(t)); 91 | cout << endl; 92 | } 93 | } 94 | 95 | int main(int argc, char** argv) { 96 | vector companys; 97 | FROM(argc, argv, companys); 98 | vector tuples; 99 | runSelect(companys, tuples); 100 | printTuples(tuples); 101 | } 102 | -------------------------------------------------------------------------------- /src/example/proto_generated_query3.cc: -------------------------------------------------------------------------------- 1 | /* 2 | SELECT all_employees.id, (financial.quarterly_revenues/all_employees.active_direct_reports) FROM Example1.Company WHERE ((all_employees.active_direct_reports > 0) AND ((financial.quarterly_revenues*2) > 1)) 3 | 4 | with (company = parseFromFile()) { 5 | for each quarterly_revenue in company.financial().quarterly_revenues() { 6 | if (!((financial.quarterly_revenues*2) > 1)) { continue; } 7 | for each all_employee in company.all_employees() { 8 | tuples.add(all_employees.id) 9 | for each active_direct_report in all_employee.active_direct_reports() { 10 | if (!(all_employees.active_direct_reports > 0)) { continue; } 11 | tuples.add((financial.quarterly_revenues/all_employees.active_direct_reports)) 12 | tuples.record() 13 | } //active_direct_report 14 | } //all_employee 15 | } //quarterly_revenue 16 | } //company 17 | tuples.print('all_employees.id', '(financial.quarterly_revenues/all_employees.active_direct_reports)') 18 | */ 19 | #include "example1.pb.h" 20 | #include "proto_example_utils.h" 21 | #include "protobuf_generated_common.h" 22 | 23 | using namespace std; 24 | using namespace oq; 25 | 26 | vector header = { 27 | "all_employees.id", 28 | "(financial.quarterly_revenues/all_employees.active_direct_reports)", 29 | }; 30 | 31 | auto $c1 = 0; 32 | auto $c3 = 1; 33 | auto $c2 = 2; 34 | 35 | using S0 = optional; /* active_direct_reports() */ 36 | using S1 = optional; /* id() */ 37 | using S2 = optional; /* financial().quarterly_revenues() */ 38 | using S3 = decltype(Divide(S2(), S0())); /* (financial.quarterly_revenues/all_employees.active_direct_reports) */ 39 | using TupleType = tuple; 40 | 41 | void runSelect(const vector& companys, vector& tuples) { 42 | for (const auto* company : Iterators::mk_vec_iterator(&companys)) { 43 | for (const auto* quarterly_revenue : Iterators::mk_pb_iterator(company ? &company->financial().quarterly_revenues() : nullptr)) { 44 | S2 s2 = S2(); 45 | if (quarterly_revenue) { 46 | s2 = *quarterly_revenue; 47 | } 48 | if (!Gt(Mult(s2, &$c2), &$c3)) { continue; } 49 | for (const auto* all_employee : Iterators::mk_pb_iterator(company ? &company->all_employees() : nullptr)) { 50 | S1 s1 = S1(); 51 | if (all_employee && all_employee->has_id()) { 52 | s1 = all_employee->id(); 53 | } 54 | for (const auto* active_direct_report : Iterators::mk_pb_iterator(all_employee ? &all_employee->active_direct_reports() : nullptr)) { 55 | S0 s0 = S0(); 56 | if (active_direct_report) { 57 | s0 = *active_direct_report; 58 | } 59 | if (!Gt(s0, &$c1)) { continue; } 60 | S3 s3 = Divide(s2, s0); 61 | tuples.emplace_back(s1, s3); 62 | } 63 | } 64 | } 65 | } 66 | } 67 | 68 | void printTuples(const vector& tuples) { 69 | vector sizes; 70 | for (size_t i=0; i(t))); 75 | sizes[1] = max(sizes[1], PrintSize(get<1>(t))); 76 | } 77 | cout << std::left; 78 | for (size_t i=0; i(t)); 88 | Print(cout << " | " << setw(sizes[1]), get<1>(t)); 89 | cout << endl; 90 | } 91 | } 92 | 93 | int main(int argc, char** argv) { 94 | vector companys; 95 | FROM(argc, argv, companys); 96 | vector tuples; 97 | runSelect(companys, tuples); 98 | printTuples(tuples); 99 | } 100 | -------------------------------------------------------------------------------- /src/example/proto_generated_query4.cc: -------------------------------------------------------------------------------- 1 | /* 2 | SELECT financial.quarterly_profits, all_employees.name, all_employees.active FROM Example1.Company ORDER BY all_employees.active, financial.quarterly_profits DESC, all_employees.id 3 | 4 | with (company = parseFromFile()) { 5 | for each quarterly_profit in company.financial().quarterly_profits() { 6 | tuples.add(financial.quarterly_profits) 7 | for each all_employee in company.all_employees() { 8 | tuples.add(all_employees.name) 9 | tuples.add(all_employees.active) 10 | tuples.add(all_employees.id) 11 | tuples.record() 12 | } //all_employee 13 | } //quarterly_profit 14 | } //company 15 | tuples.sortBy('all_employees.active', 'financial.quarterly_profits', 'all_employees.id') 16 | tuples.print('financial.quarterly_profits', 'all_employees.name', 'all_employees.active') 17 | */ 18 | #include "example1.pb.h" 19 | #include "proto_example_utils.h" 20 | #include "protobuf_generated_common.h" 21 | 22 | using namespace std; 23 | using namespace oq; 24 | 25 | vector header = { 26 | "financial.quarterly_profits", 27 | "all_employees.name", 28 | "all_employees.active", 29 | }; 30 | 31 | using S0 = optional; /* active() */ 32 | using S1 = optional; /* id() */ 33 | using S2 = optional; /* name() */ 34 | using S3 = optional; /* financial().quarterly_profits() */ 35 | using TupleType = tuple; 36 | 37 | void runSelect(const vector& companys, vector& tuples) { 38 | for (const auto* company : Iterators::mk_vec_iterator(&companys)) { 39 | for (const auto* quarterly_profit : Iterators::mk_pb_iterator(company ? &company->financial().quarterly_profits() : nullptr)) { 40 | S3 s3 = S3(); 41 | if (quarterly_profit) { 42 | s3 = *quarterly_profit; 43 | } 44 | for (const auto* all_employee : Iterators::mk_pb_iterator(company ? &company->all_employees() : nullptr)) { 45 | S1 s1 = S1(); 46 | if (all_employee && all_employee->has_id()) { 47 | s1 = all_employee->id(); 48 | } 49 | S2 s2 = S2(); 50 | if (all_employee && all_employee->has_name()) { 51 | s2 = MyString(&(all_employee->name())); 52 | } 53 | S0 s0 = S0(); 54 | if (all_employee && all_employee->has_active()) { 55 | s0 = all_employee->active(); 56 | } 57 | tuples.emplace_back(s3, s2, s0, s1); 58 | } 59 | } 60 | } 61 | } 62 | 63 | bool compareTuples(const TupleType& t1, const TupleType& t2) { 64 | int c; 65 | c = Compare(get<2>(t1), get<2>(t2)); 66 | if (c < 0) {return true;} else if (c > 0) {return false;} 67 | c = -Compare(get<0>(t1), get<0>(t2)); 68 | if (c < 0) {return true;} else if (c > 0) {return false;} 69 | c = Compare(get<3>(t1), get<3>(t2)); 70 | if (c < 0) {return true;} else if (c > 0) {return false;} 71 | return false; 72 | } 73 | 74 | void printTuples(const vector& tuples) { 75 | vector sizes; 76 | for (size_t i=0; i(t))); 81 | sizes[1] = max(sizes[1], PrintSize(get<1>(t))); 82 | sizes[2] = max(sizes[2], PrintSize(get<2>(t))); 83 | } 84 | cout << std::left; 85 | for (size_t i=0; i(t)); 95 | Print(cout << " | " << setw(sizes[1]), get<1>(t)); 96 | Print(cout << " | " << setw(sizes[2]), get<2>(t)); 97 | cout << endl; 98 | } 99 | } 100 | 101 | int main(int argc, char** argv) { 102 | vector companys; 103 | FROM(argc, argv, companys); 104 | vector tuples; 105 | runSelect(companys, tuples); 106 | std::sort(tuples.begin(), tuples.end(), compareTuples); 107 | printTuples(tuples); 108 | } 109 | -------------------------------------------------------------------------------- /src/example/proto_generated_query5.cc: -------------------------------------------------------------------------------- 1 | /* 2 | SELECT (((((STR(all_employees.id)+': ')+all_employees.name)+' (')+STR(all_employees.active))+')') AS employee, ((((STR(all_employees.id)+' ')+employee)+' ')+STR(founded)) AS employee2 FROM Example1.Company WHERE (employee2 LIKE '.*true.*') 3 | 4 | with (company = parseFromFile()) { 5 | for each all_employee in company.all_employees() { 6 | if (!(((((STR(all_employees.id)+' ')+(((((STR(all_employees.id)+': ')+all_employees.name)+' (')+STR(all_employees.active))+')'))+' ')+STR(founded)) LIKE '.*true.*')) { continue; } 7 | tuples.add((((((STR(all_employees.id)+': ')+all_employees.name)+' (')+STR(all_employees.active))+')')) 8 | tuples.add(((((STR(all_employees.id)+' ')+(((((STR(all_employees.id)+': ')+all_employees.name)+' (')+STR(all_employees.active))+')'))+' ')+STR(founded))) 9 | tuples.record() 10 | } //all_employee 11 | } //company 12 | tuples.print('(((((STR(all_employees.id)+': ')+all_employees.name)+' (')+STR(all_employees.active))+')')', '((((STR(all_employees.id)+' ')+(((((STR(all_employees.id)+': ')+all_employees.name)+' (')+STR(all_employees.active))+')'))+' ')+STR(founded))') 13 | */ 14 | #include "example1.pb.h" 15 | #include "proto_example_utils.h" 16 | #include "protobuf_generated_common.h" 17 | 18 | using namespace std; 19 | using namespace oq; 20 | 21 | vector header = { 22 | "employee", 23 | "employee2", 24 | }; 25 | 26 | string $c4 = " "; 27 | string $c2 = " ("; 28 | string $c3 = ")"; 29 | regex $c5 = regex(".*true.*", regex::optimize); 30 | string $c1 = ": "; 31 | 32 | template 33 | optional $STR(const optional& arg0) { 34 | if (arg0) { 35 | return optional(STR(*arg0)); 36 | } else { 37 | return optional(); 38 | } 39 | } 40 | 41 | using S0 = optional; /* active() */ 42 | using S1 = optional; /* id() */ 43 | using S2 = optional; /* name() */ 44 | using S3 = optional; /* founded() */ 45 | using S4 = decltype(Plus(Plus(Plus(Plus(Plus($STR(S1()), &$c1), S2()), &$c2), $STR(S0())), &$c3)); /* (((((STR(all_employees.id)+': ')+all_employees.name)+' (')+STR(all_employees.active))+')') */ 46 | using S5 = decltype(Plus(Plus(Plus(Plus($STR(S1()), &$c4), Plus(Plus(Plus(Plus(Plus($STR(S1()), &$c1), S2()), &$c2), $STR(S0())), &$c3)), &$c4), $STR(S3()))); /* ((((STR(all_employees.id)+' ')+(((((STR(all_employees.id)+': ')+all_employees.name)+' (')+STR(all_employees.active))+')'))+' ')+STR(founded)) */ 47 | using TupleType = tuple; 48 | 49 | void runSelect(const vector& companys, vector& tuples) { 50 | for (const auto* company : Iterators::mk_vec_iterator(&companys)) { 51 | S3 s3 = S3(); 52 | if (company && company->has_founded()) { 53 | s3 = company->founded(); 54 | } 55 | for (const auto* all_employee : Iterators::mk_pb_iterator(company ? &company->all_employees() : nullptr)) { 56 | S1 s1 = S1(); 57 | if (all_employee && all_employee->has_id()) { 58 | s1 = all_employee->id(); 59 | } 60 | S2 s2 = S2(); 61 | if (all_employee && all_employee->has_name()) { 62 | s2 = MyString(&(all_employee->name())); 63 | } 64 | S0 s0 = S0(); 65 | if (all_employee && all_employee->has_active()) { 66 | s0 = all_employee->active(); 67 | } 68 | if (!Like(Plus(Plus(Plus(Plus($STR(s1), &$c4), Plus(Plus(Plus(Plus(Plus($STR(s1), &$c1), s2), &$c2), $STR(s0)), &$c3)), &$c4), $STR(s3)), $c5)) { continue; } 69 | S4 s4 = Plus(Plus(Plus(Plus(Plus($STR(s1), &$c1), s2), &$c2), $STR(s0)), &$c3); 70 | S5 s5 = Plus(Plus(Plus(Plus($STR(s1), &$c4), Plus(Plus(Plus(Plus(Plus($STR(s1), &$c1), s2), &$c2), $STR(s0)), &$c3)), &$c4), $STR(s3)); 71 | tuples.emplace_back(s4, s5); 72 | } 73 | } 74 | } 75 | 76 | void printTuples(const vector& tuples) { 77 | vector sizes; 78 | for (size_t i=0; i(t))); 83 | sizes[1] = max(sizes[1], PrintSize(get<1>(t))); 84 | } 85 | cout << std::left; 86 | for (size_t i=0; i(t)); 96 | Print(cout << " | " << setw(sizes[1]), get<1>(t)); 97 | cout << endl; 98 | } 99 | } 100 | 101 | int main(int argc, char** argv) { 102 | vector companys; 103 | FROM(argc, argv, companys); 104 | vector tuples; 105 | runSelect(companys, tuples); 106 | printTuples(tuples); 107 | } 108 | -------------------------------------------------------------------------------- /src/example/proto_generated_query6.cc: -------------------------------------------------------------------------------- 1 | /* 2 | SELECT all_employees.name, all_employees.active_direct_reports FROM Example1.Company WHERE all_employees.active_direct_reports IS NOT NULL 3 | 4 | with (company = parseFromFile()) { 5 | for each all_employee in company.all_employees() { 6 | tuples.add(all_employees.name) 7 | for each active_direct_report in all_employee.active_direct_reports() { 8 | if (!all_employees.active_direct_reports IS NOT NULL) { continue; } 9 | tuples.add(all_employees.active_direct_reports) 10 | tuples.record() 11 | } //active_direct_report 12 | } //all_employee 13 | } //company 14 | tuples.print('all_employees.name', 'all_employees.active_direct_reports') 15 | */ 16 | #include "example1.pb.h" 17 | #include "proto_example_utils.h" 18 | #include "protobuf_generated_common.h" 19 | 20 | using namespace std; 21 | using namespace oq; 22 | 23 | vector header = { 24 | "all_employees.name", 25 | "all_employees.active_direct_reports", 26 | }; 27 | 28 | using S0 = optional; /* active_direct_reports() */ 29 | using S1 = optional; /* name() */ 30 | using TupleType = tuple; 31 | 32 | void runSelect(const vector& companys, vector& tuples) { 33 | for (const auto* company : Iterators::mk_vec_iterator(&companys)) { 34 | for (const auto* all_employee : Iterators::mk_pb_iterator(company ? &company->all_employees() : nullptr)) { 35 | S1 s1 = S1(); 36 | if (all_employee && all_employee->has_name()) { 37 | s1 = MyString(&(all_employee->name())); 38 | } 39 | for (const auto* active_direct_report : Iterators::mk_pb_iterator(all_employee ? &all_employee->active_direct_reports() : nullptr)) { 40 | S0 s0 = S0(); 41 | if (active_direct_report) { 42 | s0 = *active_direct_report; 43 | } 44 | if (!IsNotNull(s0)) { continue; } 45 | tuples.emplace_back(s1, s0); 46 | } 47 | } 48 | } 49 | } 50 | 51 | void printTuples(const vector& tuples) { 52 | vector sizes; 53 | for (size_t i=0; i(t))); 58 | sizes[1] = max(sizes[1], PrintSize(get<1>(t))); 59 | } 60 | cout << std::left; 61 | for (size_t i=0; i(t)); 71 | Print(cout << " | " << setw(sizes[1]), get<1>(t)); 72 | cout << endl; 73 | } 74 | } 75 | 76 | int main(int argc, char** argv) { 77 | vector companys; 78 | FROM(argc, argv, companys); 79 | vector tuples; 80 | runSelect(companys, tuples); 81 | printTuples(tuples); 82 | } 83 | -------------------------------------------------------------------------------- /src/example/proto_generated_query7.cc: -------------------------------------------------------------------------------- 1 | /* 2 | SELECT EmployeeStr(all_employees.name,all_employees.id), STR(all_employees.id), STR(all_employees) FROM Example1.Company 3 | 4 | with (company = parseFromFile()) { 5 | for each all_employee in company.all_employees() { 6 | tuples.add(EmployeeStr(all_employees.name,all_employees.id)) 7 | tuples.add(STR(all_employees.id)) 8 | tuples.add(STR(all_employees)) 9 | tuples.record() 10 | } //all_employee 11 | } //company 12 | tuples.print('EmployeeStr(all_employees.name,all_employees.id)', 'STR(all_employees.id)', 'STR(all_employees)') 13 | */ 14 | #include "example1.pb.h" 15 | #include "proto_example_utils.h" 16 | #include "protobuf_generated_common.h" 17 | 18 | using namespace std; 19 | using namespace oq; 20 | 21 | vector header = { 22 | "EmployeeStr(all_employees.name,all_employees.id)", 23 | "STR(all_employees.id)", 24 | "STR(all_employees)", 25 | }; 26 | 27 | template 28 | optional $EmployeeStr(const optional& arg0, const optional& arg1) { 29 | if (arg0 && arg1) { 30 | return optional(EmployeeStr(*arg0, *arg1)); 31 | } else { 32 | return optional(); 33 | } 34 | } 35 | template 36 | optional $STR(const optional& arg0) { 37 | if (arg0) { 38 | return optional(STR(*arg0)); 39 | } else { 40 | return optional(); 41 | } 42 | } 43 | 44 | using S0 = optional; /* all_employees() */ 45 | using S1 = optional; /* id() */ 46 | using S2 = optional; /* name() */ 47 | using S3 = decltype($EmployeeStr(S2(), S1())); /* EmployeeStr(all_employees.name,all_employees.id) */ 48 | using S4 = decltype($STR(S1())); /* STR(all_employees.id) */ 49 | using S5 = decltype($STR(S0())); /* STR(all_employees) */ 50 | using TupleType = tuple; 51 | 52 | void runSelect(const vector& companys, vector& tuples) { 53 | for (const auto* company : Iterators::mk_vec_iterator(&companys)) { 54 | for (const auto* all_employee : Iterators::mk_pb_iterator(company ? &company->all_employees() : nullptr)) { 55 | S0 s0 = S0(); 56 | if (all_employee) { 57 | s0 = *all_employee; 58 | } 59 | S1 s1 = S1(); 60 | if (all_employee && all_employee->has_id()) { 61 | s1 = all_employee->id(); 62 | } 63 | S2 s2 = S2(); 64 | if (all_employee && all_employee->has_name()) { 65 | s2 = MyString(&(all_employee->name())); 66 | } 67 | S3 s3 = $EmployeeStr(s2, s1); 68 | S4 s4 = $STR(s1); 69 | S5 s5 = $STR(s0); 70 | tuples.emplace_back(s3, s4, s5); 71 | } 72 | } 73 | } 74 | 75 | void printTuples(const vector& tuples) { 76 | vector sizes; 77 | for (size_t i=0; i(t))); 82 | sizes[1] = max(sizes[1], PrintSize(get<1>(t))); 83 | sizes[2] = max(sizes[2], PrintSize(get<2>(t))); 84 | } 85 | cout << std::left; 86 | for (size_t i=0; i(t)); 96 | Print(cout << " | " << setw(sizes[1]), get<1>(t)); 97 | Print(cout << " | " << setw(sizes[2]), get<2>(t)); 98 | cout << endl; 99 | } 100 | } 101 | 102 | int main(int argc, char** argv) { 103 | vector companys; 104 | FROM(argc, argv, companys); 105 | vector tuples; 106 | runSelect(companys, tuples); 107 | printTuples(tuples); 108 | } 109 | -------------------------------------------------------------------------------- /src/example/proto_generated_query8.cc: -------------------------------------------------------------------------------- 1 | /* 2 | SELECT *, all_employees.* AS emp FROM Example1.Company 3 | 4 | with (company = parseFromFile()) { 5 | tuples.add(founded) 6 | for each all_employee in company.all_employees() { 7 | tuples.add(all_employees.id) 8 | tuples.add(all_employees.name) 9 | tuples.add(all_employees.active) 10 | tuples.add(all_employees.enumx) 11 | tuples.record() 12 | } //all_employee 13 | } //company 14 | tuples.print('founded', 'all_employees.id', 'all_employees.name', 'all_employees.active', 'all_employees.enumx') 15 | */ 16 | #include "example1.pb.h" 17 | #include "proto_example_utils.h" 18 | #include "protobuf_generated_common.h" 19 | 20 | using namespace std; 21 | using namespace oq; 22 | 23 | vector header = { 24 | "founded", 25 | "emp.id", 26 | "emp.name", 27 | "emp.active", 28 | "emp.enumx", 29 | }; 30 | 31 | using S0 = optional; /* active() */ 32 | using S1 = optional; /* enumx() */ 33 | using S2 = optional; /* id() */ 34 | using S3 = optional; /* name() */ 35 | using S4 = optional; /* founded() */ 36 | using TupleType = tuple; 37 | 38 | void runSelect(const vector& companys, vector& tuples) { 39 | for (const auto* company : Iterators::mk_vec_iterator(&companys)) { 40 | S4 s4 = S4(); 41 | if (company && company->has_founded()) { 42 | s4 = company->founded(); 43 | } 44 | for (const auto* all_employee : Iterators::mk_pb_iterator(company ? &company->all_employees() : nullptr)) { 45 | S2 s2 = S2(); 46 | if (all_employee && all_employee->has_id()) { 47 | s2 = all_employee->id(); 48 | } 49 | S3 s3 = S3(); 50 | if (all_employee && all_employee->has_name()) { 51 | s3 = MyString(&(all_employee->name())); 52 | } 53 | S0 s0 = S0(); 54 | if (all_employee && all_employee->has_active()) { 55 | s0 = all_employee->active(); 56 | } 57 | S1 s1 = S1(); 58 | if (all_employee && all_employee->has_enumx()) { 59 | s1 = MyString(&(Example1::EnumX_Name(static_cast(all_employee->enumx())))); 60 | } 61 | tuples.emplace_back(s4, s2, s3, s0, s1); 62 | } 63 | } 64 | } 65 | 66 | void printTuples(const vector& tuples) { 67 | vector sizes; 68 | for (size_t i=0; i(t))); 73 | sizes[1] = max(sizes[1], PrintSize(get<1>(t))); 74 | sizes[2] = max(sizes[2], PrintSize(get<2>(t))); 75 | sizes[3] = max(sizes[3], PrintSize(get<3>(t))); 76 | sizes[4] = max(sizes[4], PrintSize(get<4>(t))); 77 | } 78 | cout << std::left; 79 | for (size_t i=0; i(t)); 89 | Print(cout << " | " << setw(sizes[1]), get<1>(t)); 90 | Print(cout << " | " << setw(sizes[2]), get<2>(t)); 91 | Print(cout << " | " << setw(sizes[3]), get<3>(t)); 92 | Print(cout << " | " << setw(sizes[4]), get<4>(t)); 93 | cout << endl; 94 | } 95 | } 96 | 97 | int main(int argc, char** argv) { 98 | vector companys; 99 | FROM(argc, argv, companys); 100 | vector tuples; 101 | runSelect(companys, tuples); 102 | printTuples(tuples); 103 | } 104 | -------------------------------------------------------------------------------- /src/example/proto_golden2.out: -------------------------------------------------------------------------------- 1 | all_employees.id | all_employees.name 2 | ---------------- | ------------------ 3 | 1 | abc 4 | 2 | def 5 | 1 | abc 6 | 2 | def 7 | -------------------------------------------------------------------------------- /src/example/proto_golden3.out: -------------------------------------------------------------------------------- 1 | all_employees.id | (financial.quarterly_revenues/all_employees.active_direct_reports) 2 | ---------------- | ------------------------------------------------------------------ 3 | 2 | 1.98925 4 | 2 | 0.994623 5 | 2 | 2.27499 6 | 2 | 1.13749 7 | -------------------------------------------------------------------------------- /src/example/proto_golden4.out: -------------------------------------------------------------------------------- 1 | financial.quarterly_profits | all_employees.name | all_employees.active 2 | --------------------------- | ------------------ | -------------------- 3 | 2.43243 | abc | false 4 | 1.32242 | abc | false 5 | 2.43243 | def | true 6 | 1.32242 | def | true 7 | -------------------------------------------------------------------------------- /src/example/proto_golden5.out: -------------------------------------------------------------------------------- 1 | employee | employee2 2 | ------------- | ----------------- 3 | 2: def (true) | 2 2: def (true) 1 4 | -------------------------------------------------------------------------------- /src/example/proto_golden6.out: -------------------------------------------------------------------------------- 1 | all_employees.name | all_employees.active_direct_reports 2 | ------------------ | ----------------------------------- 3 | def | 1 4 | def | 2 5 | -------------------------------------------------------------------------------- /src/example/proto_golden7.out: -------------------------------------------------------------------------------- 1 | EmployeeStr(all_employees.name,all_employees.id) | STR(all_employees.id) | STR(all_employees) 2 | ------------------------------------------------ | --------------------- | ------------------ 3 | abc(id=1) | 1 | abc(id=1) 4 | def(id=2) | 2 | def(id=2) 5 | -------------------------------------------------------------------------------- /src/example/proto_golden8.out: -------------------------------------------------------------------------------- 1 | founded | emp.id | emp.name | emp.active | emp.enumx 2 | ------- | ------ | -------- | ---------- | --------- 3 | 1 | 1 | abc | false | ENUMX_X1 4 | 1 | 2 | def | true | NULL 5 | -------------------------------------------------------------------------------- /src/json-query/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | include_directories( 3 | ${CMAKE_SOURCE_DIR}/common 4 | ${CMAKE_SOURCE_DIR}/sql 5 | ${CMAKE_SOURCE_DIR}/json-query 6 | ${CMAKE_SOURCE_DIR}/third-party/rapidjson/include 7 | ) 8 | 9 | add_library(JsonQueryEngine json_generated_common.h json_query_engine.h json_query_engine.cc) 10 | target_link_libraries(JsonQueryEngine Utils SqlParser) 11 | 12 | add_subdirectory(test) 13 | -------------------------------------------------------------------------------- /src/json-query/json_query_engine.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 https://github.com/na-ka-na 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain the License at http://www.apache.org/licenses/LICENSE-2.0 7 | */ 8 | 9 | #include 10 | #include 11 | #include "utils.h" 12 | #include "json_query_engine.h" 13 | 14 | using namespace std; 15 | using namespace oq; 16 | using namespace oq::json; 17 | 18 | bool JsonField::operator<(const JsonField& other) const { 19 | return fieldParts < other.fieldParts; 20 | } 21 | 22 | bool JsonField::operator==(const JsonField& other) const { 23 | return fieldParts == other.fieldParts; 24 | } 25 | 26 | void JsonField::addFieldPart(const string& fieldPart) { 27 | fieldParts.push_back(fieldPart); 28 | } 29 | 30 | bool JsonField::repeated() const { 31 | return true; 32 | } 33 | 34 | string JsonField::code_type() const { 35 | return "JsonValue"; 36 | } 37 | 38 | string JsonField::accessor() const { 39 | return Utils::joinVec(".", fieldParts, Utils::string2str); 40 | } 41 | 42 | const string& JsonField::lastFieldPart() const { 43 | ASSERT(!fieldParts.empty(), "Fields expected to be not empty"); 44 | return fieldParts.back(); 45 | } 46 | 47 | string JsonQueryTree::getRootName() const { 48 | return "document"; 49 | } 50 | 51 | string JsonQueryTree::getRootType() const { 52 | return "rapidjson::Document"; 53 | } 54 | 55 | JsonField JsonQueryTree::newField() const { 56 | return JsonField(); 57 | } 58 | 59 | string JsonQueryTree::generatedCommonHeader() const { 60 | return "json_generated_common.h"; 61 | } 62 | 63 | void JsonQueryTree::printRootForLoop( 64 | ostream& out, const string& ind, const Node& node) const { 65 | out << ind << "for (const auto* " << node.objName 66 | << " : Iterators::mk_json_iterator(" 67 | << Utils::makePlural(root.objName) << ")) {" << endl; 68 | } 69 | 70 | void JsonQueryTree::printNonRootForLoop( 71 | ostream& out, const string& ind, const Node& node, 72 | const Node& parent) const { 73 | out << ind << "for (const auto* " << node.objName 74 | << " : Iterators::mk_json_iterator(" 75 | << "\"" << node.repeatedField.accessor() << "\"" << ", " 76 | << parent.objName << ", \"" << node.repeatedField.lastFieldPart() 77 | << "\")) {" << endl; 78 | } 79 | 80 | void JsonQueryTree::printFieldAssignment( 81 | ostream& out, const string& ind, const Node& node, 82 | const JsonField& /*field*/, bool /*repeating*/, const string& fieldType, 83 | const string& fieldVar, const string& fieldDefault) const { 84 | out << ind << fieldType << " " << fieldVar << " = " << node.objName 85 | << " ? *" << node.objName << " : " << fieldDefault << ";" << endl; 86 | } 87 | 88 | JsonQueryEngine::JsonQueryEngine(const CodeGenSpec& spec, const string& rawSql, ostream& out) : 89 | spec(spec), query(SelectQuery(rawSql)), out(out) {} 90 | 91 | void JsonQueryEngine::process() { 92 | ASSERT(query.parse(), "Parsing select query failed"); 93 | out << "/*" << endl; 94 | out << query.str() << endl << endl; 95 | auto resolver = [] (const string& identifier, vector&) { 96 | THROW("Star identifiers not allowed for json queries", identifier); 97 | }; 98 | query.resolveSelectStars(resolver); 99 | query.removeSelectAliases(); 100 | queryTree.process(query); 101 | queryTree.printPlan(query, out); 102 | out << "*/" << endl; 103 | queryTree.printCode(query, out, spec); 104 | } 105 | -------------------------------------------------------------------------------- /src/json-query/json_query_engine.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 https://github.com/na-ka-na 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain the License at http://www.apache.org/licenses/LICENSE-2.0 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include "utils.h" 17 | #include "query_tree.h" 18 | #include "select_query.h" 19 | 20 | using namespace std; 21 | 22 | namespace oq { 23 | namespace json { 24 | 25 | class JsonField : public Field { 26 | public: 27 | JsonField() = default; 28 | bool operator<(const JsonField& other) const; 29 | bool operator==(const JsonField& other) const; 30 | void addFieldPart(const string&) override; 31 | bool repeated() const override; 32 | string code_type() const override; 33 | string accessor() const override; 34 | // custom JsonField functions 35 | const string& lastFieldPart() const; 36 | private: 37 | vector fieldParts; 38 | }; 39 | 40 | class JsonQueryTree : public QueryTree { 41 | public: 42 | string getRootName() const override; 43 | string getRootType() const override; 44 | JsonField newField() const override; 45 | 46 | string generatedCommonHeader() const override; 47 | void printRootForLoop(ostream& out, const string& ind, 48 | const Node& node) const override; 49 | void printNonRootForLoop(ostream& out, const string& ind, 50 | const Node& node, 51 | const Node& parent) const override; 52 | void printFieldAssignment(ostream& out, const string& ind, 53 | const Node& node, 54 | const JsonField& field, 55 | bool repeating, 56 | const string& fieldType, 57 | const string& fieldVar, 58 | const string& fieldDefault) const override; 59 | }; 60 | 61 | class JsonQueryEngine { 62 | public: 63 | JsonQueryEngine(const CodeGenSpec& spec, const string& rawSql, ostream& out); 64 | void process(); 65 | 66 | private: 67 | CodeGenSpec spec; 68 | SelectQuery query; 69 | JsonQueryTree queryTree; 70 | ostream& out; 71 | }; 72 | 73 | } // namespace json 74 | } // namespace oq 75 | -------------------------------------------------------------------------------- /src/json-query/test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include_directories( 2 | SYSTEM ${CMAKE_SOURCE_DIR}/third-party/rapidjson/include 3 | ${CMAKE_SOURCE_DIR}/json-query 4 | ${CMAKE_SOURCE_DIR}/common/test 5 | ) 6 | 7 | add_executable(JsonGeneratedCommonTest json_generated_common_test.cc) 8 | target_link_libraries(JsonGeneratedCommonTest) 9 | add_test(JsonGeneratedCommonTest JsonGeneratedCommonTest) 10 | -------------------------------------------------------------------------------- /src/json-query/test/json_generated_common_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 https://github.com/na-ka-na 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain the License at http://www.apache.org/licenses/LICENSE-2.0 7 | */ 8 | 9 | // Unit tests for json_generated_common.h 10 | 11 | #include "test_commons.h" 12 | #include "json_generated_common.h" 13 | 14 | using namespace oq; 15 | 16 | void TestMyRangeIteratorEmpty() { 17 | rapidjson::Document object; 18 | object.Parse("{\"abc\": 123}"); 19 | EXPECT_FALSE(object.HasParseError()); 20 | JsonValue value(object); 21 | auto&& myit = Iterators::mk_json_iterator("", &value, "xyz"); 22 | auto&& begin = myit.begin(); 23 | auto&& end = myit.end(); 24 | EXPECT_NE(begin, end); 25 | EXPECT_EQ((const JsonValue*) nullptr, *begin); 26 | ++begin; 27 | EXPECT_EQ(begin, end); 28 | } 29 | 30 | void TestMyRangeIteratorEmptyArray() { 31 | rapidjson::Document object; 32 | object.Parse("{\"abc\": []}"); 33 | EXPECT_FALSE(object.HasParseError()); 34 | JsonValue value(object); 35 | auto&& myit = Iterators::mk_json_iterator("", &value, "abc"); 36 | auto&& begin = myit.begin(); 37 | auto&& end = myit.end(); 38 | EXPECT_NE(begin, end); 39 | EXPECT_EQ((const JsonValue*) nullptr, *begin); 40 | ++begin; 41 | EXPECT_EQ(begin, end); 42 | } 43 | 44 | void TestMyRangeIteratorNonEmpty() { 45 | rapidjson::Document object; 46 | object.Parse("{\"abc\": \"def\"}"); 47 | EXPECT_FALSE(object.HasParseError()); 48 | JsonValue value(object); 49 | auto&& myit = Iterators::mk_json_iterator("", &value, "abc"); 50 | auto&& begin = myit.begin(); 51 | auto&& end = myit.end(); 52 | EXPECT_NE(begin, end); 53 | EXPECT_EQ(JsonValue(object["abc"]), **begin); 54 | stringstream ss; 55 | ss << **begin; 56 | EXPECT_EQ("def", ss.str()); 57 | ++begin; 58 | EXPECT_EQ(begin, end); 59 | } 60 | 61 | void TestMyRangeIteratorNonEmptyArray() { 62 | rapidjson::Document object; 63 | object.Parse("{\"abc\": [1.322423, 456]}"); 64 | EXPECT_FALSE(object.HasParseError()); 65 | JsonValue value(object); 66 | auto&& myit = Iterators::mk_json_iterator("", &value, "abc"); 67 | auto&& begin = myit.begin(); 68 | auto&& end = myit.end(); 69 | EXPECT_NE(begin, end); 70 | EXPECT_EQ(JsonValue(object["abc"][0]), **begin); 71 | stringstream ss; 72 | ss << **begin; 73 | EXPECT_EQ("1.32242", ss.str()); 74 | ++begin; 75 | EXPECT_NE(begin, end); 76 | EXPECT_EQ(JsonValue(object["abc"][1]), **begin); 77 | stringstream ss1; 78 | ss1 << **begin; 79 | EXPECT_EQ("456", ss1.str()); 80 | ++begin; 81 | EXPECT_EQ(begin, end); 82 | } 83 | 84 | int main() { 85 | TestMyRangeIteratorEmpty(); 86 | TestMyRangeIteratorEmptyArray(); 87 | TestMyRangeIteratorNonEmpty(); 88 | TestMyRangeIteratorNonEmptyArray(); 89 | } 90 | -------------------------------------------------------------------------------- /src/main/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include_directories( 2 | ${CMAKE_SOURCE_DIR}/common 3 | ${CMAKE_SOURCE_DIR}/sql 4 | ${CMAKE_SOURCE_DIR}/protobuf-query 5 | ${CMAKE_SOURCE_DIR}/json-query 6 | ) 7 | 8 | add_executable(RunQuery run_query.cc) 9 | target_link_libraries(RunQuery dl gflags ProtobufQueryEngine JsonQueryEngine) 10 | -------------------------------------------------------------------------------- /src/protobuf-query/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | include_directories( 3 | ${CMAKE_SOURCE_DIR}/common 4 | ${CMAKE_SOURCE_DIR}/sql 5 | ${CMAKE_SOURCE_DIR}/protobuf-query 6 | ) 7 | 8 | add_library(ProtobufQueryEngine protobuf_generated_common.h protobuf_query_engine.cc) 9 | target_link_libraries(ProtobufQueryEngine ${PROTOBUF_LIBRARIES} Utils SqlParser) 10 | 11 | add_subdirectory(test) 12 | -------------------------------------------------------------------------------- /src/protobuf-query/protobuf_generated_common.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 https://github.com/na-ka-na 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain the License at http://www.apache.org/licenses/LICENSE-2.0 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include "global_include.h" 29 | #include "generated_common.h" 30 | 31 | using namespace std; 32 | 33 | using int8 = ::google::protobuf::int8; 34 | using int16 = ::google::protobuf::int16; 35 | using int32 = ::google::protobuf::int32; 36 | using int64 = ::google::protobuf::int64; 37 | using uint8 = ::google::protobuf::uint8; 38 | using uint16 = ::google::protobuf::uint16; 39 | using uint32 = ::google::protobuf::uint32; 40 | using uint64 = ::google::protobuf::uint64; 41 | 42 | namespace oq { 43 | 44 | bool GetProtoFromString(const string& data, google::protobuf::Message& proto) { 45 | if (data.size() && ((data[0] == '{') || (data[0] == '['))) { 46 | // First try json format, then try binary format 47 | return google::protobuf::util::JsonStringToMessage(data, &proto).ok() || 48 | proto.ParseFromString(data); 49 | } else { 50 | // First try binary format, else try json format 51 | return proto.ParseFromString(data) || 52 | google::protobuf::util::JsonStringToMessage(data, &proto).ok(); 53 | } 54 | } 55 | 56 | void ReadFromZeroCopyInputStream( 57 | google::protobuf::io::ZeroCopyInputStream& steam, string& data) { 58 | const void* buffer; 59 | int size; 60 | while (steam.Next(&buffer, &size)) { 61 | data.append((const char*) buffer, size); 62 | } 63 | } 64 | 65 | void GetProtoFromFile(const string& file, google::protobuf::Message& proto) { 66 | int fd = open(file.c_str(), O_RDONLY); 67 | ASSERT(fd >= 0, "Unable to open file", file); 68 | string data; 69 | if ((file.size() > 3) && (file.substr(file.size()-3) == ".gz")) { 70 | google::protobuf::io::FileInputStream fis(fd); 71 | google::protobuf::io::GzipInputStream gzfis(&fis); 72 | ReadFromZeroCopyInputStream(gzfis, data); 73 | } else { 74 | google::protobuf::io::FileInputStream fis(fd); 75 | ReadFromZeroCopyInputStream(fis, data); 76 | } 77 | ASSERT(close(fd) == 0, "Unable to close file", file); 78 | ASSERT(GetProtoFromString(data, proto), "Unable to parse", file); 79 | } 80 | 81 | #ifndef FROM 82 | #define FROM(argc, argv, protos) \ 83 | ASSERT(argc > 1, "Proto file(s) not provided");\ 84 | for (int i=1; i 93 | static 94 | MyRangeIterator::const_iterator> 95 | mk_pb_iterator(const ::google::protobuf::RepeatedField* rf) { 96 | auto convert_fn = [](const T* t, T&) {return t;}; 97 | if (rf) { 98 | return MyRangeIterator::const_iterator>::mk_normal( 99 | convert_fn, rf->begin(), rf->end()); 100 | } else { 101 | return MyRangeIterator::const_iterator>::mk_singular( 102 | convert_fn); 103 | } 104 | } 105 | 106 | template 107 | static 108 | MyRangeIterator::const_iterator> 109 | mk_pb_iterator(const ::google::protobuf::RepeatedPtrField* rpf) { 110 | auto convert_fn = [](const T* t, T&) {return t;}; 111 | if (rpf) { 112 | return MyRangeIterator::const_iterator>::mk_normal( 113 | convert_fn, rpf->begin(), rpf->end()); 114 | } else { 115 | return MyRangeIterator::const_iterator>::mk_singular( 116 | convert_fn); 117 | } 118 | } 119 | }; 120 | 121 | } // namespace oq 122 | -------------------------------------------------------------------------------- /src/protobuf-query/protobuf_query_engine.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 https://github.com/na-ka-na 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain the License at http://www.apache.org/licenses/LICENSE-2.0 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "utils.h" 18 | #include "query_tree.h" 19 | #include "select_query.h" 20 | 21 | using namespace std; 22 | using namespace google::protobuf; 23 | 24 | namespace oq { 25 | namespace pb { 26 | 27 | class PbFieldPart { 28 | public: 29 | static string full_name_to_cpp_type(const string& full_name); 30 | static PbFieldPart parseFrom(const Descriptor& parentDescriptor, 31 | const string& partName); 32 | enum Type { NORMAL, SIZE, HAS }; 33 | PbFieldPart(const FieldDescriptor* descriptor, Type type=NORMAL); 34 | bool operator<(const PbFieldPart& other) const; 35 | bool operator==(const PbFieldPart& other) const; 36 | string name() const; 37 | FieldDescriptor::Type type() const; 38 | string type_name() const; 39 | FieldDescriptor::CppType cpp_type() const; 40 | string cpp_type_name() const; 41 | bool is_message() const; 42 | const Descriptor* message_descriptor() const; 43 | bool is_repeated() const; 44 | bool is_enum() const; 45 | const EnumDescriptor* enum_descriptor() const; 46 | string code_type() const; 47 | string accessor() const; 48 | bool needs_has_check() const; 49 | string has_accessor() const; 50 | private: 51 | const FieldDescriptor* descriptor; 52 | Type part_type; 53 | }; 54 | 55 | class PbField : public Field { 56 | public: 57 | PbField() = default; 58 | PbField(const Descriptor* rootDescriptor); 59 | bool operator<(const PbField& other) const; 60 | bool operator==(const PbField& other) const; 61 | void addFieldPart(const string&) override; 62 | bool repeated() const override; 63 | string code_type() const override; 64 | string accessor() const override; 65 | // custom PbField functions 66 | bool is_enum() const; 67 | string get_wrapped_accessor(const string& accessor) const; 68 | string has_check(const string& objName) const; 69 | private: 70 | vector fieldParts; 71 | const Descriptor* descriptor = nullptr; 72 | }; 73 | 74 | class PbQueryTree : public QueryTree { 75 | public: 76 | void initProto(const string& protoName); 77 | void resolveStarIdentifier(const string& star_identifier, 78 | vector& resolved_identifiers); 79 | string getRootType() const override; 80 | string getRootName() const override; 81 | PbField newField() const override; 82 | 83 | string generatedCommonHeader() const override; 84 | void printRootForLoop(ostream& out, const string& ind, 85 | const Node& node) const override; 86 | void printNonRootForLoop(ostream& out, const string& ind, 87 | const Node& node, 88 | const Node& parent) const override; 89 | void printFieldAssignment(ostream& out, const string& ind, 90 | const Node& node, 91 | const PbField& field, 92 | bool repeating, 93 | const string& fieldType, 94 | const string& fieldVar, 95 | const string& fieldDefault) const override; 96 | private: 97 | const Descriptor* protoDescriptor; 98 | }; 99 | 100 | class ProtobufQueryEngine { 101 | public: 102 | ProtobufQueryEngine(const CodeGenSpec& spec, const string& rawSql, ostream& out); 103 | void process(); 104 | 105 | private: 106 | CodeGenSpec spec; 107 | SelectQuery query; 108 | PbQueryTree queryTree; 109 | ostream& out; 110 | }; 111 | 112 | } // namespace pb 113 | } // namespace oq 114 | -------------------------------------------------------------------------------- /src/protobuf-query/test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include_directories( 2 | SYSTEM ${PROTOBUF_INCLUDE_DIRS} 3 | ${CMAKE_SOURCE_DIR}/protobuf-query 4 | ${CMAKE_SOURCE_DIR}/common/test 5 | ) 6 | 7 | add_executable(ProtobufGeneratedCommonTest protobuf_generated_common_test.cc) 8 | target_link_libraries(ProtobufGeneratedCommonTest ${PROTOBUF_LIBRARIES}) 9 | add_test(ProtobufGeneratedCommonTest ProtobufGeneratedCommonTest) 10 | -------------------------------------------------------------------------------- /src/protobuf-query/test/protobuf_generated_common_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 https://github.com/na-ka-na 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain the License at http://www.apache.org/licenses/LICENSE-2.0 7 | */ 8 | 9 | // Unit tests for protobuf_generated_common.h 10 | 11 | #include "test_commons.h" 12 | #include "protobuf_generated_common.h" 13 | 14 | using namespace oq; 15 | 16 | void TestMyRangeIteratorEmpty() { 17 | ::google::protobuf::RepeatedField rf; 18 | auto&& myit = Iterators::mk_pb_iterator(&rf); 19 | auto&& begin = myit.begin(); 20 | auto&& end = myit.end(); 21 | EXPECT_NE(begin, end); 22 | EXPECT_EQ((int*) nullptr, *begin); 23 | ++begin; 24 | EXPECT_EQ(begin, end); 25 | } 26 | 27 | void TestMyRangeIteratorNonEmpty() { 28 | ::google::protobuf::RepeatedField rf; 29 | rf.Add(1); 30 | rf.Add(2); 31 | auto&& myit = Iterators::mk_pb_iterator(&rf); 32 | auto&& begin = myit.begin(); 33 | auto&& end = myit.end(); 34 | EXPECT_NE(begin, end); 35 | EXPECT_EQ(&rf.Get(0), *begin); 36 | ++begin; 37 | EXPECT_NE(begin, end); 38 | EXPECT_EQ(&rf.Get(1), *begin); 39 | ++begin; 40 | EXPECT_EQ(begin, end); 41 | } 42 | 43 | int main() { 44 | TestMyRangeIteratorEmpty(); 45 | TestMyRangeIteratorNonEmpty(); 46 | } 47 | -------------------------------------------------------------------------------- /src/sql/BISON_FLEX_README: -------------------------------------------------------------------------------- 1 | # Generating yy::SqlParser 2 | # all of yy directory is generated 3 | cd yy 4 | 5 | /usr/local/opt/bison/bin/bison -Wall --report=all -d ../sql.yy 6 | # Generates location.hh, position.hh, sql.tab.hh, sql.tab.cc, stack.hh 7 | 8 | /usr/local/opt/flex/bin/flex --outfile=sql.lex.cc ../sql.ll 9 | # Generates sql.lex.cc 10 | -------------------------------------------------------------------------------- /src/sql/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | include_directories( 3 | ${CMAKE_SOURCE_DIR}/common 4 | yy 5 | ) 6 | 7 | add_library(SqlParser query_tree.h query_tree.hpp select_parts.h select_query.h select_query.cc yy/sql.tab.cc yy/sql.lex.cc) 8 | target_link_libraries(Utils) 9 | 10 | add_subdirectory(test) 11 | -------------------------------------------------------------------------------- /src/sql/query_tree.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 https://github.com/na-ka-na 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain the License at http://www.apache.org/licenses/LICENSE-2.0 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include "select_query.h" 16 | 17 | using namespace std; 18 | 19 | namespace oq { 20 | 21 | enum NodeType { 22 | ROOT, REPEATED_MESSAGE, REPEATED_LEAF 23 | }; 24 | 25 | template 26 | struct Node; 27 | 28 | // Function invoked when node is visited. Parent will be null and indent=0 for root. 29 | template 30 | using StartNodeFn = function& node, Node* parent)>; 31 | 32 | // Function invoked to mark node ending. 33 | template 34 | using EndNodeFn = function& node)>; 35 | 36 | // Root will be a node and all repeated fields will be nodes 37 | template 38 | struct Node { 39 | // this is the variable name in the generated code 40 | string objName; 41 | // this will be set for non root nodes 42 | FieldT repeatedField; 43 | // children of this node, repeated fields, repeated field => Node. 44 | map children; 45 | // list of all (repeating + non-repeating) read fields for this node. 46 | map allFields; // value is if the field is repeating 47 | // list of all canonical where clauses 48 | vector whereClauses; 49 | // list of all select and order by exprs 50 | vector selectAndOrderByExprs; 51 | 52 | // Node tree walk, modified DFS which vists each node twice, 53 | // one in depth first order, second in reverse order. 54 | static void walkNode(Node& root, 55 | StartNodeFn& startNodeFn, 56 | EndNodeFn& endNodeFn, 57 | uint32_t indentInc = 2); 58 | 59 | static void walkNode(Node* parent, 60 | Node& node, 61 | int& indent, 62 | StartNodeFn& startNodeFn, 63 | uint32_t indentInc, 64 | map*>& endNodesMap); 65 | }; 66 | 67 | // Fields should also implement ==, < 68 | class Field { 69 | public: 70 | virtual ~Field() {}; 71 | virtual void addFieldPart(const string&) = 0; 72 | virtual bool repeated() const = 0; 73 | virtual string code_type() const = 0; 74 | virtual string accessor() const = 0; 75 | }; 76 | 77 | template 78 | struct QueryTree { 79 | static_assert(std::is_base_of::value, 80 | "FieldT must inherit from Field"); 81 | 82 | QueryTree() {}; 83 | virtual ~QueryTree() {}; 84 | 85 | Node root; 86 | map idFieldMap; 87 | 88 | virtual string getRootName() const = 0; 89 | virtual string getRootType() const = 0; 90 | virtual FieldT newField() const = 0; 91 | 92 | virtual string generatedCommonHeader() const = 0; 93 | virtual void printRootForLoop(ostream& out, const string& ind, 94 | const Node& node) const = 0; 95 | virtual void printNonRootForLoop(ostream& out, const string& ind, 96 | const Node& node, 97 | const Node& parent) const = 0; 98 | virtual void printFieldAssignment(ostream& out, const string& ind, 99 | const Node& node, 100 | const FieldT& field, 101 | bool repeating, 102 | const string& fieldType, 103 | const string& fieldVar, 104 | const string& fieldDefault) const = 0; 105 | 106 | void process(const SelectQuery& query); 107 | void printPlan(const SelectQuery& query, ostream& out); 108 | void printCode(const SelectQuery& query, ostream& out, 109 | const CodeGenSpec& spec); 110 | 111 | void addReadIdentifier(const string& identifier); 112 | void processSelect(const SelectStmt& selectStmt); 113 | void processWhere(const WhereStmt& whereStmt); 114 | void processOrderBy(const OrderByStmt& orderByStmt); 115 | void processExpr(const set& identifiers, 116 | const function& node)>& callback); 117 | static void addExpr(vector& exprs, const Expr* expr); 118 | }; 119 | 120 | } // namespace oq 121 | 122 | #include "query_tree.hpp" 123 | -------------------------------------------------------------------------------- /src/sql/select_query.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 https://github.com/na-ka-na 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain the License at http://www.apache.org/licenses/LICENSE-2.0 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | #include "select_parts.h" 14 | #include "yy/sql.tab.hh" 15 | 16 | using namespace std; 17 | 18 | // declare yylex for bison 19 | oq::yy::SqlParser::symbol_type yylex(oq::SelectQuery& query); 20 | 21 | // declare yylex for flex 22 | #ifndef YY_TYPEDEF_YY_SCANNER_T 23 | #define YY_TYPEDEF_YY_SCANNER_T 24 | typedef void* yyscan_t; 25 | #endif 26 | #define YY_DECL oq::yy::SqlParser::symbol_type yylex_flex(oq::SelectQuery& query, yyscan_t yyscanner) 27 | YY_DECL; 28 | 29 | // Fwd declaration of flex functions, generated header file doesn't work for us 30 | // for some reason 31 | int yylex_init(yyscan_t*); 32 | struct yy_buffer_state; 33 | #ifndef YY_TYPEDEF_YY_BUFFER_STATE 34 | #define YY_TYPEDEF_YY_BUFFER_STATE 35 | typedef struct yy_buffer_state* YY_BUFFER_STATE; 36 | #endif 37 | YY_BUFFER_STATE yy_scan_string(const char*, yyscan_t); 38 | void yy_delete_buffer(YY_BUFFER_STATE, yyscan_t); 39 | int yylex_destroy(yyscan_t); 40 | 41 | namespace oq { 42 | 43 | class SelectQuery { 44 | public: 45 | SelectQuery(const string& rawSql) : rawSql(rawSql) {} 46 | string rawSql; 47 | yy::location loc; 48 | yyscan_t yyscanner = nullptr; 49 | 50 | SelectStmt selectStmt; 51 | FromStmt fromStmt; 52 | WhereStmt whereStmt; 53 | OrderByStmt orderByStmt; 54 | 55 | bool parse(); 56 | void mark_lexer_invalid_char(char c); 57 | void mark_parse_error( 58 | const yy::SqlParser::location_type& loc, 59 | const string& msg); 60 | void resolveSelectStars(const StarFieldResolver& resolver); 61 | void removeSelectAliases(); 62 | void extractStatics(CodeGenReqs& cgr) const; 63 | string str() const; 64 | }; 65 | 66 | } // namespace oq 67 | -------------------------------------------------------------------------------- /src/sql/sql.ll: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 https://github.com/na-ka-na 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain the License at http://www.apache.org/licenses/LICENSE-2.0 7 | */ 8 | 9 | %{ 10 | #include 11 | #include 12 | #include "../select_query.h" 13 | #include "sql.tab.hh" 14 | %} 15 | 16 | %option reentrant noyywrap nounput batch debug noinput 17 | 18 | string '[^\n']*' 19 | ws [ \t] 20 | alpha [A-Za-z] 21 | dig [0-9] 22 | name ({alpha}|[_$:])({alpha}|{dig}|[_$:])* 23 | iden {name}(\.{name})* 24 | siden {iden}\.\* 25 | num1 [-+]?{dig}+\.?([eE][-+]?{dig}+)? 26 | num2 [-+]?{dig}*\.{dig}+([eE][-+]?{dig}+)? 27 | number {num1}|{num2} 28 | 29 | %{ 30 | // Code run each time a pattern is matched. 31 | #define YY_USER_ACTION query.loc.columns(yyleng); 32 | %} 33 | 34 | %% 35 | 36 | %{ 37 | // Code run each time yylex is called. 38 | query.loc.step(); 39 | %} 40 | 41 | {ws}+ query.loc.step(); 42 | [\n]+ query.loc.lines(yyleng); query.loc.step(); 43 | "SELECT" return oq::yy::SqlParser::make_SELECT(query.loc); 44 | "FROM" return oq::yy::SqlParser::make_FROM(query.loc); 45 | "WHERE" return oq::yy::SqlParser::make_WHERE(query.loc); 46 | "GROUP" return oq::yy::SqlParser::make_GROUP(query.loc); 47 | "HAVING" return oq::yy::SqlParser::make_HAVING(query.loc); 48 | "ORDER" return oq::yy::SqlParser::make_ORDER(query.loc); 49 | "BY" return oq::yy::SqlParser::make_BY(query.loc); 50 | "AS" return oq::yy::SqlParser::make_AS(query.loc); 51 | "," return oq::yy::SqlParser::make_COMMA(query.loc); 52 | "+" return oq::yy::SqlParser::make_PLUS(query.loc); 53 | "-" return oq::yy::SqlParser::make_MINUS(query.loc); 54 | "*" return oq::yy::SqlParser::make_STAR(query.loc); 55 | "/" return oq::yy::SqlParser::make_DIVIDE(query.loc); 56 | "=" return oq::yy::SqlParser::make_EQ(query.loc); 57 | "!=" return oq::yy::SqlParser::make_NE(query.loc); 58 | "<" return oq::yy::SqlParser::make_LT(query.loc); 59 | ">" return oq::yy::SqlParser::make_GT(query.loc); 60 | "<=" return oq::yy::SqlParser::make_LE(query.loc); 61 | ">=" return oq::yy::SqlParser::make_GE(query.loc); 62 | "LIKE" return oq::yy::SqlParser::make_LIKE(query.loc); 63 | "IS" return oq::yy::SqlParser::make_IS(query.loc); 64 | "NOT" return oq::yy::SqlParser::make_NOT(query.loc); 65 | "NULL" return oq::yy::SqlParser::make_NULL(query.loc); 66 | "AND" return oq::yy::SqlParser::make_AND(query.loc); 67 | "OR" return oq::yy::SqlParser::make_OR(query.loc); 68 | "(" return oq::yy::SqlParser::make_LPAREN(query.loc); 69 | ")" return oq::yy::SqlParser::make_RPAREN(query.loc); 70 | "DISTINCT" return oq::yy::SqlParser::make_DISTINCT(query.loc); 71 | "ASC" return oq::yy::SqlParser::make_ASC(query.loc); 72 | "DESC" return oq::yy::SqlParser::make_DESC(query.loc); 73 | "TRUE" return oq::yy::SqlParser::make_BOOL(true, query.loc); 74 | "FALSE" return oq::yy::SqlParser::make_BOOL(false, query.loc); 75 | "true" return oq::yy::SqlParser::make_BOOL(true, query.loc); 76 | "false" return oq::yy::SqlParser::make_BOOL(false, query.loc); 77 | 78 | {string} {string s = yytext; s = s.substr(1, s.size()-2); 79 | return oq::yy::SqlParser::make_STRING(s, query.loc);} 80 | 81 | {dig}+ {long n = std::strtol(yytext, NULL, 10); 82 | return oq::yy::SqlParser::make_LONG(n, query.loc);} 83 | 84 | {number} {double d = std::strtod(yytext, NULL); 85 | return oq::yy::SqlParser::make_DOUBLE(d, query.loc);} 86 | 87 | {iden} return oq::yy::SqlParser::make_IDENTIFIER(yytext, query.loc); 88 | {siden} return oq::yy::SqlParser::make_STAR_IDENTIFIER(yytext, query.loc); 89 | 90 | . query.mark_lexer_invalid_char(yytext[0]); 91 | <> return oq::yy::SqlParser::make_END(query.loc); 92 | %% 93 | 94 | -------------------------------------------------------------------------------- /src/sql/sql.yy: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 https://github.com/na-ka-na 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain the License at http://www.apache.org/licenses/LICENSE-2.0 7 | */ 8 | 9 | %skeleton "lalr1.cc" /* -*- C++ -*- */ 10 | %require "3.0.4" 11 | %defines 12 | %define api.namespace {oq::yy} 13 | %define parser_class_name {SqlParser} 14 | %define api.token.constructor 15 | %define api.value.type variant 16 | %define parse.assert 17 | 18 | %code requires 19 | { 20 | #include "../select_parts.h" 21 | } 22 | %param { SelectQuery& query } 23 | 24 | %locations 25 | %define parse.error verbose 26 | 27 | %code 28 | { 29 | #include "../select_query.h" 30 | } 31 | 32 | %define api.token.prefix {TOK_} 33 | 34 | %token 35 | END 0 "end of file" 36 | SELECT "SELECT" 37 | FROM "FROM" 38 | WHERE "WHERE" 39 | GROUP "GROUP" 40 | HAVING "HAVING" 41 | ORDER "ORDER" 42 | BY "BY" 43 | AS "AS" 44 | COMMA "," 45 | PLUS "+" 46 | MINUS "-" 47 | STAR "*" 48 | DIVIDE "/" 49 | EQ "=" 50 | NE "!=" 51 | LT "<" 52 | GT ">" 53 | LE "<=" 54 | GE ">=" 55 | LIKE "LIKE" 56 | IS "IS" 57 | NOT "NOT" 58 | NULL "NULL" 59 | AND "AND" 60 | OR "OR" 61 | LPAREN "(" 62 | RPAREN ")" 63 | DISTINCT "DISTINCT" 64 | ASC "ASC" 65 | DESC "DESC" 66 | ; 67 | 68 | %token IDENTIFIER "identifier" 69 | %token STAR_IDENTIFIER "star_identifier" 70 | %token STRING "string" 71 | %token LONG "long" 72 | %token DOUBLE "double" 73 | %token BOOL "bool" 74 | 75 | %type select_stmt 76 | %type > select_fields 77 | %type select_field 78 | %type as_alias 79 | 80 | %type order_by_stmt 81 | %type > order_by_fields 82 | %type order_by_field 83 | 84 | %type from_stmt 85 | 86 | %type where_stmt 87 | %type boolean_expr 88 | %type expr 89 | %type > exprs 90 | %type > exprs1 91 | 92 | %printer { yyoutput << $$; } <*>; 93 | %% 94 | 95 | query: select_stmt 96 | from_stmt 97 | where_stmt 98 | group_by_stmt 99 | having_stmt 100 | order_by_stmt 101 | {query.selectStmt = $1; 102 | query.fromStmt = $2; 103 | query.whereStmt = $3; 104 | query.orderByStmt = $6;} 105 | ; 106 | 107 | select_stmt: "SELECT" select_fields {$$=SelectStmt::create($2,false);} 108 | | "SELECT" "DISTINCT" select_fields {$$=SelectStmt::create($3,true);} 109 | ; 110 | select_fields: select_field {$$=vector{$1};} 111 | | select_fields "," select_field {$$=$1; $$.push_back($3);} 112 | ; 113 | select_field: "*" as_alias {$$=RawSelectField::create("*",$2);} 114 | | "star_identifier" as_alias {$$=RawSelectField::create($1,$2);} 115 | | expr as_alias {$$=RawSelectField::create($1,$2);} 116 | ; 117 | as_alias: %empty {$$="";} 118 | | "AS" "identifier" {$$=$2;} 119 | ; 120 | 121 | from_stmt: "FROM" "identifier" {$$=FromStmt::create($2);}; 122 | 123 | where_stmt: %empty {$$=WhereStmt::create();} 124 | | "WHERE" boolean_expr {$$=WhereStmt::create($2);} 125 | ; 126 | 127 | %left "AND"; 128 | %left "OR"; 129 | boolean_expr: 130 | "(" boolean_expr ")" {$$=$2;} 131 | | boolean_expr "AND" boolean_expr {$$=BooleanExpr::create(AND,$1,$3);} 132 | | boolean_expr "OR" boolean_expr {$$=BooleanExpr::create(OR,$1,$3);} 133 | | expr "=" expr {$$=BooleanExpr::create(EQ,$1,$3);} 134 | | expr "!=" expr {$$=BooleanExpr::create(NE,$1,$3);} 135 | | expr ">" expr {$$=BooleanExpr::create(GT,$1,$3);} 136 | | expr "<" expr {$$=BooleanExpr::create(LT,$1,$3);} 137 | | expr ">=" expr {$$=BooleanExpr::create(GE,$1,$3);} 138 | | expr "<=" expr {$$=BooleanExpr::create(LT,$1,$3);} 139 | | expr "LIKE" expr {$$=BooleanExpr::create(LIKE,$1,$3);} 140 | | "identifier" "IS" "NULL" {$$=BooleanExpr::createNullary(true, $1);} 141 | | "identifier" "IS" "NOT" "NULL" {$$=BooleanExpr::createNullary(false, $1);} 142 | ; 143 | 144 | exprs: %empty {$$=vector{};} 145 | | exprs1 {$$=$1;} 146 | 147 | exprs1: expr {$$=vector{$1};} 148 | | exprs1 "," expr {$$=$1; $$.push_back($3);} 149 | 150 | %left "+" "-"; 151 | %left "*" "/"; 152 | %precedence UMINUS; 153 | expr: 154 | "(" expr ")" {$$=$2;} 155 | | expr "+" expr {$$=Expr::create(PLUS,$1,$3);} 156 | | expr "-" expr {$$=Expr::create(MINUS,$1,$3);} 157 | | expr "*" expr {$$=Expr::create(MULT,$1,$3);} 158 | | expr "/" expr {$$=Expr::create(DIVIDE,$1,$3);} 159 | | "-" expr %prec UMINUS {$$=Expr::create(UMINUS,$2);} 160 | | "identifier" "(" exprs ")" {$$=Expr::createFnCall($1,$3);} 161 | | "identifier" {$$=Expr::createIdentifier($1);} 162 | | "string" {$$=Expr::createPrimitive($1);} 163 | | "long" {$$=Expr::createPrimitive($1);} 164 | | "double" {$$=Expr::createPrimitive($1);} 165 | | "bool" {$$=Expr::createPrimitive($1);} 166 | ; 167 | 168 | group_by_stmt: %empty | "GROUP" "BY" group_by_fields; 169 | group_by_fields: group_by_field | group_by_fields "," group_by_field; 170 | group_by_field: "identifier"; 171 | 172 | having_stmt: %empty | "HAVING" boolean_expr; 173 | 174 | order_by_stmt: %empty {$$=OrderByStmt::create();} 175 | | "ORDER" "BY" order_by_fields {$$=OrderByStmt::create($3);} 176 | ; 177 | order_by_fields: order_by_field {$$=vector{$1};} 178 | | order_by_fields "," order_by_field {$$=$1; $$.push_back($3);} 179 | ; 180 | order_by_field: expr {$$=OrderByField::create($1,false);} 181 | | expr "ASC" {$$=OrderByField::create($1,false);} 182 | | expr "DESC" {$$=OrderByField::create($1,true);} 183 | ; 184 | 185 | %% 186 | void oq::yy::SqlParser::error(const oq::yy::SqlParser::location_type& loc, 187 | const std::string& msg) { 188 | query.mark_parse_error(loc, msg); 189 | } 190 | -------------------------------------------------------------------------------- /src/sql/test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include_directories( 2 | ${CMAKE_SOURCE_DIR}/sql 3 | ${CMAKE_SOURCE_DIR}/common/test 4 | ) 5 | 6 | add_executable(SelectQueryTest select_query_test.cc) 7 | target_link_libraries(SelectQueryTest SqlParser) 8 | add_test(SelectQueryTest SelectQueryTest) 9 | -------------------------------------------------------------------------------- /src/sql/test/select_query_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 https://github.com/na-ka-na 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain the License at http://www.apache.org/licenses/LICENSE-2.0 7 | */ 8 | 9 | // Unit tests for select_query_test.cc 10 | 11 | #include "test_commons.h" 12 | #include "select_parts.h" 13 | 14 | using namespace oq; 15 | 16 | void TestExpr() { 17 | Expr x = Expr::createIdentifier("x"); 18 | Expr y = Expr::createIdentifier("y"); 19 | Expr e1 = Expr::create(PLUS, x, y); 20 | Expr e2 = Expr::create(MINUS, x, e1); 21 | Expr e3 = Expr::create(MULT, y, e2); 22 | EXPECT_EQ("(y*(x-(x+y)))", e3.str()); 23 | EXPECT_EQ("Mult(y, Minus(x, Plus(x, y)))", e3.code({})); 24 | CodeGenReqs cgr; 25 | cgr.idVarMap = {{"x", "s0"}, {"y", "s1"}}; 26 | cgr.idDefaultMap = {{"x", "S0()"}, {"y", "S1()"}}; 27 | EXPECT_EQ("Mult(s1, Minus(s0, Plus(s0, s1)))", e3.code(cgr)); 28 | EXPECT_EQ("decltype(Mult(S1(), Minus(S0(), Plus(S0(), S1()))))", 29 | e3.cppType(cgr)); 30 | } 31 | 32 | int main() { 33 | TestExpr(); 34 | } 35 | -------------------------------------------------------------------------------- /src/sql/yy/location.hh: -------------------------------------------------------------------------------- 1 | // A Bison parser, made by GNU Bison 3.0.4. 2 | 3 | // Locations for Bison parsers in C++ 4 | 5 | // Copyright (C) 2002-2015 Free Software Foundation, Inc. 6 | 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | 20 | // As a special exception, you may create a larger work that contains 21 | // part or all of the Bison parser skeleton and distribute that work 22 | // under terms of your choice, so long as that work isn't itself a 23 | // parser generator using the skeleton or a modified version thereof 24 | // as a parser skeleton. Alternatively, if you modify or redistribute 25 | // the parser skeleton itself, you may (at your option) remove this 26 | // special exception, which will cause the skeleton and the resulting 27 | // Bison output files to be licensed under the GNU General Public 28 | // License without this special exception. 29 | 30 | // This special exception was added by the Free Software Foundation in 31 | // version 2.2 of Bison. 32 | 33 | /** 34 | ** \file location.hh 35 | ** Define the oq::yy::location class. 36 | */ 37 | 38 | #ifndef YY_YY_LOCATION_HH_INCLUDED 39 | # define YY_YY_LOCATION_HH_INCLUDED 40 | 41 | # include "position.hh" 42 | 43 | #line 12 "../sql.yy" // location.cc:337 44 | namespace oq { namespace yy { 45 | #line 46 "location.hh" // location.cc:337 46 | /// Abstract a location. 47 | class location 48 | { 49 | public: 50 | 51 | /// Construct a location from \a b to \a e. 52 | location (const position& b, const position& e) 53 | : begin (b) 54 | , end (e) 55 | { 56 | } 57 | 58 | /// Construct a 0-width location in \a p. 59 | explicit location (const position& p = position ()) 60 | : begin (p) 61 | , end (p) 62 | { 63 | } 64 | 65 | /// Construct a 0-width location in \a f, \a l, \a c. 66 | explicit location (std::string* f, 67 | unsigned int l = 1u, 68 | unsigned int c = 1u) 69 | : begin (f, l, c) 70 | , end (f, l, c) 71 | { 72 | } 73 | 74 | 75 | /// Initialization. 76 | void initialize (std::string* f = YY_NULLPTR, 77 | unsigned int l = 1u, 78 | unsigned int c = 1u) 79 | { 80 | begin.initialize (f, l, c); 81 | end = begin; 82 | } 83 | 84 | /** \name Line and Column related manipulators 85 | ** \{ */ 86 | public: 87 | /// Reset initial location to final location. 88 | void step () 89 | { 90 | begin = end; 91 | } 92 | 93 | /// Extend the current location to the COUNT next columns. 94 | void columns (int count = 1) 95 | { 96 | end += count; 97 | } 98 | 99 | /// Extend the current location to the COUNT next lines. 100 | void lines (int count = 1) 101 | { 102 | end.lines (count); 103 | } 104 | /** \} */ 105 | 106 | 107 | public: 108 | /// Beginning of the located region. 109 | position begin; 110 | /// End of the located region. 111 | position end; 112 | }; 113 | 114 | /// Join two locations, in place. 115 | inline location& operator+= (location& res, const location& end) 116 | { 117 | res.end = end.end; 118 | return res; 119 | } 120 | 121 | /// Join two locations. 122 | inline location operator+ (location res, const location& end) 123 | { 124 | return res += end; 125 | } 126 | 127 | /// Add \a width columns to the end position, in place. 128 | inline location& operator+= (location& res, int width) 129 | { 130 | res.columns (width); 131 | return res; 132 | } 133 | 134 | /// Add \a width columns to the end position. 135 | inline location operator+ (location res, int width) 136 | { 137 | return res += width; 138 | } 139 | 140 | /// Subtract \a width columns to the end position, in place. 141 | inline location& operator-= (location& res, int width) 142 | { 143 | return res += -width; 144 | } 145 | 146 | /// Subtract \a width columns to the end position. 147 | inline location operator- (location res, int width) 148 | { 149 | return res -= width; 150 | } 151 | 152 | /// Compare two location objects. 153 | inline bool 154 | operator== (const location& loc1, const location& loc2) 155 | { 156 | return loc1.begin == loc2.begin && loc1.end == loc2.end; 157 | } 158 | 159 | /// Compare two location objects. 160 | inline bool 161 | operator!= (const location& loc1, const location& loc2) 162 | { 163 | return !(loc1 == loc2); 164 | } 165 | 166 | /** \brief Intercept output stream redirection. 167 | ** \param ostr the destination output stream 168 | ** \param loc a reference to the location to redirect 169 | ** 170 | ** Avoid duplicate information. 171 | */ 172 | template 173 | inline std::basic_ostream& 174 | operator<< (std::basic_ostream& ostr, const location& loc) 175 | { 176 | unsigned int end_col = 0 < loc.end.column ? loc.end.column - 1 : 0; 177 | ostr << loc.begin; 178 | if (loc.end.filename 179 | && (!loc.begin.filename 180 | || *loc.begin.filename != *loc.end.filename)) 181 | ostr << '-' << loc.end.filename << ':' << loc.end.line << '.' << end_col; 182 | else if (loc.begin.line < loc.end.line) 183 | ostr << '-' << loc.end.line << '.' << end_col; 184 | else if (loc.begin.column < end_col) 185 | ostr << '-' << end_col; 186 | return ostr; 187 | } 188 | 189 | #line 12 "../sql.yy" // location.cc:337 190 | } } // oq::yy 191 | #line 192 "location.hh" // location.cc:337 192 | #endif // !YY_YY_LOCATION_HH_INCLUDED 193 | -------------------------------------------------------------------------------- /src/sql/yy/position.hh: -------------------------------------------------------------------------------- 1 | // A Bison parser, made by GNU Bison 3.0.4. 2 | 3 | // Positions for Bison parsers in C++ 4 | 5 | // Copyright (C) 2002-2015 Free Software Foundation, Inc. 6 | 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | 20 | // As a special exception, you may create a larger work that contains 21 | // part or all of the Bison parser skeleton and distribute that work 22 | // under terms of your choice, so long as that work isn't itself a 23 | // parser generator using the skeleton or a modified version thereof 24 | // as a parser skeleton. Alternatively, if you modify or redistribute 25 | // the parser skeleton itself, you may (at your option) remove this 26 | // special exception, which will cause the skeleton and the resulting 27 | // Bison output files to be licensed under the GNU General Public 28 | // License without this special exception. 29 | 30 | // This special exception was added by the Free Software Foundation in 31 | // version 2.2 of Bison. 32 | 33 | /** 34 | ** \file position.hh 35 | ** Define the oq::yy::position class. 36 | */ 37 | 38 | #ifndef YY_YY_POSITION_HH_INCLUDED 39 | # define YY_YY_POSITION_HH_INCLUDED 40 | 41 | # include // std::max 42 | # include 43 | # include 44 | 45 | # ifndef YY_NULLPTR 46 | # if defined __cplusplus && 201103L <= __cplusplus 47 | # define YY_NULLPTR nullptr 48 | # else 49 | # define YY_NULLPTR 0 50 | # endif 51 | # endif 52 | 53 | #line 12 "../sql.yy" // location.cc:337 54 | namespace oq { namespace yy { 55 | #line 56 "position.hh" // location.cc:337 56 | /// Abstract a position. 57 | class position 58 | { 59 | public: 60 | /// Construct a position. 61 | explicit position (std::string* f = YY_NULLPTR, 62 | unsigned int l = 1u, 63 | unsigned int c = 1u) 64 | : filename (f) 65 | , line (l) 66 | , column (c) 67 | { 68 | } 69 | 70 | 71 | /// Initialization. 72 | void initialize (std::string* fn = YY_NULLPTR, 73 | unsigned int l = 1u, 74 | unsigned int c = 1u) 75 | { 76 | filename = fn; 77 | line = l; 78 | column = c; 79 | } 80 | 81 | /** \name Line and Column related manipulators 82 | ** \{ */ 83 | /// (line related) Advance to the COUNT next lines. 84 | void lines (int count = 1) 85 | { 86 | if (count) 87 | { 88 | column = 1u; 89 | line = add_ (line, count, 1); 90 | } 91 | } 92 | 93 | /// (column related) Advance to the COUNT next columns. 94 | void columns (int count = 1) 95 | { 96 | column = add_ (column, count, 1); 97 | } 98 | /** \} */ 99 | 100 | /// File name to which this position refers. 101 | std::string* filename; 102 | /// Current line number. 103 | unsigned int line; 104 | /// Current column number. 105 | unsigned int column; 106 | 107 | private: 108 | /// Compute max(min, lhs+rhs) (provided min <= lhs). 109 | static unsigned int add_ (unsigned int lhs, int rhs, unsigned int min) 110 | { 111 | return (0 < rhs || -static_cast(rhs) < lhs 112 | ? rhs + lhs 113 | : min); 114 | } 115 | }; 116 | 117 | /// Add \a width columns, in place. 118 | inline position& 119 | operator+= (position& res, int width) 120 | { 121 | res.columns (width); 122 | return res; 123 | } 124 | 125 | /// Add \a width columns. 126 | inline position 127 | operator+ (position res, int width) 128 | { 129 | return res += width; 130 | } 131 | 132 | /// Subtract \a width columns, in place. 133 | inline position& 134 | operator-= (position& res, int width) 135 | { 136 | return res += -width; 137 | } 138 | 139 | /// Subtract \a width columns. 140 | inline position 141 | operator- (position res, int width) 142 | { 143 | return res -= width; 144 | } 145 | 146 | /// Compare two position objects. 147 | inline bool 148 | operator== (const position& pos1, const position& pos2) 149 | { 150 | return (pos1.line == pos2.line 151 | && pos1.column == pos2.column 152 | && (pos1.filename == pos2.filename 153 | || (pos1.filename && pos2.filename 154 | && *pos1.filename == *pos2.filename))); 155 | } 156 | 157 | /// Compare two position objects. 158 | inline bool 159 | operator!= (const position& pos1, const position& pos2) 160 | { 161 | return !(pos1 == pos2); 162 | } 163 | 164 | /** \brief Intercept output stream redirection. 165 | ** \param ostr the destination output stream 166 | ** \param pos a reference to the position to redirect 167 | */ 168 | template 169 | inline std::basic_ostream& 170 | operator<< (std::basic_ostream& ostr, const position& pos) 171 | { 172 | if (pos.filename) 173 | ostr << *pos.filename << ':'; 174 | return ostr << pos.line << '.' << pos.column; 175 | } 176 | 177 | #line 12 "../sql.yy" // location.cc:337 178 | } } // oq::yy 179 | #line 180 "position.hh" // location.cc:337 180 | #endif // !YY_YY_POSITION_HH_INCLUDED 181 | -------------------------------------------------------------------------------- /src/sql/yy/stack.hh: -------------------------------------------------------------------------------- 1 | // A Bison parser, made by GNU Bison 3.0.4. 2 | 3 | // Stack handling for Bison parsers in C++ 4 | 5 | // Copyright (C) 2002-2015 Free Software Foundation, Inc. 6 | 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | 20 | // As a special exception, you may create a larger work that contains 21 | // part or all of the Bison parser skeleton and distribute that work 22 | // under terms of your choice, so long as that work isn't itself a 23 | // parser generator using the skeleton or a modified version thereof 24 | // as a parser skeleton. Alternatively, if you modify or redistribute 25 | // the parser skeleton itself, you may (at your option) remove this 26 | // special exception, which will cause the skeleton and the resulting 27 | // Bison output files to be licensed under the GNU General Public 28 | // License without this special exception. 29 | 30 | // This special exception was added by the Free Software Foundation in 31 | // version 2.2 of Bison. 32 | 33 | /** 34 | ** \file stack.hh 35 | ** Define the oq::yy::stack class. 36 | */ 37 | 38 | #ifndef YY_YY_STACK_HH_INCLUDED 39 | # define YY_YY_STACK_HH_INCLUDED 40 | 41 | # include 42 | 43 | #line 12 "../sql.yy" // stack.hh:151 44 | namespace oq { namespace yy { 45 | #line 46 "stack.hh" // stack.hh:151 46 | template > 47 | class stack 48 | { 49 | public: 50 | // Hide our reversed order. 51 | typedef typename S::reverse_iterator iterator; 52 | typedef typename S::const_reverse_iterator const_iterator; 53 | 54 | stack () 55 | : seq_ () 56 | { 57 | seq_.reserve (200); 58 | } 59 | 60 | stack (unsigned int n) 61 | : seq_ (n) 62 | {} 63 | 64 | inline 65 | T& 66 | operator[] (unsigned int i) 67 | { 68 | return seq_[seq_.size () - 1 - i]; 69 | } 70 | 71 | inline 72 | const T& 73 | operator[] (unsigned int i) const 74 | { 75 | return seq_[seq_.size () - 1 - i]; 76 | } 77 | 78 | /// Steal the contents of \a t. 79 | /// 80 | /// Close to move-semantics. 81 | inline 82 | void 83 | push (T& t) 84 | { 85 | seq_.push_back (T()); 86 | operator[](0).move (t); 87 | } 88 | 89 | inline 90 | void 91 | pop (unsigned int n = 1) 92 | { 93 | for (; n; --n) 94 | seq_.pop_back (); 95 | } 96 | 97 | void 98 | clear () 99 | { 100 | seq_.clear (); 101 | } 102 | 103 | inline 104 | typename S::size_type 105 | size () const 106 | { 107 | return seq_.size (); 108 | } 109 | 110 | inline 111 | const_iterator 112 | begin () const 113 | { 114 | return seq_.rbegin (); 115 | } 116 | 117 | inline 118 | const_iterator 119 | end () const 120 | { 121 | return seq_.rend (); 122 | } 123 | 124 | private: 125 | stack (const stack&); 126 | stack& operator= (const stack&); 127 | /// The wrapped container. 128 | S seq_; 129 | }; 130 | 131 | /// Present a slice of the top of a stack. 132 | template > 133 | class slice 134 | { 135 | public: 136 | slice (const S& stack, unsigned int range) 137 | : stack_ (stack) 138 | , range_ (range) 139 | {} 140 | 141 | inline 142 | const T& 143 | operator [] (unsigned int i) const 144 | { 145 | return stack_[range_ - i]; 146 | } 147 | 148 | private: 149 | const S& stack_; 150 | unsigned int range_; 151 | }; 152 | 153 | #line 12 "../sql.yy" // stack.hh:151 154 | } } // oq::yy 155 | #line 156 "stack.hh" // stack.hh:151 156 | 157 | #endif // !YY_YY_STACK_HH_INCLUDED 158 | -------------------------------------------------------------------------------- /src/third-party/rapidjson: -------------------------------------------------------------------------------- 1 | rapidjson-1.1.0 -------------------------------------------------------------------------------- /src/third-party/rapidjson-1.1.0/include/rapidjson/error/en.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_ERROR_EN_H_ 16 | #define RAPIDJSON_ERROR_EN_H_ 17 | 18 | #include "error.h" 19 | 20 | #ifdef __clang__ 21 | RAPIDJSON_DIAG_PUSH 22 | RAPIDJSON_DIAG_OFF(switch-enum) 23 | RAPIDJSON_DIAG_OFF(covered-switch-default) 24 | #endif 25 | 26 | RAPIDJSON_NAMESPACE_BEGIN 27 | 28 | //! Maps error code of parsing into error message. 29 | /*! 30 | \ingroup RAPIDJSON_ERRORS 31 | \param parseErrorCode Error code obtained in parsing. 32 | \return the error message. 33 | \note User can make a copy of this function for localization. 34 | Using switch-case is safer for future modification of error codes. 35 | */ 36 | inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErrorCode) { 37 | switch (parseErrorCode) { 38 | case kParseErrorNone: return RAPIDJSON_ERROR_STRING("No error."); 39 | 40 | case kParseErrorDocumentEmpty: return RAPIDJSON_ERROR_STRING("The document is empty."); 41 | case kParseErrorDocumentRootNotSingular: return RAPIDJSON_ERROR_STRING("The document root must not be followed by other values."); 42 | 43 | case kParseErrorValueInvalid: return RAPIDJSON_ERROR_STRING("Invalid value."); 44 | 45 | case kParseErrorObjectMissName: return RAPIDJSON_ERROR_STRING("Missing a name for object member."); 46 | case kParseErrorObjectMissColon: return RAPIDJSON_ERROR_STRING("Missing a colon after a name of object member."); 47 | case kParseErrorObjectMissCommaOrCurlyBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or '}' after an object member."); 48 | 49 | case kParseErrorArrayMissCommaOrSquareBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or ']' after an array element."); 50 | 51 | case kParseErrorStringUnicodeEscapeInvalidHex: return RAPIDJSON_ERROR_STRING("Incorrect hex digit after \\u escape in string."); 52 | case kParseErrorStringUnicodeSurrogateInvalid: return RAPIDJSON_ERROR_STRING("The surrogate pair in string is invalid."); 53 | case kParseErrorStringEscapeInvalid: return RAPIDJSON_ERROR_STRING("Invalid escape character in string."); 54 | case kParseErrorStringMissQuotationMark: return RAPIDJSON_ERROR_STRING("Missing a closing quotation mark in string."); 55 | case kParseErrorStringInvalidEncoding: return RAPIDJSON_ERROR_STRING("Invalid encoding in string."); 56 | 57 | case kParseErrorNumberTooBig: return RAPIDJSON_ERROR_STRING("Number too big to be stored in double."); 58 | case kParseErrorNumberMissFraction: return RAPIDJSON_ERROR_STRING("Miss fraction part in number."); 59 | case kParseErrorNumberMissExponent: return RAPIDJSON_ERROR_STRING("Miss exponent in number."); 60 | 61 | case kParseErrorTermination: return RAPIDJSON_ERROR_STRING("Terminate parsing due to Handler error."); 62 | case kParseErrorUnspecificSyntaxError: return RAPIDJSON_ERROR_STRING("Unspecific syntax error."); 63 | 64 | default: return RAPIDJSON_ERROR_STRING("Unknown error."); 65 | } 66 | } 67 | 68 | RAPIDJSON_NAMESPACE_END 69 | 70 | #ifdef __clang__ 71 | RAPIDJSON_DIAG_POP 72 | #endif 73 | 74 | #endif // RAPIDJSON_ERROR_EN_H_ 75 | -------------------------------------------------------------------------------- /src/third-party/rapidjson-1.1.0/include/rapidjson/error/error.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_ERROR_ERROR_H_ 16 | #define RAPIDJSON_ERROR_ERROR_H_ 17 | 18 | #include "../rapidjson.h" 19 | 20 | #ifdef __clang__ 21 | RAPIDJSON_DIAG_PUSH 22 | RAPIDJSON_DIAG_OFF(padded) 23 | #endif 24 | 25 | /*! \file error.h */ 26 | 27 | /*! \defgroup RAPIDJSON_ERRORS RapidJSON error handling */ 28 | 29 | /////////////////////////////////////////////////////////////////////////////// 30 | // RAPIDJSON_ERROR_CHARTYPE 31 | 32 | //! Character type of error messages. 33 | /*! \ingroup RAPIDJSON_ERRORS 34 | The default character type is \c char. 35 | On Windows, user can define this macro as \c TCHAR for supporting both 36 | unicode/non-unicode settings. 37 | */ 38 | #ifndef RAPIDJSON_ERROR_CHARTYPE 39 | #define RAPIDJSON_ERROR_CHARTYPE char 40 | #endif 41 | 42 | /////////////////////////////////////////////////////////////////////////////// 43 | // RAPIDJSON_ERROR_STRING 44 | 45 | //! Macro for converting string literial to \ref RAPIDJSON_ERROR_CHARTYPE[]. 46 | /*! \ingroup RAPIDJSON_ERRORS 47 | By default this conversion macro does nothing. 48 | On Windows, user can define this macro as \c _T(x) for supporting both 49 | unicode/non-unicode settings. 50 | */ 51 | #ifndef RAPIDJSON_ERROR_STRING 52 | #define RAPIDJSON_ERROR_STRING(x) x 53 | #endif 54 | 55 | RAPIDJSON_NAMESPACE_BEGIN 56 | 57 | /////////////////////////////////////////////////////////////////////////////// 58 | // ParseErrorCode 59 | 60 | //! Error code of parsing. 61 | /*! \ingroup RAPIDJSON_ERRORS 62 | \see GenericReader::Parse, GenericReader::GetParseErrorCode 63 | */ 64 | enum ParseErrorCode { 65 | kParseErrorNone = 0, //!< No error. 66 | 67 | kParseErrorDocumentEmpty, //!< The document is empty. 68 | kParseErrorDocumentRootNotSingular, //!< The document root must not follow by other values. 69 | 70 | kParseErrorValueInvalid, //!< Invalid value. 71 | 72 | kParseErrorObjectMissName, //!< Missing a name for object member. 73 | kParseErrorObjectMissColon, //!< Missing a colon after a name of object member. 74 | kParseErrorObjectMissCommaOrCurlyBracket, //!< Missing a comma or '}' after an object member. 75 | 76 | kParseErrorArrayMissCommaOrSquareBracket, //!< Missing a comma or ']' after an array element. 77 | 78 | kParseErrorStringUnicodeEscapeInvalidHex, //!< Incorrect hex digit after \\u escape in string. 79 | kParseErrorStringUnicodeSurrogateInvalid, //!< The surrogate pair in string is invalid. 80 | kParseErrorStringEscapeInvalid, //!< Invalid escape character in string. 81 | kParseErrorStringMissQuotationMark, //!< Missing a closing quotation mark in string. 82 | kParseErrorStringInvalidEncoding, //!< Invalid encoding in string. 83 | 84 | kParseErrorNumberTooBig, //!< Number too big to be stored in double. 85 | kParseErrorNumberMissFraction, //!< Miss fraction part in number. 86 | kParseErrorNumberMissExponent, //!< Miss exponent in number. 87 | 88 | kParseErrorTermination, //!< Parsing was terminated. 89 | kParseErrorUnspecificSyntaxError //!< Unspecific syntax error. 90 | }; 91 | 92 | //! Result of parsing (wraps ParseErrorCode) 93 | /*! 94 | \ingroup RAPIDJSON_ERRORS 95 | \code 96 | Document doc; 97 | ParseResult ok = doc.Parse("[42]"); 98 | if (!ok) { 99 | fprintf(stderr, "JSON parse error: %s (%u)", 100 | GetParseError_En(ok.Code()), ok.Offset()); 101 | exit(EXIT_FAILURE); 102 | } 103 | \endcode 104 | \see GenericReader::Parse, GenericDocument::Parse 105 | */ 106 | struct ParseResult { 107 | public: 108 | //! Default constructor, no error. 109 | ParseResult() : code_(kParseErrorNone), offset_(0) {} 110 | //! Constructor to set an error. 111 | ParseResult(ParseErrorCode code, size_t offset) : code_(code), offset_(offset) {} 112 | 113 | //! Get the error code. 114 | ParseErrorCode Code() const { return code_; } 115 | //! Get the error offset, if \ref IsError(), 0 otherwise. 116 | size_t Offset() const { return offset_; } 117 | 118 | //! Conversion to \c bool, returns \c true, iff !\ref IsError(). 119 | operator bool() const { return !IsError(); } 120 | //! Whether the result is an error. 121 | bool IsError() const { return code_ != kParseErrorNone; } 122 | 123 | bool operator==(const ParseResult& that) const { return code_ == that.code_; } 124 | bool operator==(ParseErrorCode code) const { return code_ == code; } 125 | friend bool operator==(ParseErrorCode code, const ParseResult & err) { return code == err.code_; } 126 | 127 | //! Reset error code. 128 | void Clear() { Set(kParseErrorNone); } 129 | //! Update error code and offset. 130 | void Set(ParseErrorCode code, size_t offset = 0) { code_ = code; offset_ = offset; } 131 | 132 | private: 133 | ParseErrorCode code_; 134 | size_t offset_; 135 | }; 136 | 137 | //! Function pointer type of GetParseError(). 138 | /*! \ingroup RAPIDJSON_ERRORS 139 | 140 | This is the prototype for \c GetParseError_X(), where \c X is a locale. 141 | User can dynamically change locale in runtime, e.g.: 142 | \code 143 | GetParseErrorFunc GetParseError = GetParseError_En; // or whatever 144 | const RAPIDJSON_ERROR_CHARTYPE* s = GetParseError(document.GetParseErrorCode()); 145 | \endcode 146 | */ 147 | typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetParseErrorFunc)(ParseErrorCode); 148 | 149 | RAPIDJSON_NAMESPACE_END 150 | 151 | #ifdef __clang__ 152 | RAPIDJSON_DIAG_POP 153 | #endif 154 | 155 | #endif // RAPIDJSON_ERROR_ERROR_H_ 156 | -------------------------------------------------------------------------------- /src/third-party/rapidjson-1.1.0/include/rapidjson/filereadstream.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_FILEREADSTREAM_H_ 16 | #define RAPIDJSON_FILEREADSTREAM_H_ 17 | 18 | #include "stream.h" 19 | #include 20 | 21 | #ifdef __clang__ 22 | RAPIDJSON_DIAG_PUSH 23 | RAPIDJSON_DIAG_OFF(padded) 24 | RAPIDJSON_DIAG_OFF(unreachable-code) 25 | RAPIDJSON_DIAG_OFF(missing-noreturn) 26 | #endif 27 | 28 | RAPIDJSON_NAMESPACE_BEGIN 29 | 30 | //! File byte stream for input using fread(). 31 | /*! 32 | \note implements Stream concept 33 | */ 34 | class FileReadStream { 35 | public: 36 | typedef char Ch; //!< Character type (byte). 37 | 38 | //! Constructor. 39 | /*! 40 | \param fp File pointer opened for read. 41 | \param buffer user-supplied buffer. 42 | \param bufferSize size of buffer in bytes. Must >=4 bytes. 43 | */ 44 | FileReadStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) { 45 | RAPIDJSON_ASSERT(fp_ != 0); 46 | RAPIDJSON_ASSERT(bufferSize >= 4); 47 | Read(); 48 | } 49 | 50 | Ch Peek() const { return *current_; } 51 | Ch Take() { Ch c = *current_; Read(); return c; } 52 | size_t Tell() const { return count_ + static_cast(current_ - buffer_); } 53 | 54 | // Not implemented 55 | void Put(Ch) { RAPIDJSON_ASSERT(false); } 56 | void Flush() { RAPIDJSON_ASSERT(false); } 57 | Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 58 | size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } 59 | 60 | // For encoding detection only. 61 | const Ch* Peek4() const { 62 | return (current_ + 4 <= bufferLast_) ? current_ : 0; 63 | } 64 | 65 | private: 66 | void Read() { 67 | if (current_ < bufferLast_) 68 | ++current_; 69 | else if (!eof_) { 70 | count_ += readCount_; 71 | readCount_ = fread(buffer_, 1, bufferSize_, fp_); 72 | bufferLast_ = buffer_ + readCount_ - 1; 73 | current_ = buffer_; 74 | 75 | if (readCount_ < bufferSize_) { 76 | buffer_[readCount_] = '\0'; 77 | ++bufferLast_; 78 | eof_ = true; 79 | } 80 | } 81 | } 82 | 83 | std::FILE* fp_; 84 | Ch *buffer_; 85 | size_t bufferSize_; 86 | Ch *bufferLast_; 87 | Ch *current_; 88 | size_t readCount_; 89 | size_t count_; //!< Number of characters read 90 | bool eof_; 91 | }; 92 | 93 | RAPIDJSON_NAMESPACE_END 94 | 95 | #ifdef __clang__ 96 | RAPIDJSON_DIAG_POP 97 | #endif 98 | 99 | #endif // RAPIDJSON_FILESTREAM_H_ 100 | -------------------------------------------------------------------------------- /src/third-party/rapidjson-1.1.0/include/rapidjson/filewritestream.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_FILEWRITESTREAM_H_ 16 | #define RAPIDJSON_FILEWRITESTREAM_H_ 17 | 18 | #include "stream.h" 19 | #include 20 | 21 | #ifdef __clang__ 22 | RAPIDJSON_DIAG_PUSH 23 | RAPIDJSON_DIAG_OFF(unreachable-code) 24 | #endif 25 | 26 | RAPIDJSON_NAMESPACE_BEGIN 27 | 28 | //! Wrapper of C file stream for input using fread(). 29 | /*! 30 | \note implements Stream concept 31 | */ 32 | class FileWriteStream { 33 | public: 34 | typedef char Ch; //!< Character type. Only support char. 35 | 36 | FileWriteStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferEnd_(buffer + bufferSize), current_(buffer_) { 37 | RAPIDJSON_ASSERT(fp_ != 0); 38 | } 39 | 40 | void Put(char c) { 41 | if (current_ >= bufferEnd_) 42 | Flush(); 43 | 44 | *current_++ = c; 45 | } 46 | 47 | void PutN(char c, size_t n) { 48 | size_t avail = static_cast(bufferEnd_ - current_); 49 | while (n > avail) { 50 | std::memset(current_, c, avail); 51 | current_ += avail; 52 | Flush(); 53 | n -= avail; 54 | avail = static_cast(bufferEnd_ - current_); 55 | } 56 | 57 | if (n > 0) { 58 | std::memset(current_, c, n); 59 | current_ += n; 60 | } 61 | } 62 | 63 | void Flush() { 64 | if (current_ != buffer_) { 65 | size_t result = fwrite(buffer_, 1, static_cast(current_ - buffer_), fp_); 66 | if (result < static_cast(current_ - buffer_)) { 67 | // failure deliberately ignored at this time 68 | // added to avoid warn_unused_result build errors 69 | } 70 | current_ = buffer_; 71 | } 72 | } 73 | 74 | // Not implemented 75 | char Peek() const { RAPIDJSON_ASSERT(false); return 0; } 76 | char Take() { RAPIDJSON_ASSERT(false); return 0; } 77 | size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } 78 | char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 79 | size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; } 80 | 81 | private: 82 | // Prohibit copy constructor & assignment operator. 83 | FileWriteStream(const FileWriteStream&); 84 | FileWriteStream& operator=(const FileWriteStream&); 85 | 86 | std::FILE* fp_; 87 | char *buffer_; 88 | char *bufferEnd_; 89 | char *current_; 90 | }; 91 | 92 | //! Implement specialized version of PutN() with memset() for better performance. 93 | template<> 94 | inline void PutN(FileWriteStream& stream, char c, size_t n) { 95 | stream.PutN(c, n); 96 | } 97 | 98 | RAPIDJSON_NAMESPACE_END 99 | 100 | #ifdef __clang__ 101 | RAPIDJSON_DIAG_POP 102 | #endif 103 | 104 | #endif // RAPIDJSON_FILESTREAM_H_ 105 | -------------------------------------------------------------------------------- /src/third-party/rapidjson-1.1.0/include/rapidjson/fwd.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_FWD_H_ 16 | #define RAPIDJSON_FWD_H_ 17 | 18 | #include "rapidjson.h" 19 | 20 | RAPIDJSON_NAMESPACE_BEGIN 21 | 22 | // encodings.h 23 | 24 | template struct UTF8; 25 | template struct UTF16; 26 | template struct UTF16BE; 27 | template struct UTF16LE; 28 | template struct UTF32; 29 | template struct UTF32BE; 30 | template struct UTF32LE; 31 | template struct ASCII; 32 | template struct AutoUTF; 33 | 34 | template 35 | struct Transcoder; 36 | 37 | // allocators.h 38 | 39 | class CrtAllocator; 40 | 41 | template 42 | class MemoryPoolAllocator; 43 | 44 | // stream.h 45 | 46 | template 47 | struct GenericStringStream; 48 | 49 | typedef GenericStringStream > StringStream; 50 | 51 | template 52 | struct GenericInsituStringStream; 53 | 54 | typedef GenericInsituStringStream > InsituStringStream; 55 | 56 | // stringbuffer.h 57 | 58 | template 59 | class GenericStringBuffer; 60 | 61 | typedef GenericStringBuffer, CrtAllocator> StringBuffer; 62 | 63 | // filereadstream.h 64 | 65 | class FileReadStream; 66 | 67 | // filewritestream.h 68 | 69 | class FileWriteStream; 70 | 71 | // memorybuffer.h 72 | 73 | template 74 | struct GenericMemoryBuffer; 75 | 76 | typedef GenericMemoryBuffer MemoryBuffer; 77 | 78 | // memorystream.h 79 | 80 | struct MemoryStream; 81 | 82 | // reader.h 83 | 84 | template 85 | struct BaseReaderHandler; 86 | 87 | template 88 | class GenericReader; 89 | 90 | typedef GenericReader, UTF8, CrtAllocator> Reader; 91 | 92 | // writer.h 93 | 94 | template 95 | class Writer; 96 | 97 | // prettywriter.h 98 | 99 | template 100 | class PrettyWriter; 101 | 102 | // document.h 103 | 104 | template 105 | struct GenericMember; 106 | 107 | template 108 | class GenericMemberIterator; 109 | 110 | template 111 | struct GenericStringRef; 112 | 113 | template 114 | class GenericValue; 115 | 116 | typedef GenericValue, MemoryPoolAllocator > Value; 117 | 118 | template 119 | class GenericDocument; 120 | 121 | typedef GenericDocument, MemoryPoolAllocator, CrtAllocator> Document; 122 | 123 | // pointer.h 124 | 125 | template 126 | class GenericPointer; 127 | 128 | typedef GenericPointer Pointer; 129 | 130 | // schema.h 131 | 132 | template 133 | class IGenericRemoteSchemaDocumentProvider; 134 | 135 | template 136 | class GenericSchemaDocument; 137 | 138 | typedef GenericSchemaDocument SchemaDocument; 139 | typedef IGenericRemoteSchemaDocumentProvider IRemoteSchemaDocumentProvider; 140 | 141 | template < 142 | typename SchemaDocumentType, 143 | typename OutputHandler, 144 | typename StateAllocator> 145 | class GenericSchemaValidator; 146 | 147 | typedef GenericSchemaValidator, void>, CrtAllocator> SchemaValidator; 148 | 149 | RAPIDJSON_NAMESPACE_END 150 | 151 | #endif // RAPIDJSON_RAPIDJSONFWD_H_ 152 | -------------------------------------------------------------------------------- /src/third-party/rapidjson-1.1.0/include/rapidjson/internal/ieee754.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_IEEE754_ 16 | #define RAPIDJSON_IEEE754_ 17 | 18 | #include "../rapidjson.h" 19 | 20 | RAPIDJSON_NAMESPACE_BEGIN 21 | namespace internal { 22 | 23 | class Double { 24 | public: 25 | Double() {} 26 | Double(double d) : d_(d) {} 27 | Double(uint64_t u) : u_(u) {} 28 | 29 | double Value() const { return d_; } 30 | uint64_t Uint64Value() const { return u_; } 31 | 32 | double NextPositiveDouble() const { 33 | RAPIDJSON_ASSERT(!Sign()); 34 | return Double(u_ + 1).Value(); 35 | } 36 | 37 | bool Sign() const { return (u_ & kSignMask) != 0; } 38 | uint64_t Significand() const { return u_ & kSignificandMask; } 39 | int Exponent() const { return static_cast(((u_ & kExponentMask) >> kSignificandSize) - kExponentBias); } 40 | 41 | bool IsNan() const { return (u_ & kExponentMask) == kExponentMask && Significand() != 0; } 42 | bool IsInf() const { return (u_ & kExponentMask) == kExponentMask && Significand() == 0; } 43 | bool IsNanOrInf() const { return (u_ & kExponentMask) == kExponentMask; } 44 | bool IsNormal() const { return (u_ & kExponentMask) != 0 || Significand() == 0; } 45 | bool IsZero() const { return (u_ & (kExponentMask | kSignificandMask)) == 0; } 46 | 47 | uint64_t IntegerSignificand() const { return IsNormal() ? Significand() | kHiddenBit : Significand(); } 48 | int IntegerExponent() const { return (IsNormal() ? Exponent() : kDenormalExponent) - kSignificandSize; } 49 | uint64_t ToBias() const { return (u_ & kSignMask) ? ~u_ + 1 : u_ | kSignMask; } 50 | 51 | static unsigned EffectiveSignificandSize(int order) { 52 | if (order >= -1021) 53 | return 53; 54 | else if (order <= -1074) 55 | return 0; 56 | else 57 | return static_cast(order) + 1074; 58 | } 59 | 60 | private: 61 | static const int kSignificandSize = 52; 62 | static const int kExponentBias = 0x3FF; 63 | static const int kDenormalExponent = 1 - kExponentBias; 64 | static const uint64_t kSignMask = RAPIDJSON_UINT64_C2(0x80000000, 0x00000000); 65 | static const uint64_t kExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000); 66 | static const uint64_t kSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF); 67 | static const uint64_t kHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000); 68 | 69 | union { 70 | double d_; 71 | uint64_t u_; 72 | }; 73 | }; 74 | 75 | } // namespace internal 76 | RAPIDJSON_NAMESPACE_END 77 | 78 | #endif // RAPIDJSON_IEEE754_ 79 | -------------------------------------------------------------------------------- /src/third-party/rapidjson-1.1.0/include/rapidjson/internal/meta.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_INTERNAL_META_H_ 16 | #define RAPIDJSON_INTERNAL_META_H_ 17 | 18 | #include "../rapidjson.h" 19 | 20 | #ifdef __GNUC__ 21 | RAPIDJSON_DIAG_PUSH 22 | RAPIDJSON_DIAG_OFF(effc++) 23 | #endif 24 | #if defined(_MSC_VER) 25 | RAPIDJSON_DIAG_PUSH 26 | RAPIDJSON_DIAG_OFF(6334) 27 | #endif 28 | 29 | #if RAPIDJSON_HAS_CXX11_TYPETRAITS 30 | #include 31 | #endif 32 | 33 | //@cond RAPIDJSON_INTERNAL 34 | RAPIDJSON_NAMESPACE_BEGIN 35 | namespace internal { 36 | 37 | // Helper to wrap/convert arbitrary types to void, useful for arbitrary type matching 38 | template struct Void { typedef void Type; }; 39 | 40 | /////////////////////////////////////////////////////////////////////////////// 41 | // BoolType, TrueType, FalseType 42 | // 43 | template struct BoolType { 44 | static const bool Value = Cond; 45 | typedef BoolType Type; 46 | }; 47 | typedef BoolType TrueType; 48 | typedef BoolType FalseType; 49 | 50 | 51 | /////////////////////////////////////////////////////////////////////////////// 52 | // SelectIf, BoolExpr, NotExpr, AndExpr, OrExpr 53 | // 54 | 55 | template struct SelectIfImpl { template struct Apply { typedef T1 Type; }; }; 56 | template <> struct SelectIfImpl { template struct Apply { typedef T2 Type; }; }; 57 | template struct SelectIfCond : SelectIfImpl::template Apply {}; 58 | template struct SelectIf : SelectIfCond {}; 59 | 60 | template struct AndExprCond : FalseType {}; 61 | template <> struct AndExprCond : TrueType {}; 62 | template struct OrExprCond : TrueType {}; 63 | template <> struct OrExprCond : FalseType {}; 64 | 65 | template struct BoolExpr : SelectIf::Type {}; 66 | template struct NotExpr : SelectIf::Type {}; 67 | template struct AndExpr : AndExprCond::Type {}; 68 | template struct OrExpr : OrExprCond::Type {}; 69 | 70 | 71 | /////////////////////////////////////////////////////////////////////////////// 72 | // AddConst, MaybeAddConst, RemoveConst 73 | template struct AddConst { typedef const T Type; }; 74 | template struct MaybeAddConst : SelectIfCond {}; 75 | template struct RemoveConst { typedef T Type; }; 76 | template struct RemoveConst { typedef T Type; }; 77 | 78 | 79 | /////////////////////////////////////////////////////////////////////////////// 80 | // IsSame, IsConst, IsMoreConst, IsPointer 81 | // 82 | template struct IsSame : FalseType {}; 83 | template struct IsSame : TrueType {}; 84 | 85 | template struct IsConst : FalseType {}; 86 | template struct IsConst : TrueType {}; 87 | 88 | template 89 | struct IsMoreConst 90 | : AndExpr::Type, typename RemoveConst::Type>, 91 | BoolType::Value >= IsConst::Value> >::Type {}; 92 | 93 | template struct IsPointer : FalseType {}; 94 | template struct IsPointer : TrueType {}; 95 | 96 | /////////////////////////////////////////////////////////////////////////////// 97 | // IsBaseOf 98 | // 99 | #if RAPIDJSON_HAS_CXX11_TYPETRAITS 100 | 101 | template struct IsBaseOf 102 | : BoolType< ::std::is_base_of::value> {}; 103 | 104 | #else // simplified version adopted from Boost 105 | 106 | template struct IsBaseOfImpl { 107 | RAPIDJSON_STATIC_ASSERT(sizeof(B) != 0); 108 | RAPIDJSON_STATIC_ASSERT(sizeof(D) != 0); 109 | 110 | typedef char (&Yes)[1]; 111 | typedef char (&No) [2]; 112 | 113 | template 114 | static Yes Check(const D*, T); 115 | static No Check(const B*, int); 116 | 117 | struct Host { 118 | operator const B*() const; 119 | operator const D*(); 120 | }; 121 | 122 | enum { Value = (sizeof(Check(Host(), 0)) == sizeof(Yes)) }; 123 | }; 124 | 125 | template struct IsBaseOf 126 | : OrExpr, BoolExpr > >::Type {}; 127 | 128 | #endif // RAPIDJSON_HAS_CXX11_TYPETRAITS 129 | 130 | 131 | ////////////////////////////////////////////////////////////////////////// 132 | // EnableIf / DisableIf 133 | // 134 | template struct EnableIfCond { typedef T Type; }; 135 | template struct EnableIfCond { /* empty */ }; 136 | 137 | template struct DisableIfCond { typedef T Type; }; 138 | template struct DisableIfCond { /* empty */ }; 139 | 140 | template 141 | struct EnableIf : EnableIfCond {}; 142 | 143 | template 144 | struct DisableIf : DisableIfCond {}; 145 | 146 | // SFINAE helpers 147 | struct SfinaeTag {}; 148 | template struct RemoveSfinaeTag; 149 | template struct RemoveSfinaeTag { typedef T Type; }; 150 | 151 | #define RAPIDJSON_REMOVEFPTR_(type) \ 152 | typename ::RAPIDJSON_NAMESPACE::internal::RemoveSfinaeTag \ 153 | < ::RAPIDJSON_NAMESPACE::internal::SfinaeTag&(*) type>::Type 154 | 155 | #define RAPIDJSON_ENABLEIF(cond) \ 156 | typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \ 157 | ::Type * = NULL 158 | 159 | #define RAPIDJSON_DISABLEIF(cond) \ 160 | typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \ 161 | ::Type * = NULL 162 | 163 | #define RAPIDJSON_ENABLEIF_RETURN(cond,returntype) \ 164 | typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \ 165 | ::Type 167 | 168 | #define RAPIDJSON_DISABLEIF_RETURN(cond,returntype) \ 169 | typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \ 170 | ::Type 172 | 173 | } // namespace internal 174 | RAPIDJSON_NAMESPACE_END 175 | //@endcond 176 | 177 | #if defined(__GNUC__) || defined(_MSC_VER) 178 | RAPIDJSON_DIAG_POP 179 | #endif 180 | 181 | #endif // RAPIDJSON_INTERNAL_META_H_ 182 | -------------------------------------------------------------------------------- /src/third-party/rapidjson-1.1.0/include/rapidjson/internal/pow10.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_POW10_ 16 | #define RAPIDJSON_POW10_ 17 | 18 | #include "../rapidjson.h" 19 | 20 | RAPIDJSON_NAMESPACE_BEGIN 21 | namespace internal { 22 | 23 | //! Computes integer powers of 10 in double (10.0^n). 24 | /*! This function uses lookup table for fast and accurate results. 25 | \param n non-negative exponent. Must <= 308. 26 | \return 10.0^n 27 | */ 28 | inline double Pow10(int n) { 29 | static const double e[] = { // 1e-0...1e308: 309 * 8 bytes = 2472 bytes 30 | 1e+0, 31 | 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20, 32 | 1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40, 33 | 1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60, 34 | 1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80, 35 | 1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100, 36 | 1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120, 37 | 1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140, 38 | 1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160, 39 | 1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180, 40 | 1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200, 41 | 1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220, 42 | 1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240, 43 | 1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260, 44 | 1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280, 45 | 1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300, 46 | 1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308 47 | }; 48 | RAPIDJSON_ASSERT(n >= 0 && n <= 308); 49 | return e[n]; 50 | } 51 | 52 | } // namespace internal 53 | RAPIDJSON_NAMESPACE_END 54 | 55 | #endif // RAPIDJSON_POW10_ 56 | -------------------------------------------------------------------------------- /src/third-party/rapidjson-1.1.0/include/rapidjson/internal/strfunc.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_INTERNAL_STRFUNC_H_ 16 | #define RAPIDJSON_INTERNAL_STRFUNC_H_ 17 | 18 | #include "../stream.h" 19 | 20 | RAPIDJSON_NAMESPACE_BEGIN 21 | namespace internal { 22 | 23 | //! Custom strlen() which works on different character types. 24 | /*! \tparam Ch Character type (e.g. char, wchar_t, short) 25 | \param s Null-terminated input string. 26 | \return Number of characters in the string. 27 | \note This has the same semantics as strlen(), the return value is not number of Unicode codepoints. 28 | */ 29 | template 30 | inline SizeType StrLen(const Ch* s) { 31 | const Ch* p = s; 32 | while (*p) ++p; 33 | return SizeType(p - s); 34 | } 35 | 36 | //! Returns number of code points in a encoded string. 37 | template 38 | bool CountStringCodePoint(const typename Encoding::Ch* s, SizeType length, SizeType* outCount) { 39 | GenericStringStream is(s); 40 | const typename Encoding::Ch* end = s + length; 41 | SizeType count = 0; 42 | while (is.src_ < end) { 43 | unsigned codepoint; 44 | if (!Encoding::Decode(is, &codepoint)) 45 | return false; 46 | count++; 47 | } 48 | *outCount = count; 49 | return true; 50 | } 51 | 52 | } // namespace internal 53 | RAPIDJSON_NAMESPACE_END 54 | 55 | #endif // RAPIDJSON_INTERNAL_STRFUNC_H_ 56 | -------------------------------------------------------------------------------- /src/third-party/rapidjson-1.1.0/include/rapidjson/internal/swap.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_INTERNAL_SWAP_H_ 16 | #define RAPIDJSON_INTERNAL_SWAP_H_ 17 | 18 | #include "../rapidjson.h" 19 | 20 | #if defined(__clang__) 21 | RAPIDJSON_DIAG_PUSH 22 | RAPIDJSON_DIAG_OFF(c++98-compat) 23 | #endif 24 | 25 | RAPIDJSON_NAMESPACE_BEGIN 26 | namespace internal { 27 | 28 | //! Custom swap() to avoid dependency on C++ header 29 | /*! \tparam T Type of the arguments to swap, should be instantiated with primitive C++ types only. 30 | \note This has the same semantics as std::swap(). 31 | */ 32 | template 33 | inline void Swap(T& a, T& b) RAPIDJSON_NOEXCEPT { 34 | T tmp = a; 35 | a = b; 36 | b = tmp; 37 | } 38 | 39 | } // namespace internal 40 | RAPIDJSON_NAMESPACE_END 41 | 42 | #if defined(__clang__) 43 | RAPIDJSON_DIAG_POP 44 | #endif 45 | 46 | #endif // RAPIDJSON_INTERNAL_SWAP_H_ 47 | -------------------------------------------------------------------------------- /src/third-party/rapidjson-1.1.0/include/rapidjson/istreamwrapper.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_ISTREAMWRAPPER_H_ 16 | #define RAPIDJSON_ISTREAMWRAPPER_H_ 17 | 18 | #include "stream.h" 19 | #include 20 | 21 | #ifdef __clang__ 22 | RAPIDJSON_DIAG_PUSH 23 | RAPIDJSON_DIAG_OFF(padded) 24 | #endif 25 | 26 | #ifdef _MSC_VER 27 | RAPIDJSON_DIAG_PUSH 28 | RAPIDJSON_DIAG_OFF(4351) // new behavior: elements of array 'array' will be default initialized 29 | #endif 30 | 31 | RAPIDJSON_NAMESPACE_BEGIN 32 | 33 | //! Wrapper of \c std::basic_istream into RapidJSON's Stream concept. 34 | /*! 35 | The classes can be wrapped including but not limited to: 36 | 37 | - \c std::istringstream 38 | - \c std::stringstream 39 | - \c std::wistringstream 40 | - \c std::wstringstream 41 | - \c std::ifstream 42 | - \c std::fstream 43 | - \c std::wifstream 44 | - \c std::wfstream 45 | 46 | \tparam StreamType Class derived from \c std::basic_istream. 47 | */ 48 | 49 | template 50 | class BasicIStreamWrapper { 51 | public: 52 | typedef typename StreamType::char_type Ch; 53 | BasicIStreamWrapper(StreamType& stream) : stream_(stream), count_(), peekBuffer_() {} 54 | 55 | Ch Peek() const { 56 | typename StreamType::int_type c = stream_.peek(); 57 | return RAPIDJSON_LIKELY(c != StreamType::traits_type::eof()) ? static_cast(c) : '\0'; 58 | } 59 | 60 | Ch Take() { 61 | typename StreamType::int_type c = stream_.get(); 62 | if (RAPIDJSON_LIKELY(c != StreamType::traits_type::eof())) { 63 | count_++; 64 | return static_cast(c); 65 | } 66 | else 67 | return '\0'; 68 | } 69 | 70 | // tellg() may return -1 when failed. So we count by ourself. 71 | size_t Tell() const { return count_; } 72 | 73 | Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 74 | void Put(Ch) { RAPIDJSON_ASSERT(false); } 75 | void Flush() { RAPIDJSON_ASSERT(false); } 76 | size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } 77 | 78 | // For encoding detection only. 79 | const Ch* Peek4() const { 80 | RAPIDJSON_ASSERT(sizeof(Ch) == 1); // Only usable for byte stream. 81 | int i; 82 | bool hasError = false; 83 | for (i = 0; i < 4; ++i) { 84 | typename StreamType::int_type c = stream_.get(); 85 | if (c == StreamType::traits_type::eof()) { 86 | hasError = true; 87 | stream_.clear(); 88 | break; 89 | } 90 | peekBuffer_[i] = static_cast(c); 91 | } 92 | for (--i; i >= 0; --i) 93 | stream_.putback(peekBuffer_[i]); 94 | return !hasError ? peekBuffer_ : 0; 95 | } 96 | 97 | private: 98 | BasicIStreamWrapper(const BasicIStreamWrapper&); 99 | BasicIStreamWrapper& operator=(const BasicIStreamWrapper&); 100 | 101 | StreamType& stream_; 102 | size_t count_; //!< Number of characters read. Note: 103 | mutable Ch peekBuffer_[4]; 104 | }; 105 | 106 | typedef BasicIStreamWrapper IStreamWrapper; 107 | typedef BasicIStreamWrapper WIStreamWrapper; 108 | 109 | #if defined(__clang__) || defined(_MSC_VER) 110 | RAPIDJSON_DIAG_POP 111 | #endif 112 | 113 | RAPIDJSON_NAMESPACE_END 114 | 115 | #endif // RAPIDJSON_ISTREAMWRAPPER_H_ 116 | -------------------------------------------------------------------------------- /src/third-party/rapidjson-1.1.0/include/rapidjson/memorybuffer.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_MEMORYBUFFER_H_ 16 | #define RAPIDJSON_MEMORYBUFFER_H_ 17 | 18 | #include "stream.h" 19 | #include "internal/stack.h" 20 | 21 | RAPIDJSON_NAMESPACE_BEGIN 22 | 23 | //! Represents an in-memory output byte stream. 24 | /*! 25 | This class is mainly for being wrapped by EncodedOutputStream or AutoUTFOutputStream. 26 | 27 | It is similar to FileWriteBuffer but the destination is an in-memory buffer instead of a file. 28 | 29 | Differences between MemoryBuffer and StringBuffer: 30 | 1. StringBuffer has Encoding but MemoryBuffer is only a byte buffer. 31 | 2. StringBuffer::GetString() returns a null-terminated string. MemoryBuffer::GetBuffer() returns a buffer without terminator. 32 | 33 | \tparam Allocator type for allocating memory buffer. 34 | \note implements Stream concept 35 | */ 36 | template 37 | struct GenericMemoryBuffer { 38 | typedef char Ch; // byte 39 | 40 | GenericMemoryBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {} 41 | 42 | void Put(Ch c) { *stack_.template Push() = c; } 43 | void Flush() {} 44 | 45 | void Clear() { stack_.Clear(); } 46 | void ShrinkToFit() { stack_.ShrinkToFit(); } 47 | Ch* Push(size_t count) { return stack_.template Push(count); } 48 | void Pop(size_t count) { stack_.template Pop(count); } 49 | 50 | const Ch* GetBuffer() const { 51 | return stack_.template Bottom(); 52 | } 53 | 54 | size_t GetSize() const { return stack_.GetSize(); } 55 | 56 | static const size_t kDefaultCapacity = 256; 57 | mutable internal::Stack stack_; 58 | }; 59 | 60 | typedef GenericMemoryBuffer<> MemoryBuffer; 61 | 62 | //! Implement specialized version of PutN() with memset() for better performance. 63 | template<> 64 | inline void PutN(MemoryBuffer& memoryBuffer, char c, size_t n) { 65 | std::memset(memoryBuffer.stack_.Push(n), c, n * sizeof(c)); 66 | } 67 | 68 | RAPIDJSON_NAMESPACE_END 69 | 70 | #endif // RAPIDJSON_MEMORYBUFFER_H_ 71 | -------------------------------------------------------------------------------- /src/third-party/rapidjson-1.1.0/include/rapidjson/memorystream.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_MEMORYSTREAM_H_ 16 | #define RAPIDJSON_MEMORYSTREAM_H_ 17 | 18 | #include "stream.h" 19 | 20 | #ifdef __clang__ 21 | RAPIDJSON_DIAG_PUSH 22 | RAPIDJSON_DIAG_OFF(unreachable-code) 23 | RAPIDJSON_DIAG_OFF(missing-noreturn) 24 | #endif 25 | 26 | RAPIDJSON_NAMESPACE_BEGIN 27 | 28 | //! Represents an in-memory input byte stream. 29 | /*! 30 | This class is mainly for being wrapped by EncodedInputStream or AutoUTFInputStream. 31 | 32 | It is similar to FileReadBuffer but the source is an in-memory buffer instead of a file. 33 | 34 | Differences between MemoryStream and StringStream: 35 | 1. StringStream has encoding but MemoryStream is a byte stream. 36 | 2. MemoryStream needs size of the source buffer and the buffer don't need to be null terminated. StringStream assume null-terminated string as source. 37 | 3. MemoryStream supports Peek4() for encoding detection. StringStream is specified with an encoding so it should not have Peek4(). 38 | \note implements Stream concept 39 | */ 40 | struct MemoryStream { 41 | typedef char Ch; // byte 42 | 43 | MemoryStream(const Ch *src, size_t size) : src_(src), begin_(src), end_(src + size), size_(size) {} 44 | 45 | Ch Peek() const { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_; } 46 | Ch Take() { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_++; } 47 | size_t Tell() const { return static_cast(src_ - begin_); } 48 | 49 | Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 50 | void Put(Ch) { RAPIDJSON_ASSERT(false); } 51 | void Flush() { RAPIDJSON_ASSERT(false); } 52 | size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } 53 | 54 | // For encoding detection only. 55 | const Ch* Peek4() const { 56 | return Tell() + 4 <= size_ ? src_ : 0; 57 | } 58 | 59 | const Ch* src_; //!< Current read position. 60 | const Ch* begin_; //!< Original head of the string. 61 | const Ch* end_; //!< End of stream. 62 | size_t size_; //!< Size of the stream. 63 | }; 64 | 65 | RAPIDJSON_NAMESPACE_END 66 | 67 | #ifdef __clang__ 68 | RAPIDJSON_DIAG_POP 69 | #endif 70 | 71 | #endif // RAPIDJSON_MEMORYBUFFER_H_ 72 | -------------------------------------------------------------------------------- /src/third-party/rapidjson-1.1.0/include/rapidjson/ostreamwrapper.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_OSTREAMWRAPPER_H_ 16 | #define RAPIDJSON_OSTREAMWRAPPER_H_ 17 | 18 | #include "stream.h" 19 | #include 20 | 21 | #ifdef __clang__ 22 | RAPIDJSON_DIAG_PUSH 23 | RAPIDJSON_DIAG_OFF(padded) 24 | #endif 25 | 26 | RAPIDJSON_NAMESPACE_BEGIN 27 | 28 | //! Wrapper of \c std::basic_ostream into RapidJSON's Stream concept. 29 | /*! 30 | The classes can be wrapped including but not limited to: 31 | 32 | - \c std::ostringstream 33 | - \c std::stringstream 34 | - \c std::wpstringstream 35 | - \c std::wstringstream 36 | - \c std::ifstream 37 | - \c std::fstream 38 | - \c std::wofstream 39 | - \c std::wfstream 40 | 41 | \tparam StreamType Class derived from \c std::basic_ostream. 42 | */ 43 | 44 | template 45 | class BasicOStreamWrapper { 46 | public: 47 | typedef typename StreamType::char_type Ch; 48 | BasicOStreamWrapper(StreamType& stream) : stream_(stream) {} 49 | 50 | void Put(Ch c) { 51 | stream_.put(c); 52 | } 53 | 54 | void Flush() { 55 | stream_.flush(); 56 | } 57 | 58 | // Not implemented 59 | char Peek() const { RAPIDJSON_ASSERT(false); return 0; } 60 | char Take() { RAPIDJSON_ASSERT(false); return 0; } 61 | size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } 62 | char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 63 | size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; } 64 | 65 | private: 66 | BasicOStreamWrapper(const BasicOStreamWrapper&); 67 | BasicOStreamWrapper& operator=(const BasicOStreamWrapper&); 68 | 69 | StreamType& stream_; 70 | }; 71 | 72 | typedef BasicOStreamWrapper OStreamWrapper; 73 | typedef BasicOStreamWrapper WOStreamWrapper; 74 | 75 | #ifdef __clang__ 76 | RAPIDJSON_DIAG_POP 77 | #endif 78 | 79 | RAPIDJSON_NAMESPACE_END 80 | 81 | #endif // RAPIDJSON_OSTREAMWRAPPER_H_ 82 | -------------------------------------------------------------------------------- /src/third-party/rapidjson-1.1.0/include/rapidjson/stream.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #include "rapidjson.h" 16 | 17 | #ifndef RAPIDJSON_STREAM_H_ 18 | #define RAPIDJSON_STREAM_H_ 19 | 20 | #include "encodings.h" 21 | 22 | RAPIDJSON_NAMESPACE_BEGIN 23 | 24 | /////////////////////////////////////////////////////////////////////////////// 25 | // Stream 26 | 27 | /*! \class rapidjson::Stream 28 | \brief Concept for reading and writing characters. 29 | 30 | For read-only stream, no need to implement PutBegin(), Put(), Flush() and PutEnd(). 31 | 32 | For write-only stream, only need to implement Put() and Flush(). 33 | 34 | \code 35 | concept Stream { 36 | typename Ch; //!< Character type of the stream. 37 | 38 | //! Read the current character from stream without moving the read cursor. 39 | Ch Peek() const; 40 | 41 | //! Read the current character from stream and moving the read cursor to next character. 42 | Ch Take(); 43 | 44 | //! Get the current read cursor. 45 | //! \return Number of characters read from start. 46 | size_t Tell(); 47 | 48 | //! Begin writing operation at the current read pointer. 49 | //! \return The begin writer pointer. 50 | Ch* PutBegin(); 51 | 52 | //! Write a character. 53 | void Put(Ch c); 54 | 55 | //! Flush the buffer. 56 | void Flush(); 57 | 58 | //! End the writing operation. 59 | //! \param begin The begin write pointer returned by PutBegin(). 60 | //! \return Number of characters written. 61 | size_t PutEnd(Ch* begin); 62 | } 63 | \endcode 64 | */ 65 | 66 | //! Provides additional information for stream. 67 | /*! 68 | By using traits pattern, this type provides a default configuration for stream. 69 | For custom stream, this type can be specialized for other configuration. 70 | See TEST(Reader, CustomStringStream) in readertest.cpp for example. 71 | */ 72 | template 73 | struct StreamTraits { 74 | //! Whether to make local copy of stream for optimization during parsing. 75 | /*! 76 | By default, for safety, streams do not use local copy optimization. 77 | Stream that can be copied fast should specialize this, like StreamTraits. 78 | */ 79 | enum { copyOptimization = 0 }; 80 | }; 81 | 82 | //! Reserve n characters for writing to a stream. 83 | template 84 | inline void PutReserve(Stream& stream, size_t count) { 85 | (void)stream; 86 | (void)count; 87 | } 88 | 89 | //! Write character to a stream, presuming buffer is reserved. 90 | template 91 | inline void PutUnsafe(Stream& stream, typename Stream::Ch c) { 92 | stream.Put(c); 93 | } 94 | 95 | //! Put N copies of a character to a stream. 96 | template 97 | inline void PutN(Stream& stream, Ch c, size_t n) { 98 | PutReserve(stream, n); 99 | for (size_t i = 0; i < n; i++) 100 | PutUnsafe(stream, c); 101 | } 102 | 103 | /////////////////////////////////////////////////////////////////////////////// 104 | // StringStream 105 | 106 | //! Read-only string stream. 107 | /*! \note implements Stream concept 108 | */ 109 | template 110 | struct GenericStringStream { 111 | typedef typename Encoding::Ch Ch; 112 | 113 | GenericStringStream(const Ch *src) : src_(src), head_(src) {} 114 | 115 | Ch Peek() const { return *src_; } 116 | Ch Take() { return *src_++; } 117 | size_t Tell() const { return static_cast(src_ - head_); } 118 | 119 | Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 120 | void Put(Ch) { RAPIDJSON_ASSERT(false); } 121 | void Flush() { RAPIDJSON_ASSERT(false); } 122 | size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } 123 | 124 | const Ch* src_; //!< Current read position. 125 | const Ch* head_; //!< Original head of the string. 126 | }; 127 | 128 | template 129 | struct StreamTraits > { 130 | enum { copyOptimization = 1 }; 131 | }; 132 | 133 | //! String stream with UTF8 encoding. 134 | typedef GenericStringStream > StringStream; 135 | 136 | /////////////////////////////////////////////////////////////////////////////// 137 | // InsituStringStream 138 | 139 | //! A read-write string stream. 140 | /*! This string stream is particularly designed for in-situ parsing. 141 | \note implements Stream concept 142 | */ 143 | template 144 | struct GenericInsituStringStream { 145 | typedef typename Encoding::Ch Ch; 146 | 147 | GenericInsituStringStream(Ch *src) : src_(src), dst_(0), head_(src) {} 148 | 149 | // Read 150 | Ch Peek() { return *src_; } 151 | Ch Take() { return *src_++; } 152 | size_t Tell() { return static_cast(src_ - head_); } 153 | 154 | // Write 155 | void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; } 156 | 157 | Ch* PutBegin() { return dst_ = src_; } 158 | size_t PutEnd(Ch* begin) { return static_cast(dst_ - begin); } 159 | void Flush() {} 160 | 161 | Ch* Push(size_t count) { Ch* begin = dst_; dst_ += count; return begin; } 162 | void Pop(size_t count) { dst_ -= count; } 163 | 164 | Ch* src_; 165 | Ch* dst_; 166 | Ch* head_; 167 | }; 168 | 169 | template 170 | struct StreamTraits > { 171 | enum { copyOptimization = 1 }; 172 | }; 173 | 174 | //! Insitu string stream with UTF8 encoding. 175 | typedef GenericInsituStringStream > InsituStringStream; 176 | 177 | RAPIDJSON_NAMESPACE_END 178 | 179 | #endif // RAPIDJSON_STREAM_H_ 180 | -------------------------------------------------------------------------------- /src/third-party/rapidjson-1.1.0/include/rapidjson/stringbuffer.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_STRINGBUFFER_H_ 16 | #define RAPIDJSON_STRINGBUFFER_H_ 17 | 18 | #include "stream.h" 19 | #include "internal/stack.h" 20 | 21 | #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 22 | #include // std::move 23 | #endif 24 | 25 | #include "internal/stack.h" 26 | 27 | #if defined(__clang__) 28 | RAPIDJSON_DIAG_PUSH 29 | RAPIDJSON_DIAG_OFF(c++98-compat) 30 | #endif 31 | 32 | RAPIDJSON_NAMESPACE_BEGIN 33 | 34 | //! Represents an in-memory output stream. 35 | /*! 36 | \tparam Encoding Encoding of the stream. 37 | \tparam Allocator type for allocating memory buffer. 38 | \note implements Stream concept 39 | */ 40 | template 41 | class GenericStringBuffer { 42 | public: 43 | typedef typename Encoding::Ch Ch; 44 | 45 | GenericStringBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {} 46 | 47 | #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 48 | GenericStringBuffer(GenericStringBuffer&& rhs) : stack_(std::move(rhs.stack_)) {} 49 | GenericStringBuffer& operator=(GenericStringBuffer&& rhs) { 50 | if (&rhs != this) 51 | stack_ = std::move(rhs.stack_); 52 | return *this; 53 | } 54 | #endif 55 | 56 | void Put(Ch c) { *stack_.template Push() = c; } 57 | void PutUnsafe(Ch c) { *stack_.template PushUnsafe() = c; } 58 | void Flush() {} 59 | 60 | void Clear() { stack_.Clear(); } 61 | void ShrinkToFit() { 62 | // Push and pop a null terminator. This is safe. 63 | *stack_.template Push() = '\0'; 64 | stack_.ShrinkToFit(); 65 | stack_.template Pop(1); 66 | } 67 | 68 | void Reserve(size_t count) { stack_.template Reserve(count); } 69 | Ch* Push(size_t count) { return stack_.template Push(count); } 70 | Ch* PushUnsafe(size_t count) { return stack_.template PushUnsafe(count); } 71 | void Pop(size_t count) { stack_.template Pop(count); } 72 | 73 | const Ch* GetString() const { 74 | // Push and pop a null terminator. This is safe. 75 | *stack_.template Push() = '\0'; 76 | stack_.template Pop(1); 77 | 78 | return stack_.template Bottom(); 79 | } 80 | 81 | size_t GetSize() const { return stack_.GetSize(); } 82 | 83 | static const size_t kDefaultCapacity = 256; 84 | mutable internal::Stack stack_; 85 | 86 | private: 87 | // Prohibit copy constructor & assignment operator. 88 | GenericStringBuffer(const GenericStringBuffer&); 89 | GenericStringBuffer& operator=(const GenericStringBuffer&); 90 | }; 91 | 92 | //! String buffer with UTF8 encoding 93 | typedef GenericStringBuffer > StringBuffer; 94 | 95 | template 96 | inline void PutReserve(GenericStringBuffer& stream, size_t count) { 97 | stream.Reserve(count); 98 | } 99 | 100 | template 101 | inline void PutUnsafe(GenericStringBuffer& stream, typename Encoding::Ch c) { 102 | stream.PutUnsafe(c); 103 | } 104 | 105 | //! Implement specialized version of PutN() with memset() for better performance. 106 | template<> 107 | inline void PutN(GenericStringBuffer >& stream, char c, size_t n) { 108 | std::memset(stream.stack_.Push(n), c, n * sizeof(c)); 109 | } 110 | 111 | RAPIDJSON_NAMESPACE_END 112 | 113 | #if defined(__clang__) 114 | RAPIDJSON_DIAG_POP 115 | #endif 116 | 117 | #endif // RAPIDJSON_STRINGBUFFER_H_ 118 | -------------------------------------------------------------------------------- /src/third-party/rapidjson-1.1.0/license.txt: -------------------------------------------------------------------------------- 1 | Tencent is pleased to support the open source community by making RapidJSON available. 2 | 3 | Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | 5 | If you have downloaded a copy of the RapidJSON binary from Tencent, please note that the RapidJSON binary is licensed under the MIT License. 6 | If you have downloaded a copy of the RapidJSON source code from Tencent, please note that RapidJSON source code is licensed under the MIT License, except for the third-party components listed below which are subject to different license terms. Your integration of RapidJSON into your own projects may require compliance with the MIT License, as well as the other licenses applicable to the third-party components included within RapidJSON. To avoid the problematic JSON license in your own projects, it's sufficient to exclude the bin/jsonchecker/ directory, as it's the only code under the JSON license. 7 | A copy of the MIT License is included in this file. 8 | 9 | Other dependencies and licenses: 10 | 11 | Open Source Software Licensed Under the BSD License: 12 | -------------------------------------------------------------------- 13 | 14 | The msinttypes r29 15 | Copyright (c) 2006-2013 Alexander Chemeris 16 | All rights reserved. 17 | 18 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 19 | 20 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 21 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 22 | * Neither the name of copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 23 | 24 | THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | Open Source Software Licensed Under the JSON License: 27 | -------------------------------------------------------------------- 28 | 29 | json.org 30 | Copyright (c) 2002 JSON.org 31 | All Rights Reserved. 32 | 33 | JSON_checker 34 | Copyright (c) 2002 JSON.org 35 | All Rights Reserved. 36 | 37 | 38 | Terms of the JSON License: 39 | --------------------------------------------------- 40 | 41 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 42 | 43 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 44 | 45 | The Software shall be used for Good, not Evil. 46 | 47 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 48 | 49 | 50 | Terms of the MIT License: 51 | -------------------------------------------------------------------- 52 | 53 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 54 | 55 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 56 | 57 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 58 | --------------------------------------------------------------------------------