greenplumn varchar2 源码
greenplumn varchar2 代码
文件路径:/gpcontrib/orafce/varchar2.c
/*----------------------------------------------------------------------------
*
* varchar2.c
* VARCHAR2 type for PostgreSQL.
*
*----------------------------------------------------------------------------
*/
#include "postgres.h"
#include "access/hash.h"
#include "libpq/pqformat.h"
#include "nodes/nodeFuncs.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "mb/pg_wchar.h"
#include "fmgr.h"
#include "orafce.h"
#include "builtins.h"
PG_FUNCTION_INFO_V1(varchar2in);
PG_FUNCTION_INFO_V1(varchar2out);
PG_FUNCTION_INFO_V1(varchar2);
PG_FUNCTION_INFO_V1(varchar2recv);
PG_FUNCTION_INFO_V1(orafce_concat2);
PG_FUNCTION_INFO_V1(orafce_varchar_transform);
bool orafce_varchar2_null_safe_concat = false;
/*
* varchar2_input -- common guts of varchar2in and varchar2recv
*
* s is the input text of length len (may not be null-terminated)
* atttypmod is the typmod value to apply
*
* If the input string is too long, raise an error
*
* Uses the C string to text conversion function, which is only appropriate
* if VarChar and text are equivalent types.
*/
static VarChar *
varchar2_input(const char *s, size_t len, int32 atttypmod)
{
VarChar *result; /* input data */
size_t maxlen;
maxlen = atttypmod - VARHDRSZ;
/*
* Perform the typmod check; error out if value too long for VARCHAR2
*/
if (atttypmod >= (int32) VARHDRSZ && len > maxlen)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("input value length is %zd; too long for type varchar2(%zd)", len , maxlen)));
result = (VarChar *) cstring_to_text_with_len(s, size2int(len));
return result;
}
/*
* Converts a C string to VARCHAR2 internal representation. atttypmod
* is the declared length of the type plus VARHDRSZ.
*/
Datum
varchar2in(PG_FUNCTION_ARGS)
{
char *s = PG_GETARG_CSTRING(0);
#ifdef NOT_USED
Oid typelem = PG_GETARG_OID(1);
#endif
int32 atttypmod = PG_GETARG_INT32(2);
VarChar *result;
result = varchar2_input(s, strlen(s), atttypmod);
PG_RETURN_VARCHAR_P(result);
}
/*
* converts a VARCHAR2 value to a C string.
*
* Uses the text to C string conversion function, which is only appropriate
* if VarChar and text are equivalent types.
*/
Datum
varchar2out(PG_FUNCTION_ARGS)
{
Datum txt = PG_GETARG_DATUM(0);
PG_RETURN_CSTRING(TextDatumGetCString(txt));
}
/*
* converts external binary format to varchar
*/
Datum
varchar2recv(PG_FUNCTION_ARGS)
{
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
#ifdef NOT_USED
Oid typelem = PG_GETARG_OID(1);
#endif
int32 atttypmod = PG_GETARG_INT32(2); /* typmod of the receiving column */
VarChar *result;
char *str; /* received data */
int nbytes; /* length in bytes of recived data */
str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
result = varchar2_input(str, nbytes, atttypmod);
pfree(str);
PG_RETURN_VARCHAR_P(result);
}
/*
* varchar2send -- convert varchar2 to binary value
*
* just use varcharsend()
*/
/*
* varchar2_transform()
* Flatten calls to varchar's length coercion function that set the new maximum
* length >= the previous maximum length. We can ignore the isExplicit
* argument, since that only affects truncation cases.
*
* just use varchar_transform()
*/
Datum
orafce_varchar_transform(PG_FUNCTION_ARGS)
{
#if PG_VERSION_NUM < 120000
return varchar_transform(fcinfo);
#else
return varchar_support(fcinfo);
#endif
}
/*
* Converts a VARCHAR2 type to the specified size.
*
* maxlen is the typmod, ie, declared length plus VARHDRSZ bytes.
* isExplicit is true if this is for an explicit cast to varchar2(N).
*
* Truncation rules: for an explicit cast, silently truncate to the given
* length; for an implicit cast, raise error if length limit is exceeded
*/
Datum
varchar2(PG_FUNCTION_ARGS)
{
VarChar *source = PG_GETARG_VARCHAR_PP(0);
int32 typmod = PG_GETARG_INT32(1);
bool isExplicit = PG_GETARG_BOOL(2);
int32 len,
maxlen;
char *s_data;
len = VARSIZE_ANY_EXHDR(source);
s_data = VARDATA_ANY(source);
maxlen = typmod - VARHDRSZ;
/* No work if typmod is invalid or supplied data fits it already */
if (maxlen < 0 || len <= maxlen)
PG_RETURN_VARCHAR_P(source);
/* error out if value too long unless it's an explicit cast */
if (!isExplicit)
{
if (len > maxlen)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("input value length is %d; too long for type varchar2(%d)",len ,maxlen)));
}
PG_RETURN_VARCHAR_P((VarChar *) cstring_to_text_with_len(s_data,maxlen));
}
/*
* varchar2typmodin -- type modifier input function
*
* just use varchartypmodin()
*/
/*
* varchar2typmodout -- type modifier output function
*
* just use varchartypmodout()
*/
/*
* orafce_concat2 - null safe concat
*
* returns NULL instead empty string
*/
Datum
orafce_concat2(PG_FUNCTION_ARGS)
{
text *arg1 = NULL,
*arg2 = NULL,
*result;
int32 len1 = 0,
len2 = 0,
len;
char *ptr;
if (!PG_ARGISNULL(0))
{
arg1 = PG_GETARG_TEXT_PP(0);
len1 = VARSIZE_ANY_EXHDR(arg1);
}
if (!PG_ARGISNULL(1))
{
arg2 = PG_GETARG_TEXT_PP(1);
len2 = VARSIZE_ANY_EXHDR(arg2);
}
/* default behave should be compatible with Postgres */
if (!orafce_varchar2_null_safe_concat)
{
if (PG_ARGISNULL(0) || PG_ARGISNULL(1))
PG_RETURN_NULL();
}
else
{
if (len1 == 0 && len2 == 0)
PG_RETURN_NULL();
}
/* hard work, we should to concat strings */
len = len1 + len2 + VARHDRSZ;
result = (text *) palloc(len);
SET_VARSIZE(result, len);
ptr = VARDATA(result);
if (len1 > 0)
memcpy(ptr, VARDATA_ANY(arg1), len1);
if (len2 > 0)
memcpy(ptr + len1, VARDATA_ANY(arg2), len2);
PG_RETURN_TEXT_P(result);
}
相关信息
相关文章
0
赞
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
8、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