Revert "Reorganise jsonpath operators and methods"
authorPeter Eisentraut <peter@eisentraut.org>
Wed, 3 Jan 2024 20:02:49 +0000 (21:02 +0100)
committerPeter Eisentraut <peter@eisentraut.org>
Wed, 3 Jan 2024 20:02:49 +0000 (21:02 +0100)
This reverts commit 283a95da923605c1cc148155db2d865d0801b419.

The reordering of JsonPathItemType affects the binary on-disk
compatibility of the jsonpath type, so we must not change it.  Revert
for now and consider.

doc/src/sgml/func.sgml
src/backend/utils/adt/jsonpath.c
src/backend/utils/adt/jsonpath_exec.c
src/backend/utils/adt/jsonpath_gram.y
src/include/utils/jsonpath.h

index 8f2a2315d8e768005d06225a407bb27d39e0c843..cec21e42c05b139d36e220f1ed2bb883c7c99cb8 100644 (file)
@@ -17691,43 +17691,43 @@ strict $.**.HR
 
       <row>
        <entry role="func_table_entry"><para role="func_signature">
-        <replaceable>number</replaceable> <literal>.</literal> <literal>abs()</literal>
+        <replaceable>number</replaceable> <literal>.</literal> <literal>ceiling()</literal>
         <returnvalue><replaceable>number</replaceable></returnvalue>
        </para>
        <para>
-        Absolute value of the given number
+        Nearest integer greater than or equal to the given number
        </para>
        <para>
-        <literal>jsonb_path_query('{"z": -0.3}', '$.z.abs()')</literal>
-        <returnvalue>0.3</returnvalue>
+        <literal>jsonb_path_query('{"h": 1.3}', '$.h.ceiling()')</literal>
+        <returnvalue>2</returnvalue>
        </para></entry>
       </row>
 
       <row>
        <entry role="func_table_entry"><para role="func_signature">
-        <replaceable>number</replaceable> <literal>.</literal> <literal>ceiling()</literal>
+        <replaceable>number</replaceable> <literal>.</literal> <literal>floor()</literal>
         <returnvalue><replaceable>number</replaceable></returnvalue>
        </para>
        <para>
-        Nearest integer greater than or equal to the given number
+        Nearest integer less than or equal to the given number
        </para>
        <para>
-        <literal>jsonb_path_query('{"h": 1.3}', '$.h.ceiling()')</literal>
-        <returnvalue>2</returnvalue>
+        <literal>jsonb_path_query('{"h": 1.7}', '$.h.floor()')</literal>
+        <returnvalue>1</returnvalue>
        </para></entry>
       </row>
 
       <row>
        <entry role="func_table_entry"><para role="func_signature">
-        <replaceable>number</replaceable> <literal>.</literal> <literal>floor()</literal>
+        <replaceable>number</replaceable> <literal>.</literal> <literal>abs()</literal>
         <returnvalue><replaceable>number</replaceable></returnvalue>
        </para>
        <para>
-        Nearest integer less than or equal to the given number
+        Absolute value of the given number
        </para>
        <para>
-        <literal>jsonb_path_query('{"h": 1.7}', '$.h.floor()')</literal>
-        <returnvalue>1</returnvalue>
+        <literal>jsonb_path_query('{"z": -0.3}', '$.z.abs()')</literal>
+        <returnvalue>0.3</returnvalue>
        </para></entry>
       </row>
 
