You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@age.apache.org by jg...@apache.org on 2022/07/13 15:55:24 UTC

[age] branch master updated: Fix issue #240 - negative array bounds - addendum

This is an automated email from the ASF dual-hosted git repository.

jgemignani 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 5ded59f  Fix issue #240 - negative array bounds - addendum
5ded59f is described below

commit 5ded59fca7b43612abb9baf50cf2905deb349ebb
Author: John Gemignani <jr...@gmail.com>
AuthorDate: Tue Jul 12 15:51:56 2022 -0700

    Fix issue #240 - negative array bounds - addendum
    
    Fixed github issue #240 - negative array bounds - addendum.
    
    There was found to be an issue with the transform_A_Indirection
    function. Previous work on the function removed a few important
    lines. This caused it to improperly transform nested indirections.
    These lines were added back in.
    
    Additionally, since the previous work on transform_A_Indirection,
    some new functionality was added to transform_ColumnRef. This
    allowed the removal of some unnecessary code as well.
    
    Added regression tests to cover nested access and slice operations.
---
 regress/expected/expr.out        | 111 ++++++++++++++++++++++++++++
 regress/sql/expr.sql             |  24 +++++++
 src/backend/parser/cypher_expr.c |  90 ++++++++---------------
 src/backend/utils/adt/agtype.c   | 151 +++++++++++++++++++++++++++++++--------
 4 files changed, 287 insertions(+), 89 deletions(-)

diff --git a/regress/expected/expr.out b/regress/expected/expr.out
index 61f4816..5f28e36 100644
--- a/regress/expected/expr.out
+++ b/regress/expected/expr.out
@@ -405,6 +405,117 @@ $$RETURN [0][0..-2147483649]$$) as r(a agtype);
  []
 (1 row)
 
