Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean up agtype_to_int8, agtype_to_int4, & agtype_to_int2 #1354

Merged
merged 1 commit into from
Nov 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions regress/expected/agtype.out
Original file line number Diff line number Diff line change
Expand Up @@ -2829,6 +2829,10 @@ SELECT agtype_to_int8(Inf);
ERROR: column "inf" does not exist
LINE 1: SELECT agtype_to_int8(Inf);
^
SELECT agtype_to_int8('{"name":"John"}');
ERROR: invalid agtype string to int8 type: 17
SELECT agtype_to_int8('[1,2,3]');
ERROR: invalid agtype string to int8 type: 16
--
-- Test boolean to integer cast
--
Expand Down Expand Up @@ -2959,6 +2963,10 @@ SELECT agtype_to_int4(Inf);
ERROR: column "inf" does not exist
LINE 1: SELECT agtype_to_int4(Inf);
^
SELECT agtype_to_int4('{"name":"John"}');
ERROR: invalid agtype string to int4 type: 17
SELECT agtype_to_int4('[1,2,3]');
ERROR: invalid agtype string to int4 type: 16
--
-- Test boolean to integer2 cast
--
Expand Down Expand Up @@ -3089,6 +3097,10 @@ SELECT agtype_to_int2(Inf);
ERROR: column "inf" does not exist
LINE 1: SELECT agtype_to_int2(Inf);
^
SELECT agtype_to_int2('{"name":"John"}');
ERROR: invalid agtype string to int2 type: 17
SELECT agtype_to_int2('[1,2,3]');
ERROR: invalid agtype string to int2 type: 16
--
-- Test agtype to int[]
--
Expand Down
7 changes: 6 additions & 1 deletion regress/sql/agtype.sql
Original file line number Diff line number Diff line change
Expand Up @@ -693,6 +693,8 @@ SELECT agtype_to_int8('NaN');
SELECT agtype_to_int8('Inf');
SELECT agtype_to_int8(NaN);
SELECT agtype_to_int8(Inf);
SELECT agtype_to_int8('{"name":"John"}');
SELECT agtype_to_int8('[1,2,3]');

--
-- Test boolean to integer cast
Expand Down Expand Up @@ -728,7 +730,8 @@ SELECT agtype_to_int4('NaN');
SELECT agtype_to_int4('Inf');
SELECT agtype_to_int4(NaN);
SELECT agtype_to_int4(Inf);

SELECT agtype_to_int4('{"name":"John"}');
SELECT agtype_to_int4('[1,2,3]');
--
-- Test boolean to integer2 cast
--
Expand Down Expand Up @@ -763,6 +766,8 @@ SELECT agtype_to_int2('NaN');
SELECT agtype_to_int2('Inf');
SELECT agtype_to_int2(NaN);
SELECT agtype_to_int2(Inf);
SELECT agtype_to_int2('{"name":"John"}');
SELECT agtype_to_int2('[1,2,3]');

--
-- Test agtype to int[]
Expand Down
77 changes: 58 additions & 19 deletions src/backend/utils/adt/agtype.c
Original file line number Diff line number Diff line change
Expand Up @@ -2663,28 +2663,41 @@ Datum agtype_to_int8(PG_FUNCTION_ARGS)
{
agtype_value *temp = NULL;

/* convert the string to an agtype_value */
/*
* Convert the string to an agtype_value. Remember that a returned
* scalar value is returned in a one element array.
*/
temp = agtype_value_from_cstring(agtv_p->val.string.val,
agtv_p->val.string.len);

/* this will catch anything that isn't an array and isn't a scalar */
if (temp->type != AGTV_ARRAY ||
!temp->val.array.raw_scalar)
{
elog(ERROR, "invalid agtype type: %d", (int)agtv_p->type);
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid agtype string to int8 type: %d",
(int)temp->type)));
}

/* save the top agtype_value */
container = temp;
/* get the wrapped agtype_value */
temp = &temp->val.array.elems[0];

/* these we expect */
if (temp->type == AGTV_FLOAT ||
temp->type == AGTV_INTEGER ||
temp->type == AGTV_NUMERIC ||
temp->type == AGTV_BOOL)
{
agtv_p = temp;
}
else
{
elog(ERROR, "unexpected string type: %d in agtype_to_int8",
(int)temp->type);
}
}

