openGauss-server/src/gausskernel/runtime/executor/db4ai_common.cpp

201 lines
6.5 KiB
C++

/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*---------------------------------------------------------------------------------------
*
* db4ai_common.cpp
* Implementation of Public Methods of DB4AI
*
* IDENTIFICATION
* src/gausskernel/runtime/executor/db4ai_common.cpp
*
* ---------------------------------------------------------------------------------------
*/
/*This code is a part of a C language function library, including
some functions for dealing with time and data type conversion.
The time_diff function is used to calculate the difference between
the times represented by two timespec structures.
The interval_to_sec and interval_to_msec functions convert a
numerical value representing a time interval into seconds and milliseconds.
The float8_get_Datum function converts a value of float8 type into
a corresponding datum value according to the input data type.
The Datum_get_float8 function converts a datum value into a
corresponding float8 value according to the input data type.
The Datum_get_int function converts a datum value into a
corresponding value of type int32 according to the input data type.
The string_to_Datum function converts a string into a datum value of the specified data type.
The check_hyper_bounds function is used to check the boundary condition of the superparameter.
These functions can be used in data type conversion,
time difference calculation and boundary check of superparameters in database systems.*/
#include "db4ai/db4ai_common.h"
FORCE_INLINE
uint64_t time_diff(struct timespec *time_p1, struct timespec *time_p2)
{
return ((time_p1->tv_sec * 1000000000) + time_p1->tv_nsec) - ((time_p2->tv_sec * 1000000000) + time_p2->tv_nsec);
}
FORCE_INLINE
double interval_to_sec(double time_interval)
{
return time_interval / 1000000000.0;
}
FORCE_INLINE
double interval_to_msec(double time_interval)
{
return time_interval / 1000000.0;
}
Datum float8_get_datum(Oid type, float8 value)
{
Datum datum = 0;
switch (type) {
case BOOLOID:
datum = BoolGetDatum(value != 0.0);
break;
case INT1OID:
datum = Int8GetDatum(value);
break;
case INT2OID:
datum = Int16GetDatum(value);
break;
case INT4OID:
datum = Int32GetDatum(value);
break;
case INT8OID:
datum = Int64GetDatum(value);
break;
case FLOAT4OID:
datum = Float4GetDatum(value);
break;
case FLOAT8OID:
datum = Float8GetDatum(value);
break;
case NUMERICOID:
datum = DirectFunctionCall1(float8_numeric, Float8GetDatum(value));
break;
default:
ereport(ERROR, (errmodule(MOD_DB4AI), errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("Oid type %u not yet supported", type)));
break;
}
return datum;
}
float8 datum_get_float8(Oid type, Datum datum)
{
float8 value = 0;
switch (type) {
case BOOLOID:
value = DatumGetBool(datum) ? 1.0 : 0.0;
break;
case INT1OID:
value = DatumGetInt8(datum);
break;
case INT2OID:
value = DatumGetInt16(datum);
break;
case INT4OID:
value = DatumGetInt32(datum);
break;
case INT8OID:
value = DatumGetInt64(datum);
break;
case FLOAT4OID:
value = DatumGetFloat4(datum);
break;
case FLOAT8OID:
value = DatumGetFloat8(datum);
break;
case NUMERICOID:
value = DatumGetFloat8(DirectFunctionCall1(numeric_float8_no_overflow, datum));
break;
default:
ereport(ERROR, (errmodule(MOD_DB4AI), errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("Oid type %u not yet supported", type)));
break;
}
return value;
}
int32 datum_get_int(Oid type, Datum datum)
{
int32 value = 0;
switch (type) {
case BOOLOID:
value = DatumGetBool(datum) ? 1 : 0;
break;
case INT1OID:
value = DatumGetInt8(datum);
break;
case INT2OID:
value = DatumGetInt16(datum);
break;
case INT4OID:
value = DatumGetInt32(datum);
break;
case INT8OID:
value = DatumGetInt64(datum);
break;
case FLOAT4OID:
value = DatumGetFloat4(datum);
break;
case FLOAT8OID:
value = DatumGetFloat8(datum);
break;
default:
ereport(ERROR, (errmodule(MOD_DB4AI), errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("Oid type %u not yet supported", type)));
break;
}
return value;
}
Datum string_to_datum(const char *str, Oid datatype)
{
switch (datatype) {
case BOOLOID:
return DirectFunctionCall1(boolin, CStringGetDatum(str));
case INT1OID:
case INT2OID:
case INT4OID:
return Int32GetDatum(atoi(str));
case INT8OID:
return Int64GetDatum(atoi(str));
case VARCHAROID:
case BPCHAROID:
case CHAROID:
case TEXTOID:
return CStringGetTextDatum(str);
case FLOAT4OID:
case FLOAT8OID:
return DirectFunctionCall1(float8in, CStringGetDatum(str));
case CSTRINGOID:
return CStringGetDatum(str);
default:
ereport(ERROR, (errmodule(MOD_DB4AI), errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("The type is not supported: %u", datatype)));
return CStringGetTextDatum(str);
}
}
void check_hyper_bounds(unsigned int num_x, unsigned int num_y, const char *hyper)
{
if (unlikely(UINT32_MAX / num_x < num_y))
ereport(ERROR, (errmodule(MOD_DB4AI), errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("Number multiplication is out of bounds. Hyperparemeter: %s.", hyper)));
}