+-- access and slice operators nested
+SELECT * from cypher('expr', $$ WITH [0, 1, [2, 3, 4], 5, [6, 7, 8], 9] as l RETURN l[0] $$) as (results agtype);
+ results 
+---------
+ 0
+(1 row)
+
+SELECT * from cypher('expr', $$ WITH [0, 1, [2, 3, 4], 5, [6, 7, 8], 9] as l RETURN l[2] $$) as (results agtype);
+  results  
+-----------
+ [2, 3, 4]
+(1 row)
+
+SELECT * from cypher('expr', $$ WITH [0, 1, [2, 3, 4], 5, [6, 7, 8], 9] as l RETURN l[-1] $$) as (results agtype);
+ results 
+---------
+ 9
+(1 row)
+
+SELECT * from cypher('expr', $$ WITH [0, 1, [2, 3, 4], 5, [6, 7, 8], 9] as l RETURN l[2][-2] $$) as (results agtype);
+ results 
+---------
+ 3
+(1 row)
+
+SELECT * from cypher('expr', $$ WITH [0, 1, [2, 3, 4], 5, [6, 7, 8], 9] as l RETURN l[2][-2..] $$) as (results agtype);
+ results 
+---------
+ [3, 4]
+(1 row)
+
+SELECT * from cypher('expr', $$ WITH [0, 1, [2, 3, 4], 5, [6, 7, 8], 9] as l RETURN l[-2..] $$) as (results agtype);
+    results     
+----------------
+ [[6, 7, 8], 9]
+(1 row)
+
+SELECT * from cypher('expr', $$ WITH [0, 1, [2, 3, 4], 5, [6, 7, 8], 9] as l RETURN l[-2..][-1..][-1..] $$) as (results agtype);
+ results 
+---------
+ [9]
+(1 row)
+
+SELECT * from cypher('expr', $$ WITH [0, 1, [2, 3, 4], 5, [6, 7, 8], 9] as l RETURN l[-2..][-1..][0] $$) as (results agtype);
+ results 
+---------
+ 9
+(1 row)
+
+SELECT * from cypher('expr', $$ WITH [0, 1, [2, 3, 4], 5, [6, 7, 8], 9] as l RETURN l[-2..][-1..][-1] $$) as (results agtype);
+ results 
+---------
+ 9
+(1 row)
+
+SELECT * from cypher('expr', $$ WITH [0, 1, [2, 3, 4], 5, [6, 7, 8], 9] as l RETURN l[-2..][-2..-1] $$) as (results agtype);
+   results   
+-------------
+ [[6, 7, 8]]
+(1 row)
+
+SELECT * from cypher('expr', $$ WITH [0, 1, [2, 3, 4], 5, [6, 7, 8], 9] as l RETURN l[-4..-2] $$) as (results agtype);
+    results     
+----------------
+ [[2, 3, 4], 5]
+(1 row)
+
+SELECT * from cypher('expr', $$ WITH [0, 1, [2, 3, 4], 5, [6, 7, 8], 9] as l RETURN l[-4..-2][-2] $$) as (results agtype);
+  results  
+-----------
+ [2, 3, 4]
+(1 row)
+
+SELECT * from cypher('expr', $$ WITH [0, 1, [2, 3, 4], 5, [6, 7, 8], 9] as l RETURN l[-4..-2][0] $$) as (results agtype);
+  results  
+-----------
+ [2, 3, 4]
+(1 row)
+
+SELECT * from cypher('expr', $$ WITH [0, 1, [2, 3, 4], 5, [6, 7, 8], 9] as l RETURN l[-4..-2][-2][-2..] $$) as (results agtype);
+ results 
+---------
+ [3, 4]
+(1 row)
+
+SELECT * from cypher('expr', $$ WITH [0, 1, [2, 3, 4], 5, [6, 7, 8], 9] as l RETURN l[-4..-2][-2][-2..][0] $$) as (results agtype);
+ results 
+---------
+ 3
+(1 row)
+
+-- empty list
+SELECT * from cypher('expr', $$ WITH [0, 1, [2, 3, 4], 5, [6, 7, 8], 9] as l RETURN l[-2..][-1..][-2..-2] $$) as (results agtype);
+ results 
+---------
+ []
+(1 row)
+
+-- should return null
+SELECT * from cypher('expr', $$ WITH [0, 1, [2, 3, 4], 5, [6, 7, 8], 9] as l RETURN l[2][3] $$) as (results agtype);
+ results 
+---------
+ 
+(1 row)
+
+SELECT * from cypher('expr', $$ WITH [0, 1, [2, 3, 4], 5, [6, 7, 8], 9] as l RETURN l[-2..][-1..][-2] $$) as (results agtype);
+ results 
+---------
+ 
+(1 row)
+
 --
 -- String operators
 --
diff --git a/regress/sql/expr.sql b/regress/sql/expr.sql
index c8ad89d..7fe904f 100644
--- a/regress/sql/expr.sql
+++ b/regress/sql/expr.sql
@@ -192,6 +192,30 @@ $$RETURN 0[[0]..[1]]$$) as r(a agtype);
 SELECT * from cypher('expr',
 $$RETURN [0][0..-2147483649]$$) as r(a agtype);
 
