greenplumn convert 源码
greenplumn convert 代码
文件路径:/gpcontrib/orafce/convert.c
#include <float.h>
#include "postgres.h"
#include "fmgr.h"
#include "lib/stringinfo.h"
#include "mb/pg_wchar.h"
#include "utils/builtins.h"
#include "utils/numeric.h"
#include "utils/pg_locale.h"
#include "utils/formatting.h"
#include "orafce.h"
#include "builtins.h"
PG_FUNCTION_INFO_V1(orafce_to_char_int4);
PG_FUNCTION_INFO_V1(orafce_to_char_int8);
PG_FUNCTION_INFO_V1(orafce_to_char_float4);
PG_FUNCTION_INFO_V1(orafce_to_char_float8);
PG_FUNCTION_INFO_V1(orafce_to_char_numeric);
PG_FUNCTION_INFO_V1(orafce_to_char_timestamp);
PG_FUNCTION_INFO_V1(orafce_to_number);
PG_FUNCTION_INFO_V1(orafce_to_multi_byte);
PG_FUNCTION_INFO_V1(orafce_to_single_byte);
static int getindex(const char **map, char *mbchar, int mblen);
Datum
orafce_to_char_int4(PG_FUNCTION_ARGS)
{
int32 arg0 = PG_GETARG_INT32(0);
StringInfo buf = makeStringInfo();
appendStringInfo(buf, "%d", arg0);
PG_RETURN_TEXT_P(cstring_to_text(buf->data));
}
Datum
orafce_to_char_int8(PG_FUNCTION_ARGS)
{
int64 arg0 = PG_GETARG_INT64(0);
StringInfo buf = makeStringInfo();
appendStringInfo(buf, INT64_FORMAT, arg0);
PG_RETURN_TEXT_P(cstring_to_text(buf->data));
}
Datum
orafce_to_char_float4(PG_FUNCTION_ARGS)
{
char *p;
char *result;
struct lconv *lconv = PGLC_localeconv();
result = DatumGetCString(DirectFunctionCall1(float4out, PG_GETARG_DATUM(0)));
for (p = result; *p; p++)
if (*p == '.')
*p = lconv->decimal_point[0];
PG_RETURN_TEXT_P(cstring_to_text(result));
}
Datum
orafce_to_char_float8(PG_FUNCTION_ARGS)
{
char *p;
char *result;
struct lconv *lconv = PGLC_localeconv();
result = DatumGetCString(DirectFunctionCall1(float8out, PG_GETARG_DATUM(0)));
for (p = result; *p; p++)
if (*p == '.')
*p = lconv->decimal_point[0];
PG_RETURN_TEXT_P(cstring_to_text(result));
}
Datum
orafce_to_char_numeric(PG_FUNCTION_ARGS)
{
Numeric arg0 = PG_GETARG_NUMERIC(0);
StringInfo buf = makeStringInfo();
struct lconv *lconv = PGLC_localeconv();
char *p;
char *decimal = NULL;
appendStringInfoString(buf, DatumGetCString(DirectFunctionCall1(numeric_out, NumericGetDatum(arg0))));
for (p = buf->data; *p; p++)
if (*p == '.')
{
*p = lconv->decimal_point[0];
decimal = p; /* save decimal point position for the next loop */
}
/* Simulate the default Oracle to_char template (TM9 - Text Minimum)
by removing unneeded digits after the decimal point;
if no digits are left, then remove the decimal point too
*/
for (p = buf->data + buf->len - 1; decimal && p >= decimal; p--)
{
if (*p == '0' || *p == lconv->decimal_point[0])
*p = 0;
else
break; /* non-zero digit found, exit the loop */
}
PG_RETURN_TEXT_P(cstring_to_text(buf->data));
}
/********************************************************************
*
* orafec_to_char_timestamp
*
* Syntax:
*
* text to_date(timestamp date_txt)
*
* Purpose:
*
* Returns date and time format w.r.t NLS_DATE_FORMAT GUC
*
*********************************************************************/
Datum
orafce_to_char_timestamp(PG_FUNCTION_ARGS)
{
Timestamp ts = PG_GETARG_TIMESTAMP(0);
text *result = NULL;
if(nls_date_format && strlen(nls_date_format) > 0)
{
/* it will return the DATE in nls_date_format*/
result = DatumGetTextP(DirectFunctionCall2(timestamp_to_char,
TimestampGetDatum(ts),
CStringGetDatum(cstring_to_text(nls_date_format))));
}
else
{
result = cstring_to_text(DatumGetCString(DirectFunctionCall1(timestamp_out,
TimestampGetDatum(ts))));
}
PG_RETURN_TEXT_P(result);
}
Datum
orafce_to_number(PG_FUNCTION_ARGS)
{
text *arg0 = PG_GETARG_TEXT_PP(0);
char *buf;
struct lconv *lconv = PGLC_localeconv();
Numeric res;
char *p;
buf = text_to_cstring(arg0);
for (p = buf; *p; p++)
if (*p == lconv->decimal_point[0] && lconv->decimal_point[0])
*p = '.';
else if (*p == lconv->thousands_sep[0] && lconv->thousands_sep[0])
*p = ',';
res = DatumGetNumeric(DirectFunctionCall3(numeric_in, CStringGetDatum(buf), 0, -1));
PG_RETURN_NUMERIC(res);
}
/* 3 is enough, but it is defined as 4 in backend code. */
#ifndef MAX_CONVERSION_GROWTH
#define MAX_CONVERSION_GROWTH 4
#endif
/*
* Convert a tilde (~) to ...
* 1: a full width tilde. (same as JA16EUCTILDE in oracle)
* 0: a full width overline. (same as JA16EUC in oracle)
*
* Note - there is a difference with Oracle - it returns \342\210\274
* what is a tilde char. Orafce returns fullwidth tilde. If it is a
* problem, fix it for sef in code.
*/
#define JA_TO_FULL_WIDTH_TILDE 1
static const char *
TO_MULTI_BYTE_UTF8[95] =
{
"\343\200\200",
"\357\274\201",
"\342\200\235",
"\357\274\203",
"\357\274\204",
"\357\274\205",
"\357\274\206",
"\342\200\231",
"\357\274\210",
"\357\274\211",
"\357\274\212",
"\357\274\213",
"\357\274\214",
"\357\274\215",
"\357\274\216",
"\357\274\217",
"\357\274\220",
"\357\274\221",
"\357\274\222",
"\357\274\223",
"\357\274\224",
"\357\274\225",
"\357\274\226",
"\357\274\227",
"\357\274\230",
"\357\274\231",
"\357\274\232",
"\357\274\233",
"\357\274\234",
"\357\274\235",
"\357\274\236",
"\357\274\237",
"\357\274\240",
"\357\274\241",
"\357\274\242",
"\357\274\243",
"\357\274\244",
"\357\274\245",
"\357\274\246",
"\357\274\247",
"\357\274\250",
"\357\274\251",
"\357\274\252",
"\357\274\253",
"\357\274\254",
"\357\274\255",
"\357\274\256",
"\357\274\257",
"\357\274\260",
"\357\274\261",
"\357\274\262",
"\357\274\263",
"\357\274\264",
"\357\274\265",
"\357\274\266",
"\357\274\267",
"\357\274\270",
"\357\274\271",
"\357\274\272",
"\357\274\273",
"\357\274\274",
"\357\274\275",
"\357\274\276",
"\357\274\277",
"\342\200\230",
"\357\275\201",
"\357\275\202",
"\357\275\203",
"\357\275\204",
"\357\275\205",
"\357\275\206",
"\357\275\207",
"\357\275\210",
"\357\275\211",
"\357\275\212",
"\357\275\213",
"\357\275\214",
"\357\275\215",
"\357\275\216",
"\357\275\217",
"\357\275\220",
"\357\275\221",
"\357\275\222",
"\357\275\223",
"\357\275\224",
"\357\275\225",
"\357\275\226",
"\357\275\227",
"\357\275\230",
"\357\275\231",
"\357\275\232",
"\357\275\233",
"\357\275\234",
"\357\275\235",
#if JA_TO_FULL_WIDTH_TILDE
"\357\275\236"
#else
"\357\277\243"
#endif
};
static const char *
TO_MULTI_BYTE_EUCJP[95] =
{
"\241\241",
"\241\252",
"\241\311",
"\241\364",
"\241\360",
"\241\363",
"\241\365",
"\241\307",
"\241\312",
"\241\313",
"\241\366",
"\241\334",
"\241\244",
"\241\335",
"\241\245",
"\241\277",
"\243\260",
"\243\261",
"\243\262",
"\243\263",
"\243\264",
"\243\265",
"\243\266",
"\243\267",
"\243\270",
"\243\271",
"\241\247",
"\241\250",
"\241\343",
"\241\341",
"\241\344",
"\241\251",
"\241\367",
"\243\301",
"\243\302",
"\243\303",
"\243\304",
"\243\305",
"\243\306",
"\243\307",
"\243\310",
"\243\311",
"\243\312",
"\243\313",
"\243\314",
"\243\315",
"\243\316",
"\243\317",
"\243\320",
"\243\321",
"\243\322",
"\243\323",
"\243\324",
"\243\325",
"\243\326",
"\243\327",
"\243\330",
"\243\331",
"\243\332",
"\241\316",
"\241\357",
"\241\317",
"\241\260",
"\241\262",
"\241\306", /* Oracle returns different value \241\307 */
"\243\341",
"\243\342",
"\243\343",
"\243\344",
"\243\345",
"\243\346",
"\243\347",
"\243\350",
"\243\351",
"\243\352",
"\243\353",
"\243\354",
"\243\355",
"\243\356",
"\243\357",
"\243\360",
"\243\361",
"\243\362",
"\243\363",
"\243\364",
"\243\365",
"\243\366",
"\243\367",
"\243\370",
"\243\371",
"\243\372",
"\241\320",
"\241\303",
"\241\321",
#if JA_TO_FULL_WIDTH_TILDE
"\241\301"
#else
"\241\261"
#endif
};
Datum
orafce_to_multi_byte(PG_FUNCTION_ARGS)
{
text *src;
text *dst;
const char *s;
char *d;
int srclen;
#if defined(_MSC_VER) && (defined(_M_X64) || defined(__amd64__))
__int64 dstlen;
#else
int dstlen;
#endif
int i;
const char **map;
switch (GetDatabaseEncoding())
{
case PG_UTF8:
map = TO_MULTI_BYTE_UTF8;
break;
case PG_EUC_JP:
case PG_EUC_JIS_2004:
map = TO_MULTI_BYTE_EUCJP;
break;
/*
* TODO: Add converter for encodings.
*/
default: /* no need to convert */
PG_RETURN_DATUM(PG_GETARG_DATUM(0));
}
src = PG_GETARG_TEXT_PP(0);
s = VARDATA_ANY(src);
srclen = VARSIZE_ANY_EXHDR(src);
dst = (text *) palloc(VARHDRSZ + srclen * MAX_CONVERSION_GROWTH);
d = VARDATA(dst);
for (i = 0; i < srclen; i++)
{
unsigned char u = (unsigned char) s[i];
if (0x20 <= u && u <= 0x7e)
{
const char *m = map[u - 0x20];
while (*m)
{
*d++ = *m++;
}
}
else
{
*d++ = s[i];
}
}
dstlen = d - VARDATA(dst);
SET_VARSIZE(dst, VARHDRSZ + dstlen);
PG_RETURN_TEXT_P(dst);
}
static int
getindex(const char **map, char *mbchar, int mblen)
{
int i;
for (i = 0; i < 95; i++)
{
if (!memcmp(map[i], mbchar, mblen))
return i;
}
return -1;
}
Datum
orafce_to_single_byte(PG_FUNCTION_ARGS)
{
text *src;
text *dst;
char *s;
char *d;
int srclen;
#if defined(_MSC_VER) && (defined(_M_X64) || defined(__amd64__))
__int64 dstlen;
#else
int dstlen;
#endif
const char **map;
switch (GetDatabaseEncoding())
{
case PG_UTF8:
map = TO_MULTI_BYTE_UTF8;
break;
case PG_EUC_JP:
case PG_EUC_JIS_2004:
map = TO_MULTI_BYTE_EUCJP;
break;
/*
* TODO: Add converter for encodings.
*/
default: /* no need to convert */
PG_RETURN_DATUM(PG_GETARG_DATUM(0));
}
src = PG_GETARG_TEXT_PP(0);
s = VARDATA_ANY(src);
srclen = VARSIZE_ANY_EXHDR(src);
/* XXX - The output length should be <= input length */
dst = (text *) palloc0(VARHDRSZ + srclen);
d = VARDATA(dst);
while (*s && (s - VARDATA_ANY(src) < srclen))
{
char *u = s;
int clen;
int mapindex;
clen = pg_mblen(u);
s += clen;
if (clen == 1)
*d++ = *u;
else if ((mapindex = getindex(map, u, clen)) >= 0)
{
const char m = 0x20 + mapindex;
*d++ = m;
}
else
{
memcpy(d, u, clen);
d += clen;
}
}
dstlen = d - VARDATA(dst);
SET_VARSIZE(dst, VARHDRSZ + dstlen);
PG_RETURN_TEXT_P(dst);
}
相关信息
相关文章
0
赞
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
8、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