699 lines
23 KiB
C++
699 lines
23 KiB
C++
/*=============================================================================
|
|
# Filename: QueryTree.cpp
|
|
# Author: Jiaqi, Chen
|
|
# Mail: chenjiaqi93@163.com
|
|
# Last Modified: 2017-03-13
|
|
# Description: implement functions in QueryTree.h
|
|
=============================================================================*/
|
|
|
|
#include "QueryTree.h"
|
|
|
|
using namespace std;
|
|
|
|
void QueryTree::GroupPattern::FilterTree::FilterTreeNode::getVarset(Varset &varset)
|
|
{
|
|
for (int i = 0; i < (int)this->child.size(); i++)
|
|
{
|
|
if (this->child[i].node_type == FilterTreeChild::String_type && this->child[i].str[0] == '?')
|
|
varset.addVar(this->child[i].str);
|
|
if (this->child[i].node_type == FilterTreeChild::Tree_type)
|
|
this->child[i].node.getVarset(varset);
|
|
}
|
|
}
|
|
|
|
void QueryTree::GroupPattern::FilterTree::FilterTreeNode::mapVarPos2Varset(Varset &varset, Varset &entity_literal_varset)
|
|
{
|
|
if (this->oper_type == Not_type)
|
|
{
|
|
this->child[0].node.mapVarPos2Varset(varset, entity_literal_varset);
|
|
}
|
|
else if (this->oper_type == Or_type || this->oper_type == And_type)
|
|
{
|
|
this->child[0].node.mapVarPos2Varset(varset, entity_literal_varset);
|
|
this->child[1].node.mapVarPos2Varset(varset, entity_literal_varset);
|
|
}
|
|
else if (Equal_type <= this->oper_type && this->oper_type <= GreaterOrEqual_type)
|
|
{
|
|
if (this->child[0].node_type == FilterTreeChild::Tree_type)
|
|
this->child[0].node.mapVarPos2Varset(varset, entity_literal_varset);
|
|
else if (this->child[0].node_type == FilterTreeChild::String_type && this->child[0].str[0] == '?')
|
|
{
|
|
this->child[0].pos = Varset(this->child[0].str).mapTo(varset)[0];
|
|
this->child[0].isel = entity_literal_varset.findVar(this->child[0].str);
|
|
}
|
|
|
|
if (this->child[1].node_type == FilterTreeChild::Tree_type)
|
|
this->child[1].node.mapVarPos2Varset(varset, entity_literal_varset);
|
|
else if (this->child[1].node_type == FilterTreeChild::String_type && this->child[1].str[0] == '?')
|
|
{
|
|
this->child[1].pos = Varset(this->child[1].str).mapTo(varset)[0];
|
|
this->child[1].isel = entity_literal_varset.findVar(this->child[1].str);
|
|
}
|
|
}
|
|
else if (this->oper_type == Builtin_regex_type ||
|
|
this->oper_type == Builtin_str_type ||
|
|
this->oper_type == Builtin_isiri_type ||
|
|
this->oper_type == Builtin_isuri_type ||
|
|
this->oper_type == Builtin_isliteral_type ||
|
|
this->oper_type == Builtin_isnumeric_type ||
|
|
this->oper_type == Builtin_lang_type ||
|
|
this->oper_type == Builtin_langmatches_type ||
|
|
this->oper_type == Builtin_bound_type ||
|
|
this->oper_type == Builtin_in_type)
|
|
{
|
|
if (this->child[0].node_type == FilterTreeChild::Tree_type)
|
|
this->child[0].node.mapVarPos2Varset(varset, entity_literal_varset);
|
|
else if (this->child[0].node_type == FilterTreeChild::String_type && this->child[0].str[0] == '?')
|
|
{
|
|
this->child[0].pos = Varset(this->child[0].str).mapTo(varset)[0];
|
|
this->child[0].isel = entity_literal_varset.findVar(this->child[0].str);
|
|
}
|
|
}
|
|
}
|
|
|
|
void QueryTree::GroupPattern::FilterTree::FilterTreeNode::print(int dep)
|
|
{
|
|
if (this->oper_type == Not_type) printf("!");
|
|
if (this->oper_type == Builtin_regex_type) printf("REGEX");
|
|
if (this->oper_type == Builtin_str_type) printf("STR");
|
|
if (this->oper_type == Builtin_isiri_type) printf("ISIRI");
|
|
if (this->oper_type == Builtin_isuri_type) printf("ISURI");
|
|
if (this->oper_type == Builtin_isliteral_type) printf("ISLITERAL");
|
|
if (this->oper_type == Builtin_isnumeric_type) printf("ISNUMERIC");
|
|
if (this->oper_type == Builtin_lang_type) printf("LANG");
|
|
if (this->oper_type == Builtin_langmatches_type) printf("LANGMATCHES");
|
|
if (this->oper_type == Builtin_bound_type) printf("BOUND");
|
|
|
|
if (this->oper_type == Builtin_in_type)
|
|
{
|
|
printf("(");
|
|
if (this->child[0].node_type == FilterTreeChild::String_type) printf("%s", this->child[0].str.c_str());
|
|
if (this->child[0].node_type == FilterTreeChild::Tree_type) this->child[0].node.print(dep);
|
|
printf(" IN (");
|
|
for (int i = 1; i < (int)this->child.size(); i++)
|
|
{
|
|
if (i != 1) printf(", ");
|
|
if (this->child[i].node_type == FilterTreeChild::String_type) printf("%s", this->child[i].str.c_str());
|
|
if (this->child[i].node_type == FilterTreeChild::Tree_type) this->child[i].node.print(dep);
|
|
}
|
|
printf("))");
|
|
|
|
return;
|
|
}
|
|
|
|
printf("(");
|
|
|
|
if ((int)this->child.size() >= 1)
|
|
{
|
|
if (this->child[0].node_type == FilterTreeChild::String_type) printf("%s", this->child[0].str.c_str());
|
|
if (this->child[0].node_type == FilterTreeChild::Tree_type) this->child[0].node.print(dep);
|
|
}
|
|
|
|
if (this->oper_type == Or_type) printf(" || ");
|
|
if (this->oper_type == And_type) printf(" && ");
|
|
if (this->oper_type == Equal_type) printf(" = ");
|
|
if (this->oper_type == NotEqual_type) printf(" != ");
|
|
if (this->oper_type == Less_type) printf(" < ");
|
|
if (this->oper_type == LessOrEqual_type) printf(" <= ");
|
|
if (this->oper_type == Greater_type) printf(" > ");
|
|
if (this->oper_type == GreaterOrEqual_type) printf(" >= ");
|
|
|
|
if (this->oper_type == Builtin_regex_type || this->oper_type == Builtin_langmatches_type) printf(", ");
|
|
|
|
if ((int)this->child.size() >= 2)
|
|
{
|
|
if (this->child[1].node_type == FilterTreeChild::String_type) printf("%s", this->child[1].str.c_str());
|
|
if (this->child[1].node_type == FilterTreeChild::Tree_type) this->child[1].node.print(dep);
|
|
}
|
|
|
|
if ((int)this->child.size() >= 3)
|
|
{
|
|
if (this->oper_type == FilterTreeNode::Builtin_regex_type && this->child[2].node_type == FilterTreeChild::String_type)
|
|
printf(", %s", this->child[2].str.c_str());
|
|
}
|
|
|
|
printf(")");
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
void QueryTree::GroupPattern::addOnePattern(Pattern _pattern)
|
|
{
|
|
this->sub_grouppattern.push_back(SubGroupPattern(SubGroupPattern::Pattern_type));
|
|
this->sub_grouppattern.back().pattern = _pattern;
|
|
}
|
|
|
|
void QueryTree::GroupPattern::addOneGroupUnion()
|
|
{
|
|
this->sub_grouppattern.push_back(SubGroupPattern(SubGroupPattern::Union_type));
|
|
}
|
|
|
|
void QueryTree::GroupPattern::addOneUnion()
|
|
{
|
|
if (this->sub_grouppattern.back().type != SubGroupPattern::Union_type)
|
|
throw "QueryTree::GroupPattern::addOneUnion failed";
|
|
|
|
this->sub_grouppattern.back().unions.push_back(GroupPattern());
|
|
}
|
|
|
|
QueryTree::GroupPattern& QueryTree::GroupPattern::getLastUnion()
|
|
{
|
|
if (this->sub_grouppattern.back().type != SubGroupPattern::Union_type || this->sub_grouppattern.back().unions.empty())
|
|
throw "QueryTree::GroupPattern::getLastUnion failed";
|
|
|
|
return this->sub_grouppattern.back().unions.back();
|
|
}
|
|
|
|
void QueryTree::GroupPattern::addOneOptional(int _type)
|
|
{
|
|
SubGroupPattern::SubGroupPatternType type = (SubGroupPattern::SubGroupPatternType)_type;
|
|
if (type != SubGroupPattern::Optional_type && type != SubGroupPattern::Minus_type)
|
|
throw "QueryTree::GroupPattern::addOneOptional failed";
|
|
|
|
this->sub_grouppattern.push_back(SubGroupPattern(type));
|
|
}
|
|
|
|
QueryTree::GroupPattern& QueryTree::GroupPattern::getLastOptional()
|
|
{
|
|
if (this->sub_grouppattern.back().type != SubGroupPattern::Optional_type && this->sub_grouppattern.back().type != SubGroupPattern::Minus_type)
|
|
throw "QueryTree::GroupPattern::getLastOptional failed";
|
|
|
|
return this->sub_grouppattern.back().optional;
|
|
}
|
|
|
|
void QueryTree::GroupPattern::addOneFilter()
|
|
{
|
|
this->sub_grouppattern.push_back(SubGroupPattern(SubGroupPattern::Filter_type));
|
|
}
|
|
|
|
QueryTree::GroupPattern::FilterTree& QueryTree::GroupPattern::getLastFilter()
|
|
{
|
|
if (this->sub_grouppattern.back().type != SubGroupPattern::Filter_type)
|
|
throw "QueryTree::GroupPattern::getLastFilter failed";
|
|
|
|
return this->sub_grouppattern.back().filter;
|
|
}
|
|
|
|
void QueryTree::GroupPattern::addOneBind()
|
|
{
|
|
this->sub_grouppattern.push_back(SubGroupPattern(SubGroupPattern::Bind_type));
|
|
}
|
|
|
|
QueryTree::GroupPattern::Bind& QueryTree::GroupPattern::getLastBind()
|
|
{
|
|
if (this->sub_grouppattern.back().type != SubGroupPattern::Bind_type)
|
|
throw "QueryTree::GroupPattern::getLastBind failed";
|
|
|
|
return this->sub_grouppattern.back().bind;
|
|
}
|
|
|
|
void QueryTree::GroupPattern::getVarset()
|
|
{
|
|
for (int i = 0; i < (int)this->sub_grouppattern.size(); i++)
|
|
if (this->sub_grouppattern[i].type == SubGroupPattern::Pattern_type)
|
|
{
|
|
if (this->sub_grouppattern[i].pattern.subject.value[0] == '?')
|
|
{
|
|
this->sub_grouppattern[i].pattern.varset.addVar(this->sub_grouppattern[i].pattern.subject.value);
|
|
this->sub_grouppattern[i].pattern.subject_object_varset.addVar(this->sub_grouppattern[i].pattern.subject.value);
|
|
this->grouppattern_subject_object_maximal_varset.addVar(this->sub_grouppattern[i].pattern.subject.value);
|
|
}
|
|
if (this->sub_grouppattern[i].pattern.predicate.value[0] == '?')
|
|
{
|
|
this->sub_grouppattern[i].pattern.varset.addVar(this->sub_grouppattern[i].pattern.predicate.value);
|
|
this->grouppattern_predicate_maximal_varset.addVar(this->sub_grouppattern[i].pattern.predicate.value);
|
|
}
|
|
if (this->sub_grouppattern[i].pattern.object.value[0] == '?')
|
|
{
|
|
this->sub_grouppattern[i].pattern.varset.addVar(this->sub_grouppattern[i].pattern.object.value);
|
|
this->sub_grouppattern[i].pattern.subject_object_varset.addVar(this->sub_grouppattern[i].pattern.object.value);
|
|
this->grouppattern_subject_object_maximal_varset.addVar(this->sub_grouppattern[i].pattern.object.value);
|
|
}
|
|
this->grouppattern_resultset_minimal_varset += this->sub_grouppattern[i].pattern.varset;
|
|
this->grouppattern_resultset_maximal_varset += this->sub_grouppattern[i].pattern.varset;
|
|
}
|
|
else if (this->sub_grouppattern[i].type == SubGroupPattern::Union_type)
|
|
{
|
|
Varset minimal_varset;
|
|
|
|
for (int j = 0; j < (int)this->sub_grouppattern[i].unions.size(); j++)
|
|
{
|
|
this->sub_grouppattern[i].unions[j].getVarset();
|
|
if (j == 0)
|
|
minimal_varset = this->sub_grouppattern[i].unions[j].grouppattern_resultset_minimal_varset;
|
|
else
|
|
minimal_varset = minimal_varset * this->sub_grouppattern[i].unions[j].grouppattern_resultset_minimal_varset;
|
|
this->grouppattern_resultset_maximal_varset += this->sub_grouppattern[i].unions[j].grouppattern_resultset_maximal_varset;
|
|
this->grouppattern_subject_object_maximal_varset += this->sub_grouppattern[i].unions[j].grouppattern_subject_object_maximal_varset;
|
|
this->grouppattern_predicate_maximal_varset += this->sub_grouppattern[i].unions[j].grouppattern_predicate_maximal_varset;
|
|
}
|
|
|
|
this->grouppattern_resultset_minimal_varset += minimal_varset;
|
|
}
|
|
else if (this->sub_grouppattern[i].type == SubGroupPattern::Optional_type)
|
|
{
|
|
this->sub_grouppattern[i].optional.getVarset();
|
|
|
|
this->grouppattern_resultset_maximal_varset += this->sub_grouppattern[i].optional.grouppattern_resultset_maximal_varset;
|
|
this->grouppattern_subject_object_maximal_varset += this->sub_grouppattern[i].optional.grouppattern_subject_object_maximal_varset;
|
|
this->grouppattern_predicate_maximal_varset += this->sub_grouppattern[i].optional.grouppattern_predicate_maximal_varset;
|
|
}
|
|
else if (this->sub_grouppattern[i].type == SubGroupPattern::Minus_type)
|
|
{
|
|
this->sub_grouppattern[i].optional.getVarset();
|
|
}
|
|
else if (this->sub_grouppattern[i].type == SubGroupPattern::Filter_type)
|
|
{
|
|
this->sub_grouppattern[i].filter.root.getVarset(this->sub_grouppattern[i].filter.varset);
|
|
}
|
|
else if (this->sub_grouppattern[i].type == SubGroupPattern::Bind_type)
|
|
{
|
|
this->sub_grouppattern[i].bind.varset = Varset(this->sub_grouppattern[i].bind.var);
|
|
this->grouppattern_resultset_minimal_varset += this->sub_grouppattern[i].bind.varset;
|
|
this->grouppattern_resultset_maximal_varset += this->sub_grouppattern[i].bind.varset;
|
|
}
|
|
}
|
|
|
|
pair<Varset, Varset> QueryTree::GroupPattern::checkNoMinusAndOptionalVarAndSafeFilter(Varset occur_varset, Varset ban_varset, bool &check_condition)
|
|
//return occur varset and ban varset
|
|
{
|
|
if (!check_condition) return make_pair(Varset(), Varset());
|
|
|
|
Varset new_ban_varset;
|
|
|
|
for (int i = 0; i < (int)this->sub_grouppattern.size(); i++)
|
|
if (!check_condition) break;
|
|
else if (this->sub_grouppattern[i].type == SubGroupPattern::Pattern_type)
|
|
{
|
|
if (this->sub_grouppattern[i].pattern.varset.hasCommonVar(ban_varset))
|
|
check_condition = false;
|
|
|
|
occur_varset += this->sub_grouppattern[i].pattern.varset;
|
|
}
|
|
else if (this->sub_grouppattern[i].type == SubGroupPattern::Union_type)
|
|
{
|
|
Varset sub_occur_varset, sub_ban_varset;
|
|
|
|
for (int j = 0; j < (int)this->sub_grouppattern[i].unions.size(); j++)
|
|
{
|
|
pair<Varset, Varset> sub_return_varset =
|
|
this->sub_grouppattern[i].unions[j].checkNoMinusAndOptionalVarAndSafeFilter(occur_varset, ban_varset, check_condition);
|
|
|
|
if (j == 0)
|
|
sub_occur_varset = sub_return_varset.first;
|
|
else
|
|
sub_occur_varset = sub_occur_varset * sub_return_varset.first;
|
|
|
|
sub_ban_varset += sub_return_varset.second;
|
|
}
|
|
|
|
new_ban_varset += sub_ban_varset;
|
|
occur_varset += sub_occur_varset;
|
|
ban_varset += new_ban_varset;
|
|
}
|
|
else if (this->sub_grouppattern[i].type == SubGroupPattern::Optional_type)
|
|
{
|
|
pair<Varset, Varset> sub_return_varset =
|
|
this->sub_grouppattern[i].optional.checkNoMinusAndOptionalVarAndSafeFilter(Varset(), ban_varset, check_condition);
|
|
|
|
//occur before
|
|
if (occur_varset.hasCommonVar(sub_return_varset.second))
|
|
check_condition = false;
|
|
|
|
new_ban_varset += sub_return_varset.second;
|
|
new_ban_varset += this->sub_grouppattern[i].optional.grouppattern_resultset_maximal_varset - occur_varset;
|
|
occur_varset += sub_return_varset.first;
|
|
ban_varset += new_ban_varset;
|
|
}
|
|
else if (this->sub_grouppattern[i].type == SubGroupPattern::Minus_type)
|
|
{
|
|
check_condition = false;
|
|
}
|
|
else if (this->sub_grouppattern[i].type == SubGroupPattern::Filter_type)
|
|
{
|
|
if (!this->sub_grouppattern[i].filter.varset.belongTo(occur_varset))
|
|
check_condition = false;
|
|
}
|
|
else if (this->sub_grouppattern[i].type == SubGroupPattern::Bind_type)
|
|
{
|
|
if (this->sub_grouppattern[i].bind.varset.hasCommonVar(ban_varset))
|
|
check_condition = false;
|
|
|
|
occur_varset += this->sub_grouppattern[i].bind.varset;
|
|
}
|
|
|
|
return make_pair(occur_varset, new_ban_varset);
|
|
}
|
|
|
|
void QueryTree::GroupPattern::initPatternBlockid()
|
|
{
|
|
for (int i = 0; i < (int)this->sub_grouppattern.size(); i++)
|
|
if (this->sub_grouppattern[i].type == SubGroupPattern::Pattern_type)
|
|
this->sub_grouppattern[i].pattern.blockid = i;
|
|
}
|
|
|
|
int QueryTree::GroupPattern::getRootPatternBlockID(int x)
|
|
{
|
|
if (this->sub_grouppattern[x].type != SubGroupPattern::Pattern_type)
|
|
throw "QueryTree::GroupPattern::getRootPatternBlockID failed";
|
|
|
|
if (this->sub_grouppattern[x].pattern.blockid == x)
|
|
return x;
|
|
this->sub_grouppattern[x].pattern.blockid = this->getRootPatternBlockID(this->sub_grouppattern[x].pattern.blockid);
|
|
|
|
return this->sub_grouppattern[x].pattern.blockid;
|
|
}
|
|
|
|
void QueryTree::GroupPattern::mergePatternBlockID(int x, int y)
|
|
{
|
|
int px = this->getRootPatternBlockID(x);
|
|
int py = this->getRootPatternBlockID(y);
|
|
this->sub_grouppattern[px].pattern.blockid = py;
|
|
}
|
|
|
|
void QueryTree::GroupPattern::print(int dep)
|
|
{
|
|
for (int t = 0; t < dep; t++) printf("\t"); printf("{\n");
|
|
|
|
for (int i = 0; i < (int)this->sub_grouppattern.size(); i++)
|
|
if (this->sub_grouppattern[i].type == SubGroupPattern::Pattern_type)
|
|
{
|
|
for (int t = 0; t <= dep; t++) printf("\t");
|
|
printf("%s\t%s\t%s.\n", this->sub_grouppattern[i].pattern.subject.value.c_str(),
|
|
this->sub_grouppattern[i].pattern.predicate.value.c_str(),
|
|
this->sub_grouppattern[i].pattern.object.value.c_str());
|
|
}
|
|
else if (this->sub_grouppattern[i].type == SubGroupPattern::Union_type)
|
|
{
|
|
for (int j = 0; j < (int)this->sub_grouppattern[i].unions.size(); j++)
|
|
{
|
|
if (j != 0)
|
|
{
|
|
for (int t = 0; t <= dep; t++) printf("\t"); printf("UNION\n");
|
|
}
|
|
this->sub_grouppattern[i].unions[j].print(dep + 1);
|
|
}
|
|
}
|
|
else if (this->sub_grouppattern[i].type == SubGroupPattern::Optional_type || this->sub_grouppattern[i].type == SubGroupPattern::Minus_type)
|
|
{
|
|
for (int t = 0; t <= dep; t++) printf("\t");
|
|
if (this->sub_grouppattern[i].type == SubGroupPattern::Optional_type) printf("OPTIONAL\n");
|
|
if (this->sub_grouppattern[i].type == SubGroupPattern::Minus_type) printf("MINUS\n");
|
|
this->sub_grouppattern[i].optional.print(dep + 1);
|
|
}
|
|
else if (this->sub_grouppattern[i].type == SubGroupPattern::Filter_type)
|
|
{
|
|
for (int t = 0; t <= dep; t++) printf("\t"); printf("FILTER\t");
|
|
this->sub_grouppattern[i].filter.root.print(dep + 1);
|
|
printf("\n");
|
|
}
|
|
else if (this->sub_grouppattern[i].type == SubGroupPattern::Bind_type)
|
|
{
|
|
for (int t = 0; t <= dep; t++) printf("\t");
|
|
printf("BIND(%s\tAS\t%s)", this->sub_grouppattern[i].bind.str.c_str(), this->sub_grouppattern[i].bind.var.c_str());
|
|
printf("\n");
|
|
}
|
|
|
|
for (int t = 0; t < dep; t++) printf("\t"); printf("}\n");
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
void QueryTree::setQueryForm(QueryForm _queryform)
|
|
{
|
|
this->query_form = _queryform;
|
|
}
|
|
|
|
QueryTree::QueryForm QueryTree::getQueryForm()
|
|
{
|
|
return this->query_form;
|
|
}
|
|
|
|
void QueryTree::setProjectionModifier(ProjectionModifier _projection_modifier)
|
|
{
|
|
this->projection_modifier = _projection_modifier;
|
|
}
|
|
|
|
QueryTree::ProjectionModifier QueryTree::getProjectionModifier()
|
|
{
|
|
return this->projection_modifier;
|
|
}
|
|
|
|
void QueryTree::addProjectionVar()
|
|
{
|
|
this->projection.push_back(ProjectionVar());
|
|
}
|
|
|
|
QueryTree::ProjectionVar& QueryTree::getLastProjectionVar()
|
|
{
|
|
return this->projection.back();
|
|
}
|
|
|
|
vector<QueryTree::ProjectionVar>& QueryTree::getProjection()
|
|
{
|
|
return this->projection;
|
|
}
|
|
|
|
Varset QueryTree::getProjectionVarset()
|
|
{
|
|
Varset varset;
|
|
|
|
for (int i = 0; i < (int)this->projection.size(); i++)
|
|
varset.addVar(this->projection[i].var);
|
|
|
|
return varset;
|
|
}
|
|
|
|
Varset QueryTree::getResultProjectionVarset()
|
|
{
|
|
Varset varset;
|
|
|
|
for (int i = 0; i < (int)this->projection.size(); i++)
|
|
if (this->projection[i].aggregate_type == ProjectionVar::None_type)
|
|
varset.addVar(this->projection[i].var);
|
|
else if (this->projection[i].aggregate_var != "*")
|
|
varset.addVar(this->projection[i].aggregate_var);
|
|
|
|
return varset;
|
|
}
|
|
|
|
void QueryTree::setProjectionAsterisk()
|
|
{
|
|
this->projection_asterisk = true;
|
|
}
|
|
|
|
bool QueryTree::checkProjectionAsterisk()
|
|
{
|
|
return this->projection_asterisk;
|
|
}
|
|
|
|
void QueryTree::addGroupByVar(string &_var)
|
|
{
|
|
this->group_by.addVar(_var);
|
|
}
|
|
|
|
Varset& QueryTree::getGroupByVarset()
|
|
{
|
|
return this->group_by;
|
|
}
|
|
|
|
void QueryTree::addOrderVar(string &_var, bool _descending)
|
|
{
|
|
this->order_by.push_back(Order(_var, _descending));
|
|
}
|
|
|
|
vector<QueryTree::Order>& QueryTree::getOrderVarVector()
|
|
{
|
|
return this->order_by;
|
|
}
|
|
|
|
Varset QueryTree::getOrderByVarset()
|
|
{
|
|
Varset varset;
|
|
|
|
for (int i = 0; i < (int)this->order_by.size(); i++)
|
|
varset.addVar(this->order_by[i].var);
|
|
|
|
return varset;
|
|
}
|
|
|
|
void QueryTree::setOffset(int _offset)
|
|
{
|
|
this->offset = _offset;
|
|
}
|
|
|
|
int QueryTree::getOffset()
|
|
{
|
|
return this->offset;
|
|
}
|
|
|
|
void QueryTree::setLimit(int _limit)
|
|
{
|
|
this->limit = _limit;
|
|
}
|
|
|
|
int QueryTree::getLimit()
|
|
{
|
|
return this->limit;
|
|
}
|
|
|
|
QueryTree::GroupPattern& QueryTree::getGroupPattern()
|
|
{
|
|
return this->grouppattern;
|
|
}
|
|
|
|
void QueryTree::setUpdateType(UpdateType _updatetype)
|
|
{
|
|
this->update_type = _updatetype;
|
|
}
|
|
|
|
QueryTree::UpdateType QueryTree::getUpdateType()
|
|
{
|
|
return this->update_type;
|
|
}
|
|
|
|
QueryTree::GroupPattern& QueryTree::getInsertPatterns()
|
|
{
|
|
return this->insert_patterns;
|
|
}
|
|
|
|
QueryTree::GroupPattern& QueryTree::getDeletePatterns()
|
|
{
|
|
return this->delete_patterns;
|
|
}
|
|
|
|
bool QueryTree::checkWellDesigned()
|
|
{
|
|
bool check_condition = true;
|
|
this->grouppattern.checkNoMinusAndOptionalVarAndSafeFilter(Varset(), Varset(), check_condition);
|
|
return check_condition;
|
|
}
|
|
|
|
bool QueryTree::checkAtLeastOneAggregateFunction()
|
|
{
|
|
for (int i = 0; i < (int)this->projection.size(); i++)
|
|
if (this->projection[i].aggregate_type != ProjectionVar::None_type)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
bool QueryTree::checkSelectAggregateFunctionGroupByValid()
|
|
{
|
|
if (this->checkAtLeastOneAggregateFunction() && this->group_by.empty())
|
|
{
|
|
for (int i = 0; i < (int)this->projection.size(); i++)
|
|
if (this->projection[i].aggregate_type == ProjectionVar::None_type)
|
|
return false;
|
|
}
|
|
|
|
if (!this->group_by.empty())
|
|
{
|
|
for (int i = 0; i < (int)this->projection.size(); i++)
|
|
if (this->projection[i].aggregate_type == ProjectionVar::None_type && !this->group_by.findVar(this->projection[i].var))
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void QueryTree::print()
|
|
{
|
|
for (int j = 0; j < 80; j++) printf("="); printf("\n");
|
|
|
|
if (this->update_type == Not_Update)
|
|
{
|
|
if (this->query_form == Select_Query)
|
|
{
|
|
printf("SELECT");
|
|
if (this->projection_modifier == Modifier_Distinct)
|
|
printf(" DISTINCT");
|
|
printf("\n");
|
|
|
|
printf("Var: \t");
|
|
for (int i = 0; i < (int)this->projection.size(); i++)
|
|
{
|
|
if (this->projection[i].aggregate_type == QueryTree::ProjectionVar::None_type)
|
|
printf("%s\t", this->projection[i].var.c_str());
|
|
else
|
|
{
|
|
printf("(");
|
|
if (this->projection[i].aggregate_type == QueryTree::ProjectionVar::Count_type)
|
|
printf("COUNT(");
|
|
if (this->projection[i].aggregate_type == QueryTree::ProjectionVar::Sum_type)
|
|
printf("SUM(");
|
|
if (this->projection[i].aggregate_type == QueryTree::ProjectionVar::Min_type)
|
|
printf("MIN(");
|
|
if (this->projection[i].aggregate_type == QueryTree::ProjectionVar::Max_type)
|
|
printf("MAX(");
|
|
if (this->projection[i].aggregate_type == QueryTree::ProjectionVar::Avg_type)
|
|
printf("AVG(");
|
|
if (this->projection[i].distinct)
|
|
printf("DISTINCT ");
|
|
printf("%s) AS %s)\t", this->projection[i].aggregate_var.c_str(), this->projection[i].var.c_str());
|
|
}
|
|
}
|
|
if (this->projection_asterisk && !this->checkAtLeastOneAggregateFunction())
|
|
printf("*");
|
|
printf("\n");
|
|
}
|
|
else printf("ASK\n");
|
|
|
|
printf("GroupPattern:\n");
|
|
this->grouppattern.print(0);
|
|
|
|
if (this->query_form == Select_Query)
|
|
{
|
|
if (!this->group_by.empty())
|
|
{
|
|
printf("GROUP BY\t");
|
|
|
|
for (int i = 0; i < (int)this->group_by.vars.size(); i++)
|
|
printf("%s\t", this->group_by.vars[i].c_str());
|
|
|
|
printf("\n");
|
|
}
|
|
|
|
if (!this->order_by.empty())
|
|
{
|
|
printf("ORDER BY\t");
|
|
|
|
for (int i = 0; i < (int)this->order_by.size(); i++)
|
|
{
|
|
if (!this->order_by[i].descending) printf("ASC(");
|
|
else printf("DESC(");
|
|
printf("%s)\t", this->order_by[i].var.c_str());
|
|
}
|
|
printf("\n");
|
|
}
|
|
if (this->offset != 0)
|
|
printf("OFFSET\t%d\n", this->offset);
|
|
if (this->limit != -1)
|
|
printf("LIMIT\t%d\n", this->limit);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
printf("UPDATE\n");
|
|
if (this->update_type == Delete_Data || this->update_type == Delete_Where ||
|
|
this->update_type == Delete_Clause || this->update_type == Modify_Clause)
|
|
{
|
|
printf("Delete:\n");
|
|
this->delete_patterns.print(0);
|
|
}
|
|
if (this->update_type == Insert_Data || this->update_type == Insert_Clause || this->update_type == Modify_Clause)
|
|
{
|
|
printf("Insert:\n");
|
|
this->insert_patterns.print(0);
|
|
}
|
|
if (this->update_type == Delete_Where || this->update_type == Insert_Clause ||
|
|
this->update_type == Delete_Clause || this->update_type == Modify_Clause)
|
|
{
|
|
printf("GroupPattern:\n");
|
|
this->grouppattern.print(0);
|
|
}
|
|
}
|
|
|
|
for (int j = 0; j < 80; j++) printf("="); printf("\n");
|
|
}
|