index 8ff9b5646fb9c8eca7c3e56ef74f9200a578aed6..c5ba3b7f1d0525da8b681b2232caab8550563c29 100644 (file)
@@ -439,10 +439,10 @@ flattenJsonPathParseItem(StringInfo buf, int *result, struct Node *escontext,
                        break;
                case jpiType:
                case jpiSize:
-               case jpiDouble:
                case jpiAbs:
-               case jpiCeiling:
                case jpiFloor:
+               case jpiCeiling:
+               case jpiDouble:
                case jpiKeyValue:
                        break;
                default:
@@ -610,6 +610,18 @@ printJsonPathItem(StringInfo buf, JsonPathItem *v, bool inKey,
                        if (printBracketes)
                                appendStringInfoChar(buf, ')');
                        break;
+               case jpiPlus:
+               case jpiMinus:
+                       if (printBracketes)
+                               appendStringInfoChar(buf, '(');
+                       appendStringInfoChar(buf, v->type == jpiPlus ? '+' : '-');
+                       jspGetArg(v, &elem);
+                       printJsonPathItem(buf, &elem, false,
+                                                         operationPriority(elem.type) <=
+                                                         operationPriority(v->type));
+                       if (printBracketes)
+                               appendStringInfoChar(buf, ')');
+                       break;
                case jpiFilter:
                        appendStringInfoString(buf, "?(");
                        jspGetArg(v, &elem);
@@ -700,35 +712,23 @@ printJsonPathItem(StringInfo buf, JsonPathItem *v, bool inKey,
                                                                 v->content.anybounds.first,
                                                                 v->content.anybounds.last);
                        break;
-               case jpiPlus:
-               case jpiMinus:
-                       if (printBracketes)
-                               appendStringInfoChar(buf, '(');
-                       appendStringInfoChar(buf, v->type == jpiPlus ? '+' : '-');
-                       jspGetArg(v, &elem);
-                       printJsonPathItem(buf, &elem, false,
-                                                         operationPriority(elem.type) <=
-                                                         operationPriority(v->type));
-                       if (printBracketes)
-                               appendStringInfoChar(buf, ')');
-                       break;
                case jpiType:
                        appendStringInfoString(buf, ".type()");
                        break;
                case jpiSize:
                        appendStringInfoString(buf, ".size()");
                        break;
-               case jpiDouble:
-                       appendStringInfoString(buf, ".double()");
-                       break;
                case jpiAbs:
                        appendStringInfoString(buf, ".abs()");
                        break;
+               case jpiFloor:
+                       appendStringInfoString(buf, ".floor()");
+                       break;
                case jpiCeiling:
                        appendStringInfoString(buf, ".ceiling()");
                        break;
-               case jpiFloor:
-                       appendStringInfoString(buf, ".floor()");
+               case jpiDouble:
+                       appendStringInfoString(buf, ".double()");
                        break;
                case jpiDatetime:
                        appendStringInfoString(buf, ".datetime(");
@@ -771,11 +771,11 @@ jspOperationName(JsonPathItemType type)
                        return "<=";
                case jpiGreaterOrEqual:
                        return ">=";
-               case jpiAdd:
                case jpiPlus:
+               case jpiAdd:
                        return "+";
-               case jpiSub:
                case jpiMinus:
+               case jpiSub:
                        return "-";
                case jpiMul:
                        return "*";
@@ -783,26 +783,26 @@ jspOperationName(JsonPathItemType type)
                        return "/";
                case jpiMod:
                        return "%";
+               case jpiStartsWith:
+                       return "starts with";
+               case jpiLikeRegex:
+                       return "like_regex";
                case jpiType:
                        return "type";
                case jpiSize:
                        return "size";
+               case jpiKeyValue:
+                       return "keyvalue";
                case jpiDouble:
                        return "double";
                case jpiAbs:
                        return "abs";
-               case jpiCeiling:
-                       return "ceiling";
                case jpiFloor:
                        return "floor";
+               case jpiCeiling:
+                       return "ceiling";
                case jpiDatetime:
                        return "datetime";
-               case jpiKeyValue:
-                       return "keyvalue";
-               case jpiStartsWith:
-                       return "starts with";
-               case jpiLikeRegex:
-                       return "like_regex";
                default:
                        elog(ERROR, "unrecognized jsonpath item type: %d", type);
                        return NULL;
@@ -893,10 +893,10 @@ jspInitByBuffer(JsonPathItem *v, char *base, int32 pos)
                case jpiAnyKey:
                case jpiType:
                case jpiSize:
-               case jpiDouble:
                case jpiAbs:
-               case jpiCeiling:
                case jpiFloor:
+               case jpiCeiling:
+               case jpiDouble:
                case jpiKeyValue:
                case jpiLast:
                        break;
@@ -935,9 +935,9 @@ jspInitByBuffer(JsonPathItem *v, char *base, int32 pos)
                case jpiNot:
                case jpiExists:
                case jpiIsUnknown:
-               case jpiFilter:
                case jpiPlus:
                case jpiMinus:
+               case jpiFilter:
                case jpiDatetime:
                        read_int32(v->content.arg, base, pos);
                        break;
@@ -989,6 +989,13 @@ jspGetNext(JsonPathItem *v, JsonPathItem *a)
                           v->type == jpiRoot ||
                           v->type == jpiVariable ||
                           v->type == jpiLast ||
+                          v->type == jpiAdd ||
+                          v->type == jpiSub ||
+                          v->type == jpiMul ||
+                          v->type == jpiDiv ||
+                          v->type == jpiMod ||
+                          v->type == jpiPlus ||
+                          v->type == jpiMinus ||
                           v->type == jpiEqual ||
                           v->type == jpiNotEqual ||
                           v->type == jpiGreater ||
@@ -999,19 +1006,12 @@ jspGetNext(JsonPathItem *v, JsonPathItem *a)
                           v->type == jpiOr ||
                           v->type == jpiNot ||
                           v->type == jpiIsUnknown ||
-                          v->type == jpiAdd ||
-                          v->type == jpiPlus ||
-                          v->type == jpiSub ||
-                          v->type == jpiMinus ||
-                          v->type == jpiMul ||
-                          v->type == jpiDiv ||
-                          v->type == jpiMod ||
                           v->type == jpiType ||
                           v->type == jpiSize ||
-                          v->type == jpiDouble ||
                           v->type == jpiAbs ||
-                          v->type == jpiCeiling ||
                           v->type == jpiFloor ||
+                          v->type == jpiCeiling ||
+                          v->type == jpiDouble ||
                           v->type == jpiDatetime ||
                           v->type == jpiKeyValue ||
                           v->type == jpiStartsWith ||
index 86b5b76d4eedad7ca304974d514dcdb4b2bf14d2..9a09604f6423004900e49ea16376b6d5161dba10 100644 (file)
@@ -874,6 +874,33 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
                        }
                        break;
 
+               case jpiAdd:
+                       return executeBinaryArithmExpr(cxt, jsp, jb,
+                                                                                  numeric_add_opt_error, found);
+
+               case jpiSub:
+                       return executeBinaryArithmExpr(cxt, jsp, jb,
+                                                                                  numeric_sub_opt_error, found);
+
+               case jpiMul:
+                       return executeBinaryArithmExpr(cxt, jsp, jb,
+                                                                                  numeric_mul_opt_error, found);
+
+               case jpiDiv:
+                       return executeBinaryArithmExpr(cxt, jsp, jb,
+                                                                                  numeric_div_opt_error, found);
+
+               case jpiMod:
+                       return executeBinaryArithmExpr(cxt, jsp, jb,
+                                                                                  numeric_mod_opt_error, found);
+
+               case jpiPlus:
+                       return executeUnaryArithmExpr(cxt, jsp, jb, NULL, found);
+
+               case jpiMinus:
+                       return executeUnaryArithmExpr(cxt, jsp, jb, numeric_uminus,
+                                                                                 found);
+
                case jpiFilter:
                        {
                                JsonPathBool st;
@@ -953,33 +980,6 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
                        }
                        break;
 
-               case jpiAdd:
-                       return executeBinaryArithmExpr(cxt, jsp, jb,
-                                                                                  numeric_add_opt_error, found);
-
-               case jpiPlus:
-                       return executeUnaryArithmExpr(cxt, jsp, jb, NULL, found);
-
-               case jpiSub:
-                       return executeBinaryArithmExpr(cxt, jsp, jb,
-                                                                                  numeric_sub_opt_error, found);
-
-               case jpiMinus:
-                       return executeUnaryArithmExpr(cxt, jsp, jb, numeric_uminus,
-                                                                                 found);
-
-               case jpiMul:
-                       return executeBinaryArithmExpr(cxt, jsp, jb,
-                                                                                  numeric_mul_opt_error, found);
-
-               case jpiDiv:
-                       return executeBinaryArithmExpr(cxt, jsp, jb,
-                                                                                  numeric_div_opt_error, found);
-
-               case jpiMod:
-                       return executeBinaryArithmExpr(cxt, jsp, jb,
-                                                                                  numeric_mod_opt_error, found);
-
                case jpiType:
                        {
                                JsonbValue *jbv = palloc(sizeof(*jbv));
@@ -1021,6 +1021,18 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
                        }
                        break;
 
+               case jpiAbs:
+                       return executeNumericItemMethod(cxt, jsp, jb, unwrap, numeric_abs,
+                                                                                       found);
+
+               case jpiFloor:
+                       return executeNumericItemMethod(cxt, jsp, jb, unwrap, numeric_floor,
+                                                                                       found);
+
+               case jpiCeiling:
+                       return executeNumericItemMethod(cxt, jsp, jb, unwrap, numeric_ceil,
+                                                                                       found);
+
                case jpiDouble:
                        {
                                JsonbValue      jbv;
@@ -1086,18 +1098,6 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
                        }
                        break;
 
-               case jpiAbs:
-                       return executeNumericItemMethod(cxt, jsp, jb, unwrap, numeric_abs,
-                                                                                       found);
-
-               case jpiCeiling:
-                       return executeNumericItemMethod(cxt, jsp, jb, unwrap, numeric_ceil,
-                                                                                       found);
-
-               case jpiFloor:
-                       return executeNumericItemMethod(cxt, jsp, jb, unwrap, numeric_floor,
-                                                                                       found);
-
                case jpiDatetime:
                        if (unwrap && JsonbType(jb) == jbvArray)
                                return executeItemUnwrapTargetArray(cxt, jsp, jb, found, false);
index 4233eedc1b410c73b627f10e0d912717f742bf3a..adc259d5bf88c9b41028d9b82136e69ba10b72dd 100644 (file)
@@ -80,7 +80,7 @@ static bool makeItemLikeRegex(JsonPathParseItem *expr,
 %token <str>           OR_P AND_P NOT_P
 %token <str>           LESS_P LESSEQUAL_P EQUAL_P NOTEQUAL_P GREATEREQUAL_P GREATER_P
 %token <str>           ANY_P STRICT_P LAX_P LAST_P STARTS_P WITH_P LIKE_REGEX_P FLAG_P
-%token <str>           TYPE_P SIZE_P DOUBLE_P ABS_P CEILING_P FLOOR_P KEYVALUE_P
+%token <str>           ABS_P SIZE_P TYPE_P FLOOR_P DOUBLE_P CEILING_P KEYVALUE_P
 %token <str>           DATETIME_P
 
 %type  <result>        result
@@ -206,10 +206,10 @@ accessor_expr:
 expr:
        accessor_expr                                   { $$ = makeItemList($1); }
        | '(' expr ')'                                  { $$ = $2; }
-       | expr '+' expr                                 { $$ = makeItemBinary(jpiAdd, $1, $3); }
        | '+' expr %prec UMINUS                 { $$ = makeItemUnary(jpiPlus, $2); }
-       | expr '-' expr                                 { $$ = makeItemBinary(jpiSub, $1, $3); }
        | '-' expr %prec UMINUS                 { $$ = makeItemUnary(jpiMinus, $2); }
+       | expr '+' expr                                 { $$ = makeItemBinary(jpiAdd, $1, $3); }
+       | expr '-' expr                                 { $$ = makeItemBinary(jpiSub, $1, $3); }
        | expr '*' expr                                 { $$ = makeItemBinary(jpiMul, $1, $3); }
        | expr '/' expr                                 { $$ = makeItemBinary(jpiDiv, $1, $3); }
        | expr '%' expr                                 { $$ = makeItemBinary(jpiMod, $1, $3); }
@@ -278,28 +278,28 @@ key_name:
        | EXISTS_P
        | STRICT_P
        | LAX_P
-       | LAST_P
-       | FLAG_P
-       | TYPE_P
+       | ABS_P
        | SIZE_P
+       | TYPE_P
+       | FLOOR_P
        | DOUBLE_P
-       | ABS_P
        | CEILING_P
-       | FLOOR_P
        | DATETIME_P
        | KEYVALUE_P
+       | LAST_P
        | STARTS_P
        | WITH_P
        | LIKE_REGEX_P
+       | FLAG_P
        ;
 
 method:
-       TYPE_P                                                  { $$ = jpiType; }
+       ABS_P                                                   { $$ = jpiAbs; }
        | SIZE_P                                                { $$ = jpiSize; }
+       | TYPE_P                                                { $$ = jpiType; }
+       | FLOOR_P                                               { $$ = jpiFloor; }
        | DOUBLE_P                                              { $$ = jpiDouble; }
-       | ABS_P                                                 { $$ = jpiAbs; }
        | CEILING_P                                             { $$ = jpiCeiling; }
-       | FLOOR_P                                               { $$ = jpiFloor; }
        | KEYVALUE_P                                    { $$ = jpiKeyValue; }
        ;
 %%
index 59dc233a08dbf290d3415a3d0ae98f31d72caa62..f0181e045f795207f866b5b10069bbca207a3756 100644 (file)
@@ -66,6 +66,13 @@ typedef enum JsonPathItemType
        jpiGreater,                                     /* expr > expr */
        jpiLessOrEqual,                         /* expr <= expr */
        jpiGreaterOrEqual,                      /* expr >= expr */
+       jpiAdd,                                         /* expr + expr */
+       jpiSub,                                         /* expr - expr */
+       jpiMul,                                         /* expr * expr */
+       jpiDiv,                                         /* expr / expr */
+       jpiMod,                                         /* expr % expr */
+       jpiPlus,                                        /* + expr */
+       jpiMinus,                                       /* - expr */
        jpiAnyArray,                            /* [*] */
        jpiAnyKey,                                      /* .* */
        jpiIndexArray,                          /* [subscript, ...] */
@@ -76,28 +83,14 @@ typedef enum JsonPathItemType
        jpiVariable,                            /* $variable */
        jpiFilter,                                      /* ? (predicate) */
        jpiExists,                                      /* EXISTS (expr) predicate */
-
-       /*
-        * For better maintainability or readability, keep the order of the below
-        * jsonpath Operators and Methods at the other places, like in the
-        * documentation, switch() cases, keywords list, etc., too.
-        */
-       jpiAdd,                                         /* expr + expr */
-       jpiPlus,                                        /* + expr */
-       jpiSub,                                         /* expr - expr */
-       jpiMinus,                                       /* - expr */
-       jpiMul,                                         /* expr * expr */
-       jpiDiv,                                         /* expr / expr */
-       jpiMod,                                         /* expr % expr */
        jpiType,                                        /* .type() item method */
        jpiSize,                                        /* .size() item method */
-       jpiDouble,                                      /* .double() item method */
        jpiAbs,                                         /* .abs() item method */
-       jpiCeiling,                                     /* .ceiling() item method */
        jpiFloor,                                       /* .floor() item method */
+       jpiCeiling,                                     /* .ceiling() item method */
+       jpiDouble,                                      /* .double() item method */
        jpiDatetime,                            /* .datetime() item method */
        jpiKeyValue,                            /* .keyvalue() item method */
-
        jpiSubscript,                           /* array subscript: 'expr' or 'expr TO expr' */
        jpiLast,                                        /* LAST array subscript */
        jpiStartsWith,                          /* STARTS WITH predicate */