+-- access and slice operators nested
+SELECT * from cypher('expr', $$ WITH [0, 1, [2, 3, 4], 5, [6, 7, 8], 9] as l RETURN l[0] $$) as (results agtype);
+SELECT * from cypher('expr', $$ WITH [0, 1, [2, 3, 4], 5, [6, 7, 8], 9] as l RETURN l[2] $$) as (results agtype);
+SELECT * from cypher('expr', $$ WITH [0, 1, [2, 3, 4], 5, [6, 7, 8], 9] as l RETURN l[-1] $$) as (results agtype);
+SELECT * from cypher('expr', $$ WITH [0, 1, [2, 3, 4], 5, [6, 7, 8], 9] as l RETURN l[2][-2] $$) as (results agtype);
+SELECT * from cypher('expr', $$ WITH [0, 1, [2, 3, 4], 5, [6, 7, 8], 9] as l RETURN l[2][-2..] $$) as (results agtype);
+SELECT * from cypher('expr', $$ WITH [0, 1, [2, 3, 4], 5, [6, 7, 8], 9] as l RETURN l[-2..] $$) as (results agtype);
+SELECT * from cypher('expr', $$ WITH [0, 1, [2, 3, 4], 5, [6, 7, 8], 9] as l RETURN l[-2..][-1..][-1..] $$) as (results agtype);
+SELECT * from cypher('expr', $$ WITH [0, 1, [2, 3, 4], 5, [6, 7, 8], 9] as l RETURN l[-2..][-1..][0] $$) as (results agtype);
+SELECT * from cypher('expr', $$ WITH [0, 1, [2, 3, 4], 5, [6, 7, 8], 9] as l RETURN l[-2..][-1..][-1] $$) as (results agtype);
+SELECT * from cypher('expr', $$ WITH [0, 1, [2, 3, 4], 5, [6, 7, 8], 9] as l RETURN l[-2..][-2..-1] $$) as (results agtype);
+SELECT * from cypher('expr', $$ WITH [0, 1, [2, 3, 4], 5, [6, 7, 8], 9] as l RETURN l[-4..-2] $$) as (results agtype);
+SELECT * from cypher('expr', $$ WITH [0, 1, [2, 3, 4], 5, [6, 7, 8], 9] as l RETURN l[-4..-2][-2] $$) as (results agtype);
+SELECT * from cypher('expr', $$ WITH [0, 1, [2, 3, 4], 5, [6, 7, 8], 9] as l RETURN l[-4..-2][0] $$) as (results agtype);
+SELECT * from cypher('expr', $$ WITH [0, 1, [2, 3, 4], 5, [6, 7, 8], 9] as l RETURN l[-4..-2][-2][-2..] $$) as (results agtype);
+SELECT * from cypher('expr', $$ WITH [0, 1, [2, 3, 4], 5, [6, 7, 8], 9] as l RETURN l[-4..-2][-2][-2..][0] $$) as (results agtype);
+
+-- empty list
+SELECT * from cypher('expr', $$ WITH [0, 1, [2, 3, 4], 5, [6, 7, 8], 9] as l RETURN l[-2..][-1..][-2..-2] $$) as (results agtype);
+
+-- should return null
+SELECT * from cypher('expr', $$ WITH [0, 1, [2, 3, 4], 5, [6, 7, 8], 9] as l RETURN l[2][3] $$) as (results agtype);
+SELECT * from cypher('expr', $$ WITH [0, 1, [2, 3, 4], 5, [6, 7, 8], 9] as l RETURN l[-2..][-1..][-2] $$) as (results agtype);
+
 --
 -- String operators
 --
diff --git a/src/backend/parser/cypher_expr.c b/src/backend/parser/cypher_expr.c
index 914ab29..cb43788 100644
--- a/src/backend/parser/cypher_expr.c
+++ b/src/backend/parser/cypher_expr.c
@@ -94,8 +94,7 @@ static Node *transform_FuncCall(cypher_parsestate *cpstate, FuncCall *fn);
 static Node *transform_WholeRowRef(ParseState *pstate, RangeTblEntry *rte,
                                    int location);
 static ArrayExpr *make_agtype_array_expr(List *args);
-static Node *transform_column_ref_for_indirection(cypher_parsestate *cpstate,
-                                                  ColumnRef *cr);
+
 /* transform a cypher expression */
 Node *transform_cypher_expr(cypher_parsestate *cpstate, Node *expr,
                             ParseExprKind expr_kind)
@@ -703,57 +702,15 @@ static ArrayExpr *make_agtype_array_expr(List *args)
     return newa;
 }
 
