Zainab-Saad commented on PR #1160:
URL: https://github.com/apache/age/pull/1160#issuecomment-1690460031
@rafsun42
As far as I have researched, such implementations are done with the extra
serialization step when the deserialized `agtype_value` is provided or in the
other case `agtype` structure itself is provided. `alter_property_value` is an
example for this.
So for doing this directly with `agtype_value`, I have written a helper
function that recursively copies the values and works with the non-scalar
values i.e; objects and arrays as well (I have tested with the added tests in
cypher_set.sql in this PR)
```
agtype_value *alter_properties(agtype_value *original_properties,
agtype *new_properties)
{
...
parsed_agtype_value = push_agtype_value(&parse_state, WAGT_BEGIN_OBJECT,
NULL);
// Copy original properties.
if (original_properties)
{
if (original_properties->type != AGTV_OBJECT)
{
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("a map is expected")));
}
copy_original_properties(parse_state, original_properties,
&parsed_agtype_value, true);
}
...
}
```
This one might need some refactoring
```
/*
* helper function to copy the original properties for SET plus-equal
* given the original properties are in agtype_value format
* this function helps skip the serialization step
*/
void copy_original_properties(agtype_parse_state* pstate, agtype_value*
props,
agtype_value **copied_properties, bool
is_top_level)
{
int i = 0;
check_stack_depth();
if (props->type == AGTV_OBJECT)
{
if (!is_top_level)
{
*copied_properties = push_agtype_value(&pstate,
WAGT_BEGIN_OBJECT,
NULL);
}
for(; i < props->val.object.num_pairs; i ++)
{
agtype_pair *pair = props->val.object.pairs + i;
*copied_properties = push_agtype_value(&pstate, WAGT_KEY,
&pair->key);
if (IS_A_AGTYPE_SCALAR(&pair->value))
{
*copied_properties = push_agtype_value(&pstate, WAGT_VALUE,
&pair->value);
}
else
{
copy_original_properties(pstate, &pair->value,
copied_properties, false);
}
}
if (!is_top_level)
{
*copied_properties = push_agtype_value(&pstate, WAGT_END_OBJECT,
NULL);
}
}
else if (props->type == AGTV_ARRAY)
{
*copied_properties = push_agtype_value(&pstate, WAGT_BEGIN_ARRAY,
NULL);
for (; i < props->val.array.num_elems; i++)
{
agtype_value elem = props->val.array.elems[i];
if (IS_A_AGTYPE_SCALAR(&elem))
{
*copied_properties = push_agtype_value(&pstate, WAGT_ELEM,
&elem);
}
else
{
copy_original_properties(pstate, &elem,
copied_properties, false);
}
}
*copied_properties = push_agtype_value(&pstate, WAGT_END_ARRAY,
NULL);
}
else
{
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("invalid type provided")));
}
}
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]