summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Eisentraut2024-01-03 10:25:33 +0000
committerPeter Eisentraut2024-01-03 10:25:33 +0000
commit283a95da923605c1cc148155db2d865d0801b419 (patch)
treeba18d24db7e71cab5ab8f6ce0224760e77a42fce
parentc1b9e1e56d8c11a00869766a02de537d349586cd (diff)
Reorganise jsonpath operators and methods
Various jsonpath operators and methods add various keywords, switch cases, and documentation entries in some order. However, they are not consistent; reorder them for better maintainability or readability. Author: Jeevan Chalke <[email protected]> Discussion: https://www.postgresql.org/message-id/flat/CAM2+6=XjTyqrrqHAOj80r0wVQxJSxc0iyib9bPC55uFO9VKatg@mail.gmail.com
-rw-r--r--doc/src/sgml/func.sgml24
-rw-r--r--src/backend/utils/adt/jsonpath.c82
-rw-r--r--src/backend/utils/adt/jsonpath_exec.c78
-rw-r--r--src/backend/utils/adt/jsonpath_gram.y22
-rw-r--r--src/include/utils/jsonpath.h25
5 files changed, 119 insertions, 112 deletions
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index cec21e42c05..8f2a2315d8e 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -17691,43 +17691,43 @@ strict $.**.HR
<row>
<entry role="func_table_entry"><para role="func_signature">
- <replaceable>number</replaceable> <literal>.</literal> <literal>ceiling()</literal>
+ <replaceable>number</replaceable> <literal>.</literal> <literal>abs()</literal>
<returnvalue><replaceable>number</replaceable></returnvalue>
</para>
<para>
- Nearest integer greater than or equal to the given number
+ Absolute value of the given number
</para>
<para>
- <literal>jsonb_path_query('{"h": 1.3}', '$.h.ceiling()')</literal>
- <returnvalue>2</returnvalue>
+ <literal>jsonb_path_query('{"z": -0.3}', '$.z.abs()')</literal>
+ <returnvalue>0.3</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>ceiling()</literal>
<returnvalue><replaceable>number</replaceable></returnvalue>
</para>
<para>
- Nearest integer less than or equal to the given number
+ Nearest integer greater than or equal to the given number
</para>
<para>
- <literal>jsonb_path_query('{"h": 1.7}', '$.h.floor()')</literal>
- <returnvalue>1</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>abs()</literal>
+ <replaceable>number</replaceable> <literal>.</literal> <literal>floor()</literal>
<returnvalue><replaceable>number</replaceable></returnvalue>
</para>
<para>
- Absolute value of the given number
+ Nearest integer less 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.7}', '$.h.floor()')</literal>
+ <returnvalue>1</returnvalue>
</para></entry>
</row>
diff --git a/src/backend/utils/adt/jsonpath.c b/src/backend/utils/adt/jsonpath.c
index c5ba3b7f1d0..8ff9b5646fb 100644
--- a/src/backend/utils/adt/jsonpath.c
+++ b/src/backend/utils/adt/jsonpath.c
@@ -439,10 +439,10 @@ flattenJsonPathParseItem(StringInfo buf, int *result, struct Node *escontext,
break;
case jpiType:
case jpiSize:
+ case jpiDouble:
case jpiAbs:
- case jpiFloor:
case jpiCeiling:
- case jpiDouble:
+ case jpiFloor:
case jpiKeyValue:
break;
default:
@@ -610,18 +610,6 @@ 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);
@@ -712,23 +700,35 @@ 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 jpiDouble:
- appendStringInfoString(buf, ".double()");
+ case jpiFloor:
+ appendStringInfoString(buf, ".floor()");
break;
case jpiDatetime:
appendStringInfoString(buf, ".datetime(");
@@ -771,11 +771,11 @@ jspOperationName(JsonPathItemType type)
return "<=";
case jpiGreaterOrEqual:
return ">=";
- case jpiPlus:
case jpiAdd:
+ case jpiPlus:
return "+";
- case jpiMinus:
case jpiSub:
+ case jpiMinus:
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 jpiFloor:
- return "floor";
case jpiCeiling:
return "ceiling";
+ case jpiFloor:
+ return "floor";
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 jpiFloor:
case jpiCeiling:
- case jpiDouble:
+ case jpiFloor:
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,13 +989,6 @@ 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 ||
@@ -1006,12 +999,19 @@ 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 == jpiFloor ||
v->type == jpiCeiling ||
- v->type == jpiDouble ||
+ v->type == jpiFloor ||
v->type == jpiDatetime ||
v->type == jpiKeyValue ||
v->type == jpiStartsWith ||
diff --git a/src/backend/utils/adt/jsonpath_exec.c b/src/backend/utils/adt/jsonpath_exec.c
index 9a09604f642..86b5b76d4ee 100644
--- a/src/backend/utils/adt/jsonpath_exec.c
+++ b/src/backend/utils/adt/jsonpath_exec.c
@@ -874,33 +874,6 @@ 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;
@@ -980,6 +953,33 @@ 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,18 +1021,6 @@ 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;
@@ -1098,6 +1086,18 @@ 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);
diff --git a/src/backend/utils/adt/jsonpath_gram.y b/src/backend/utils/adt/jsonpath_gram.y
index adc259d5bf8..4233eedc1b4 100644
--- a/src/backend/utils/adt/jsonpath_gram.y
+++ b/src/backend/utils/adt/jsonpath_gram.y
@@ -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> ABS_P SIZE_P TYPE_P FLOOR_P DOUBLE_P CEILING_P KEYVALUE_P
+%token <str> TYPE_P SIZE_P DOUBLE_P ABS_P CEILING_P FLOOR_P KEYVALUE_P
%token <str> DATETIME_P
%type <result> result
@@ -206,10 +206,10 @@ accessor_expr:
expr:
accessor_expr { $$ = makeItemList($1); }
| '(' expr ')' { $$ = $2; }
- | '+' expr %prec UMINUS { $$ = makeItemUnary(jpiPlus, $2); }
- | '-' expr %prec UMINUS { $$ = makeItemUnary(jpiMinus, $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(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
- | ABS_P
- | SIZE_P
+ | LAST_P
+ | FLAG_P
| TYPE_P
- | FLOOR_P
+ | SIZE_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:
- ABS_P { $$ = jpiAbs; }
+ TYPE_P { $$ = jpiType; }
| SIZE_P { $$ = jpiSize; }
- | TYPE_P { $$ = jpiType; }
- | FLOOR_P { $$ = jpiFloor; }
| DOUBLE_P { $$ = jpiDouble; }
+ | ABS_P { $$ = jpiAbs; }
| CEILING_P { $$ = jpiCeiling; }
+ | FLOOR_P { $$ = jpiFloor; }
| KEYVALUE_P { $$ = jpiKeyValue; }
;
%%
diff --git a/src/include/utils/jsonpath.h b/src/include/utils/jsonpath.h
index f0181e045f7..59dc233a08d 100644
--- a/src/include/utils/jsonpath.h
+++ b/src/include/utils/jsonpath.h
@@ -66,13 +66,6 @@ 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, ...] */
@@ -83,14 +76,28 @@ 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 */
- jpiFloor, /* .floor() item method */
jpiCeiling, /* .ceiling() item method */
- jpiDouble, /* .double() item method */
+ jpiFloor, /* .floor() 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 */