-/*
- * Transforms a column ref for indirection. Try to find the rte that the
- * columnRef is references and pass the properties of that rte as what the
- * columnRef is referencing. Otherwise, reference the Var
- */
-static Node *transform_column_ref_for_indirection(cypher_parsestate *cpstate,
-                                                  ColumnRef *cr)
-{
-    ParseState *pstate = (ParseState *)cpstate;
-    RangeTblEntry *rte = NULL;
-    Node *field1 = linitial(cr->fields);
-    char *relname = NULL;
-    Node *node = NULL;
-
-    Assert(IsA(field1, String));
-    relname = strVal(field1);
-
-    // locate the referenced RTE
-    rte = find_rte(cpstate, relname);
-    if (rte == NULL)
-    {
-        /*
-         * This column ref is referencing something that was created in
-         * a previous query and is a variable.
-         */
-        return transform_cypher_expr_recurse(cpstate, (Node *)cr);
-    }
-
-    // try to identify the properties column of the RTE
-    node = scanRTEForColumn(pstate, rte, "properties", cr->location, 0, NULL);
-
-    if (node == NULL)
-    {
-        ereport(ERROR,
-                (errcode(ERRCODE_UNDEFINED_OBJECT),
-                 errmsg("could not find rte for %s", relname)));
-
-    }
-
-    return node;
-}
-
 static Node *transform_A_Indirection(cypher_parsestate *cpstate,
                                      A_Indirection *a_ind)
 {
     int location;
-    ListCell *lc;
-    Node *ind_arg_expr;
+    ListCell *lc = NULL;
+    Node *ind_arg_expr = NULL;
     FuncExpr *func_expr = NULL;
-    Oid func_access_oid;
-    Oid func_slice_oid;
+    Oid func_access_oid = InvalidOid;
+    Oid func_slice_oid = InvalidOid;
     List *args = NIL;
     bool is_access = false;
 
@@ -766,20 +723,16 @@ static Node *transform_A_Indirection(cypher_parsestate *cpstate,
     func_slice_oid = get_ag_func_oid("agtype_access_slice", 3, AGTYPEOID,
                                      AGTYPEOID, AGTYPEOID);
 
-    if (IsA(a_ind->arg, ColumnRef))
-    {
-        ColumnRef *cr = (ColumnRef *)a_ind->arg;
-
-        ind_arg_expr = transform_column_ref_for_indirection(cpstate, cr);
-    }
-    else
-    {
-        ind_arg_expr = transform_cypher_expr_recurse(cpstate, a_ind->arg);
-    }
+    /* transform indirection argument expression */
+    ind_arg_expr = transform_cypher_expr_recurse(cpstate, a_ind->arg);
 
+    /* get the location of the expression */
     location = exprLocation(ind_arg_expr);
 
+    /* add the expression as the first entry */
     args = lappend(args, ind_arg_expr);
+
+    /* iterate through the indirections */
     foreach (lc, a_ind->indirection)
     {
         Node *node = lfirst(lc);
@@ -799,12 +752,21 @@ static Node *transform_A_Indirection(cypher_parsestate *cpstate,
                                          InvalidOid, InvalidOid,
                                          COERCE_EXPLICIT_CALL);
 
+                func_expr->funcvariadic = true;
+                func_expr->location = location;
+
+                /*
+                 * The result of this function is the input to the next access
+                 * or slice operator. So we need to start out with a new arg
+                 * list with this function expression.
+                 */
+                args = lappend(NIL, func_expr);
+
                 /* we are no longer working on an access */
                 is_access = false;
 
-                func_expr->funcvariadic = true;
-
             }
+
             /* add slice bounds to args */
             if (!indices->lidx)
             {
@@ -832,11 +794,18 @@ static Node *transform_A_Indirection(cypher_parsestate *cpstate,
                 node = transform_cypher_expr_recurse(cpstate, indices->uidx);
             }
             args = lappend(args, node);
+
             /* wrap and close it */
             func_expr = makeFuncExpr(func_slice_oid, AGTYPEOID, args,
                                      InvalidOid, InvalidOid,
                                      COERCE_EXPLICIT_CALL);
             func_expr->location = location;
+
+            /*
+             * The result of this function is the input to the next access
+             * or slice operator. So we need to start out with a new arg
+             * list with this function expression.
+             */
             args = lappend(NIL, func_expr);
         }
         /* is this a string or index?*/
@@ -844,6 +813,7 @@ static Node *transform_A_Indirection(cypher_parsestate *cpstate,
         {
             /* we are working on an access */
             is_access = true;
+
             /* is this an index? */
             if (IsA(node, A_Indices))
             {
diff --git a/src/backend/utils/adt/agtype.c b/src/backend/utils/adt/agtype.c
index 52d72bf..908f388 100644
--- a/src/backend/utils/adt/agtype.c
+++ b/src/backend/utils/adt/agtype.c
@@ -512,9 +512,11 @@ static void agtype_typecast_object(agtype_in_state *state, char *annotation)
                 last_updated_value->type = AGTV_VERTEX;
         }
         else
+        {
             ereport(ERROR,
-                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-                 errmsg("object is not a vertex")));
+                    (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                     errmsg("object is not a vertex")));
+        }
 
     }
     /* check for a cast to an edge */
@@ -529,15 +531,19 @@ static void agtype_typecast_object(agtype_in_state *state, char *annotation)
                 last_updated_value->type = AGTV_EDGE;
         }
         else
