예제 #1
0
Variable* Expression::opPostfix(Variable *&a, TokenType op){
    VarNumber* tmp = new VarNumber();
    tmp->value = 1;
    Variable* res = a;
    res->retain();
    switch (op){
        case INCREASE : {               //    ++
            Variable* tt = opAdditive(a, TokenType::PLUS, tmp);
			Variable* tt2 = Variable::assign(&a, tt);
            tt->release();
            tt2->release();
            break;
        }
        case DECREASE :{                //    --
            Variable* tt = opAdditive(a, TokenType::MINUS, tmp);
			Variable* tt2 = Variable::assign(&a, tt);
            tt->release();
            tt2->release();
            break;
        }
        default :
            throw ExpressionException();
            break;
    }
    tmp->release();
    return res;
}
예제 #2
0
AbstractExpression *GetMoreSpecialized(ExpressionType c, L *l, R *r) {
  assert(l);
  assert(r);
  switch (c) {
    case (EXPRESSION_TYPE_COMPARE_EQUAL):
      return new InlinedComparisonExpression<CmpEq, L, R>(c, l, r);
    case (EXPRESSION_TYPE_COMPARE_NOTEQUAL):
      return new InlinedComparisonExpression<CmpNe, L, R>(c, l, r);
    case (EXPRESSION_TYPE_COMPARE_LESSTHAN):
      return new InlinedComparisonExpression<CmpLt, L, R>(c, l, r);
    case (EXPRESSION_TYPE_COMPARE_GREATERTHAN):
      return new InlinedComparisonExpression<CmpGt, L, R>(c, l, r);
    case (EXPRESSION_TYPE_COMPARE_LESSTHANOREQUALTO):
      return new InlinedComparisonExpression<CmpLte, L, R>(c, l, r);
    case (EXPRESSION_TYPE_COMPARE_GREATERTHANOREQUALTO):
      return new InlinedComparisonExpression<CmpGte, L, R>(c, l, r);
    case (EXPRESSION_TYPE_COMPARE_LIKE):
      return new InlinedComparisonExpression<CmpLike, L, R>(
          c, l, r);  // added by michael
    case (EXPRESSION_TYPE_COMPARE_IN):
      return new InlinedComparisonExpression<CmpIn, L, R>(
          c, l,
          r);  // added by michael
    default:
      char message[256];
      sprintf(message,
              "Invalid ExpressionType '%s' called for"
              " ComparisonExpression",
              ExpressionTypeToString(c).c_str());
      throw ExpressionException(message);
  }
}
예제 #3
0
// convert the enumerated value type into a concrete c type for the
//  operator expression templated ctors
AbstractExpression *OperatorFactory(ExpressionType et, AbstractExpression *lc,
                                    AbstractExpression *rc) {
  AbstractExpression *ret = nullptr;

  switch (et) {
    case (EXPRESSION_TYPE_OPERATOR_PLUS):
      ret = new OperatorExpression<OpPlus>(et, lc, rc);
      break;

    case (EXPRESSION_TYPE_OPERATOR_MINUS):
      ret = new OperatorExpression<OpMinus>(et, lc, rc);
      break;

    case (EXPRESSION_TYPE_OPERATOR_MULTIPLY):
      ret = new OperatorExpression<OpMultiply>(et, lc, rc);
      break;

    case (EXPRESSION_TYPE_OPERATOR_DIVIDE):
      ret = new OperatorExpression<OpDivide>(et, lc, rc);
      break;

    case (EXPRESSION_TYPE_OPERATOR_NOT):
      ret = new OperatorNotExpression(lc);
      break;

    case (EXPRESSION_TYPE_OPERATOR_MOD):
      throw ExpressionException("Mod operator is not yet supported.");

    case (EXPRESSION_TYPE_OPERATOR_CONCAT):
      throw ExpressionException("Concat operator not yet supported.");

    case (EXPRESSION_TYPE_OPERATOR_CAST):
      throw ExpressionException("Cast operator not yet supported.");

    default:
      throw ExpressionException("operator ctor helper out of sync");
  }
  return ret;
}
예제 #4
0
Variable* Expression::opEqual(Variable *a, TokenType op, Variable*b){
	if (op != TokenType::EQUAL && op != TokenType::UNEQUAL)
        throw ExpressionException();

	VarBoolean* res = new VarBoolean();
    bool isEqual = false;
    if (a->type == Variable::BOOLEAN || a->type == Variable::NUMBER  //convert to number for comparison
     || b->type == Variable::BOOLEAN || b->type == Variable::NUMBER){
         VarNumber* ta = a->toVarNumber();
		 VarNumber* tb = b->toVarNumber();

         if (ta->numType == VarNumber::NANUMBER || tb->numType == NANUMBER)
            isEqual = (op != TokenType::EQUAL);
         else isEqual = (ta->toString() == tb->toString());

         ta->release();
         tb->release();
     } else if (a->type == Variable::OBJECT && ((VarObject*)a)->value != NULL
		 && b->type == Variable::OBJECT && ((VarObject*)b)->value != NULL)
         isEqual = (a == b);
      else isEqual = a->toString() == b->toString();

    switch (op){
        case EQUAL :{                   //    ==
            res->value = isEqual;
            break;
        }
        case UNEQUAL :{                 //    !=
            res->value = !isEqual;
            break;
        }
        default:
            throw ExpressionException();
            break;
    }
    return res;
}
예제 #5
0
Variable* Expression::opAdditive(Variable *a, TokenType op, Variable *b){
    Variable *res = NULL;
    if ((a->type == Variable::STRING || a->type == Variable::FUNCTION ||
        b->type == Variable::STRING || b->type == Variable::FUNCTION)
        && op == TokenType::PLUS){
		VarString* tmp = new VarString();
		tmp->value = a->toString() + b->toString();
		res = tmp;
    } else{
		VarNumber* tmp = new VarNumber();
		VarNumber* ta = a->toVarNumber();
		VarNumber* tb = b->toVarNumber();
		if (ta->numType == VarNumber::NANUMBER || tb->numType == VarNumber::NANUMBER){
			tmp->numType = VarNumber::NANUMBER;
			res = tmp;
		}
        else {
            switch (op){
                case MINUS :                  // -
                    if (tb->numType == VarNumber::INF) tb->numType = VarNumber::NEG_INF;
                    else if (tb->numType == VarNumber::NEG_INF) tb->numType = VarNumber::INF;
                    else tb->value = -tb->value;
                case PLUS :                    //    +
                    if (ta->numType == VarNumber::INF && tb->numType == VarNumber::NEG_INF)
						tmp->numType = VarNumber::NANUMBER;
                    else if (ta->numType == VarNumber::NEG_INF && tb->numType == VarNumber::INF)
						tmp->numType = VarNumber::NANUMBER;
                    else if (ta->numType == VarNumber::NEG_INF || tb->numType == VarNumber::NEG_INF)
						tmp->numType = VarNumber::NEG_INF;
                    else if (ta->numType == VarNumber::INF || tb->numType == VarNumber::INF)
						tmp->numType = VarNumber::INF;
                    else {
						tmp->numType = VarNumber::NORMAL;
						tmp->value = ta->value + tb->value;
                    }
					res = tmp;
                    break;
                default :
                    throw ExpressionException();
                    break;
            }
        }
        ta->release();
        tb->release();
    }
    return res;
}
예제 #6
0
Variable* Expression::opUnary(TokenType op, Variable *a){
    Variable* res = NULL;

    switch (op){
        case NOT :{                     //    !
            VarBoolean* tmp = new VarBoolean();
            tmp->value = !a->toBoolean();
			res = tmp;
			break;
        }
        case INCREASE : {               //    ++
            VarNumber* tmp = new VarNumber();
            tmp->value = 1;
            res = opAdditive(a, TokenType::PLUS, tmp);
            tmp->release();
            break;
        }
        case DECREASE : {               //    --
            VarNumber* tmp = new VarNumber();
            tmp->value = 1;
            res = opAdditive(a, TokenType::MINUS, tmp);
            tmp->release();
            break;
        }
        case REVERSE :{                 //    ~

            break;
        }
        case PLUS :  {                  //    +
            VarNumber* tmp = a->toVarNumber();
			res = tmp;
            break;
        }
        case MINUS :  {                 //    -
            VarNumber* tmp = new VarNumber();
            res = opAdditive(tmp, TokenType::MINUS, a);
            tmp->release();
            break;
        }
        default :
            throw ExpressionException();
            break;
    }
    return res;
}
예제 #7
0
// convert the enumerated value type into a concrete c type for the
//  operator expression templated ctors
AbstractExpression *ExpressionUtil::OperatorFactory(
    ExpressionType et, ValueType vt, AbstractExpression *first,
    AbstractExpression *second, AbstractExpression *third,
    AbstractExpression *fourth) {
  AbstractExpression *ret = nullptr;

  switch (et) {
    case (EXPRESSION_TYPE_OPERATOR_PLUS):
      ret = new OperatorExpression<OpPlus>(et, vt, first, second);
      break;

    case EXPRESSION_TYPE_OPERATOR_UNARY_MINUS:
      ret = new OperatorUnaryMinusExpression(first);
      break;

    case (EXPRESSION_TYPE_OPERATOR_MINUS):
      ret = new OperatorExpression<OpMinus>(et, vt, first, second);
      break;

    case (EXPRESSION_TYPE_OPERATOR_MULTIPLY):
      ret = new OperatorExpression<OpMultiply>(et, vt, first, second);
      break;

    case (EXPRESSION_TYPE_OPERATOR_DIVIDE):
      ret = new OperatorExpression<OpDivide>(et, vt, first, second);
      break;

    case (EXPRESSION_TYPE_OPERATOR_NOT):
      ret = new OperatorUnaryNotExpression(first);
      break;
    case (EXPRESSION_TYPE_SUBSTR):
      ret = new SubstringExpression(first, second, third);
      break;

    case (EXPRESSION_TYPE_CONCAT):
      ret = new ConcatExpression(first, second);
      break;

    case (EXPRESSION_TYPE_ASCII):
      ret = new AsciiExpression(first);
      break;

    case (EXPRESSION_TYPE_CHAR):
      ret = new CharExpression(first);
      break;

    case (EXPRESSION_TYPE_CHAR_LEN):
      ret = new CharLengthExpression(first);
      break;

    case (EXPRESSION_TYPE_OCTET_LEN):
      ret = new OctetLengthExpression(first);
      break;
    case (EXPRESSION_TYPE_POSITION):
      ret = new PositionExpression(first, second);
      break;
    case (EXPRESSION_TYPE_REPEAT):
      ret = new RepeatExpression(first, second);
      break;
    case (EXPRESSION_TYPE_LEFT):
      ret = new LeftExpression(first, second);
      break;
    case (EXPRESSION_TYPE_RIGHT):
      ret = new RightExpression(first, second);
      break;
    case (EXPRESSION_TYPE_REPLACE):
      ret = new ReplaceExpression(first, second, third);
      break;
    case (EXPRESSION_TYPE_OVERLAY):
      ret = new OverlayExpression(first, second, third, fourth);
      break;

    case (EXPRESSION_TYPE_LTRIM):
      ret = new LTrimExpression(first, second);
      break;
    case (EXPRESSION_TYPE_RTRIM):
      ret = new RTrimExpression(first, second);
      break;
    case (EXPRESSION_TYPE_BTRIM):
      ret = new BTrimExpression(first, second);
      break;
    case (EXPRESSION_TYPE_OPERATOR_MOD):
      ret = new OperatorExpression<OpMod>(et, vt, first, second);
      break;
    case (EXPRESSION_TYPE_EXTRACT):
      ret = new ExtractExpression(first, second);
      break;
    case (EXPRESSION_TYPE_DATE_TO_TIMESTAMP):
      ret = new DateToTimestampExpression(first);
      break;
    case (EXPRESSION_TYPE_OPERATOR_CONCAT):
      throw ExpressionException("Concat operator not yet supported.");

    case (EXPRESSION_TYPE_OPERATOR_CAST):
      throw ExpressionException("Cast operator not yet supported.");

    default:
      throw ExpressionException("operator ctor helper out of sync");
  }
  return ret;
}
예제 #8
0
AbstractExpression *AbstractExpression::CreateExpressionTreeRecurse(
    json_spirit::Object &obj) {
  // build a tree recursively from the bottom upwards.
  // when the expression node is instantiated, its type,
  // value and child types will have been discovered.

  ExpressionType peek_type = EXPRESSION_TYPE_INVALID;
  ValueType value_type = VALUE_TYPE_INVALID;
  AbstractExpression *left_child = nullptr;
  AbstractExpression *right_child = nullptr;

  // read the expression type
  json_spirit::Value expression_type_value =
      json_spirit::find_value(obj, "TYPE");

  if (expression_type_value == json_spirit::Value::null) {
    throw ExpressionException(
        "AbstractExpression:: buildExpressionTree_recurse:"
        "Couldn't find TYPE value");
  }

  assert(StringToExpressionType(expression_type_value.get_str()) !=
         EXPRESSION_TYPE_INVALID);
  peek_type = StringToExpressionType(expression_type_value.get_str());

  // and the value type
  json_spirit::Value valueTypeValue =
      json_spirit::find_value(obj, "VALUE_TYPE");
  if (valueTypeValue == json_spirit::Value::null) {
    throw ExpressionException(
        "AbstractExpression:: buildExpressionTree_recurse:"
        " Couldn't find VALUE_TYPE value");
  }

  std::string value_type_string = valueTypeValue.get_str();
  value_type = StringToValueType(value_type_string);

  // this should be relatively safe, though it ignores overflow.
  if ((value_type == VALUE_TYPE_TINYINT) ||
      (value_type == VALUE_TYPE_SMALLINT) ||
      (value_type == VALUE_TYPE_INTEGER)) {
    value_type = VALUE_TYPE_BIGINT;
  }

  assert(value_type != VALUE_TYPE_INVALID);

  // add the value size
  json_spirit::Value value_size_value =
      json_spirit::find_value(obj, "VALUE_SIZE");

  if (value_size_value == json_spirit::Value::null) {
    throw ExpressionException(
        "AbstractExpression:: buildExpressionTree_recurse:"
        " Couldn't find VALUE_SIZE value");
  }

  int value_size = value_size_value.get_int();

  // recurse to children
  try {
    json_spirit::Value leftValue = json_spirit::find_value(obj, "LEFT");

    if (!(leftValue == json_spirit::Value::null)) {
      left_child =
          AbstractExpression::CreateExpressionTreeRecurse(leftValue.get_obj());
    } else {
      left_child = nullptr;
    }

    json_spirit::Value rightValue = json_spirit::find_value(obj, "RIGHT");

    if (!(rightValue == json_spirit::Value::null)) {
      right_child =
          AbstractExpression::CreateExpressionTreeRecurse(rightValue.get_obj());
    } else {
      right_child = nullptr;
    }

    // Invoke the factory. obviously it has to handle null children.
    // pass it the serialization stream in case a subclass has more
    // to read. yes, the per-class data really does follow the
    // child serializations.

    return ExpressionUtil::ExpressionFactory(obj, peek_type, value_type, value_size, left_child,
                             right_child);
  } catch (ExpressionException &ex) {
    // clean up children
    delete left_child;
    delete right_child;
    throw;
  }
}
예제 #9
0
Variable* Expression::opMultiplicative(Variable *a, TokenType op, Variable *b){

    VarNumber* res = new VarNumber();
	VarNumber* ta = a->toVarNumber();
	VarNumber* tb = b->toVarNumber();
    if (ta->numType == VarNumber::NANUMBER || tb->numType == VarNumber::NANUMBER)
       res->numType = VarNumber::NANUMBER;
    else {
        bool nega = ta->numType == VarNumber::NEG_INF
                || (ta->numType == VarNumber::NORMAL && ta->value < 0);
        bool negb = tb->numType == VarNumber::NEG_INF
                || (tb->numType == VarNumber::NORMAL && tb->value < 0);
        bool negres = nega != negb;

        switch (op){
            case TIMES :                   //    *
                if (ta->numType == VarNumber::INF && tb->numType == VarNumber::NORMAL && fabs(tb->value) <1e-9)
                    res->numType = VarNumber::NANUMBER;
                else if (tb->numType == VarNumber::INF && ta->numType == VarNumber::NORMAL && ta->value <1e-9)
                    res->numType = VarNumber::NANUMBER;
                else {

                    if (ta->numType != VarNumber::NORMAL)
                        res->numType = negres ? VarNumber::NEG_INF : VarNumber::INF;
                    else if (tb->numType != VarNumber::NORMAL)
                        res->numType = negres ? VarNumber::NEG_INF : VarNumber::INF;
                    else {
						res->numType = VarNumber::NORMAL;
                        res->value = ta->value * tb->value;
                    }
                }
                break;
            case OVER :                    //    /
                if (ta->numType != VarNumber::NORMAL && tb->numType != VarNumber::NORMAL)
                    res->numType = VarNumber::NANUMBER;
                else if (ta->numType != VarNumber::NORMAL)
                    res->numType = negres ? VarNumber::NEG_INF : VarNumber::INF;
                else if (tb->numType != VarNumber::NORMAL){
                    res->numType = VarNumber::NORMAL;
                    res->value = 0;
                } else if (fabs(tb->value) < 1e-9)
					res->numType = VarNumber::NANUMBER;
                else {
                    res->numType = VarNumber::NORMAL;
                    res->value = ta->value / tb->value;
                }
                break;
            case MOD :                     //    %
                if (ta->numType != VarNumber::NORMAL && tb->numType != VarNumber::NORMAL)
                    res->numType = VarNumber::NANUMBER;
                else if (ta->numType != VarNumber::NORMAL
                        || (tb->numType == VarNumber::NORMAL && fabs(tb->value) < 1e-9
                            || tb->numType == VarNumber::INF))
                    res->numType = VarNumber::NANUMBER;
                else if (tb->numType != VarNumber::NORMAL){
                    res->numType = VarNumber::NORMAL;
                    res->value = ta->value;
                } else if (ta->value == 0){
                    res->numType = VarNumber::NORMAL;
                    res->value = 0;
				}
                else {
                    res->numType = VarNumber::NORMAL;
					res->value = (long long)(ta->value) % (long long)(tb->value);
                }
                break;
            default :
                throw ExpressionException();
                break;
        }
    }
    ta->release();
    tb->release();
    return res;
}
예제 #10
0
Variable* Expression::opAssign(Variable *&a, TokenType op, Variable *b){
    Variable* res = NULL;
    switch (op){
        case ASSIGN :{                  //    =
            res = Variable::assign(&a, b);
            break;
        }
		case PASSIGN: {                //    +=
			Variable* tmp = opAdditive(a, TokenType::PLUS, b);
			res = Variable::assign(&a, tmp);
			tmp->release();
			break;
		}
        case MINUSASSIGN :{            //    -=
			Variable* tmp = opAdditive(a, TokenType::MINUS, b);
			res = Variable::assign(&a, tmp);
            tmp->release();
            break;
        }
		case TASSIGN:{              //    *=
			Variable* tmp = opMultiplicative(a, TokenType::TIMES, b);
			res = Variable::assign(&a, tmp);
			tmp->release();
			break;
		}                
		case OASSIGN: {              //    /=
			Variable* tmp = opMultiplicative(a, TokenType::OVER, b);
			res = Variable::assign(&a, tmp);
			tmp->release();
			break;
		}                
        case MODASSIGN :{              //    %=
			Variable* tmp = opMultiplicative(a, TokenType::MOD, b);
			res = Variable::assign(&a, tmp);
            tmp->release();
            break;
        }
        case ORASSIGN : {              //    |=
			Variable* tmp = opMultiplicative(a, TokenType::OR, b);
			res = Variable::assign(&a, tmp);
            tmp->release();
            break;
        }
        case XORASSIGN :{              //    ^=
			Variable* tmp = opMultiplicative(a, TokenType::XOR, b);
			res = Variable::assign(&a, tmp);
            tmp->release();
            break;
        }
        case ANDASSIGN :{              //    &=
			Variable * tmp = opLogical(a, TokenType::AND, b);
			res = Variable::assign(&a, tmp);
            tmp->release();
            break;
        }
        default :{
            throw ExpressionException();
            break;
        }
    }
    return res;
}
예제 #11
0
Variable* Expression::opRelation(Variable *a, TokenType op, Variable *b){
	VarBoolean* res = new VarBoolean();

    if (a->type == Variable::BOOLEAN || a->type == Variable::NUMBER  //convert to number for comparison
     || b->type == Variable::BOOLEAN || b->type == Variable::NUMBER){
         VarNumber* ta = a->toVarNumber();
		 VarNumber* tb = b->toVarNumber();

         if (ta->numType == VarNumber::NANUMBER || tb->numType == VarNumber::NANUMBER)
            res->value = false;
         else {
             switch (op){
                 case LESS :                    //    <
                    res->value = (ta->type == VarNumber::NEG_INF && tb->type == VarNumber::INF)
                              || (ta->type == VarNumber::NEG_INF && tb->type == VarNumber::NORMAL)
                              || (ta->type == VarNumber::NORMAL && tb->type == VarNumber::INF)
                              || (ta->type == VarNumber::NORMAL && tb->type == VarNumber::NORMAL
                              &&  ta->toNumber() < tb->toNumber());
                    break;
                 case GREAT :                   //    >
                    res->value = (ta->type == VarNumber::INF && tb->type == VarNumber::NEG_INF)
                           || (ta->type == VarNumber::INF && tb->type == VarNumber::NORMAL)
                           || (ta->type == VarNumber::NORMAL && tb->type == VarNumber::NEG_INF)
                           || (ta->type == VarNumber::NORMAL && tb->type == VarNumber::NORMAL
                           &&  ta->toNumber() > tb->toNumber());
                     break;
                 case LESSEUQAL :               //    <=
                    res->value = (ta->type == VarNumber::NEG_INF && tb->type == VarNumber::INF)
                           || (ta->type == VarNumber::NEG_INF && tb->type == VarNumber::NORMAL)
                           || (ta->type == VarNumber::NORMAL && tb->type == VarNumber::INF)
                           || (ta->type == VarNumber::INF && tb->type == VarNumber::INF)
                           || (ta->type == VarNumber::NEG_INF && tb->type == VarNumber::NEG_INF)
                           || (ta->type == VarNumber::NORMAL && tb->type == VarNumber::NORMAL
                           &&  ta->toNumber() <= tb->toNumber());
                     break;
                 case GREATQUAL :               //    >=
                 res->value = (ta->type == VarNumber::INF && tb->type == VarNumber::NEG_INF)
                        || (ta->type == VarNumber::INF && tb->type == VarNumber::NORMAL)
                        || (ta->type == VarNumber::NORMAL && tb->type == VarNumber::NEG_INF)
                        || (ta->type == VarNumber::INF && tb->type == VarNumber::INF)
                        || (ta->type == VarNumber::NEG_INF && tb->type == VarNumber::NEG_INF)
                        || (ta->type == VarNumber::NORMAL && tb->type == VarNumber::NORMAL
                        &&  ta->toNumber() >= tb->toNumber());
                     break;
                 default :
                     throw ExpressionException();
                     break;
             }
         }
         ta->release();
         tb->release();
     } else {
         switch (op){
             case LESS :                    //    <
                 res->value = a->toString() < b->toString();
                 break;
             case GREAT :                   //    >
                 res->value = a->toString() > b->toString();
                 break;
             case LESSEUQAL :               //    <=
                 res->value = a->toString() <= b->toString();
                 break;
             case GREATQUAL :               //    >=
                 res->value = a->toString() >= b->toString();
                 break;
             default :
                 throw ExpressionException();
                 break;
         }
     }
     return res;
}