/* now check the rest */
Expand All @@ -2708,7 +2721,10 @@ Datum agtype_to_int8(PG_FUNCTION_ARGS)
}
else
{
elog(ERROR, "invalid agtype type: %d", (int)agtv_p->type);
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid conversion type in agtype_to_int8: %d",
(int)agtv_p->type)));
}

/* free the container, if it was used */
Expand Down Expand Up @@ -2767,28 +2783,41 @@ Datum agtype_to_int4(PG_FUNCTION_ARGS)
{
agtype_value *temp = NULL;

/* convert the string to an agtype_value */
/*
* Convert the string to an agtype_value. Remember that a returned
* scalar value is returned in a one element array.
*/
temp = agtype_value_from_cstring(agtv_p->val.string.val,
agtv_p->val.string.len);

/* this will catch anything that isn't an array and isn't a scalar */
if (temp->type != AGTV_ARRAY ||
!temp->val.array.raw_scalar)
{
elog(ERROR, "invalid agtype type: %d", (int)agtv_p->type);
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid agtype string to int4 type: %d",
(int)temp->type)));
}

/* save the top agtype_value */
container = temp;
/* get the wrapped agtype_value */
temp = &temp->val.array.elems[0];

/* these we expect */
if (temp->type == AGTV_FLOAT ||
temp->type == AGTV_INTEGER ||
temp->type == AGTV_NUMERIC ||
temp->type == AGTV_BOOL)
{
agtv_p = temp;
}
else
{
elog(ERROR, "unexpected string type: %d in agtype_to_int4",
(int)temp->type);
}
}

/* now check the rest */
Expand All @@ -2807,18 +2836,16 @@ Datum agtype_to_int4(PG_FUNCTION_ARGS)
result = DatumGetInt32(DirectFunctionCall1(numeric_int4,
NumericGetDatum(agtv_p->val.numeric)));
}
else if (agtv_p->type == AGTV_STRING)
{
result = DatumGetInt32(DirectFunctionCall1(int4in,
CStringGetDatum(agtv_p->val.string.val)));
}
else if (agtv_p->type == AGTV_BOOL)
{
result = (agtv_p->val.boolean) ? 1 : 0;
}
else
{
elog(ERROR, "invalid agtype type: %d", (int)agtv_p->type);
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid conversion type in agtype_to_int4: %d",
(int)agtv_p->type)));
}

/* free the container, if it was used */
Expand Down Expand Up @@ -2877,28 +2904,41 @@ Datum agtype_to_int2(PG_FUNCTION_ARGS)
{
agtype_value *temp = NULL;

/* convert the string to an agtype_value */
/*
* Convert the string to an agtype_value. Remember that a returned
* scalar value is returned in a one element array.
*/
temp = agtype_value_from_cstring(agtv_p->val.string.val,
agtv_p->val.string.len);

/* this will catch anything that isn't an array and isn't a scalar */
if (temp->type != AGTV_ARRAY ||
!temp->val.array.raw_scalar)
{
elog(ERROR, "invalid agtype type: %d", (int)agtv_p->type);
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid agtype string to int2 type: %d",
(int)temp->type)));
}

/* save the top agtype_value */
container = temp;
/* get the wrapped agtype_value */
temp = &temp->val.array.elems[0];

/* these we expect */
if (temp->type == AGTV_FLOAT ||
temp->type == AGTV_INTEGER ||
temp->type == AGTV_NUMERIC ||
temp->type == AGTV_BOOL)
{
agtv_p = temp;
}
else
{
elog(ERROR, "unexpected string type: %d in agtype_to_int2",
(int)temp->type);
}
}

/* now check the rest */
Expand All @@ -2917,18 +2957,17 @@ Datum agtype_to_int2(PG_FUNCTION_ARGS)
result = DatumGetInt16(DirectFunctionCall1(numeric_int2,
NumericGetDatum(agtv_p->val.numeric)));
}
else if (agtv_p->type == AGTV_STRING)
{
result = DatumGetInt16(DirectFunctionCall1(int2in,
CStringGetDatum(agtv_p->val.string.val)));
}
else if (agtv_p->type == AGTV_BOOL)
{
result = (agtv_p->val.boolean) ? 1 : 0;
}
else
{
elog(ERROR, "invalid agtype type: %d", (int)agtv_p->type);
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid conversion type in agtype_to_int2: %d",
(int)agtv_p->type)));

}

/* free the container, if it was used */
Expand Down