Skip to content

Commit

Permalink
Add REGTYPEOID to toString function (#1036) (#1047)
Browse files Browse the repository at this point in the history
  • Loading branch information
jrgemignani authored Jul 17, 2023
1 parent 33e5e10 commit 6123538
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 12 deletions.
29 changes: 24 additions & 5 deletions regress/expected/expr.out
Original file line number Diff line number Diff line change
Expand Up @@ -899,7 +899,7 @@ $$) AS r(result boolean);
(1 row)

SELECT * FROM cypher('expr', $$
RETURN false OR 1::bool
RETURN false OR 1::bool
$$) AS (result boolean);
result
--------
Expand All @@ -915,7 +915,7 @@ $$) AS (result boolean);
(1 row)

SELECT * FROM cypher('expr', $$
RETURN NOT 1::bool::int::bool
RETURN NOT 1::bool::int::bool
$$) AS (result boolean);
result
--------
Expand All @@ -936,11 +936,11 @@ RETURN false OR 1
$$) AS r(result boolean);
ERROR: cannot cast agtype integer to type boolean
SELECT * FROM cypher('expr', $$
RETURN 0 OR true
RETURN 0 OR true
$$) AS r(result boolean);
ERROR: cannot cast agtype integer to type boolean
SELECT * FROM cypher('expr', $$
RETURN NOT 1
RETURN NOT 1
$$) AS r(result boolean);
ERROR: cannot cast agtype integer to type boolean
SELECT * FROM cypher('expr', $$
Expand Down Expand Up @@ -968,7 +968,7 @@ RETURN false XOR 1::numeric
$$) AS (result agtype);
ERROR: cannot cast agtype numeric to type boolean
SELECT * FROM cypher('expr', $$
RETURN false OR 1::bool::int
RETURN false OR 1::bool::int
$$) AS (result boolean);
ERROR: cannot cast agtype integer to type boolean
--
Expand Down Expand Up @@ -3054,6 +3054,12 @@ SELECT * FROM age_toString('a text string'::text);
"a text string"
(1 row)

SELECT * FROM age_toString(pg_typeof(3.14));
age_tostring
--------------
"numeric"
(1 row)

-- agtypes
SELECT * FROM age_toString(agtype_in('3'));
age_tostring
Expand Down Expand Up @@ -6683,6 +6689,19 @@ SELECT * FROM cypher('list',$$ MATCH p=(n:xyz)-[e]->() SET n.array=[0, 1, 2, 3,
{"id": 1970324836974597, "label": "xyz", "properties": {"array": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100], 100]}}::vertex | {"id": 2251799813685249, "label": "KNOWS", "end_id": 1970324836974598, "start_id": 1970324836974597, "properties": {"array": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]}}::edge
(1 row)

-- pg_typeof
SELECT * FROM cypher('expr', $$MATCH (u) RETURN toString(pg_catalog.pg_typeof(u.id)) $$) AS (u agtype);
u
----------
"agtype"
"agtype"
"agtype"
"agtype"
"agtype"
"agtype"
"agtype"
(7 rows)

--
-- Cleanup
--
Expand Down
14 changes: 9 additions & 5 deletions regress/sql/expr.sql
Original file line number Diff line number Diff line change
Expand Up @@ -394,15 +394,15 @@ RETURN false XOR false
$$) AS r(result boolean);

SELECT * FROM cypher('expr', $$
RETURN false OR 1::bool
RETURN false OR 1::bool
$$) AS (result boolean);

SELECT * FROM cypher('expr', $$
RETURN false AND NOT 1::bool
$$) AS (result boolean);

SELECT * FROM cypher('expr', $$
RETURN NOT 1::bool::int::bool
RETURN NOT 1::bool::int::bool
$$) AS (result boolean);

-- Invalid operands for AND, OR, NOT, XOR
Expand All @@ -419,11 +419,11 @@ RETURN false OR 1
$$) AS r(result boolean);

SELECT * FROM cypher('expr', $$
RETURN 0 OR true
RETURN 0 OR true
$$) AS r(result boolean);

SELECT * FROM cypher('expr', $$
RETURN NOT 1
RETURN NOT 1
$$) AS r(result boolean);

SELECT * FROM cypher('expr', $$
Expand Down Expand Up @@ -451,7 +451,7 @@ RETURN false XOR 1::numeric
$$) AS (result agtype);

