-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathdocumentdb_schema.cpp
More file actions
65 lines (53 loc) · 1.69 KB
/
Copy pathdocumentdb_schema.cpp
File metadata and controls
65 lines (53 loc) · 1.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include "documentdb/documentdb.hpp"
#include "yyjson.hpp"
#include <string>
#include <unordered_map>
#include <vector>
using namespace duckdb_yyjson;
namespace documentdb {
namespace {
std::string infer_value_type(yyjson_val* value) {
if (yyjson_is_bool(value)) {
return "BOOLEAN";
}
if (yyjson_is_int(value) || yyjson_is_uint(value)) {
return "BIGINT";
}
if (yyjson_is_real(value)) {
return "DOUBLE";
}
if (yyjson_is_str(value) || yyjson_is_null(value)) {
return "VARCHAR";
}
return "VARCHAR";
}
} // namespace
std::vector<FieldType> SchemaResolver::infer_from_samples(const std::vector<std::string>& samples) {
std::vector<FieldType> fields;
std::unordered_map<std::string, std::string> inferred;
for (const std::string& sample : samples) {
yyjson_doc* document = yyjson_read(sample.data(), sample.size(), 0);
if (document == nullptr || !yyjson_is_obj(yyjson_doc_get_root(document))) {
yyjson_doc_free(document);
continue;
}
size_t index, max;
yyjson_val* key;
yyjson_val* value;
yyjson_obj_foreach(yyjson_doc_get_root(document), index, max, key, value) {
std::string field_name(yyjson_get_str(key), yyjson_get_len(key));
if (inferred.find(field_name) == inferred.end()) {
inferred[field_name] = infer_value_type(value);
}
}
yyjson_doc_free(document);
}
for (const auto& entry : inferred) {
fields.push_back({entry.first, entry.second});
}
if (fields.empty()) {
fields.push_back({"_id", "VARCHAR"});
}
return fields;
}
} // namespace documentdb