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]

Reply via email to