+        {
             ereport(ERROR,
-                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-                 errmsg("object is not a edge")));
+                    (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                     errmsg("object is not a edge")));
+        }
     }
     /* otherwise this isn't a supported typecast */
     else
+    {
         ereport(ERROR,
                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                  errmsg("invalid annotation value for object")));
+    }
 }
 
 /* function to handle array typecasts */
@@ -582,17 +588,19 @@ static void agtype_typecast_array(agtype_in_state *state, char *annotation)
                 last_updated_value->type = AGTV_PATH;
         }
         else
+        {
             ereport(ERROR,
-                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-                 errmsg("array is not a valid path")));
-
+                    (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                     errmsg("array is not a valid path")));
+        }
     }
     /* otherwise this isn't a supported typecast */
     else
+    {
         ereport(ERROR,
                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                  errmsg("invalid annotation value for object")));
-
+    }
 }
 
 /* helper function to check if an object fits a vertex */
@@ -609,7 +617,9 @@ static bool is_object_vertex(agtype_value *agtv)
 
     /* we need 3 pairs for a vertex */
     if (agtv->val.object.num_pairs != 3)
+    {
         return false;
+    }
 
     /* iterate through all pairs */
     for (i = 0; i < agtv->val.object.num_pairs; i++)
@@ -626,20 +636,28 @@ static bool is_object_vertex(agtype_value *agtv)
         if (key_len == 2 &&
             pg_strncasecmp(key_val, "id", key_len) == 0 &&
             value->type == AGTV_INTEGER)
+        {
             has_id = true;
+        }
         /* check for a label of type string */
         else if (key_len == 5 &&
-            pg_strncasecmp(key_val, "label", key_len) == 0 &&
-            value->type == AGTV_STRING)
+                 pg_strncasecmp(key_val, "label", key_len) == 0 &&
+                 value->type == AGTV_STRING)
+        {
             has_label = true;
+        }
         /* check for properties of type object */
         else if (key_len == 10 &&
-            pg_strncasecmp(key_val, "properties", key_len) == 0 &&
-            value->type == AGTV_OBJECT)
+                 pg_strncasecmp(key_val, "properties", key_len) == 0 &&
+                 value->type == AGTV_OBJECT)
+        {
             has_properties = true;
+        }
         /* if it gets to this point, it can't be a vertex */
         else
+        {
             return false;
+        }
     }
     return (has_id && has_label && has_properties);
 }
@@ -660,7 +678,9 @@ static bool is_object_edge(agtype_value *agtv)
 
     /* we need 5 pairs for an edge */
     if (agtv->val.object.num_pairs != 5)
