Esempio n. 1
0
/** 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;
}
Esempio n. 2
0
/** 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;
}