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 */