mirror of
https://github.com/postgres/postgres.git
synced 2025-11-18 02:02:55 +03:00
Allow casting between bytea and integer types.
This allows smallint, integer, and bigint values to be cast to and from bytea. The bytea value is the two's complement representation of the integer, with the most significant byte first. For example: 1234::bytea -> \x000004d2 (-1234)::bytea -> \xfffffb2e Author: Aleksander Alekseev <aleksander@timescale.com> Reviewed-by: Joel Jacobson <joel@compiler.org> Reviewed-by: Yugo Nagata <nagata@sraoss.co.jp> Reviewed-by: Peter Eisentraut <peter@eisentraut.org> Reviewed-by: Michael Paquier <michael@paquier.xyz> Reviewed-by: Dean Rasheed <dean.a.rasheed@gmail.com> Discussion: https://postgr.es/m/CAJ7c6TPtOp6%2BkFX5QX3fH1SVr7v65uHr-7yEJ%3DGMGQi5uhGtcA%40mail.gmail.com
This commit is contained in:
@@ -4057,6 +4057,102 @@ bytea_sortsupport(PG_FUNCTION_ARGS)
|
||||
PG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/* Cast bytea -> int2 */
|
||||
Datum
|
||||
bytea_int2(PG_FUNCTION_ARGS)
|
||||
{
|
||||
bytea *v = PG_GETARG_BYTEA_PP(0);
|
||||
int len = VARSIZE_ANY_EXHDR(v);
|
||||
uint16 result;
|
||||
|
||||
/* Check that the byte array is not too long */
|
||||
if (len > sizeof(result))
|
||||
ereport(ERROR,
|
||||
errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||
errmsg("smallint out of range"));
|
||||
|
||||
/* Convert it to an integer; most significant bytes come first */
|
||||
result = 0;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
result <<= BITS_PER_BYTE;
|
||||
result |= ((unsigned char *) VARDATA_ANY(v))[i];
|
||||
}
|
||||
|
||||
PG_RETURN_INT16(result);
|
||||
}
|
||||
|
||||
/* Cast bytea -> int4 */
|
||||
Datum
|
||||
bytea_int4(PG_FUNCTION_ARGS)
|
||||
{
|
||||
bytea *v = PG_GETARG_BYTEA_PP(0);
|
||||
int len = VARSIZE_ANY_EXHDR(v);
|
||||
uint32 result;
|
||||
|
||||
/* Check that the byte array is not too long */
|
||||
if (len > sizeof(result))
|
||||
ereport(ERROR,
|
||||
errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||
errmsg("integer out of range"));
|
||||
|
||||
/* Convert it to an integer; most significant bytes come first */
|
||||
result = 0;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
result <<= BITS_PER_BYTE;
|
||||
result |= ((unsigned char *) VARDATA_ANY(v))[i];
|
||||
}
|
||||
|
||||
PG_RETURN_INT32(result);
|
||||
}
|
||||
|
||||
/* Cast bytea -> int8 */
|
||||
Datum
|
||||
bytea_int8(PG_FUNCTION_ARGS)
|
||||
{
|
||||
bytea *v = PG_GETARG_BYTEA_PP(0);
|
||||
int len = VARSIZE_ANY_EXHDR(v);
|
||||
uint64 result;
|
||||
|
||||
/* Check that the byte array is not too long */
|
||||
if (len > sizeof(result))
|
||||
ereport(ERROR,
|
||||
errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||
errmsg("bigint out of range"));
|
||||
|
||||
/* Convert it to an integer; most significant bytes come first */
|
||||
result = 0;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
result <<= BITS_PER_BYTE;
|
||||
result |= ((unsigned char *) VARDATA_ANY(v))[i];
|
||||
}
|
||||
|
||||
PG_RETURN_INT64(result);
|
||||
}
|
||||
|
||||
/* Cast int2 -> bytea; can just use int2send() */
|
||||
Datum
|
||||
int2_bytea(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return int2send(fcinfo);
|
||||
}
|
||||
|
||||
/* Cast int4 -> bytea; can just use int4send() */
|
||||
Datum
|
||||
int4_bytea(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return int4send(fcinfo);
|
||||
}
|
||||
|
||||
/* Cast int8 -> bytea; can just use int8send() */
|
||||
Datum
|
||||
int8_bytea(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return int8send(fcinfo);
|
||||
}
|
||||
|
||||
/*
|
||||
* appendStringInfoText
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user