This is an automated email from the ASF dual-hosted git repository.
dehowef pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/age.git
The following commit(s) were added to refs/heads/master by this push:
new f59f9e4d Add REGTYPEOID to toString function (#1036)
f59f9e4d is described below
commit f59f9e4d130dd17bd9e31271257681c346f07387
Author: John Gemignani <[email protected]>
AuthorDate: Thu Jul 13 13:12:19 2023 -0700
Add REGTYPEOID to toString function (#1036)
Added the REGTYPEOID to the toString function. This will help in
debugging by allowing pg_typeof to work with AGE.
For example -
psql-13.9-5432-pgsql=# SELECT * FROM cypher('graph',$$
MATCH ()<-[x *]-() RETURN toString(pg_catalog.pg_typeof(x))
$$) as (a agtype);
a
----------
"agtype"
"agtype"
"agtype"
(3 rows)
Added regression tests.
---
regress/expected/expr.out | 29 ++++++++++++++++++++-----
regress/sql/expr.sql | 14 +++++++-----
src/backend/utils/adt/agtype.c | 49 ++++++++++++++++++++++++++++++++++++++++--
3 files changed, 80 insertions(+), 12 deletions(-)
diff --git a/regress/expected/expr.out b/regress/expected/expr.out
index 37c7849b..5ed3cd43 100644
--- a/regress/expected/expr.out
+++ b/regress/expected/expr.out
@@ -900,7 +900,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
--------
@@ -916,7 +916,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
--------
@@ -937,11 +937,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', $$
@@ -969,7 +969,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
--
@@ -3055,6 +3055,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
@@ -6684,6 +6690,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, [...]
(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
--
diff --git a/regress/sql/expr.sql b/regress/sql/expr.sql
index c9547e33..d1a36995 100644
--- a/regress/sql/expr.sql
+++ b/regress/sql/expr.sql
@@ -395,7 +395,7 @@ 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', $$
@@ -403,7 +403,7 @@ 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
@@ -420,11 +420,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', $$
@@ -452,7 +452,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"],
@@ -1362,6 +1362,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'));
@@ -2709,6 +2710,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
--
diff --git a/src/backend/utils/adt/agtype.c b/src/backend/utils/adt/agtype.c
index 3f26d183..1fb5dc0d 100644
--- a/src/backend/utils/adt/agtype.c
+++ b/src/backend/utils/adt/agtype.c
@@ -5785,15 +5785,20 @@ 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];
@@ -5801,29 +5806,53 @@ Datum age_tostring(PG_FUNCTION_ARGS)
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
{
@@ -5834,31 +5863,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 */