+    {
         return false;
+    }
 
     /* iterate through the pairs */
     for (i = 0; i < agtv->val.object.num_pairs; i++)
@@ -677,30 +697,42 @@ static bool is_object_edge(agtype_value *agtv)
         if (key_len == 2 &&
             pg_strncasecmp(key_val, "id", key_len) == 0 &&
             value->type == AGTV_INTEGER)
+        {
             has_id = true;
+        }
         /* check for a label of type string */
         else if (key_len == 5 &&
-            pg_strncasecmp(key_val, "label", key_len) == 0 &&
-            value->type == AGTV_STRING)
+                 pg_strncasecmp(key_val, "label", key_len) == 0 &&
+                 value->type == AGTV_STRING)
+        {
             has_label = true;
+        }
         /* check for properties of type object */
         else if (key_len == 10 &&
-            pg_strncasecmp(key_val, "properties", key_len) == 0 &&
-            value->type == AGTV_OBJECT)
+                 pg_strncasecmp(key_val, "properties", key_len) == 0 &&
+                 value->type == AGTV_OBJECT)
+        {
             has_properties = true;
+        }
         /* check for a start_id of type integer */
         else if (key_len == 8 &&
-            pg_strncasecmp(key_val, "start_id", key_len) == 0 &&
-            value->type == AGTV_INTEGER)
+                 pg_strncasecmp(key_val, "start_id", key_len) == 0 &&
+                 value->type == AGTV_INTEGER)
+        {
             has_start_id = true;
+        }
         /* check for an end_id of type integer */
         else if (key_len == 6 &&
-            pg_strncasecmp(key_val, "end_id", key_len) == 0 &&
-            value->type == AGTV_INTEGER)
+                 pg_strncasecmp(key_val, "end_id", key_len) == 0 &&
+                 value->type == AGTV_INTEGER)
+        {
             has_end_id = true;
+        }
         /* if it gets to this point, it can't be an edge */
         else
+        {
             return false;
+        }
     }
     return (has_id && has_label && has_properties &&
             has_start_id && has_end_id);
@@ -2917,8 +2949,25 @@ static agtype_value *execute_array_access_operator_internal(agtype *array,
                                                             int64 array_index)
 {
     agtype_value *array_element_value = NULL;
-    uint32 size = (array_value == NULL) ? AGT_ROOT_COUNT(array) :
-                                          array_value->val.array.num_elems;
+    uint32 size = 0;
+
+    /* get the size of the array, given the type of the input */
+    if (array_value == NULL)
+    {
+        size = AGT_ROOT_COUNT(array);
+    }
+    else if (array_value->type == AGTV_ARRAY)
+    {
+        size = array_value->val.array.num_elems;
+    }
+    else if (array_value->type == AGTV_BINARY)
+    {
+        size = AGTYPE_CONTAINER_SIZE(array_value->val.binary.data);
+    }
+    else
+    {
+        elog(ERROR, "execute_array_access_operator_internal: unexpected type");
+    }
 
     /* adjust for negative index values */
     if (array_index < 0)
@@ -3424,32 +3473,45 @@ Datum agtype_access_slice(PG_FUNCTION_ARGS)
     agtype_value *lidx_value = NULL;
     agtype_value *uidx_value = NULL;
     agtype_in_state result;
-    agtype *array;
+    agtype *array = NULL;
     int64 upper_index = 0;
     int64 lower_index = 0;
-    uint32 array_size;
-    int64 i;
+    uint32 array_size = 0;
+    int64 i = 0;
 
     /* return null if the array to slice is null */
     if (PG_ARGISNULL(0))
+    {
         PG_RETURN_NULL();
+    }
+
     /* return an error if both indices are NULL */
     if (PG_ARGISNULL(1) && PG_ARGISNULL(2))
+    {
         ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                         errmsg("slice start and/or end is required")));
