/** Given an expression type and a valuetype, find the best * templated ctor to invoke. Several helpers, above, aid in this * pursuit. Each instantiated expression must consume any * class-specific serialization from serialize_io. */ AbstractExpression* ExpressionUtil::expressionFactory(PlannerDomValue obj, ExpressionType et, ValueType vt, int vs, AbstractExpression* lc, AbstractExpression* rc, const std::vector<AbstractExpression*>* args) { AbstractExpression *ret = NULL; switch (et) { // Casts case (EXPRESSION_TYPE_OPERATOR_CAST): ret = castFactory(vt, lc); break; // Operators case (EXPRESSION_TYPE_OPERATOR_PLUS): case (EXPRESSION_TYPE_OPERATOR_MINUS): case (EXPRESSION_TYPE_OPERATOR_MULTIPLY): case (EXPRESSION_TYPE_OPERATOR_DIVIDE): case (EXPRESSION_TYPE_OPERATOR_CONCAT): case (EXPRESSION_TYPE_OPERATOR_MOD): case (EXPRESSION_TYPE_OPERATOR_NOT): case (EXPRESSION_TYPE_OPERATOR_IS_NULL): ret = operatorFactory(et, lc, rc); break; // Comparisons case (EXPRESSION_TYPE_COMPARE_EQUAL): case (EXPRESSION_TYPE_COMPARE_NOTEQUAL): case (EXPRESSION_TYPE_COMPARE_LESSTHAN): case (EXPRESSION_TYPE_COMPARE_GREATERTHAN): case (EXPRESSION_TYPE_COMPARE_LESSTHANOREQUALTO): case (EXPRESSION_TYPE_COMPARE_GREATERTHANOREQUALTO): case (EXPRESSION_TYPE_COMPARE_LIKE): case (EXPRESSION_TYPE_COMPARE_IN): ret = comparisonFactory( et, lc, rc); break; // Conjunctions case (EXPRESSION_TYPE_CONJUNCTION_AND): case (EXPRESSION_TYPE_CONJUNCTION_OR): ret = conjunctionFactory(et, lc, rc); break; // Functions and pseudo-functions case (EXPRESSION_TYPE_FUNCTION): { // add the function id int functionId = obj.valueForKey("FUNCTION_ID").asInt(); ret = functionFactory(functionId, args); if ( ! ret) { std::string nameString; if (obj.hasNonNullKey("NAME")) { nameString = obj.valueForKey("NAME").asStr(); } else { nameString = "?"; } char aliasBuffer[256]; if (obj.hasNonNullKey("ALIAS")) { std::string aliasString = obj.valueForKey("ALIAS").asStr(); snprintf(aliasBuffer, sizeof(aliasBuffer), " aliased to '%s'", aliasString.c_str()); } char fn_message[1024]; snprintf(fn_message, sizeof(fn_message), "SQL function '%s'%s with ID (%d) with (%d) parameters is not implemented in VoltDB (or may have been incorrectly parsed)", nameString.c_str(), aliasBuffer, functionId, (int)args->size()); throw SerializableEEException(VOLT_EE_EXCEPTION_TYPE_EEEXCEPTION, fn_message); } } break; case (EXPRESSION_TYPE_INLISTBUILDER): { // Parse whatever is needed out of obj and pass the pieces to inListFactory // to make it easier to unit test independently of the parsing. // The first argument is used as the list element type. // If the ValueType of the list builder expression needs to be "ARRAY" or something else, // a separate element type attribute will have to be serialized and passed in here. ret = inListFactory(vt, args); } break; // Constant Values, parameters, tuples case (EXPRESSION_TYPE_VALUE_CONSTANT): ret = constantValueFactory(obj, vt, et, lc, rc); break; case (EXPRESSION_TYPE_VALUE_PARAMETER): ret = parameterValueFactory(obj, et, lc, rc); break; case (EXPRESSION_TYPE_VALUE_TUPLE): ret = tupleValueFactory(obj, et, lc, rc); break; case (EXPRESSION_TYPE_VALUE_TUPLE_ADDRESS): ret = new TupleAddressExpression(); break; case (EXPRESSION_TYPE_HASH_RANGE): ret = hashRangeFactory(obj); break; // must handle all known expressions in this factory default: char message[256]; snprintf(message,256, "Invalid ExpressionType '%s' (%d) requested from factory", expressionToString(et).c_str(), (int)et); throw SerializableEEException(VOLT_EE_EXCEPTION_TYPE_EEEXCEPTION, message); } ret->setValueType(vt); ret->setValueSize(vs); // written thusly to ease testing/inspecting return content. VOLT_TRACE("Created expression %p", ret); return ret; }
/** Given an expression type and a valuetype, find the best * templated ctor to invoke. Several helpers, above, aid in this * pursuit. Each instantiated expression must consume any * class-specific serialization from serialize_io. */ AbstractExpression* ExpressionUtil::expressionFactory(PlannerDomValue obj, ExpressionType et, ValueType vt, int vs, AbstractExpression* lc, AbstractExpression* rc, const std::vector<AbstractExpression*>* args) { AbstractExpression *ret = NULL; switch (et) { // Casts case (EXPRESSION_TYPE_OPERATOR_CAST): ret = castFactory(vt, lc); break; // Operators case (EXPRESSION_TYPE_OPERATOR_PLUS): case (EXPRESSION_TYPE_OPERATOR_MINUS): case (EXPRESSION_TYPE_OPERATOR_MULTIPLY): case (EXPRESSION_TYPE_OPERATOR_DIVIDE): case (EXPRESSION_TYPE_OPERATOR_CONCAT): case (EXPRESSION_TYPE_OPERATOR_MOD): case (EXPRESSION_TYPE_OPERATOR_NOT): case (EXPRESSION_TYPE_OPERATOR_IS_NULL): case (EXPRESSION_TYPE_OPERATOR_EXISTS): ret = operatorFactory(et, lc, rc); break; // Comparisons case (EXPRESSION_TYPE_COMPARE_EQUAL): case (EXPRESSION_TYPE_COMPARE_NOTEQUAL): case (EXPRESSION_TYPE_COMPARE_LESSTHAN): case (EXPRESSION_TYPE_COMPARE_GREATERTHAN): case (EXPRESSION_TYPE_COMPARE_LESSTHANOREQUALTO): case (EXPRESSION_TYPE_COMPARE_GREATERTHANOREQUALTO): case (EXPRESSION_TYPE_COMPARE_LIKE): case (EXPRESSION_TYPE_COMPARE_IN): ret = comparisonFactory(obj, et, lc, rc); break; // Conjunctions case (EXPRESSION_TYPE_CONJUNCTION_AND): case (EXPRESSION_TYPE_CONJUNCTION_OR): ret = conjunctionFactory(et, lc, rc); break; // Functions and pseudo-functions case (EXPRESSION_TYPE_FUNCTION): { // add the function id int functionId = obj.valueForKey("FUNCTION_ID").asInt(); if (args) { ret = functionFactory(functionId, args); } if ( ! ret) { std::string nameString; if (obj.hasNonNullKey("NAME")) { nameString = obj.valueForKey("NAME").asStr(); } else { nameString = "?"; } raiseFunctionFactoryError(nameString, functionId, args); } } break; case (EXPRESSION_TYPE_VALUE_VECTOR): { // Parse whatever is needed out of obj and pass the pieces to inListFactory // to make it easier to unit test independently of the parsing. // The first argument is used as the list element type. // If the ValueType of the list builder expression needs to be "ARRAY" or something else, // a separate element type attribute will have to be serialized and passed in here. ret = vectorFactory(vt, args); } break; // Constant Values, parameters, tuples case (EXPRESSION_TYPE_VALUE_CONSTANT): ret = constantValueFactory(obj, vt, et, lc, rc); break; case (EXPRESSION_TYPE_VALUE_PARAMETER): ret = parameterValueFactory(obj, et, lc, rc); break; case (EXPRESSION_TYPE_VALUE_TUPLE): ret = tupleValueFactory(obj, et, lc, rc); break; case (EXPRESSION_TYPE_VALUE_TUPLE_ADDRESS): ret = new TupleAddressExpression(); break; case (EXPRESSION_TYPE_VALUE_SCALAR): ret = new ScalarValueExpression(lc); break; case (EXPRESSION_TYPE_HASH_RANGE): ret = hashRangeFactory(obj); break; case (EXPRESSION_TYPE_OPERATOR_CASE_WHEN): ret = caseWhenFactory(vt, lc, rc); break; case (EXPRESSION_TYPE_OPERATOR_ALTERNATIVE): ret = new OperatorAlternativeExpression(lc, rc); break; // Subquery case (EXPRESSION_TYPE_ROW_SUBQUERY): case (EXPRESSION_TYPE_SELECT_SUBQUERY): ret = subqueryFactory(et, obj, args); break; // must handle all known expressions in this factory default: char message[256]; snprintf(message,256, "Invalid ExpressionType '%s' (%d) requested from factory", expressionToString(et).c_str(), (int)et); throw SerializableEEException(VOLT_EE_EXCEPTION_TYPE_EEEXCEPTION, message); } ret->setValueType(vt); ret->setValueSize(vs); // written thusly to ease testing/inspecting return content. VOLT_TRACE("Created expression %p", ret); return ret; }
/** Given an expression type and a valuetype, find the best * templated ctor to invoke. Several helpers, above, aid in this * pursuit. Each instantiated expression must consume any * class-specific serialization from serialize_io. */ AbstractExpression* ExpressionUtil::expressionFactory(json_spirit::Object &obj, ExpressionType et, ValueType vt, int vs, AbstractExpression* lc, AbstractExpression* rc, const std::vector<AbstractExpression*>* args) { AbstractExpression *ret = NULL; switch (et) { // Operators case (EXPRESSION_TYPE_OPERATOR_PLUS): case (EXPRESSION_TYPE_OPERATOR_MINUS): case (EXPRESSION_TYPE_OPERATOR_MULTIPLY): case (EXPRESSION_TYPE_OPERATOR_DIVIDE): case (EXPRESSION_TYPE_OPERATOR_CONCAT): case (EXPRESSION_TYPE_OPERATOR_MOD): case (EXPRESSION_TYPE_OPERATOR_CAST): case (EXPRESSION_TYPE_OPERATOR_NOT): case (EXPRESSION_TYPE_OPERATOR_IS_NULL): ret = operatorFactory(et, lc, rc); break; // Comparisons case (EXPRESSION_TYPE_COMPARE_EQUAL): case (EXPRESSION_TYPE_COMPARE_NOTEQUAL): case (EXPRESSION_TYPE_COMPARE_LESSTHAN): case (EXPRESSION_TYPE_COMPARE_GREATERTHAN): case (EXPRESSION_TYPE_COMPARE_LESSTHANOREQUALTO): case (EXPRESSION_TYPE_COMPARE_GREATERTHANOREQUALTO): case (EXPRESSION_TYPE_COMPARE_LIKE): ret = comparisonFactory( et, lc, rc); break; // Conjunctions case (EXPRESSION_TYPE_CONJUNCTION_AND): case (EXPRESSION_TYPE_CONJUNCTION_OR): ret = conjunctionFactory(et, lc, rc); break; // Functions and pseudo-functions case (EXPRESSION_TYPE_FUNCTION): { // add the function id json_spirit::Value functionIdValue = json_spirit::find_value(obj, "FUNCTION_ID"); if (functionIdValue == json_spirit::Value::null) { throw SerializableEEException(VOLT_EE_EXCEPTION_TYPE_EEEXCEPTION, "ExpressionUtil::" "expressionFactory:" " Couldn't find FUNCTION_ID value"); } int functionId = functionIdValue.get_int(); ret = functionFactory(functionId, args); if ( ! ret) { json_spirit::Value functionNameValue = json_spirit::find_value(obj, "NAME"); std::string nameString; if (functionNameValue == json_spirit::Value::null) { nameString = "?"; } else { nameString = functionNameValue.get_str(); } char aliasBuffer[256]; json_spirit::Value functionAliasValue = json_spirit::find_value(obj, "ALIAS"); if (functionAliasValue == json_spirit::Value::null) { aliasBuffer[0] = '\0'; } else { std::string aliasString = functionAliasValue.get_str(); snprintf(aliasBuffer, sizeof(aliasBuffer), " aliased to '%s'", aliasString.c_str()); } char fn_message[1024]; snprintf(fn_message, sizeof(fn_message), "SQL function '%s'%s with ID (%d) with (%d) parameters is not implemented in VoltDB (or may have been incorrectly parsed)", nameString.c_str(), aliasBuffer, functionId, (int)args->size()); throw SerializableEEException(VOLT_EE_EXCEPTION_TYPE_EEEXCEPTION, fn_message); } } break; // Constant Values, parameters, tuples case (EXPRESSION_TYPE_VALUE_CONSTANT): ret = constantValueFactory(obj, vt, et, lc, rc); break; case (EXPRESSION_TYPE_VALUE_PARAMETER): ret = parameterValueFactory(obj, et, lc, rc); break; case (EXPRESSION_TYPE_VALUE_TUPLE): ret = tupleValueFactory(obj, et, lc, rc); break; case (EXPRESSION_TYPE_VALUE_TUPLE_ADDRESS): ret = new TupleAddressExpression(); break; // must handle all known expressions in this factory default: char message[256]; snprintf(message,256, "Invalid ExpressionType '%s' (%d) requested from factory", expressionToString(et).c_str(), (int)et); throw SerializableEEException(VOLT_EE_EXCEPTION_TYPE_EEEXCEPTION, message); } ret->setValueType(vt); ret->setValueSize(vs); // written thusly to ease testing/inspecting return content. VOLT_TRACE("Created expression %p", ret); return ret; }