SELECT * FROM cypher('expr', $$
RETURN false OR 1::bool::int
RETURN false OR 1::bool::int
$$) AS (result boolean);
--
-- Test indirection transform logic for object.property, object["property"],
Expand Down Expand Up @@ -1361,6 +1361,7 @@ SELECT * FROM age_toString(false);
SELECT * FROM age_toString('a string');
SELECT * FROM age_toString('a cstring'::cstring);
SELECT * FROM age_toString('a text string'::text);
SELECT * FROM age_toString(pg_typeof(3.14));
-- agtypes
SELECT * FROM age_toString(agtype_in('3'));
SELECT * FROM age_toString(agtype_in('3.14'));
Expand Down Expand Up @@ -2708,6 +2709,9 @@ SELECT * FROM cypher('list',$$ MATCH p=(n:xyz)-[e]->() SET n.array=[0, 1, 2, 3,
90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
e.array, 100] return n,e $$) as (a agtype, b agtype);

-- pg_typeof
SELECT * FROM cypher('expr', $$MATCH (u) RETURN toString(pg_catalog.pg_typeof(u.id)) $$) AS (u agtype);

--
-- Cleanup
--
Expand Down
49 changes: 47 additions & 2 deletions src/backend/utils/adt/agtype.c
Original file line number Diff line number Diff line change
Expand Up @@ -5771,45 +5771,74 @@ Datum age_tostring(PG_FUNCTION_ARGS)

/* check number of args */
if (nargs > 1)
{
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("toString() only supports one argument")));
}

/* check for null */
if (nargs < 0 || nulls[0])
{
PG_RETURN_NULL();
}

/*
* toString() supports integer, float, numeric, text, cstring, boolean or
* the agtype integer, float, numeric, string, boolean input
* toString() supports integer, float, numeric, text, cstring, boolean,
* regtype or the agtypes: integer, float, numeric, string, boolean input
*/
arg = args[0];
type = types[0];

if (type != AGTYPEOID)
{
if (type == INT2OID)
{
string = DatumGetCString(DirectFunctionCall1(int8out,
Int64GetDatum((int64) DatumGetInt16(arg))));
}
else if (type == INT4OID)
{
string = DatumGetCString(DirectFunctionCall1(int8out,
Int64GetDatum((int64) DatumGetInt32(arg))));
}
else if (type == INT8OID)
{
string = DatumGetCString(DirectFunctionCall1(int8out, arg));
}
else if (type == FLOAT4OID)
{
string = DatumGetCString(DirectFunctionCall1(float8out, arg));
}
else if (type == FLOAT8OID)
{
string = DatumGetCString(DirectFunctionCall1(float8out, arg));
}
else if (type == NUMERICOID)
{
string = DatumGetCString(DirectFunctionCall1(numeric_out, arg));
}
else if (type == CSTRINGOID)
{
string = DatumGetCString(arg);
}
else if (type == TEXTOID)
{
string = text_to_cstring(DatumGetTextPP(arg));
}
else if (type == BOOLOID)
{
string = DatumGetBool(arg) ? "true" : "false";
}
else if (type == REGTYPEOID)
{
string = DatumGetCString(DirectFunctionCall1(regtypeout, arg));
}
else
{
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("toString() unsupported argument type %d",
type)));
}
}
else
{
Expand All @@ -5820,31 +5849,47 @@ Datum age_tostring(PG_FUNCTION_ARGS)
agt_arg = DATUM_GET_AGTYPE_P(arg);

if (!AGT_ROOT_IS_SCALAR(agt_arg))
{
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("toString() only supports scalar arguments")));
}

agtv_value = get_ith_agtype_value_from_container(&agt_arg->root, 0);

if (agtv_value->type == AGTV_NULL)
{
PG_RETURN_NULL();
}
else if (agtv_value->type == AGTV_INTEGER)
{
string = DatumGetCString(DirectFunctionCall1(int8out,
Int64GetDatum(agtv_value->val.int_value)));
}
else if (agtv_value->type == AGTV_FLOAT)
{
string = DatumGetCString(DirectFunctionCall1(float8out,
Float8GetDatum(agtv_value->val.float_value)));
}
else if (agtv_value->type == AGTV_STRING)
{
string = pnstrdup(agtv_value->val.string.val,
agtv_value->val.string.len);
}
else if (agtv_value->type == AGTV_NUMERIC)
{
string = DatumGetCString(DirectFunctionCall1(numeric_out,
PointerGetDatum(agtv_value->val.numeric)));
}
else if (agtv_value->type == AGTV_BOOL)
{
string = (agtv_value->val.boolean) ? "true" : "false";
}
else
{
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("toString() unsupported argument agtype %d",
agtv_value->type)));
}
}

/* build the result */
Expand Down

0 comments on commit 6123538

Please sign in to comment.