Commit a3209cd2 authored by yiwenshao's avatar yiwenshao

modify reuse.cc:rawMySQLReturnValue_to_ResType to handle null input

parent 49d287e7
......@@ -225,7 +225,8 @@ main(int argc,char**argv) {
SharedProxyState *shared_ps =
new SharedProxyState(ci, embeddedDir , master_key, determineSecurityRating());
assert(shared_ps!=NULL);
std::string query1 = "insert into student values(1,\"ZHAOYUN\"),(2,'XC'),(3,'KK')";
//std::string query1 = "insert into student values(1,\"ZHAOYUN\"),(2,'XC'),(3,'KK')";
std::string query1 = "insert into student values(NULL)";
std::vector<std::string> querys{query1};
for(auto item:querys){
std::cout<<item<<std::endl;
......
......@@ -51,7 +51,7 @@ main() {
ConnectionInfo ci("localhost", "root", "letmein",3306);
SharedProxyState *shared_ps = new SharedProxyState(ci, embeddedDir , master_key, determineSecurityRating());
assert(shared_ps!=NULL);
std::string query1 = "insert into child values(1,\"zh Z D D\")";
std::string query1 = "insert into student values(NULL)";
std::vector<std::string> querys{query1};
for(auto item:querys){
std::cout<<item<<std::endl;
......
/*
To make this work properly, you should at least make sure that the database tdb exists.
*/
#include <iostream>
#include <vector>
#include <functional>
#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>
#include <main/Connect.hh>
#include <main/rewrite_util.hh>
#include <main/sql_handler.hh>
#include <main/dml_handler.hh>
#include <main/ddl_handler.hh>
#include <main/CryptoHandlers.hh>
#include "wrapper/reuse.hh"
static std::string embeddedDir="/t/cryt/shadow";
struct help_select{
ReturnMeta rmeta;
std::string query;
};
SharedProxyState *shared_ps;
Connect *globalConn;
ProxyState *ps;
static
void parseResType(const ResType &rd) {
for(auto name:rd.names){
std::cout<<name<<"\t";
}
std::cout<<std::endl;
for(auto row:rd.rows){
for(auto item:row){
std::cout<<ItemToString(*item)<<"\t";
}
std::cout<<std::endl;
}
}
static void sp_next_first(const help_select &hs){
ps->safeCreateEmbeddedTHD();
try{
//AbstractQueryExecutor::ResultType::QUERY_COME_AGAIN
ps->getSchemaCache().updateStaleness(ps->getEConn(),false);
const std::string next_query = hs.query;
rawMySQLReturnValue resRemote = executeAndGetResultRemote(globalConn,next_query);
const auto &againGet = rawMySQLReturnValue_to_ResType(false,&resRemote);
rawMySQLReturnValue str;
transform_to_rawMySQLReturnValue(str,const_cast<ResType &>(againGet));
str.fieldNames = againGet.names;
// write_row_data(str,"tdb","student","tdata/");
//AbstractQueryExecutor::ResultType::RESULTS
const auto &res = decryptResults(againGet,hs.rmeta);
parseResType(res);
}catch(...){
std::cout<<"first next error"<<std::endl;
}
}
//=================================gather part======================================
static
RewritePlan *
my_gather(const Item_field &i, Analysis &a){
const std::string fieldname = i.field_name;
const std::string table = i.table_name;//we donot deduce here
FieldMeta &fm =
a.getFieldMeta(a.getDatabaseName(), table, fieldname);
const EncSet es = EncSet(a, &fm);
const std::string why = "is a field";
reason rsn(es, why, i);
return new RewritePlan(es, rsn);
}
static
void
my_gatherAndAddAnalysisRewritePlan(const Item &i, Analysis &a){
a.rewritePlans[&i] = std::unique_ptr<RewritePlan>(my_gather(static_cast<const Item_field&>(i), a));
}
static
void
my_process_select_lex(const st_select_lex &select_lex, Analysis &a){
auto item_it =
RiboldMYSQL::constList_iterator<Item>(select_lex.item_list);
for (;;) {
/*not used in normal insert queries;
processes id and name in the table student
*/
const Item *const item = item_it++;
if (!item)
break;
my_gatherAndAddAnalysisRewritePlan(*item, a);
}
}
static void my_gather_select(Analysis &a, LEX *const lex){
my_process_select_lex(lex->select_lex, a);
}
//===========================================Rewrite=============================================
/*Rewrite an Item_field using the selected OLK.(get the anno field name)
The OLK comes from the chooseOne function
*/
static
Item *
my_do_rewrite_type(const Item_field &i, const OLK &constr,
const RewritePlan &rp, Analysis &a) {
const std::string &db_name = a.getDatabaseName();
const std::string plain_table_name = i.table_name;
const FieldMeta &fm =
a.getFieldMeta(db_name, plain_table_name, i.field_name);
//check if we need onion adjustment
const OnionMeta &om =
a.getOnionMeta(db_name, plain_table_name, i.field_name,
constr.o);
const SECLEVEL onion_level = a.getOnionLevel(om);
assert(onion_level != SECLEVEL::INVALID);
if (constr.l < onion_level) {
//need adjustment, throw exception
const TableMeta &tm =
a.getTableMeta(db_name, plain_table_name);
throw OnionAdjustExcept(tm, fm, constr.o, constr.l);
}
bool is_alias;
const std::string anon_table_name =
a.getAnonTableName(db_name, plain_table_name, &is_alias);
const std::string anon_field_name = om.getAnonOnionName();
Item_field * const res =
make_item_field(i, anon_table_name, anon_field_name);
// HACK: to get aliases to work in DELETE FROM statements
if (a.inject_alias && is_alias) {
res->db_name = NULL;
}
// This information is only relevant if it comes from a
// HAVING clause.
// FIXME: Enforce this semantically.
a.item_cache[&i] = std::make_pair(res, constr);
return res;
}
static Item* my_rewrite(const Item &i, const EncSet &req_enc, Analysis &a){
const std::unique_ptr<RewritePlan> &rp = constGetAssert(a.rewritePlans, &i);
const EncSet solution = rp->es_out.intersect(req_enc);
TEST_NoAvailableEncSet(solution, i.type(), req_enc, rp->r.why,
std::vector<std::shared_ptr<RewritePlan> >());
return my_do_rewrite_type(static_cast<const Item_field&>(i), solution.chooseOne(), *rp.get(), a);
}
static void
my_rewrite_proj(const Item &i, const RewritePlan &rp, Analysis &a,
List<Item> *const newList) {
AssignOnce<OLK> olk;
AssignOnce<Item *> ir;
if (i.type() == Item::Type::FIELD_ITEM) {
const Item_field &field_i = static_cast<const Item_field &>(i);
const auto &cached_rewritten_i = a.item_cache.find(&field_i);
if (cached_rewritten_i != a.item_cache.end()) {
ir = cached_rewritten_i->second.first;
olk = cached_rewritten_i->second.second;
} else {
ir = my_rewrite(i, rp.es_out, a);
olk = rp.es_out.chooseOne();
}
} else {
exit(0);
}
//和insert不同, select的时候, 只要一个洋葱, 选取一个进行改写就可以了, 不需要扩展.
assert(ir.assigned() && ir.get());
newList->push_back(ir.get());
const bool use_salt = needsSalt(olk.get());
// This line implicity handles field aliasing for at least some cases.
// As i->name can/will be the alias.
addToReturn(&a.rmeta, a.pos++, olk.get(), use_salt, i.name);
if (use_salt) {
TEST_TextMessageError(Item::Type::FIELD_ITEM == ir.get()->type(),
"a projection requires a salt and is not a field; cryptdb"
" does not currently support such behavior");
const std::string &anon_table_name =
static_cast<Item_field *>(ir.get())->table_name;
const std::string &anon_field_name = olk.get().key->getSaltName();
Item_field *const ir_field =
make_item_field(*static_cast<Item_field *>(ir.get()),
anon_table_name, anon_field_name);
newList->push_back(ir_field);
addSaltToReturn(&a.rmeta, a.pos++);
}
}
static st_select_lex *
my_rewrite_select_lex(const st_select_lex &select_lex, Analysis &a){
//do not support filter
st_select_lex *const new_select_lex = copyWithTHD(&select_lex);
auto item_it =
RiboldMYSQL::constList_iterator<Item>(select_lex.item_list);
List<Item> newList;
//rewrite item
for (;;) {
const Item *const item = item_it++;
if (!item)
break;
my_rewrite_proj(*item,
*constGetAssert(a.rewritePlans, item).get(),//get the rewrite plain
a, &newList);
}
new_select_lex->item_list = newList;
return new_select_lex;
}
static
help_select my_rewrite_select(Analysis &a, LEX *lex){
LEX *const new_lex = copyWithTHD(lex);
//this is actually table list instead of join list.
new_lex->select_lex.top_join_list =
rewrite_table_list(lex->select_lex.top_join_list, a);
SELECT_LEX *const select_lex_res = my_rewrite_select_lex(new_lex->select_lex, a);
set_select_lex(new_lex,select_lex_res);
help_select hs;
hs.query = lexToQuery(*new_lex);
hs.rmeta = a.rmeta;
return hs;
}
static void testCreateTableHandler(std::string query,std::string db="tdb"){
std::unique_ptr<Connect> e_conn(Connect::getEmbedded(embeddedDir));
std::unique_ptr<SchemaInfo> schema(new SchemaInfo());
std::function<DBMeta *(DBMeta *const)> loadChildren =
[&loadChildren, &e_conn](DBMeta *const parent) {
auto kids = parent->fetchChildren(e_conn);
for (auto it : kids) {
loadChildren(it);
}
return parent;
};
//load all metadata and then store it in schema
loadChildren(schema.get());
const std::unique_ptr<AES_KEY> &TK =
std::unique_ptr<AES_KEY>(getKey(std::string("113341234")));
//just like what we do in Rewrite::rewrite,dispatchOnLex
Analysis analysis(std::string("tdb"),*schema,TK,
SECURITY_RATING::SENSITIVE);
assert(analysis.getMasterKey().get()!=NULL);
assert(getKey(std::string("113341234"))!=NULL);
std::unique_ptr<query_parse> p;
p = std::unique_ptr<query_parse>(
new query_parse(db, query));
LEX *const lex = p->lex();
std::string table(lex->select_lex.table_list.first->table_name);
my_gather_select(analysis,lex);
help_select hs = my_rewrite_select(analysis,lex);
//QueryRewrite *qr = new QueryRewrite(QueryRewrite(true, analysis.rmeta, analysis.kill_zone, executor));
sp_next_first(hs);
}
int
main() {
char *buffer;
if((buffer = getcwd(NULL, 0)) == NULL){
perror("getcwd error");
}
embeddedDir = std::string(buffer)+"/shadow";
const std::string master_key = "113341234";
ConnectionInfo ci("localhost", "root", "letmein",3306);
shared_ps =
new SharedProxyState(ci, embeddedDir , master_key, determineSecurityRating());
assert(shared_ps!=NULL);
ps = new ProxyState(*shared_ps);
globalConn = new Connect(ci.server, ci.user, ci.passwd, ci.port);
globalConn->execute("use tdb");
ps->safeCreateEmbeddedTHD();
std::string query1 = "select * from student;";
std::vector<std::string> querys{query1};
for(auto item:querys){
std::cout<<item<<std::endl;
testCreateTableHandler(item);
std::cout<<std::endl;
}
return 0;
}
......@@ -121,8 +121,9 @@ ResType rawMySQLReturnValue_to_ResType(bool isNULL,rawMySQLReturnValue *inRow,in
for(auto inRows:inRow->rowValues) {
std::vector<Item *> curTempRow = itemNullVector(types.size());
for(int i=0;i< (int)(inRows.size());i++){
curTempRow[i] = (MySQLFieldTypeToItem(types[i],inRows[i]) );
}
if(inRows[i]!="NULL")
curTempRow[i] = (MySQLFieldTypeToItem(types[i],inRows[i]));//why unsinged processing is not needed here?
}
rows.push_back(curTempRow);
}
return ResType(true,0,in_last_insert_id,std::move(names),std::move(types),std::move(rows));
......
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