void SetUpdater::parse_update() { while (tokens_.size() > 0 && tokens_.size() % 3 == 0) { Token attribute = stream_get(); Token op = stream_get(); Token value = stream_get(); if (attribute.first != attribute_name) throw QuerySyntaxError("Expected attribute name: " + attribute.second); if (op.first != conditional_eq) throw QuerySyntaxError("Expected equals operator: " + op.second); if (value.first > 15 || value.first > 15) throw QuerySyntaxError("Expected literal value: " + value.second); record_->set(attribute.second, value.second); } if (tokens_.size() != 0) throw QuerySyntaxError("Set clause syntax error."); }
bool WhereMatcher::parse_conditional() { Token left_token = stream_get(); // handling of parenthesis if (left_token.first == parenthesis_left) { bool result = parse_and(); Token close_parenthesis = stream_get(); if (close_parenthesis.first != parenthesis_right) { throw QuerySyntaxError("Invalid syntax, missing closing parenthesis."); } else { return result; } } Token op_token = stream_get(); TokenType value_type = left_token.first; // the left side is an attribute_name, we need to look ahead for the type if (value_type == attribute_name) { Token right_token = stream_get(); value_type = right_token.first; stream_unget(right_token); } stream_unget(left_token); // In C++ you can't declare variables of the same name, even if they were // never actually declared, this is a really ugly fix, but if there is a way // to emulate some sort of dynamic typing C++, we could make this a lot better switch (op_token.first) { case conditional_eq: switch (value_type) { case value_numeral: return parse_value<float>() == parse_value<float>(); case value_varchar: case value_date: case value_time: return parse_value<string>().compare(parse_value<string>()) == 0; } case conditional_neq: switch (value_type) { case value_numeral: return parse_value<float>() != parse_value<float>(); case value_varchar: case value_date: case value_time: return parse_value<string>().compare(parse_value<string>()) != 0; } case conditional_lt: switch (value_type) { case value_numeral: return parse_value<float>() < parse_value<float>(); case value_varchar: case value_date: case value_time: return parse_value<string>().compare(parse_value<string>()) > 0; } case conditional_gt: switch (value_type) { case value_numeral: return parse_value<float>() > parse_value<float>(); case value_varchar: case value_date: case value_time: return parse_value<string>().compare(parse_value<string>()) < 0; } break; case conditional_lte: switch (value_type) { case value_numeral: return parse_value<float>() <= parse_value<float>(); case value_varchar: case value_date: case value_time: return parse_value<string>().compare(parse_value<string>()) >= 0; } break; case conditional_gte: switch (value_type) { case value_numeral: return parse_value<float>() >= parse_value<float>(); case value_varchar: case value_date: case value_time: return parse_value<string>().compare(parse_value<string>()) <= 0; } break; default: throw QuerySyntaxError("Unrecognized symbol: " + left_token.second); } throw QuerySyntaxError("Unknown type, internal error"); }