处理带条件的insert、delete时,发现如果按照以下代码书写filter_stmt.cpp
会导致一些问题
1、在典型情况下,左边不是属性(Attribute)时,右边必定是属性,因为比较通常涉及属性和值之间的关系。分别进行左右attribute的判断if else是否重复了?
2、因为要判断DATES字段,然而用户输入的sql语句例如 select * from a where bir = ‘2020-01-01’
或者select * from a where name =‘Mike’ ,如果按以下代码会导致无论输入的是什么chars,都会进行date判断。然而只有在需要是date并且输入符合date格式时,才会成功,在不需要date的时候,依旧会进行判断,这会造成失败。
该如何避免这种情况?
目标:需要是date字段时,一定将chars进行date判断;不需要是date字段时,则不判断。
/*接下来,根据条件信息中的左操作数类型进行处理。
如果左操作数是属性,则通过调用 get_table_and_field 函数获取相应的表和字段信息,
并初始化一个 FilterObj 对象,使用获取到的表和字段信息来初始化该对象。
然后,通过 filter_unit->set_left 方法将该 FilterObj 对象设置为 filter_unit 的左操作数。
如果左操作数是值,则直接初始化一个 FilterObj 对象,并使用左操作数的值来初始化该对象。
然后,同样通过 filter_unit->set_left 方法将该 FilterObj 对象设置为 filter_unit 的左操作数。*/
if (condition.left_is_attr) { // 如果左边是属性 //如果右边是属性 select * from a where bir = '2020-01-01' 29200101
// int select * from a where name = 'abc' chars
Table *table = nullptr;
const FieldMeta *field = nullptr;
rc = get_table_and_field(db, default_table, tables, condition.left_attr, table, field);
if (rc != RC::SUCCESS) {
LOG_WARN("cannot find attr");
return rc;
}
FilterObj filter_obj;
filter_obj.init_attr(Field(table, field));
filter_unit->set_left(filter_obj);
} else { // 如果左边不是属性 是用户输入的东西
if (condition.left_value.attr_type() == CHARS) { // 如果左边是用户输入的东西 且输入的是字符串
int32_t date = -1;
RC rc = string_to_date(condition.left_value.data(), date);
if (rc != RC::SUCCESS) {
LOG_TRACE("xxx");
return rc;
}
condition.left_value.value_destroy(const_cast<Value *>(&condition.left_value));
condition.left_value.set_date(const_cast<Value *>(&condition.left_value), date);
}
FilterObj filter_obj;
filter_obj.init_value(condition.left_value);
filter_unit->set_left(filter_obj);
}
/*类似地,根据条件信息中的右操作数类型进行处理。
如果右操作数是属性,则通过调用 get_table_and_field 函数获取相应的表和字段信息,
并初始化一个 FilterObj 对象,使用获取到的表和字段信息来初始化该对象
然后,通过 filter_unit->set_right 方法将该 FilterObj 对象设置为 filter_unit 的右操作数。
如果右操作数是值,则直接初始化一个 FilterObj 对象,并使用右操作数的值来初始化该对象。
然后,同样通过 filter_unit->set_right 方法将该 FilterObj 对象设置为 filter_unit 的右操作数。*/
if (condition.right_is_attr) { // 如果右边是属性 select * from a where '2020-01-01'= bir
// select * from a where 'abc' = name
Table *table = nullptr;
const FieldMeta *field = nullptr;
rc = get_table_and_field(db, default_table, tables, condition.right_attr, table, field);
if (rc != RC::SUCCESS) {
LOG_WARN("cannot find attr");
return rc;
}
FilterObj filter_obj;
filter_obj.init_attr(Field(table, field));
filter_unit->set_right(filter_obj);
} else { /// 这个else表示 where id = 1 如果右边是用户输入的东西 (常见情况)
if (condition.right_value.attr_type() == CHARS) { // 如果右边是用户输入的东西 且右边是字符串 则会进入
int32_t date = -1;
RC rc = string_to_date(condition.right_value.data(), date);
if (rc != RC::SUCCESS) {
LOG_TRACE("xxx");
return rc;
}
condition.right_value.value_destroy(const_cast<Value *>(&condition.right_value));
condition.right_value.set_date(const_cast<Value *>(&condition.right_value), date);
}
FilterObj filter_obj;
filter_obj.init_value(condition.right_value);
filter_unit->set_right(filter_obj);
}