test.diff

application/x-patch

Filename: test.diff
Type: application/x-patch
Part: 0
Message: Re: More new SQL/JSON item methods

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: unified
File+
src/backend/utils/adt/jsonpath.c 1 0
src/backend/utils/adt/jsonpath_exec.c 8 4
src/backend/utils/adt/jsonpath_gram.y 12 1
diff --git a/src/backend/utils/adt/jsonpath.c b/src/backend/utils/adt/jsonpath.c
index 42f325bd..460e43cb 100644
--- a/src/backend/utils/adt/jsonpath.c
+++ b/src/backend/utils/adt/jsonpath.c
@@ -1144,6 +1144,7 @@ jspGetLeftArg(JsonPathItem *v, JsonPathItem *a)
 		   v->type == jpiDiv ||
 		   v->type == jpiMod ||
 		   v->type == jpiDecimal ||
+		   v->type == jpiTimestamp ||
 		   v->type == jpiStartsWith);
 
 	jspInitByBuffer(a, v->base, v->content.args.left);
diff --git a/src/backend/utils/adt/jsonpath_exec.c b/src/backend/utils/adt/jsonpath_exec.c
index 94f1052d..4241837f 100644
--- a/src/backend/utils/adt/jsonpath_exec.c
+++ b/src/backend/utils/adt/jsonpath_exec.c
@@ -1096,7 +1096,7 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 		case jpiStringFunc:
 			{
 				JsonbValue	jbv;
-				char	   *tmp;
+				char	   *tmp = NULL;
 
 				switch (JsonbType(jb))
 				{
@@ -1159,6 +1159,7 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 				res = jperOk;
 
 				jb = &jbv;
+				Assert(tmp != NULL);	/* above switch case, covered all the case jbvType */
 				jb->val.string.val = (jb->type == jbvString) ? tmp : pstrdup(tmp);
 				jb->val.string.len = strlen(jb->val.string.val);
 				jb->type = jbvString;
@@ -1400,9 +1401,9 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 					/* cast string as number */
 					Datum		datum;
 					bool		noerr;
-					char	   *numstr = pnstrdup(jb->val.string.val,
-												  jb->val.string.len);
 					ErrorSaveContext escontext = {T_ErrorSaveContext};
+					numstr		= pnstrdup(jb->val.string.val,
+											jb->val.string.len);
 
 					noerr = DirectInputFunctionCallSafe(numeric_in, numstr,
 														InvalidOid, -1,
@@ -1439,7 +1440,6 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 				 */
 				if (jsp->type == jpiDecimal && jsp->content.args.left)
 				{
-					JsonPathItem elem;
 					Datum		numdatum;
 					Datum		dtypmod;
 					int32		precision;
@@ -2443,6 +2443,7 @@ executeDateTimeMethod(JsonPathExecContext *cxt, JsonPathItem *jsp,
 			break;
 		case jpiTimestamp:
 			{
+				Timestamp	tmp;
 				/* Convert result type to timestamp without time zone */
 				switch (typid)
 				{
@@ -2468,6 +2469,9 @@ executeDateTimeMethod(JsonPathExecContext *cxt, JsonPathItem *jsp,
 				}
 
 				typid = TIMESTAMPOID;
+				tmp = DatumGetTimestamp(value);
+				AdjustTimestampForTypmod(&tmp, 2, NULL);
+				value = TimestampGetDatum(tmp);
 			}
 			break;
 		case jpiTimestampTz:
diff --git a/src/backend/utils/adt/jsonpath_gram.y b/src/backend/utils/adt/jsonpath_gram.y
index da031e35..ec188472 100644
--- a/src/backend/utils/adt/jsonpath_gram.y
+++ b/src/backend/utils/adt/jsonpath_gram.y
@@ -264,6 +264,18 @@ accessor_op:
 					 errmsg("invalid input syntax for type %s", "jsonpath"),
 					 errdetail(".decimal() can only have an optional precision[,scale].")));
 	}
+	| '.' TIMESTAMP_P '(' opt_csv_list ')'
+	{
+		if (list_length($4) == 0)
+			$$ = makeItemBinary(jpiTimestamp, NULL, NULL);
+		else if (list_length($4) == 1)
+			$$ = makeItemBinary(jpiTimestamp, linitial($4), NULL);
+		else
+			ereturn(escontext, false,
+					(errcode(ERRCODE_SYNTAX_ERROR),
+					 errmsg("invalid input syntax for type %s", "jsonpath"),
+					 errdetail(".jpiTimestamp() can only have an optional precision.")));
+	}
 	| '.' DATETIME_P '(' opt_datetime_template ')'
 									{ $$ = makeItemUnary(jpiDatetime, $4); }
 	| '?' '(' predicate ')'			{ $$ = makeItemUnary(jpiFilter, $3); }
@@ -355,7 +367,6 @@ method:
 	| DATE_P						{ $$ = jpiDate; }
 	| TIME_P						{ $$ = jpiTime; }
 	| TIME_TZ_P						{ $$ = jpiTimeTz; }
-	| TIMESTAMP_P					{ $$ = jpiTimestamp; }
 	| TIMESTAMP_TZ_P				{ $$ = jpiTimestampTz; }
 	;
 %%