Commit f41f2731 authored by yiwenshao's avatar yiwenshao

add comments

parent d1e79c9a
......@@ -3,8 +3,8 @@
#oAGG: HOM
#oASHE: ASHE
[onions for num]
oDET: DETJOIN DET RND
#oOPE: OPE
oDET: DET RND
oOPE: OPE RND
#oAGG: HOM
#oASHE: ASHE
......
......@@ -904,19 +904,18 @@ do_optimize_const_item(T *i, Analysis &a) {
}
//层次化的解密
//Layers of decryption
static Item *
decrypt_item_layers(const Item &i, const FieldMeta *const fm, onion o,
uint64_t IV)
{
assert(!RiboldMYSQL::is_null(i));
const Item *dec = &i;
Item *out_i = NULL;
//有fieldmeta但是不用全部, 只用其中的一个onionMeta, 这个根据OLK的o来选择.
//fieldmeta is used to fetch the onionmeta wanted. The onionmeta choosen is specified by OLK.
const OnionMeta *const om = fm->getOnionMeta(o);
assert(om);
//onionmeta的使用方法很简单, getlayers, 然后层层使用.
//once we have onionmeta,we can use getlayers to fetch the encryption layers for data decryption.
const auto &enc_layers = om->getLayers();
for (auto it = enc_layers.rbegin(); it != enc_layers.rend(); ++it) {
if(o==oASHE) {
......@@ -928,7 +927,6 @@ decrypt_item_layers(const Item &i, const FieldMeta *const fm, onion o,
dec = out_i;
LOG(cdb_v) << "dec okay";
}
assert(out_i && out_i != &i);
return out_i;
}
......@@ -1462,8 +1460,7 @@ Rewriter::decryptResults(const ResType &dbres, const ReturnMeta &rmeta)
}
col_index++;
}
//加密和解密之前之后, 用的都是ResType类型.通过这个解密函数的操作.
//ResType is used before encryption and after decryption.
return ResType(dbres.ok, dbres.affected_rows, dbres.insert_id,
std::move(dec_names),
std::vector<enum_field_types>(dbres.types),
......
......@@ -186,22 +186,18 @@ collectKeyData(const LEX &lex)
// and avoid this chaining and passing f as an argument
static Create_field *
get_create_field(const Analysis &a, Create_field * const f,
const OnionMeta &om)
{
const OnionMeta &om) {
const std::string name = om.getAnonOnionName();
Create_field *new_cf = f;
// Default value is handled during INSERTion.
auto save_default = f->def;
f->def = nullptr;
const auto &enc_layers = a.getEncLayers(om);
assert(enc_layers.size() > 0);
for (const auto &it : enc_layers) {
const Create_field * const old_cf = new_cf;
new_cf = it->newCreateField(*old_cf, name);
}
// Restore the default so we don't memleak it.
f->def = save_default;
return new_cf;
......@@ -211,18 +207,13 @@ get_create_field(const Analysis &a, Create_field * const f,
// as such is handled during INSERTion.
std::vector<Create_field *>
rewrite_create_field(const FieldMeta * const fm,
Create_field * const f, const Analysis &a)
{
Create_field * const f, const Analysis &a) {
LOG(cdb_v) << "in rewrite create field for " << *f;
assert(fm->getChildren().size() > 0);
std::vector<Create_field *> output_cfields;
// Don't add the default value to the schema.
Item *const save_def = f->def;
f->def = NULL;
// create each onion column
for (auto oit : fm->orderedOnionMetas()) {
OnionMeta * const om = oit.second;
......@@ -230,7 +221,6 @@ rewrite_create_field(const FieldMeta * const fm,
output_cfields.push_back(new_cf);
}
// create salt column
if (fm->getHasSalt()) {
THD * const thd = current_thd;
......@@ -242,15 +232,12 @@ rewrite_create_field(const FieldMeta * const fm,
& ~AUTO_INCREMENT_FLAG;
f0->sql_type = MYSQL_TYPE_LONGLONG;
f0->length = 8;
output_cfields.push_back(f0);
}
// Restore the default to the original Create_field parameter.
f->def = save_def;
//for(auto item:output_cfields){
//}
return output_cfields;
}
......@@ -266,90 +253,17 @@ getOriginalKeyName(const Key &key)
if (Key::PRIMARY == key.type) {
return "PRIMARY";
}
std::string out_name = convert_lex_str(key.name);
//TEST_TextMessageError(out_name.size() > 0,
// "Non-Primary keys can not have blank name!");
if(out_name.size()==0){
out_name="nonekey";
}
return out_name;
}
/*
static std::vector<Key *>
rewrite_key(const TableMeta &tm, const Key &key, const Analysis &a)
{
std::vector<Key *> output_keys;
//从左到右分别是三种类型: oOPE, oDET, oPLAIN, 对于每个语句的index都是这样
//比如自己要alter table add 的index, 其对应index的名字, 以及相关的column信息
//比如create的时候, 产生的index, 其对应的名字以及相关的columns, 这样包含在key里面了
const std::vector<onion> key_onions = getOnionIndexTypes();
for (auto onion_it : key_onions) {
const onion o = onion_it;
THD* cthd = current_thd;
//原始key的拷贝
Key *const new_key = key.clone(cthd->mem_root);
//通过key的原始名字+onion+tm哈希获得新的key名字,用的是std::hash<string>算法.
// Set anonymous name.
const std::string new_name =
a.getAnonIndexName(tm, getOriginalKeyName(key), o);
//设置key的新名字, 以及新的key对应的column清空??
new_key->name = string_to_lex_str(new_name);
new_key->columns.empty();
//遍历原始的key的columns, 改写, 变成新key的colukns
// Set anonymous columns.
auto col_it =
RiboldMYSQL::constList_iterator<Key_part_spec>(key.columns);
for (;;) {
const Key_part_spec *const key_part = col_it++;
if (NULL == key_part) {
output_keys.push_back(new_key);
break;
}
//复制一个column信息
Key_part_spec *const new_key_part = copyWithTHD(key_part);
//原始的key_part, 也就是一个column, 里面取一个field_name出来
const std::string field_name =
convert_lex_str(new_key_part->field_name);
//通过column查tablemeta, 然后差当前的onion在不在那个tablemeta里面
// > the onion may not exist; ie oPLAIN with SENSITIVE and not
// an AUTO INCREMENT column
const FieldMeta &fm = a.getFieldMeta(tm, field_name);
const OnionMeta *const om = fm.getOnionMeta(o);
if (NULL == om) {
break;
}
//如果存在, 那么新的column的名字就是洋葱的名字, 然后new_key的column就确定了
//可以看到, 对于索引里面的每个field, 都选择一个洋葱, 如果没有合适的, 则不选择.
new_key_part->field_name =
string_to_lex_str(om->getAnonOnionName());
new_key->columns.push_back(new_key_part);
}
}
//上面, 对于一个key来说, 可以查三个洋葱
//对于每个洋葱,都可能构造一个key, 这是根据这个key对应的columns里面有没有洋葱, 有则选进来. 所以, 列扩展了以后, 索引也扩展了.
//主键特殊处理, 之根据一个洋葱构造.
// Only create one PRIMARY KEY.
if (Key::PRIMARY == key.type) {
if (output_keys.size() > 0) {
return std::vector<Key *>({output_keys.front()});
}
}
return output_keys;
}
*/
/*
only rewrite normal keys here, do not process foreign keys.
*/
static std::vector<Key *>
rewrite_key1(const TableMeta &tm, const Key &key, const Analysis &a){
......@@ -362,26 +276,19 @@ rewrite_key1(const TableMeta &tm, const Key &key, const Analysis &a){
output_keys.push_back(new_key);
return output_keys;
}
//从左到右分别是三种类型: oOPE, oDET, oPLAIN, 对于每个语句的index都是这样
//比如自己要alter table add 的index, 其对应index的名字, 以及相关的column信息
//比如create的时候, 产生的index, 其对应的名字以及相关的columns, 这样包含在key里面了
//key_onions is oOPE,oDET,oPLAIN from left to right.
const std::vector<onion> key_onions = getOnionIndexTypes();
for (auto onion_it : key_onions) {
const onion o = onion_it;
THD* cthd = current_thd;
//原始key的拷贝
Key *const new_key = key.clone(cthd->mem_root);
//通过key的原始名字+onion+tm哈希获得新的key名字,用的是std::hash<string>算法.
// Set anonymous name.
// Set anonymous key name.
const std::string new_name =
a.getAnonIndexName(tm, getOriginalKeyName(key), o);
//设置key的新名字, 以及新的key对应的column清空??
new_key->name = string_to_lex_str(new_name);
new_key->columns.empty();
//遍历原始的key的columns, 改写, 变成新key的colukns
// Set anonymous columns.
// Set anonymous columns for the key columns
auto col_it =
RiboldMYSQL::constList_iterator<Key_part_spec>(key.columns);
for (;;) {
......@@ -390,30 +297,23 @@ rewrite_key1(const TableMeta &tm, const Key &key, const Analysis &a){
output_keys.push_back(new_key);
break;
}
//复制一个column信息
Key_part_spec *const new_key_part = copyWithTHD(key_part);
//原始的key_part, 也就是一个column, 里面取一个field_name出来
//key_part is a column, and the field_name could be fetched.
const std::string field_name =
convert_lex_str(new_key_part->field_name);
//通过column查tablemeta, 然后差当前的onion在不在那个tablemeta里面
// > the onion may not exist; ie oPLAIN with SENSITIVE and not
// an AUTO INCREMENT column
const FieldMeta &fm = a.getFieldMeta(tm, field_name);
const OnionMeta *const om = fm.getOnionMeta(o);
if (NULL == om) {
break;
}
//如果存在, 那么新的column的名字就是洋葱的名字, 然后new_key的column就确定了
//可以看到, 对于索引里面的每个field, 都选择一个洋葱, 如果没有合适的, 则不选择.
//if the field has the onion that is in the key_onion, then set the key name. otherwise the key name will not be set.
new_key_part->field_name =
string_to_lex_str(om->getAnonOnionName());
new_key->columns.push_back(new_key_part);
}
}
//上面, 对于一个key来说, 可以查三个洋葱
//对于每个洋葱,都可能构造一个key, 这是根据这个key对应的columns里面有没有洋葱, 有则选进来. 所以, 列扩展了以后, 索引也扩展了.
//主键特殊处理, 之根据一个洋葱构造.
// for normal index, the key column is also expanded.
// Only create one PRIMARY KEY.
if (Key::PRIMARY == key.type) {
if (output_keys.size() > 0) {
......@@ -735,7 +635,7 @@ retrieveDefaultDatabase(unsigned long long thread_id,
out_name->clear();
std::unique_ptr<DBResult> dbres;
//这里是多行的字符串.
//multiple lines of strings.
const std::string &query =
" SELECT db FROM INFORMATION_SCHEMA.PROCESSLIST"
" WHERE id = " + std::to_string(thread_id) + ";";
......
#include <algorithm>
#include <functional>
#include <memory>
#include <parser/lex_util.hh>
#include <parser/stringify.hh>
#include <parser/mysql_type_metadata.hh>
......@@ -11,7 +10,6 @@
#include <main/dbobject.hh>
#include <main/metadata_tables.hh>
#include <main/macro_util.hh>
#include "util/onions.hh"
/*
......@@ -62,9 +60,6 @@ DBMeta::doFetchChildren(const std::unique_ptr<Connect> &e_conn,
}
return out_vec;
}
//new onion, 这里的uniq_count是通过fieldMeta获得的, 本身没有集成UniqueCounter.
OnionMeta::OnionMeta(onion o, std::vector<SECLEVEL> levels,
const AES_KEY * const m_key,
const Create_field &cf, unsigned long uniq_count,
......@@ -72,7 +67,6 @@ OnionMeta::OnionMeta(onion o, std::vector<SECLEVEL> levels,
: onionname(getpRandomName() + TypeText<onion>::toText(o)),
uniq_count(uniq_count), minimum_seclevel(minimum_seclevel) {
assert(levels.size() >= 1);
const Create_field * newcf = &cf;
//generate enclayers for encrypted field
const std::string uniqueFieldName = this->getAnonOnionName();
......@@ -91,31 +85,19 @@ OnionMeta::OnionMeta(onion o, std::vector<SECLEVEL> levels,
assert(this->layers.size() >= 1);
}
//onionmeta解序列化
std::unique_ptr<OnionMeta>
OnionMeta::deserialize(unsigned int id, const std::string &serial)
{
OnionMeta::deserialize(unsigned int id, const std::string &serial){
assert(id != 0);
const auto vec = unserialize_string(serial);
//OnionMeta序列化的结果有三个.
assert(3 == vec.size());
//名字
const std::string onionname = vec[0];
//count
const unsigned int uniq_count = atoi(vec[1].c_str());
//level
const SECLEVEL minimum_seclevel = TypeText<SECLEVEL>::toType(vec[2]);
//在什么位置调用的, id应该是查表获得的id, 为什么需要unique_count?
return std::unique_ptr<OnionMeta>
(new OnionMeta(id, onionname, uniq_count, minimum_seclevel));
}
//序列化的结果
std::string OnionMeta::serialize(const DBObject &parent) const
{
//就是名字,count,以及level分别转换成字符串, 然后用字符串序列化的方法来保存.对于onionmeta,注意name
std::string OnionMeta::serialize(const DBObject &parent) const{
const std::string &serial =
serialize_string(this->onionname) +
serialize_string(std::to_string(this->uniq_count)) +
......@@ -123,14 +105,12 @@ std::string OnionMeta::serialize(const DBObject &parent) const
return serial;
}
std::string OnionMeta::getAnonOnionName() const
{
std::string OnionMeta::getAnonOnionName() const{
return onionname;
}
std::vector<DBMeta *>
OnionMeta::fetchChildren(const std::unique_ptr<Connect> &e_conn)
{
OnionMeta::fetchChildren(const std::unique_ptr<Connect> &e_conn){
std::function<DBMeta *(const std::string &,
const std::string &,
const std::string &)>
......@@ -153,25 +133,21 @@ OnionMeta::fetchChildren(const std::unique_ptr<Connect> &e_conn)
this->layers[index] = std::move(layer);
return this->layers[index].get();
};
return DBMeta::doFetchChildren(e_conn, deserialHelper);
}
//this applyTochildren is different from that of MappedMetadata because Enclayer is stored as vector.
bool
OnionMeta::applyToChildren(std::function<bool(const DBMeta &)>
fn) const
{
fn) const{
for (const auto &it : layers) {
if (false == fn(*it.get())) {
return false;
}
}
return true;
}
UIntMetaKey const &OnionMeta::getKey(const DBMeta &child) const
{
UIntMetaKey const &OnionMeta::getKey(const DBMeta &child) const{
for (std::vector<EncLayer *>::size_type i = 0; i< layers.size(); ++i) {
if (&child == layers[i].get()) {
UIntMetaKey *const key = new UIntMetaKey(i);
......@@ -181,41 +157,33 @@ UIntMetaKey const &OnionMeta::getKey(const DBMeta &child) const
return *key;
}
}
assert(false);
}
EncLayer *OnionMeta::getLayerBack() const
{
EncLayer *OnionMeta::getLayerBack() const{
TEST_TextMessageError(layers.size() != 0,
"Tried getting EncLayer when there are none!");
return layers.back().get();
}
bool OnionMeta::hasEncLayer(const SECLEVEL &sl) const
{
bool OnionMeta::hasEncLayer(const SECLEVEL &sl) const{
for (const auto &it : layers) {
if (it->level() == sl) {
return true;
}
}
return false;
}
EncLayer *OnionMeta::getLayer(const SECLEVEL &sl) const
{
EncLayer *OnionMeta::getLayer(const SECLEVEL &sl) const{
TEST_TextMessageError(layers.size() != 0,
"Tried getting EncLayer when there are none!");
AssignOnce<EncLayer *> out;
for (const auto &it : layers) {
if (it->level() == sl) {
out = it.get();
}
}
assert(out.assigned());
return out.get();
}
......@@ -231,7 +199,6 @@ FieldMeta::deserialize(unsigned int id, const std::string &serial) {
assert(id != 0);
const auto vec = unserialize_string(serial);
assert(10 == vec.size());//We add one item,so there are ten items now
const std::string fname = vec[0];
const bool has_salt = string_to_bool(vec[1]);
const std::string salt_name = vec[2];
......@@ -242,10 +209,7 @@ FieldMeta::deserialize(unsigned int id, const std::string &serial) {
const unsigned int counter = atoi(vec[6].c_str());
const bool has_default = string_to_bool(vec[7]);
const std::string default_value = vec[8];
enum enum_field_types sql_type = ((enum enum_field_types)atoi(vec[9].c_str()));//new field added
return std::unique_ptr<FieldMeta>
(new FieldMeta(id, fname, has_salt, salt_name, onion_layout,
sec_rating, uniq_count, counter, has_default,
......@@ -255,12 +219,10 @@ FieldMeta::deserialize(unsigned int id, const std::string &serial) {
// first element is the levels that the onionmeta should implement
// second element is the minimum level that should be gone down too
static std::pair<std::vector<SECLEVEL>, SECLEVEL>
determineSecLevelData(onion o, std::vector<SECLEVEL> levels, bool unique)
{
determineSecLevelData(onion o, std::vector<SECLEVEL> levels, bool unique){
if (false == unique) {
return std::make_pair(levels, levels.front());
}
// the oDET onion should start at DET and stay at DET
if (oDET == o) {
assert(SECLEVEL::RND == levels.back());
......@@ -268,7 +230,6 @@ determineSecLevelData(onion o, std::vector<SECLEVEL> levels, bool unique)
assert(SECLEVEL::DET == levels.back());
return std::make_pair(levels, levels.front());
}
// oPLAIN may be starting at PLAINVAL if we have an autoincrement column
if (oPLAIN == o) {
assert(SECLEVEL::PLAINVAL == levels.back()
......@@ -290,27 +251,22 @@ determineSecLevelData(onion o, std::vector<SECLEVEL> levels, bool unique)
// If mkey == NULL, the field is not encrypted
static bool
init_onions_layout(const AES_KEY *const m_key, FieldMeta *const fm,
const Create_field &cf, bool unique)
{
const Create_field &cf, bool unique){
const onionlayout onion_layout = fm->getOnionLayout();
if (fm->getHasSalt() != (static_cast<bool>(m_key)
&& PLAIN_ONION_LAYOUT != onion_layout)) {
return false;
}
if (0 != fm->getChildren().size()) {
return false;
}
for (auto it: onion_layout) {
const onion o = it.first;
const std::vector<SECLEVEL> &levels = it.second;
assert(levels.size() >= 1);
const std::pair<std::vector<SECLEVEL>, SECLEVEL> level_data =
determineSecLevelData(o, levels, unique);
assert(level_data.first.size() >= 1);
// A new OnionMeta will only occur with a new FieldMeta so
// we never have to build Deltaz for our OnionMetaz.
std::unique_ptr<OnionMeta>
......@@ -345,8 +301,7 @@ FieldMeta::FieldMeta(const Create_field &field,
"Failed to build onions for new FieldMeta!");
}
std::string FieldMeta::serialize(const DBObject &parent) const
{
std::string FieldMeta::serialize(const DBObject &parent) const{
const std::string &serialized_salt_name =
true == this->has_salt ? serialize_string(getSaltName())
: serialize_string("");
......@@ -365,20 +320,17 @@ std::string FieldMeta::serialize(const DBObject &parent) const
return serial;
}
std::string FieldMeta::stringify() const
{
std::string FieldMeta::stringify() const{
const std::string res = " [FieldMeta " + fname + "]";
return res;
}
std::vector<std::pair<const OnionMetaKey *, OnionMeta *>>
FieldMeta::orderedOnionMetas() const
{
FieldMeta::orderedOnionMetas() const{
std::vector<std::pair<const OnionMetaKey *, OnionMeta *>> v;
for (const auto &it : this->getChildren()) {
v.push_back(std::make_pair(&it.first, it.second.get()));
}
std::sort(v.begin(), v.end(),
[] (std::pair<const OnionMetaKey *, OnionMeta *> a,
std::pair<const OnionMetaKey *, OnionMeta *> b) {
......@@ -389,14 +341,12 @@ FieldMeta::orderedOnionMetas() const
return v;
}
std::string FieldMeta::getSaltName() const
{
std::string FieldMeta::getSaltName() const{
assert(has_salt);
return salt_name;
}
SECLEVEL FieldMeta::getOnionLevel(onion o) const
{
SECLEVEL FieldMeta::getOnionLevel(onion o) const{
const auto om = getChild(OnionMetaKey(o));
if (om == NULL) {
return SECLEVEL::INVALID;
......@@ -405,8 +355,7 @@ SECLEVEL FieldMeta::getOnionLevel(onion o) const
return om->getSecLevel();
}
OnionMeta *FieldMeta::getOnionMeta(onion o) const
{
OnionMeta *FieldMeta::getOnionMeta(onion o) const{
return getChild(OnionMetaKey(o));
}
......@@ -423,12 +372,10 @@ onionlayout FieldMeta::determineOnionLayout(const AES_KEY *const m_key,
if (false == encryptionSupported(f)) {
return PLAIN_ONION_LAYOUT;//do not report error here
}
// Don't encrypt AUTO_INCREMENT.
if (Field::NEXT_NUMBER == f.unireg_check) {
return PLAIN_ONION_LAYOUT;
}
/*we only support sensitive rating here*/
if (SECURITY_RATING::SENSITIVE == sec_rating) {
if (true == isMySQLTypeNumeric(f)) {
......@@ -463,8 +410,7 @@ bool FieldMeta::determineHasDefault(const Create_field &cf) {
}
std::string FieldMeta::determineDefaultValue(bool has_default,
const Create_field &cf)
{
const Create_field &cf) {
const static std::string zero_string = "'0'";
const static std::string empty_string = "";
......@@ -484,8 +430,7 @@ std::string FieldMeta::determineDefaultValue(bool has_default,
}
}
bool FieldMeta::hasOnion(onion o) const
{
bool FieldMeta::hasOnion(onion o) const{
return childExists(OnionMetaKey(o));
}
......@@ -521,15 +466,13 @@ TableMeta::serialize(const DBObject &parent) const {
// FIXME: May run into problems where a plaintext table expects the regular
// name, but it shouldn't get that name from 'getAnonTableName' anyways.
std::string TableMeta::getAnonTableName() const
{
std::string TableMeta::getAnonTableName() const {
return anon_table_name;
}
// FIXME: Slow.
// > Code is also duplicated with FieldMeta::orderedOnionMetas.
std::vector<FieldMeta *> TableMeta::orderedFieldMetas() const
{
std::vector<FieldMeta *> TableMeta::orderedFieldMetas() const {
std::vector<FieldMeta *> v;
for (const auto &it : this->getChildren()) {
v.push_back(it.second.get());
......@@ -544,8 +487,7 @@ std::vector<FieldMeta *> TableMeta::orderedFieldMetas() const
}
/*use fm->hasDefault() to test whether the filed has default value*/
std::vector<FieldMeta *> TableMeta::defaultedFieldMetas() const
{
std::vector<FieldMeta *> TableMeta::defaultedFieldMetas() const {
std::vector<FieldMeta *> v;
for (const auto &it : this->getChildren()) {
v.push_back(it.second.get());
......@@ -563,37 +505,30 @@ std::vector<FieldMeta *> TableMeta::defaultedFieldMetas() const
// TODO: Add salt.
std::string TableMeta::getAnonIndexName(const std::string &index_name,
onion o) const
{
onion o) const {
const std::string hash_input =
anon_table_name + index_name + TypeText<onion>::toText(o);
const std::size_t hsh = std::hash<std::string>()(hash_input);
return std::string("index_") + std::to_string(hsh);
}
std::unique_ptr<DatabaseMeta>
DatabaseMeta::deserialize(unsigned int id, const std::string &serial)
{
DatabaseMeta::deserialize(unsigned int id, const std::string &serial) {
assert(id != 0);
return std::unique_ptr<DatabaseMeta>(new DatabaseMeta(id));
}
std::string
DatabaseMeta::serialize(const DBObject &parent) const
{
DatabaseMeta::serialize(const DBObject &parent) const {
const std::string &serial =
"Serialize to associate database name with DatabaseMeta";
return serial;
}
//查询Id对应的stale的值
//check the staleness of the specified random cache_id
static bool
lowLevelGetCurrentStaleness(const std::unique_ptr<Connect> &e_conn,
unsigned int cache_id)
{
unsigned int cache_id) {
const std::string &query =
" SELECT stale FROM " + MetaData::Table::staleness() +
" WHERE cache_id = " + std::to_string(cache_id) + ";";
......@@ -608,10 +543,10 @@ lowLevelGetCurrentStaleness(const std::unique_ptr<Connect> &e_conn,
return string_to_bool(std::string(row[0], l[0]));
}
//read metadata from disk
std::shared_ptr<const SchemaInfo>
SchemaCache::getSchema(const std::unique_ptr<Connect> &conn,
const std::unique_ptr<Connect> &e_conn) const
{
const std::unique_ptr<Connect> &e_conn) const {
if (true == this->no_loads) {
//set staleness of current id to true.
TEST_SchemaFailure(initialStaleness(e_conn));
......@@ -626,14 +561,12 @@ SchemaCache::getSchema(const std::unique_ptr<Connect> &conn,
}else{
;
}
assert(this->schema);
return this->schema;
}
static void
lowLevelAllStale(const std::unique_ptr<Connect> &e_conn)
{
lowLevelAllStale(const std::unique_ptr<Connect> &e_conn) {
const std::string &query =
" UPDATE " + MetaData::Table::staleness() +
" SET stale = TRUE;";
......@@ -643,8 +576,7 @@ lowLevelAllStale(const std::unique_ptr<Connect> &e_conn)
void
SchemaCache::updateStaleness(const std::unique_ptr<Connect> &e_conn,
bool staleness) const
{
bool staleness) const {
if (true == staleness) {
// Make everyone stale.
return lowLevelAllStale(e_conn);
......@@ -655,8 +587,7 @@ SchemaCache::updateStaleness(const std::unique_ptr<Connect> &e_conn,
}
bool
SchemaCache::initialStaleness(const std::unique_ptr<Connect> &e_conn) const
{
SchemaCache::initialStaleness(const std::unique_ptr<Connect> &e_conn) const {
const std::string seed_staleness =
" INSERT INTO " + MetaData::Table::staleness() +
" (cache_id, stale) VALUES " +
......@@ -667,8 +598,7 @@ SchemaCache::initialStaleness(const std::unique_ptr<Connect> &e_conn) const
}
bool
SchemaCache::cleanupStaleness(const std::unique_ptr<Connect> &e_conn) const
{
SchemaCache::cleanupStaleness(const std::unique_ptr<Connect> &e_conn) const {
const std::string remove_staleness =
" DELETE FROM " + MetaData::Table::staleness() +
" WHERE cache_id = " + std::to_string(this->id) + ";";
......@@ -678,28 +608,23 @@ SchemaCache::cleanupStaleness(const std::unique_ptr<Connect> &e_conn) const
}
static bool
lowLevelToggleCurrentStaleness(const std::unique_ptr<Connect> &e_conn,
unsigned int cache_id, bool staleness)
{
unsigned int cache_id, bool staleness) {
const std::string &query =
" UPDATE " + MetaData::Table::staleness() +
" SET stale = " + bool_to_string(staleness) +
" WHERE cache_id = " + std::to_string(cache_id) + ";";
RFIF(e_conn->execute(query));
return true;
}
void
SchemaCache::lowLevelCurrentStale(const std::unique_ptr<Connect> &e_conn)
const
{
const{
TEST_SchemaFailure(lowLevelToggleCurrentStaleness(e_conn, this->id, true));
}
void
SchemaCache::lowLevelCurrentUnstale(const std::unique_ptr<Connect> &e_conn)
const
{
const {
TEST_SchemaFailure(lowLevelToggleCurrentStaleness(e_conn, this->id, false));
}
......@@ -71,7 +71,7 @@ static void
returnResultSet(lua_State *L, const ResType &res);
static Item_null *
make_null(const std::string &name = ""){
make_null(const std::string &name = "") {
char *const n = current_thd->strdup(name.c_str());
return new Item_null(n);
}
......@@ -279,7 +279,7 @@ getResTypeFromLuaTable(lua_State *const L, int fields_index,
std::vector<std::vector<Item *> > rows;
lua_pushnil(L);
//没有kv对了, 则退出.
//no kv pairs, then exit.
while (lua_next(L, rows_index)) {
if (!lua_istable(L, -1))
LOG(warn) << "mismatch";
......
......@@ -554,21 +554,18 @@ do64Test(uint64_t n)
// quick n dirty unit testing
bool
test64bitZZConversions()
{
test64bitZZConversions() {
// there was a problem with numbers larger than 0x7FFFFFFFFFFFFFFF; they
// were too small by 256 after conversions
const uint64_t low_bad = 0x7FFFFFFFFFFFFFF0;
for (uint64_t i = low_bad; i <= low_bad + 50; ++i) {
RFIF(do64Test(i));
}
// try some other value
const uint64_t other_start = 0x9ABCD00012340000;
for (uint64_t i = other_start; i <= other_start + 50; ++i) {
RFIF(do64Test(i));
}
// try the biggest values
{
const uint64_t high_bad = 0xFFFFFFFFFFFFFFC0;
......@@ -577,7 +574,6 @@ test64bitZZConversions()
RFIF(do64Test(i));
} while (i++ < 0xFFFFFFFFFFFFFFFF);
}
return true;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment