1919#include "regex/regex.h"
2020#include "utils/builtins.h"
2121#include "utils/datum.h"
22+ #include "utils/float.h"
2223#include "utils/formatting.h"
2324#include "utils/json.h"
2425#include "utils/jsonpath.h"
@@ -918,7 +919,6 @@ static JsonPathExecResult
918919executeBinaryArithmExpr (JsonPathExecContext * cxt , JsonPathItem * jsp ,
919920 JsonbValue * jb , JsonValueList * found )
920921{
921- MemoryContext mcxt = CurrentMemoryContext ;
922922 JsonPathExecResult jper ;
923923 JsonPathItem elem ;
924924 JsonValueList lseq = { 0 };
@@ -927,11 +927,10 @@ executeBinaryArithmExpr(JsonPathExecContext *cxt, JsonPathItem *jsp,
927927 JsonbValue * rval ;
928928 JsonbValue lvalbuf ;
929929 JsonbValue rvalbuf ;
930- PGFunction func ;
931- Datum ldatum ;
932- Datum rdatum ;
933- Datum res ;
930+ Numeric (* func )(Numeric , Numeric , ErrorData * * );
931+ Numeric res ;
934932 bool hasNext ;
933+ ErrorData * edata ;
935934
936935 jspGetLeftArg (jsp , & elem );
937936
@@ -970,55 +969,38 @@ executeBinaryArithmExpr(JsonPathExecContext *cxt, JsonPathItem *jsp,
970969 if (!found && !hasNext )
971970 return jperOk ;
972971
973- ldatum = NumericGetDatum (lval -> val .numeric );
974- rdatum = NumericGetDatum (rval -> val .numeric );
975-
976972 switch (jsp -> type )
977973 {
978974 case jpiAdd :
979- func = numeric_add ;
975+ func = numeric_add_internal ;
980976 break ;
981977 case jpiSub :
982- func = numeric_sub ;
978+ func = numeric_sub_internal ;
983979 break ;
984980 case jpiMul :
985- func = numeric_mul ;
981+ func = numeric_mul_internal ;
986982 break ;
987983 case jpiDiv :
988- func = numeric_div ;
984+ func = numeric_div_internal ;
989985 break ;
990986 case jpiMod :
991- func = numeric_mod ;
987+ func = numeric_mod_internal ;
992988 break ;
993989 default :
994990 elog (ERROR , "unknown jsonpath arithmetic operation %d" , jsp -> type );
995991 func = NULL ;
996992 break ;
997993 }
998994
999- PG_TRY ();
1000- {
1001- res = DirectFunctionCall2 (func , ldatum , rdatum );
1002- }
1003- PG_CATCH ();
1004- {
1005- int errcode = geterrcode ();
1006- ErrorData * edata ;
1007-
1008- if (ERRCODE_TO_CATEGORY (errcode ) != ERRCODE_DATA_EXCEPTION )
1009- PG_RE_THROW ();
1010-
1011- MemoryContextSwitchTo (mcxt );
1012- edata = CopyErrorData ();
1013- FlushErrorState ();
995+ edata = NULL ;
996+ res = func (lval -> val .numeric , rval -> val .numeric , & edata );
1014997
998+ if (edata )
1015999 return jperMakeErrorData (edata );
1016- }
1017- PG_END_TRY ();
10181000
10191001 lval = palloc (sizeof (* lval ));
10201002 lval -> type = jbvNumeric ;
1021- lval -> val .numeric = DatumGetNumeric ( res ) ;
1003+ lval -> val .numeric = res ;
10221004
10231005 return recursiveExecuteNext (cxt , jsp , & elem , lval , found , false);
10241006}
@@ -2032,53 +2014,53 @@ recursiveExecuteNoUnwrap(JsonPathExecContext *cxt, JsonPathItem *jsp,
20322014 case jpiDouble :
20332015 {
20342016 JsonbValue jbv ;
2035- MemoryContext mcxt = CurrentMemoryContext ;
2017+ ErrorData * edata = NULL ;
20362018
20372019 if (JsonbType (jb ) == jbvScalar )
20382020 jb = JsonbExtractScalar (jb -> val .binary .data , & jbv );
20392021
2040- PG_TRY ();
2022+ if ( jb -> type == jbvNumeric )
20412023 {
2042- if (jb -> type == jbvNumeric )
2043- {
2044- /* only check success of numeric to double cast */
2045- DirectFunctionCall1 (numeric_float8 ,
2046- NumericGetDatum (jb -> val .numeric ));
2047- res = jperOk ;
2048- }
2049- else if (jb -> type == jbvString )
2050- {
2051- /* cast string as double */
2052- char * str = pnstrdup (jb -> val .string .val ,
2053- jb -> val .string .len );
2054- Datum val = DirectFunctionCall1 (
2055- float8in , CStringGetDatum (str ));
2056- pfree (str );
2024+ /* only check success of numeric to double cast */
2025+ (void ) numeric_float8_internal (jb -> val .numeric , & edata );
2026+ }
2027+ else if (jb -> type == jbvString )
2028+ {
2029+ /* cast string as double */
2030+ char * str = pnstrdup (jb -> val .string .val ,
2031+ jb -> val .string .len );
2032+ double val ;
20572033
2034+ val = float8in_internal_safe (str , NULL , "double precision" ,
2035+ str , & edata );
2036+ pfree (str );
2037+
2038+ if (!edata )
2039+ {
20582040 jb = & jbv ;
20592041 jb -> type = jbvNumeric ;
2060- jb -> val .numeric = DatumGetNumeric (DirectFunctionCall1 (
2061- float8_numeric , val ));
2062- res = jperOk ;
2063-
2042+ jb -> val .numeric = float8_numeric_internal (val , & edata );
20642043 }
2065- else
2066- res = jperMakeError (ERRCODE_NON_NUMERIC_JSON_ITEM );
20672044 }
2068- PG_CATCH ();
2045+ else
2046+ {
2047+ res = jperMakeError (ERRCODE_NON_NUMERIC_JSON_ITEM );
2048+ break ;
2049+ }
2050+
2051+ if (edata )
20692052 {
2070- if (ERRCODE_TO_CATEGORY (geterrcode () ) !=
2071- ERRCODE_DATA_EXCEPTION )
2072- PG_RE_THROW ( );
2053+ if (ERRCODE_TO_CATEGORY (edata -> sqlerrcode ) !=
2054+ ERRCODE_DATA_EXCEPTION )
2055+ ThrowErrorData ( edata );
20732056
2074- FlushErrorState ();
2075- MemoryContextSwitchTo (mcxt );
2057+ FreeErrorData (edata );
20762058 res = jperMakeError (ERRCODE_NON_NUMERIC_JSON_ITEM );
20772059 }
2078- PG_END_TRY ();
2079-
2080- if (res == jperOk )
2060+ else
2061+ {
20812062 res = recursiveExecuteNext (cxt , jsp , NULL , jb , found , true);
2063+ }
20822064 }
20832065 break ;
20842066 case jpiDatetime :
0 commit comments