feat(Query): Support computation in SELECT clause
This commit is contained in:
parent
c92a22fecf
commit
4f571b24bf
|
@ -320,98 +320,188 @@ void QueryParser::parseSelectAggregateFunction(SPARQLParser::ExpressionContext *
|
|||
conditionalAndexpression(0)->valueLogical(0)->relationalexpression()-> \
|
||||
numericexpression(0)->additiveexpression()->multiplicativeexpression(0)-> \
|
||||
unaryexpression(0)->primaryexpression()->builtInCall();
|
||||
if (!bicCtx)
|
||||
throw runtime_error("[ERROR] Currently only support selecting variables, "
|
||||
"the aggregate function COUNT, and path-associated built-in calls");
|
||||
antlr4::tree::ParseTree *curr = expCtx;
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
// Make sure only one children along the way
|
||||
if (curr->children.size() > 1)
|
||||
throw runtime_error("[ERROR] Currently only support selecting variables, "
|
||||
"the aggregate function COUNT, and path-associated built-in calls");
|
||||
curr = curr->children[0];
|
||||
}
|
||||
SPARQLParser::AggregateContext *aggCtx = bicCtx->aggregate();
|
||||
if (aggCtx)
|
||||
{
|
||||
string tmp = aggCtx->children[0]->getText();
|
||||
transform(tmp.begin(), tmp.end(), tmp.begin(), ::toupper);
|
||||
if (tmp != "COUNT")
|
||||
throw runtime_error("[ERROR] The supported aggregate function now is COUNT only");
|
||||
// if (!bicCtx)
|
||||
// throw runtime_error("[ERROR] Currently only support selecting variables, "
|
||||
// "the aggregate function COUNT, and path-associated built-in calls");
|
||||
if (bicCtx)
|
||||
{
|
||||
antlr4::tree::ParseTree *curr = expCtx;
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
// Make sure only one children along the way
|
||||
if (curr->children.size() > 1)
|
||||
throw runtime_error("[ERROR] Currently only support selecting variables, "
|
||||
"the aggregate function COUNT, and path-associated built-in calls");
|
||||
curr = curr->children[0];
|
||||
}
|
||||
SPARQLParser::AggregateContext *aggCtx = bicCtx->aggregate();
|
||||
if (aggCtx)
|
||||
{
|
||||
string tmp = aggCtx->children[0]->getText();
|
||||
transform(tmp.begin(), tmp.end(), tmp.begin(), ::toupper);
|
||||
if (tmp != "COUNT")
|
||||
throw runtime_error("[ERROR] The supported aggregate function now is COUNT only");
|
||||
|
||||
query_tree_ptr->addProjectionVar();
|
||||
QueryTree::ProjectionVar &proj_var = query_tree_ptr->getLastProjectionVar();
|
||||
proj_var.aggregate_type = QueryTree::ProjectionVar::Count_type;
|
||||
proj_var.aggregate_var = aggCtx->expression()->getText(); // Error would have been dealt with
|
||||
tmp = aggCtx->children[2]->getText();
|
||||
transform(tmp.begin(), tmp.end(), tmp.begin(), ::toupper);
|
||||
proj_var.distinct = aggCtx->children[2]->children.size() == 0 && tmp == "DISTINCT";
|
||||
proj_var.var = varCtx->getText();
|
||||
}
|
||||
else
|
||||
{
|
||||
string tmp = bicCtx->children[0]->getText();
|
||||
transform(tmp.begin(), tmp.end(), tmp.begin(), ::toupper);
|
||||
if (tmp != "SIMPLECYCLEPATH" && tmp != "SIMPLECYCLEBOOLEAN"
|
||||
&& tmp != "CYCLEPATH" && tmp != "CYCLEBOOLEAN"
|
||||
&& tmp != "SHORTESTPATH" && tmp != "SHORTESTPATHLEN"
|
||||
&& tmp != "KHOPREACHABLE" && tmp != "KHOPENUMERATE")
|
||||
throw runtime_error("[ERROR] Currently only support selecting variables, "
|
||||
"the aggregate function COUNT, and path-associated built-in calls");
|
||||
|
||||
query_tree_ptr->addProjectionVar();
|
||||
QueryTree::ProjectionVar &proj_var = query_tree_ptr->getLastProjectionVar();
|
||||
if (tmp == "SIMPLECYCLEPATH")
|
||||
proj_var.aggregate_type = QueryTree::ProjectionVar::simpleCyclePath_type;
|
||||
else if (tmp == "SIMPLECYCLEBOOLEAN")
|
||||
proj_var.aggregate_type = QueryTree::ProjectionVar::simpleCycleBoolean_type;
|
||||
else if (tmp == "CYCLEPATH")
|
||||
proj_var.aggregate_type = QueryTree::ProjectionVar::cyclePath_type;
|
||||
else if (tmp == "CYCLEBOOLEAN")
|
||||
proj_var.aggregate_type = QueryTree::ProjectionVar::cycleBoolean_type;
|
||||
else if (tmp == "SHORTESTPATH")
|
||||
proj_var.aggregate_type = QueryTree::ProjectionVar::shortestPath_type;
|
||||
else if (tmp == "SHORTESTPATHLEN")
|
||||
proj_var.aggregate_type = QueryTree::ProjectionVar::shortestPathLen_type;
|
||||
else if (tmp == "KHOPREACHABLE")
|
||||
proj_var.aggregate_type = QueryTree::ProjectionVar::kHopReachable_type;
|
||||
else if (tmp == "KHOPENUMERATE")
|
||||
proj_var.aggregate_type = QueryTree::ProjectionVar::kHopEnumerate_type;
|
||||
|
||||
proj_var.path_args.src = bicCtx->varOrIri(0)->getText();
|
||||
replacePrefix(proj_var.path_args.src);
|
||||
proj_var.path_args.dst = bicCtx->varOrIri(1)->getText();
|
||||
replacePrefix(proj_var.path_args.dst);
|
||||
auto predSet = bicCtx->predSet()->iri();
|
||||
for (auto pred : predSet)
|
||||
{
|
||||
string prefixedPred = pred->getText();
|
||||
replacePrefix(prefixedPred);
|
||||
proj_var.path_args.pred_set.push_back(prefixedPred);
|
||||
}
|
||||
|
||||
if (tmp == "KHOPREACHABLE" || tmp == "KHOPENUMERATE")
|
||||
{
|
||||
if (bicCtx->num_integer())
|
||||
proj_var.path_args.k = stoi(bicCtx->num_integer()->getText());
|
||||
else if (bicCtx->integer_positive())
|
||||
proj_var.path_args.k = stoi(bicCtx->integer_positive()->getText());
|
||||
else if (bicCtx->integer_negative())
|
||||
proj_var.path_args.k = stoi(bicCtx->integer_negative()->getText());
|
||||
|
||||
if (bicCtx->numericLiteral())
|
||||
proj_var.path_args.confidence = stof(bicCtx->numericLiteral()->getText());
|
||||
else
|
||||
proj_var.path_args.confidence = 1;
|
||||
}
|
||||
if (bicCtx->booleanLiteral()->getText() == "true")
|
||||
proj_var.path_args.directed = true;
|
||||
else
|
||||
proj_var.path_args.directed = false;
|
||||
|
||||
proj_var.var = varCtx->getText();
|
||||
}
|
||||
}
|
||||
else // For multi-layer computation, only consider vars, literals, and bracketted expressions for now
|
||||
{
|
||||
query_tree_ptr->addProjectionVar();
|
||||
QueryTree::ProjectionVar &proj_var = query_tree_ptr->getLastProjectionVar();
|
||||
proj_var.aggregate_type = QueryTree::ProjectionVar::Count_type;
|
||||
proj_var.aggregate_var = aggCtx->expression()->getText(); // Error would have been dealt with
|
||||
tmp = aggCtx->children[2]->getText();
|
||||
transform(tmp.begin(), tmp.end(), tmp.begin(), ::toupper);
|
||||
proj_var.distinct = aggCtx->children[2]->children.size() == 0 && tmp == "DISTINCT";
|
||||
proj_var.aggregate_type = QueryTree::ProjectionVar::CompTree_type;
|
||||
proj_var.var = varCtx->getText();
|
||||
proj_var.comp_tree_root = new QueryTree::CompTreeNode;
|
||||
buildCompTree(expCtx, -1, proj_var.comp_tree_root);
|
||||
}
|
||||
}
|
||||
|
||||
void QueryParser::buildCompTree(antlr4::tree::ParseTree *root, int oper_pos, QueryTree::CompTreeNode *curr_node)
|
||||
{
|
||||
cout << root->getText() << endl;
|
||||
cout << "#children = " << root->children.size() << endl;
|
||||
|
||||
if (root->children.size() == 1)
|
||||
{
|
||||
if (((SPARQLParser::PrimaryexpressionContext *)root)->rDFLiteral())
|
||||
{
|
||||
curr_node->oprt = "";
|
||||
curr_node->lchild = NULL;
|
||||
curr_node->rchild = NULL;
|
||||
curr_node->val = root->getText();
|
||||
}
|
||||
else if (((SPARQLParser::PrimaryexpressionContext *)root)->numericLiteral())
|
||||
{
|
||||
curr_node->oprt = "";
|
||||
curr_node->lchild = NULL;
|
||||
curr_node->rchild = NULL;
|
||||
auto numericLiteral = ((SPARQLParser::PrimaryexpressionContext *)root)->numericLiteral();
|
||||
curr_node->val = getNumeric(numericLiteral);
|
||||
}
|
||||
else if (((SPARQLParser::PrimaryexpressionContext *)root)->booleanLiteral())
|
||||
{
|
||||
curr_node->oprt = "";
|
||||
curr_node->lchild = NULL;
|
||||
curr_node->rchild = NULL;
|
||||
curr_node->val = "\"" + root->getText() + "\"" + "^^<http://www.w3.org/2001/XMLSchema#boolean>";
|
||||
}
|
||||
else if (((SPARQLParser::PrimaryexpressionContext *)root)->var())
|
||||
{
|
||||
curr_node->oprt = "";
|
||||
curr_node->lchild = NULL;
|
||||
curr_node->rchild = NULL;
|
||||
curr_node->val = root->getText();
|
||||
}
|
||||
else
|
||||
buildCompTree(root->children[0], -1, curr_node);
|
||||
}
|
||||
else if (root->children.size() == 2)
|
||||
{
|
||||
if (root->children[0]->getText()[0] != '!' \
|
||||
&& root->children[0]->getText()[0] != '+' \
|
||||
&& root->children[0]->getText()[0] != '-')
|
||||
throw runtime_error("[ERROR] Unary operator not supported");
|
||||
curr_node->oprt = root->children[0]->getText();
|
||||
curr_node->lchild = new QueryTree::CompTreeNode;
|
||||
curr_node->rchild = NULL;
|
||||
curr_node->val = "";
|
||||
buildCompTree(root->children[1], -1, curr_node->lchild);
|
||||
}
|
||||
else if (root->children.size() % 2 == 1) // >= 3, odd #children
|
||||
{
|
||||
if (root->children[0]->getText() == "(")
|
||||
buildCompTree(root->children[1], -1, curr_node);
|
||||
else
|
||||
{
|
||||
int rightmostOprtPos = (root->children.size() - 1) / 2;
|
||||
// if (oper_pos == -1)
|
||||
// oper_pos = 1;
|
||||
if (oper_pos < rightmostOprtPos)
|
||||
{
|
||||
int new_oper_pos = oper_pos + 2;
|
||||
curr_node->oprt = root->children[oper_pos + 2]->getText();
|
||||
curr_node->lchild = new QueryTree::CompTreeNode;
|
||||
curr_node->rchild = new QueryTree::CompTreeNode;
|
||||
curr_node->val = "";
|
||||
buildCompTree(root->children[oper_pos + 1], -1, curr_node->lchild);
|
||||
buildCompTree(root, oper_pos + 2, curr_node->rchild);
|
||||
}
|
||||
else // oper_pos == rightmostOprtPos, the last operator on this level has been handled
|
||||
buildCompTree(root->children[oper_pos + 1], -1, curr_node);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string tmp = bicCtx->children[0]->getText();
|
||||
transform(tmp.begin(), tmp.end(), tmp.begin(), ::toupper);
|
||||
if (tmp != "SIMPLECYCLEPATH" && tmp != "SIMPLECYCLEBOOLEAN"
|
||||
&& tmp != "CYCLEPATH" && tmp != "CYCLEBOOLEAN"
|
||||
&& tmp != "SHORTESTPATH" && tmp != "SHORTESTPATHLEN"
|
||||
&& tmp != "KHOPREACHABLE" && tmp != "KHOPENUMERATE")
|
||||
throw runtime_error("[ERROR] Currently only support selecting variables, "
|
||||
"the aggregate function COUNT, and path-associated built-in calls");
|
||||
|
||||
query_tree_ptr->addProjectionVar();
|
||||
QueryTree::ProjectionVar &proj_var = query_tree_ptr->getLastProjectionVar();
|
||||
if (tmp == "SIMPLECYCLEPATH")
|
||||
proj_var.aggregate_type = QueryTree::ProjectionVar::simpleCyclePath_type;
|
||||
else if (tmp == "SIMPLECYCLEBOOLEAN")
|
||||
proj_var.aggregate_type = QueryTree::ProjectionVar::simpleCycleBoolean_type;
|
||||
else if (tmp == "CYCLEPATH")
|
||||
proj_var.aggregate_type = QueryTree::ProjectionVar::cyclePath_type;
|
||||
else if (tmp == "CYCLEBOOLEAN")
|
||||
proj_var.aggregate_type = QueryTree::ProjectionVar::cycleBoolean_type;
|
||||
else if (tmp == "SHORTESTPATH")
|
||||
proj_var.aggregate_type = QueryTree::ProjectionVar::shortestPath_type;
|
||||
else if (tmp == "SHORTESTPATHLEN")
|
||||
proj_var.aggregate_type = QueryTree::ProjectionVar::shortestPathLen_type;
|
||||
else if (tmp == "KHOPREACHABLE")
|
||||
proj_var.aggregate_type = QueryTree::ProjectionVar::kHopReachable_type;
|
||||
else if (tmp == "KHOPENUMERATE")
|
||||
proj_var.aggregate_type = QueryTree::ProjectionVar::kHopEnumerate_type;
|
||||
|
||||
proj_var.path_args.src = bicCtx->varOrIri(0)->getText();
|
||||
replacePrefix(proj_var.path_args.src);
|
||||
proj_var.path_args.dst = bicCtx->varOrIri(1)->getText();
|
||||
replacePrefix(proj_var.path_args.dst);
|
||||
auto predSet = bicCtx->predSet()->iri();
|
||||
for (auto pred : predSet)
|
||||
{
|
||||
string prefixedPred = pred->getText();
|
||||
replacePrefix(prefixedPred);
|
||||
proj_var.path_args.pred_set.push_back(prefixedPred);
|
||||
}
|
||||
|
||||
if (tmp == "KHOPREACHABLE" || tmp == "KHOPENUMERATE")
|
||||
{
|
||||
if (bicCtx->num_integer())
|
||||
proj_var.path_args.k = stoi(bicCtx->num_integer()->getText());
|
||||
else if (bicCtx->integer_positive())
|
||||
proj_var.path_args.k = stoi(bicCtx->integer_positive()->getText());
|
||||
else if (bicCtx->integer_negative())
|
||||
proj_var.path_args.k = stoi(bicCtx->integer_negative()->getText());
|
||||
|
||||
if (bicCtx->numericLiteral())
|
||||
proj_var.path_args.confidence = stof(bicCtx->numericLiteral()->getText());
|
||||
else
|
||||
proj_var.path_args.confidence = 1;
|
||||
}
|
||||
if (bicCtx->booleanLiteral()->getText() == "true")
|
||||
proj_var.path_args.directed = true;
|
||||
else
|
||||
proj_var.path_args.directed = false;
|
||||
|
||||
proj_var.var = varCtx->getText();
|
||||
}
|
||||
throw runtime_error("[ERROR] Computation type not supported (an even #children > 2)");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -56,6 +56,7 @@ public:
|
|||
|
||||
void parseSelectAggregateFunction(SPARQLParser::ExpressionContext *expCtx, \
|
||||
SPARQLParser::VarContext *varCtx);
|
||||
void buildCompTree(antlr4::tree::ParseTree *root, int oper_pos, QueryTree::CompTreeNode *curr_node);
|
||||
void buildFilterTree(antlr4::tree::ParseTree *root, \
|
||||
QueryTree::GroupPattern::FilterTree::FilterTreeNode::FilterTreeChild *currChild, \
|
||||
QueryTree::GroupPattern::FilterTree::FilterTreeNode &filter, std::string tp);
|
||||
|
|
|
@ -1190,7 +1190,8 @@ void GeneralEvaluation::getFinalResult(ResultSet &ret_result)
|
|||
|
||||
if (result0_size == 0 && proj.size() == 1 && \
|
||||
proj[0].aggregate_type != QueryTree::ProjectionVar::None_type && \
|
||||
proj[0].aggregate_type != QueryTree::ProjectionVar::Count_type)
|
||||
proj[0].aggregate_type != QueryTree::ProjectionVar::Count_type && \
|
||||
proj[0].aggregate_type != QueryTree::ProjectionVar::CompTree_type)
|
||||
{
|
||||
// Path query, both nodes are IRI
|
||||
|
||||
|
@ -1427,6 +1428,22 @@ void GeneralEvaluation::getFinalResult(ResultSet &ret_result)
|
|||
ss << "\"^^<http://www.w3.org/2001/XMLSchema#integer>";
|
||||
ss >> new_result0.result.back().str[proj2new[i] - new_result0_id_cols];
|
||||
}
|
||||
else if (proj[i].aggregate_type == QueryTree::ProjectionVar::CompTree_type)
|
||||
{
|
||||
// Strictly speaking, not an aggregate; each original line will produce a line of results
|
||||
for (int j = begin; j <= end; j++)
|
||||
{
|
||||
new_result0.result.back().str[proj2new[i] - new_result0_id_cols] = \
|
||||
result0.doComp(proj[i].comp_tree_root, result0.result[j], result0_id_cols, stringindex, \
|
||||
query_tree.getGroupPattern().group_pattern_subject_object_maximal_varset).term_value;
|
||||
if (j < end)
|
||||
{
|
||||
new_result0.result.push_back(TempResult::ResultPair());
|
||||
new_result0.result.back().id = new unsigned[new_result0_id_cols];
|
||||
new_result0.result.back().str.resize(new_result0_str_cols);
|
||||
}
|
||||
}
|
||||
}
|
||||
else // Path query
|
||||
{
|
||||
prepPathQuery();
|
||||
|
|
|
@ -875,7 +875,8 @@ bool QueryTree::checkWellDesigned()
|
|||
|| proj.aggregate_type == ProjectionVar::shortestPath_type
|
||||
|| proj.aggregate_type == ProjectionVar::shortestPathLen_type
|
||||
|| proj.aggregate_type == ProjectionVar::kHopReachable_type
|
||||
|| proj.aggregate_type == ProjectionVar::kHopEnumerate_type)
|
||||
|| proj.aggregate_type == ProjectionVar::kHopEnumerate_type
|
||||
|| proj.aggregate_type == ProjectionVar::CompTree_type)
|
||||
{
|
||||
check_condition = false;
|
||||
break;
|
||||
|
@ -973,6 +974,11 @@ void QueryTree::print()
|
|||
printf("kHopReachable(");
|
||||
if (this->projection[i].aggregate_type == QueryTree::ProjectionVar::kHopEnumerate_type)
|
||||
printf("kHopEnumerate(");
|
||||
if (this->projection[i].aggregate_type == QueryTree::ProjectionVar::CompTree_type)
|
||||
{
|
||||
cout << endl;
|
||||
projection[i].comp_tree_root->print(0);
|
||||
}
|
||||
|
||||
if (this->projection[i].distinct)
|
||||
printf("DISTINCT ");
|
||||
|
@ -1079,3 +1085,33 @@ void QueryTree::print()
|
|||
|
||||
for (int j = 0; j < 80; j++) printf("="); printf("\n");
|
||||
}
|
||||
|
||||
void QueryTree::CompTreeNode::print(int dep)
|
||||
{
|
||||
if (!lchild && !rchild)
|
||||
{
|
||||
for (int i = 0; i < dep; i++)
|
||||
cout << '\t';
|
||||
cout << "Value: " << val << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < dep; i++)
|
||||
cout << '\t';
|
||||
cout << "Operator " << oprt << endl;
|
||||
if (lchild)
|
||||
{
|
||||
for (int i = 0; i < dep; i++)
|
||||
cout << '\t';
|
||||
cout << "lchild:" << endl;
|
||||
lchild->print(dep + 1);
|
||||
}
|
||||
if (rchild)
|
||||
{
|
||||
for (int i = 0; i < dep; i++)
|
||||
cout << '\t';
|
||||
cout << "rchild:" << endl;
|
||||
rchild->print(dep + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,6 +104,17 @@ class QueryTree
|
|||
float confidence;
|
||||
};
|
||||
|
||||
class CompTreeNode
|
||||
{
|
||||
public:
|
||||
std::string oprt; // operator
|
||||
CompTreeNode *lchild;
|
||||
CompTreeNode *rchild; // child nodes
|
||||
std::string val; // variable, or literal followed by datatype suffix
|
||||
|
||||
void print(int dep); // Print subtree rooted at this node
|
||||
};
|
||||
|
||||
class GroupPattern::FilterTree
|
||||
{
|
||||
public:
|
||||
|
@ -195,7 +206,8 @@ class QueryTree
|
|||
public:
|
||||
enum AggregateType {None_type, Count_type, Sum_type, Min_type, Max_type, Avg_type,
|
||||
simpleCyclePath_type, simpleCycleBoolean_type, cyclePath_type, cycleBoolean_type,
|
||||
shortestPath_type, shortestPathLen_type, kHopReachable_type, kHopEnumerate_type};
|
||||
shortestPath_type, shortestPathLen_type, kHopReachable_type, kHopEnumerate_type,
|
||||
CompTree_type};
|
||||
AggregateType aggregate_type;
|
||||
|
||||
std::string var, aggregate_var;
|
||||
|
@ -203,6 +215,8 @@ class QueryTree
|
|||
|
||||
PathArgs path_args;
|
||||
|
||||
CompTreeNode *comp_tree_root;
|
||||
|
||||
ProjectionVar():aggregate_type(None_type), distinct(false){}
|
||||
};
|
||||
|
||||
|
|
|
@ -889,6 +889,85 @@ EvalMultitypeValue
|
|||
return ret_femv;
|
||||
}
|
||||
|
||||
EvalMultitypeValue
|
||||
TempResult::doComp(QueryTree::CompTreeNode *root, ResultPair &row, int id_cols, StringIndex *stringindex, Varset &entity_literal_varset)
|
||||
{
|
||||
if (root->lchild == NULL && root->rchild == NULL) // leaf node
|
||||
{
|
||||
EvalMultitypeValue x;
|
||||
x.datatype = EvalMultitypeValue::rdf_term;
|
||||
if (root->val[0] == '?') // variable
|
||||
{
|
||||
int pos;
|
||||
pos = Varset(root->val).mapTo(entity_literal_varset)[0];
|
||||
if (pos == -1)
|
||||
{
|
||||
x.datatype = EvalMultitypeValue::xsd_boolean;
|
||||
x.bool_value = EvalMultitypeValue::EffectiveBooleanValue::error_value;
|
||||
return x;
|
||||
}
|
||||
if (pos < id_cols)
|
||||
{
|
||||
int id = row.id[pos];
|
||||
bool isel = entity_literal_varset.findVar(root->val);
|
||||
stringindex->randomAccess(id, &x.term_value, isel);
|
||||
}
|
||||
else
|
||||
x.term_value = row.str[pos - id_cols];
|
||||
}
|
||||
else // literal
|
||||
x.term_value = root->val;
|
||||
x.deduceTypeValue();
|
||||
cout << "x.term_value = " << x.term_value << endl;
|
||||
return x;
|
||||
}
|
||||
else
|
||||
{
|
||||
EvalMultitypeValue lRes, rRes;
|
||||
if (root->lchild)
|
||||
lRes = doComp(root->lchild, row, id_cols, stringindex, entity_literal_varset);
|
||||
if (root->rchild)
|
||||
rRes = doComp(root->rchild, row, id_cols, stringindex, entity_literal_varset);
|
||||
|
||||
if (root->oprt == "||")
|
||||
return lRes || rRes;
|
||||
else if (root->oprt == "&&")
|
||||
return lRes && rRes;
|
||||
else if (root->oprt == "=")
|
||||
return lRes == rRes;
|
||||
else if (root->oprt == "!=")
|
||||
return lRes != rRes;
|
||||
else if (root->oprt == "<")
|
||||
return lRes < rRes;
|
||||
else if (root->oprt == ">")
|
||||
return lRes > rRes;
|
||||
else if (root->oprt == "<=")
|
||||
return lRes <= rRes;
|
||||
else if (root->oprt == ">=")
|
||||
return lRes >= rRes;
|
||||
else if (root->oprt == "+")
|
||||
{
|
||||
if (!root->rchild) // unary
|
||||
return lRes;
|
||||
else // binary
|
||||
return lRes + rRes;
|
||||
}
|
||||
else if (root->oprt == "-")
|
||||
{
|
||||
if (!root->rchild) // unary
|
||||
return -lRes;
|
||||
else // binary
|
||||
return lRes - rRes;
|
||||
}
|
||||
else if (root->oprt == "*")
|
||||
return lRes * rRes;
|
||||
else if (root->oprt == "/")
|
||||
return lRes / rRes;
|
||||
else if (root->oprt == "!")
|
||||
return !lRes;
|
||||
}
|
||||
}
|
||||
|
||||
void TempResult::doFilter(QueryTree::GroupPattern::FilterTree::FilterTreeNode &filter, TempResult &r, StringIndex *stringindex, Varset &entity_literal_varset)
|
||||
{
|
||||
Varset this_varset = this->getAllVarset();
|
||||
|
|
|
@ -50,6 +50,8 @@ class TempResult
|
|||
EvalMultitypeValue matchFilterTree(QueryTree::GroupPattern::FilterTree::FilterTreeNode &filter, ResultPair &row, int id_cols, StringIndex *stringindex);
|
||||
void doFilter(QueryTree::GroupPattern::FilterTree::FilterTreeNode &filter, TempResult &r, StringIndex *stringindex, Varset &entity_literal_varset);
|
||||
|
||||
EvalMultitypeValue doComp(QueryTree::CompTreeNode *root, ResultPair &row, int id_cols, StringIndex *stringindex, Varset &entity_literal_varset);
|
||||
|
||||
void print(int no=-1);
|
||||
};
|
||||
|
||||
|
|
|
@ -226,6 +226,8 @@ EvalMultitypeValue
|
|||
return ret_femv;
|
||||
|
||||
ret_femv.bool_value = !this->bool_value;
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
|
@ -240,6 +242,8 @@ EvalMultitypeValue
|
|||
return ret_femv;
|
||||
|
||||
ret_femv.bool_value = (this->bool_value || x.bool_value);
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
|
@ -254,6 +258,8 @@ EvalMultitypeValue
|
|||
return ret_femv;
|
||||
|
||||
ret_femv.bool_value = (this->bool_value && x.bool_value);
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
|
@ -267,6 +273,8 @@ EvalMultitypeValue
|
|||
if (this->datatype == xsd_boolean && x.datatype == xsd_boolean)
|
||||
{
|
||||
ret_femv.bool_value = (this->bool_value == x.bool_value);
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
|
@ -278,6 +286,8 @@ EvalMultitypeValue
|
|||
return ret_femv;
|
||||
|
||||
ret_femv.bool_value = EffectiveBooleanValue::false_value;
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
|
@ -294,28 +304,37 @@ EvalMultitypeValue
|
|||
if (this->datatype == xsd_double && x.datatype == xsd_double)
|
||||
ret_femv.bool_value = (this->dbl_value == x.dbl_value);
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
if (this->isSimpleLiteral() && x.isSimpleLiteral())
|
||||
{
|
||||
ret_femv.bool_value = (this->str_value == x.str_value);
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
if (this->datatype == xsd_string && x.datatype == xsd_string)
|
||||
{
|
||||
ret_femv.bool_value = (this->str_value == x.str_value);
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
if (this->datatype == xsd_datetime && x.datatype == xsd_datetime)
|
||||
{
|
||||
ret_femv.bool_value = (this->dt_value == x.dt_value);
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
ret_femv.bool_value = (this->term_value == x.term_value);
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
|
@ -329,6 +348,8 @@ EvalMultitypeValue
|
|||
if (this->datatype == xsd_boolean && x.datatype == xsd_boolean)
|
||||
{
|
||||
ret_femv.bool_value = (this->bool_value != x.bool_value);
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
|
@ -340,6 +361,8 @@ EvalMultitypeValue
|
|||
return ret_femv;
|
||||
|
||||
ret_femv.bool_value = EffectiveBooleanValue::true_value;
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
|
@ -356,28 +379,37 @@ EvalMultitypeValue
|
|||
if (this->datatype == xsd_double && x.datatype == xsd_double)
|
||||
ret_femv.bool_value = (this->dbl_value != x.dbl_value);
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
if (this->isSimpleLiteral() && x.isSimpleLiteral())
|
||||
{
|
||||
ret_femv.bool_value = (this->str_value != x.str_value);
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
if (this->datatype == xsd_string && x.datatype == xsd_string)
|
||||
{
|
||||
ret_femv.bool_value = (this->str_value != x.str_value);
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
if (this->datatype == xsd_datetime && x.datatype == xsd_datetime)
|
||||
{
|
||||
ret_femv.bool_value = (this->dt_value != x.dt_value);
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
ret_femv.bool_value = (this->term_value != x.term_value);
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
|
@ -391,6 +423,8 @@ EvalMultitypeValue
|
|||
if (this->datatype == xsd_boolean && x.datatype == xsd_boolean)
|
||||
{
|
||||
ret_femv.bool_value = (this->bool_value < x.bool_value);
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
|
@ -407,27 +441,35 @@ EvalMultitypeValue
|
|||
if (this->datatype == xsd_double && x.datatype == xsd_double)
|
||||
ret_femv.bool_value = (this->dbl_value < x.dbl_value);
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
if (this->isSimpleLiteral() && x.isSimpleLiteral())
|
||||
{
|
||||
ret_femv.bool_value = (this->str_value < x.str_value);
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
if (this->datatype == xsd_string && x.datatype == xsd_string)
|
||||
{
|
||||
ret_femv.bool_value = (this->str_value < x.str_value);
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
if (this->datatype == xsd_datetime && x.datatype == xsd_datetime)
|
||||
{
|
||||
ret_femv.bool_value = (this->dt_value < x.dt_value);
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
|
@ -441,6 +483,8 @@ EvalMultitypeValue
|
|||
if (this->datatype == xsd_boolean && x.datatype == xsd_boolean)
|
||||
{
|
||||
ret_femv.bool_value = (this->bool_value <= x.bool_value);
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
|
@ -457,27 +501,35 @@ EvalMultitypeValue
|
|||
if (this->datatype == xsd_double && x.datatype == xsd_double)
|
||||
ret_femv.bool_value = (this->dbl_value <= x.dbl_value);
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
if (this->isSimpleLiteral() && x.isSimpleLiteral())
|
||||
{
|
||||
ret_femv.bool_value = (this->str_value <= x.str_value);
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
if (this->datatype == xsd_string && x.datatype == xsd_string)
|
||||
{
|
||||
ret_femv.bool_value = (this->str_value <= x.str_value);
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
if (this->datatype == xsd_datetime && x.datatype == xsd_datetime)
|
||||
{
|
||||
ret_femv.bool_value = (this->dt_value <= x.dt_value);
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
|
@ -491,6 +543,8 @@ EvalMultitypeValue
|
|||
if (this->datatype == xsd_boolean && x.datatype == xsd_boolean)
|
||||
{
|
||||
ret_femv.bool_value = (this->bool_value > x.bool_value);
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
|
@ -507,27 +561,35 @@ EvalMultitypeValue
|
|||
if (this->datatype == xsd_double && x.datatype == xsd_double)
|
||||
ret_femv.bool_value = (this->dbl_value > x.dbl_value);
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
if (this->isSimpleLiteral() && x.isSimpleLiteral())
|
||||
{
|
||||
ret_femv.bool_value = (this->str_value > x.str_value);
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
if (this->datatype == xsd_string && x.datatype == xsd_string)
|
||||
{
|
||||
ret_femv.bool_value = (this->str_value > x.str_value);
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
if (this->datatype == xsd_datetime && x.datatype == xsd_datetime)
|
||||
{
|
||||
ret_femv.bool_value = (this->dt_value > x.dt_value);
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
|
@ -541,6 +603,8 @@ EvalMultitypeValue
|
|||
if (this->datatype == xsd_boolean && x.datatype == xsd_boolean)
|
||||
{
|
||||
ret_femv.bool_value = (this->bool_value >= x.bool_value);
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
|
@ -557,30 +621,240 @@ EvalMultitypeValue
|
|||
if (this->datatype == xsd_double && x.datatype == xsd_double)
|
||||
ret_femv.bool_value = (this->dbl_value >= x.dbl_value);
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
if (this->isSimpleLiteral() && x.isSimpleLiteral())
|
||||
{
|
||||
ret_femv.bool_value = (this->str_value >= x.str_value);
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
if (this->datatype == xsd_string && x.datatype == xsd_string)
|
||||
{
|
||||
ret_femv.bool_value = (this->str_value >= x.str_value);
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
if (this->datatype == xsd_datetime && x.datatype == xsd_datetime)
|
||||
{
|
||||
ret_femv.bool_value = (this->dt_value >= x.dt_value);
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
EvalMultitypeValue
|
||||
EvalMultitypeValue::operator + (EvalMultitypeValue &x)
|
||||
{
|
||||
EvalMultitypeValue ret_femv;
|
||||
ret_femv.datatype = xsd_boolean;
|
||||
ret_femv.bool_value = EffectiveBooleanValue::error_value;
|
||||
|
||||
if (datatype != xsd_integer && datatype != xsd_decimal && datatype != xsd_float && datatype != xsd_double \
|
||||
&& x.datatype != xsd_integer && x.datatype != xsd_decimal && x.datatype != xsd_float && x.datatype != xsd_double)
|
||||
return ret_femv;
|
||||
|
||||
this->getSameNumericType(x);
|
||||
if (datatype == xsd_integer)
|
||||
{
|
||||
ret_femv.datatype = xsd_integer;
|
||||
ret_femv.int_value = int_value + x.int_value;
|
||||
}
|
||||
else if (datatype == xsd_decimal)
|
||||
{
|
||||
ret_femv.datatype = xsd_decimal;
|
||||
ret_femv.flt_value = flt_value + x.flt_value;
|
||||
}
|
||||
else if (datatype == xsd_float)
|
||||
{
|
||||
ret_femv.datatype = xsd_float;
|
||||
ret_femv.flt_value = flt_value + x.flt_value;
|
||||
}
|
||||
else if (datatype == xsd_double)
|
||||
{
|
||||
ret_femv.datatype = xsd_double;
|
||||
ret_femv.dbl_value = dbl_value + x.dbl_value;
|
||||
}
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
EvalMultitypeValue
|
||||
EvalMultitypeValue::operator - ()
|
||||
{
|
||||
EvalMultitypeValue ret_femv;
|
||||
ret_femv.datatype = xsd_boolean;
|
||||
ret_femv.bool_value = EffectiveBooleanValue::error_value;
|
||||
|
||||
if (datatype != xsd_integer && datatype != xsd_decimal && datatype != xsd_float && datatype != xsd_double)
|
||||
return ret_femv;
|
||||
|
||||
if (datatype == xsd_integer)
|
||||
{
|
||||
ret_femv.datatype = xsd_integer;
|
||||
ret_femv.int_value = -int_value;
|
||||
}
|
||||
else if (datatype == xsd_decimal)
|
||||
{
|
||||
ret_femv.datatype = xsd_decimal;
|
||||
ret_femv.flt_value = -flt_value;
|
||||
}
|
||||
else if (datatype == xsd_float)
|
||||
{
|
||||
ret_femv.datatype = xsd_float;
|
||||
ret_femv.flt_value = -flt_value;
|
||||
}
|
||||
else if (datatype == xsd_double)
|
||||
{
|
||||
ret_femv.datatype = xsd_double;
|
||||
ret_femv.dbl_value = -dbl_value;
|
||||
}
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
EvalMultitypeValue
|
||||
EvalMultitypeValue::operator - (EvalMultitypeValue &x)
|
||||
{
|
||||
EvalMultitypeValue ret_femv;
|
||||
ret_femv.datatype = xsd_boolean;
|
||||
ret_femv.bool_value = EffectiveBooleanValue::error_value;
|
||||
|
||||
if (datatype != xsd_integer && datatype != xsd_decimal && datatype != xsd_float && datatype != xsd_double \
|
||||
&& x.datatype != xsd_integer && x.datatype != xsd_decimal && x.datatype != xsd_float && x.datatype != xsd_double)
|
||||
return ret_femv;
|
||||
|
||||
this->getSameNumericType(x);
|
||||
if (datatype == xsd_integer)
|
||||
{
|
||||
ret_femv.datatype = xsd_integer;
|
||||
ret_femv.int_value = int_value - x.int_value;
|
||||
}
|
||||
else if (datatype == xsd_decimal)
|
||||
{
|
||||
ret_femv.datatype = xsd_decimal;
|
||||
ret_femv.flt_value = flt_value - x.flt_value;
|
||||
}
|
||||
else if (datatype == xsd_float)
|
||||
{
|
||||
ret_femv.datatype = xsd_float;
|
||||
ret_femv.flt_value = flt_value - x.flt_value;
|
||||
}
|
||||
else if (datatype == xsd_double)
|
||||
{
|
||||
ret_femv.datatype = xsd_double;
|
||||
ret_femv.dbl_value = dbl_value - x.dbl_value;
|
||||
}
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
EvalMultitypeValue
|
||||
EvalMultitypeValue::operator * (EvalMultitypeValue &x)
|
||||
{
|
||||
EvalMultitypeValue ret_femv;
|
||||
ret_femv.datatype = xsd_boolean;
|
||||
ret_femv.bool_value = EffectiveBooleanValue::error_value;
|
||||
|
||||
if (datatype != xsd_integer && datatype != xsd_decimal && datatype != xsd_float && datatype != xsd_double \
|
||||
&& x.datatype != xsd_integer && x.datatype != xsd_decimal && x.datatype != xsd_float && x.datatype != xsd_double)
|
||||
return ret_femv;
|
||||
|
||||
this->getSameNumericType(x);
|
||||
if (datatype == xsd_integer)
|
||||
{
|
||||
ret_femv.datatype = xsd_integer;
|
||||
ret_femv.int_value = int_value * x.int_value;
|
||||
}
|
||||
else if (datatype == xsd_decimal)
|
||||
{
|
||||
ret_femv.datatype = xsd_decimal;
|
||||
ret_femv.flt_value = flt_value * x.flt_value;
|
||||
}
|
||||
else if (datatype == xsd_float)
|
||||
{
|
||||
ret_femv.datatype = xsd_float;
|
||||
ret_femv.flt_value = flt_value * x.flt_value;
|
||||
}
|
||||
else if (datatype == xsd_double)
|
||||
{
|
||||
ret_femv.datatype = xsd_double;
|
||||
ret_femv.dbl_value = dbl_value * x.dbl_value;
|
||||
}
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
EvalMultitypeValue
|
||||
EvalMultitypeValue::operator / (EvalMultitypeValue &x)
|
||||
{
|
||||
EvalMultitypeValue ret_femv;
|
||||
ret_femv.datatype = xsd_boolean;
|
||||
ret_femv.bool_value = EffectiveBooleanValue::error_value;
|
||||
|
||||
if (datatype != xsd_integer && datatype != xsd_decimal && datatype != xsd_float && datatype != xsd_double \
|
||||
&& x.datatype != xsd_integer && x.datatype != xsd_decimal && x.datatype != xsd_float && x.datatype != xsd_double)
|
||||
return ret_femv;
|
||||
|
||||
this->getSameNumericType(x);
|
||||
if (datatype == xsd_integer)
|
||||
{
|
||||
ret_femv.datatype = xsd_integer;
|
||||
ret_femv.int_value = int_value / x.int_value;
|
||||
}
|
||||
else if (datatype == xsd_decimal)
|
||||
{
|
||||
ret_femv.datatype = xsd_decimal;
|
||||
ret_femv.flt_value = flt_value / x.flt_value;
|
||||
}
|
||||
else if (datatype == xsd_float)
|
||||
{
|
||||
ret_femv.datatype = xsd_float;
|
||||
ret_femv.flt_value = flt_value / x.flt_value;
|
||||
}
|
||||
else if (datatype == xsd_double)
|
||||
{
|
||||
ret_femv.datatype = xsd_double;
|
||||
ret_femv.dbl_value = dbl_value / x.dbl_value;
|
||||
}
|
||||
|
||||
ret_femv.deduceTermValue();
|
||||
return ret_femv;
|
||||
}
|
||||
|
||||
void EvalMultitypeValue::deduceTermValue()
|
||||
{
|
||||
if (datatype == xsd_integer)
|
||||
term_value = "\"" + to_string(int_value) + "\"^^<http://www.w3.org/2001/XMLSchema#integer>";
|
||||
else if (datatype == xsd_decimal)
|
||||
term_value = "\"" + to_string(flt_value) + "\"^^<http://www.w3.org/2001/XMLSchema#decimal>";
|
||||
else if (datatype == xsd_float)
|
||||
term_value = "\"" + to_string(flt_value) + "\"^^<http://www.w3.org/2001/XMLSchema#float>";
|
||||
else if (datatype == xsd_double)
|
||||
term_value = "\"" + to_string(dbl_value) + "\"^^<http://www.w3.org/2001/XMLSchema#double>";
|
||||
else if (datatype == xsd_boolean)
|
||||
{
|
||||
if (bool_value.value == EvalMultitypeValue::EffectiveBooleanValue::true_value)
|
||||
term_value = "\"true\"^^<http://www.w3.org/2001/XMLSchema#boolean>";
|
||||
else if (bool_value.value == EvalMultitypeValue::EffectiveBooleanValue::false_value)
|
||||
term_value = "\"false\"^^<http://www.w3.org/2001/XMLSchema#boolean>";
|
||||
}
|
||||
}
|
||||
|
||||
void EvalMultitypeValue::deduceTypeValue()
|
||||
{
|
||||
if (term_value[0] == '<' && term_value[term_value.length() - 1] == '>')
|
||||
|
|
|
@ -69,7 +69,7 @@ class EvalMultitypeValue
|
|||
std::string str_value;
|
||||
EffectiveBooleanValue bool_value;
|
||||
int int_value;
|
||||
float flt_value;
|
||||
float flt_value; // xsd_decimal and xsd_float
|
||||
double dbl_value;
|
||||
DateTime dt_value;
|
||||
|
||||
|
@ -85,9 +85,16 @@ class EvalMultitypeValue
|
|||
EvalMultitypeValue operator > (EvalMultitypeValue &x);
|
||||
EvalMultitypeValue operator >= (EvalMultitypeValue &x);
|
||||
|
||||
EvalMultitypeValue operator + (EvalMultitypeValue &x);
|
||||
EvalMultitypeValue operator - ();
|
||||
EvalMultitypeValue operator - (EvalMultitypeValue &x);
|
||||
EvalMultitypeValue operator * (EvalMultitypeValue &x);
|
||||
EvalMultitypeValue operator / (EvalMultitypeValue &x);
|
||||
|
||||
EvalMultitypeValue():datatype(rdf_term), int_value(0), flt_value(0), dbl_value(0){}
|
||||
|
||||
void deduceTypeValue(); // Set datatype and value according to term_value
|
||||
void deduceTermValue(); // Set term value according to datatype and essential value
|
||||
void deduceTypeValue(); // Set datatype and value according to term_value, for numeric & boolean
|
||||
};
|
||||
|
||||
#endif //_UTIL_EVALMULTITYPEVALUE_H
|
Loading…
Reference in New Issue