+    }
+
     /* get the array parameter and verify that it is a list */
     array = AG_GET_ARG_AGTYPE_P(0);
     if (!AGT_ROOT_IS_ARRAY(array) || AGT_ROOT_IS_SCALAR(array))
+    {
         ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                         errmsg("slice must access a list")));
+    }
+
+    /* get its size */
     array_size = AGT_ROOT_COUNT(array);
+
     /* if we don't have a lower bound, make it 0 */
     if (PG_ARGISNULL(1))
+    {
         lower_index = 0;
+    }
     else
     {
         lidx_value = get_ith_agtype_value_from_container(
-            &AG_GET_ARG_AGTYPE_P(1)->root, 0);
+            &(AG_GET_ARG_AGTYPE_P(1))->root, 0);
         /* adjust for AGTV_NULL */
         if (lidx_value->type == AGTV_NULL)
         {
@@ -3457,13 +3519,16 @@ Datum agtype_access_slice(PG_FUNCTION_ARGS)
             lidx_value = NULL;
         }
     }
+
     /* if we don't have an upper bound, make it the size of the array */
     if (PG_ARGISNULL(2))
+    {
         upper_index = array_size;
+    }
     else
     {
         uidx_value = get_ith_agtype_value_from_container(
-            &AG_GET_ARG_AGTYPE_P(2)->root, 0);
+            &(AG_GET_ARG_AGTYPE_P(2))->root, 0);
         /* adjust for AGTV_NULL */
         if (uidx_value->type == AGTV_NULL)
         {
@@ -3471,34 +3536,59 @@ Datum agtype_access_slice(PG_FUNCTION_ARGS)
             uidx_value = NULL;
         }
     }
+
     /* if both indices are NULL (AGTV_NULL) return an error */
     if (lidx_value == NULL && uidx_value == NULL)
+    {
         ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                         errmsg("slice start and/or end is required")));
+    }
+
     /* key must be an integer or NULL */
     if ((lidx_value != NULL && lidx_value->type != AGTV_INTEGER) ||
         (uidx_value != NULL && uidx_value->type != AGTV_INTEGER))
+    {
         ereport(ERROR,
                 (errmsg("array slices must resolve to an integer value")));
+    }
+
     /* set indices if not already set */
     if (lidx_value)
+    {
         lower_index = lidx_value->val.int_value;
+    }
     if (uidx_value)
+    {
         upper_index = uidx_value->val.int_value;
+    }
+
     /* adjust for negative and out of bounds index values */
     if (lower_index < 0)
+    {
         lower_index = array_size + lower_index;
+    }
     if (lower_index < 0)
+    {
         lower_index = 0;
+    }
     if (lower_index > array_size)
+    {
         lower_index = array_size;
+    }
     if (upper_index < 0)
+    {
         upper_index = array_size + upper_index;
+    }
     if (upper_index < 0)
+    {
         upper_index = 0;
+    }
     if (upper_index > array_size)
+    {
         upper_index = array_size;
+    }
 
+    /* build our result array */
     memset(&result, 0, sizeof(agtype_in_state));
 
     result.res = push_agtype_value(&result.parse_state, WAGT_BEGIN_ARRAY,
@@ -3506,9 +3596,10 @@ Datum agtype_access_slice(PG_FUNCTION_ARGS)
 
     /* get array elements */
     for (i = lower_index; i < upper_index; i++)
-        result.res = push_agtype_value(
-            &result.parse_state, WAGT_ELEM,
+    {
+        result.res = push_agtype_value(&result.parse_state, WAGT_ELEM,
             get_ith_agtype_value_from_container(&array->root, i));
+    }
 
     result.res = push_agtype_value(&result.parse_state, WAGT_END_ARRAY, NULL);
 
@@ -6743,7 +6834,9 @@ Datum age_split(PG_FUNCTION_ARGS)
         agtv_result = result.res;
     }
     else
+    {
         elog(ERROR, "split() unexpected error");
+    }
 
     PG_RETURN_POINTER(agtype_value_to_agtype(agtv_result));
 }