Skip to content

Commit

Permalink
Implement functions in parser: sqrt exp ln log2 asin tan
Browse files Browse the repository at this point in the history
  • Loading branch information
df7cb committed May 17, 2022
1 parent 80c7f28 commit b4f4673
Show file tree
Hide file tree
Showing 6 changed files with 976 additions and 652 deletions.
118 changes: 111 additions & 7 deletions unit.c
Original file line number Diff line number Diff line change
Expand Up @@ -907,21 +907,16 @@ unit_pow(PG_FUNCTION_ARGS)
PG_RETURN_POINTER(result);
}

PG_FUNCTION_INFO_V1(unit_sqrt);

Datum
unit_sqrt(PG_FUNCTION_ARGS)
void
unit_sqrt_internal(Unit *a, Unit *result)
{
Unit *a = (Unit *) PG_GETARG_POINTER(0);
Unit *result;
int i;

/* compute root of value */
if (a->value < 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
errmsg("cannot take square root of a negative-valued unit")));
result = (Unit *) palloc(sizeof(Unit));
result->value = sqrt(a->value);

/* compute root of base units */
Expand All @@ -934,7 +929,17 @@ unit_sqrt(PG_FUNCTION_ARGS)
base_units[i])));
result->units[i] = a->units[i] >> 1;
}
}

PG_FUNCTION_INFO_V1(unit_sqrt);

Datum
unit_sqrt(PG_FUNCTION_ARGS)
{
Unit *a = (Unit *) PG_GETARG_POINTER(0);
Unit *result = (Unit *) palloc(sizeof(Unit));

unit_sqrt_internal(a, result);
PG_RETURN_POINTER(result);
}

Expand Down Expand Up @@ -965,6 +970,105 @@ unit_cbrt(PG_FUNCTION_ARGS)
PG_RETURN_POINTER(result);
}

void
unit_exp_internal(Unit *a, Unit *result)
{
int i;

/* compute exp of value */
result->value = exp(a->value);

/* check dimension */
for (i = 0; i < N_UNITS; i++)
{
if (a->units[i] != 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
errmsg("cannot take base-e exponent of value that is not dimension-less")));
result->units[i] = 0;
}
}

void
unit_ln_internal(Unit *a, Unit *result)
{
int i;

/* compute ln of value */
result->value = log(a->value);

/* check dimension */
for (i = 0; i < N_UNITS; i++)
{
if (a->units[i] != 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
errmsg("cannot take ln of value that is not dimension-less")));
result->units[i] = 0;
}
}

void
unit_log2_internal(Unit *a, Unit *result)
{
int i;

/* compute log2 of value */
result->value = log2(a->value);

/* check dimension */
for (i = 0; i < N_UNITS; i++)
{
if (a->units[i] != 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
errmsg("cannot take log2 of value that is not dimension-less")));
result->units[i] = 0;
}
}

void
unit_asin_internal(Unit *a, Unit *result)
{
int i;

/* compute asin of value */
if (a->value < -1 || a->value > 1)
ereport(ERROR,
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
errmsg("cannot asin of values outside the range -1 to 1")));
result->value = asin(a->value);

/* check dimension */
for (i = 0; i < N_UNITS; i++)
{
if (a->units[i] != 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
errmsg("cannot take asin of value that is not dimension-less")));
result->units[i] = 0;
}
}

void
unit_tan_internal(Unit *a, Unit *result)
{
int i;

/* compute tan of value */
result->value = tan(a->value);

/* check dimension */
for (i = 0; i < N_UNITS; i++)
{
if (a->units[i] != 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
errmsg("cannot take tan of value that is not dimension-less")));
result->units[i] = 0;
}
}

/* obsolete version of unit_at_text used in v1..3 */
/* needs search_path = @extschema@ due to use of unit_parse() */
PG_FUNCTION_INFO_V1(unit_at);
Expand Down
28 changes: 28 additions & 0 deletions unit.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@

#define N_UNITS 8

/* functions recognized in parser */
enum parser_function {
FUNCTION_SQRT,
FUNCTION_EXP,
FUNCTION_LN,
FUNCTION_LOG2,
FUNCTION_ASIN,
FUNCTION_TAN,
};

/* defined units */

#define UNIT_NAME_LENGTH 32
Expand Down Expand Up @@ -132,4 +142,22 @@ unit_div_internal (Unit *a, Unit *b, Unit *result)
result->units[i] = a->units[i] - b->units[i];
}

void
unit_sqrt_internal(Unit *a, Unit *result);

void
unit_exp_internal(Unit *a, Unit *result);

void
unit_ln_internal(Unit *a, Unit *result);

void
unit_log2_internal(Unit *a, Unit *result);

void
unit_asin_internal(Unit *a, Unit *result);

void
unit_tan_internal(Unit *a, Unit *result);

#endif /* _UNIT_H */
30 changes: 30 additions & 0 deletions unitparse.l
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,36 @@ SUPER_9 \xe2\x81\xb9
return DOUBLE;
}
sqrt {
yyunitlval.FUNCTION = FUNCTION_SQRT;
return FUNCTION;
}
exp {
yyunitlval.FUNCTION = FUNCTION_EXP;
return FUNCTION;
}
ln {
yyunitlval.FUNCTION = FUNCTION_LN;
return FUNCTION;
}
log2 {
yyunitlval.FUNCTION = FUNCTION_LOG2;
return FUNCTION;
}
asin {
yyunitlval.FUNCTION = FUNCTION_ASIN;
return FUNCTION;
}
tan {
yyunitlval.FUNCTION = FUNCTION_TAN;
return FUNCTION;
}
{TIME_R} { /* hh:mm:ss[.sss] */
char *colon;
yyunitlval.DOUBLE = TIME_HOUR * atoi(yytext); /* hh */
Expand Down
Loading

0 comments on commit b4f4673

Please sign in to comment.