Commit 0913eec8 authored by Paul Asmuth's avatar Paul Asmuth
Browse files

implement mean/max/min

parent 7e26b44b
Loading
Loading
Loading
Loading
+127 −0
Original line number Diff line number Diff line
@@ -72,6 +72,133 @@ size_t sumExprScratchpadSize() {
  return sizeof(union sum_expr_scratchpad);
}

/**
 * MEAN() expression
 */
union mean_expr_scratchpad {
  double sum;
  int count;
};

void meanExpr(void* scratchpad, int argc, SValue* argv, SValue* out) {
  SValue* val = argv;
  union mean_expr_scratchpad* data = (union mean_expr_scratchpad*) scratchpad;

  if (argc != 1) {
    RAISE(
        kRuntimeError,
        "wrong number of arguments for mean(). expected: 1, got: %i\n",
        argc);
  }

  switch(val->getType()) {
    case SValue::T_NULL:
      return;

    default:
      data->sum += val->getFloat();
      data->count += 1;
      *out = SValue(data->sum / data->count);
      return;
  }
}

void meanExprFree(void* scratchpad) {
  /* noop */
}

size_t meanExprScratchpadSize() {
  return sizeof(union mean_expr_scratchpad);
}

/**
 * MAX() expression
 */
union max_expr_scratchpad {
  double max;
  int count;
};

void maxExpr(void* scratchpad, int argc, SValue* argv, SValue* out) {
  SValue* val = argv;
  union max_expr_scratchpad* data = (union max_expr_scratchpad*) scratchpad;

  if (argc != 1) {
    RAISE(
        kRuntimeError,
        "wrong number of arguments for max(). expected: 1, got: %i\n",
        argc);
  }

  switch(val->getType()) {
    case SValue::T_NULL:
      return;

    default: {
      auto fval = val->getFloat();
      if (data->count == 0 || fval > data->max) {
        data->max = fval;
      }

      data->count = 1;
      *out = SValue(data->max);
      return;
    }
  }
}

void maxExprFree(void* scratchpad) {
  /* noop */
}

size_t maxExprScratchpadSize() {
  return sizeof(union max_expr_scratchpad);
}

/**
 * MIN() expression
 */
union min_expr_scratchpad {
  double min;
  int count;
};

void minExpr(void* scratchpad, int argc, SValue* argv, SValue* out) {
  SValue* val = argv;
  union min_expr_scratchpad* data = (union min_expr_scratchpad*) scratchpad;

  if (argc != 1) {
    RAISE(
        kRuntimeError,
        "wrong number of arguments for min(). expected: 1, got: %i\n",
        argc);
  }

  switch(val->getType()) {
    case SValue::T_NULL:
      return;

    default: {
      auto fval = val->getFloat();
      if (data->count == 0 || fval < data->min) {
        data->min = fval;
      }

      data->count = 1;
      *out = SValue(data->min);
      return;
    }
  }
}

void minExprFree(void* scratchpad) {
  /* noop */
}

size_t minExprScratchpadSize() {
  return sizeof(union min_expr_scratchpad);
}

}
}
}
+12 −0
Original line number Diff line number Diff line
@@ -23,6 +23,18 @@ void sumExpr(void* scratchpad, int argc, SValue* argv, SValue* out);
void sumExprFree(void* scratchpad);
size_t sumExprScratchpadSize();

void meanExpr(void* scratchpad, int argc, SValue* argv, SValue* out);
void meanExprFree(void* scratchpad);
size_t meanExprScratchpadSize();

void minExpr(void* scratchpad, int argc, SValue* argv, SValue* out);
void minExprFree(void* scratchpad);
size_t minExprScratchpadSize();

void maxExpr(void* scratchpad, int argc, SValue* argv, SValue* out);
void maxExprFree(void* scratchpad);
size_t maxExprScratchpadSize();

}
}
}
+30 −0
Original line number Diff line number Diff line
@@ -30,6 +30,36 @@ DefaultRuntime::DefaultRuntime() {
      expressions::sumExprScratchpadSize(),
      &expressions::sumExprFree);

  symbol_table_.registerSymbol(
      "mean",
      &expressions::meanExpr,
      expressions::meanExprScratchpadSize(),
      &expressions::meanExprFree);

  symbol_table_.registerSymbol(
      "avg",
      &expressions::meanExpr,
      expressions::meanExprScratchpadSize(),
      &expressions::meanExprFree);

  symbol_table_.registerSymbol(
      "average",
      &expressions::meanExpr,
      expressions::meanExprScratchpadSize(),
      &expressions::meanExprFree);

  symbol_table_.registerSymbol(
      "min",
      &expressions::minExpr,
      expressions::minExprScratchpadSize(),
      &expressions::minExprFree);

  symbol_table_.registerSymbol(
      "max",
      &expressions::maxExpr,
      expressions::maxExprScratchpadSize(),
      &expressions::maxExprFree);

  /* expressions/boolean.h */
  symbol_table_.registerSymbol("eq", &expressions::eqExpr);
  symbol_table_.registerSymbol("neq", &expressions::neqExpr);
+34 −0
Original line number Diff line number Diff line
@@ -1325,3 +1325,37 @@ TEST_CASE(SQLTest, TestInvalidQueries, [] () {
    EXPECT(raised);
  }
});

TEST_CASE(SQLTest, TestMeanAggregation, [] () {
  auto results = executeTestQuery(
      "  SELECT"
      "    mean(one)"
      "  FROM"
      "    testtable2;");

  EXPECT_EQ(results->getNumRows(), 1);
  EXPECT_EQ(results->getRow(0)[0], "6.875000");
});

TEST_CASE(SQLTest, TestMaxAggregation, [] () {
  auto results = executeTestQuery(
      "  SELECT"
      "    max(one)"
      "  FROM"
      "    testtable2;");

  EXPECT_EQ(results->getNumRows(), 1);
  EXPECT_EQ(results->getRow(0)[0], "10.000000");
});

TEST_CASE(SQLTest, TestMinAggregation, [] () {
  auto results = executeTestQuery(
      "  SELECT"
      "    min(one)"
      "  FROM"
      "    testtable2;");

  EXPECT_EQ(results->getNumRows(), 1);
  EXPECT_EQ(results->getRow(0)[0], "1.000000");
});
+1 −1
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@
    - metric preview widget: auto refresh (on/off)

[ SQL ]
    - functions: round, mean, max/min, percentile, delta
    - functions: round, median, percentile, delta

[ release ]
    - svg: escape series names, labels!
Loading