19
19
#include "regex/regex.h"
20
20
#include "utils/builtins.h"
21
21
#include "utils/datum.h"
22
+ #include "utils/float.h"
22
23
#include "utils/formatting.h"
23
24
#include "utils/json.h"
24
25
#include "utils/jsonpath.h"
@@ -918,7 +919,6 @@ static JsonPathExecResult
918
919
executeBinaryArithmExpr (JsonPathExecContext * cxt , JsonPathItem * jsp ,
919
920
JsonbValue * jb , JsonValueList * found )
920
921
{
921
- MemoryContext mcxt = CurrentMemoryContext ;
922
922
JsonPathExecResult jper ;
923
923
JsonPathItem elem ;
924
924
JsonValueList lseq = { 0 };
@@ -927,11 +927,10 @@ executeBinaryArithmExpr(JsonPathExecContext *cxt, JsonPathItem *jsp,
927
927
JsonbValue * rval ;
928
928
JsonbValue lvalbuf ;
929
929
JsonbValue rvalbuf ;
930
- PGFunction func ;
931
- Datum ldatum ;
932
- Datum rdatum ;
933
- Datum res ;
930
+ Numeric (* func )(Numeric , Numeric , ErrorData * * );
931
+ Numeric res ;
934
932
bool hasNext ;
933
+ ErrorData * edata ;
935
934
936
935
jspGetLeftArg (jsp , & elem );
937
936
@@ -970,55 +969,38 @@ executeBinaryArithmExpr(JsonPathExecContext *cxt, JsonPathItem *jsp,
970
969
if (!found && !hasNext )
971
970
return jperOk ;
972
971
973
- ldatum = NumericGetDatum (lval -> val .numeric );
974
- rdatum = NumericGetDatum (rval -> val .numeric );
975
-
976
972
switch (jsp -> type )
977
973
{
978
974
case jpiAdd :
979
- func = numeric_add ;
975
+ func = numeric_add_internal ;
980
976
break ;
981
977
case jpiSub :
982
- func = numeric_sub ;
978
+ func = numeric_sub_internal ;
983
979
break ;
984
980
case jpiMul :
985
- func = numeric_mul ;
981
+ func = numeric_mul_internal ;
986
982
break ;
987
983
case jpiDiv :
988
- func = numeric_div ;
984
+ func = numeric_div_internal ;
989
985
break ;
990
986
case jpiMod :
991
- func = numeric_mod ;
987
+ func = numeric_mod_internal ;
992
988
break ;
993
989
default :
994
990
elog (ERROR , "unknown jsonpath arithmetic operation %d" , jsp -> type );
995
991
func = NULL ;
996
992
break ;
997
993
}
998
994
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 );
1014
997
998
+ if (edata )
1015
999
return jperMakeErrorData (edata );
1016
- }
1017
- PG_END_TRY ();
1018
1000
1019
1001
lval = palloc (sizeof (* lval ));
1020
1002
lval -> type = jbvNumeric ;
1021
- lval -> val .numeric = DatumGetNumeric ( res ) ;
1003
+ lval -> val .numeric = res ;
1022
1004
1023
1005
return recursiveExecuteNext (cxt , jsp , & elem , lval , found , false);
1024
1006
}
@@ -2033,53 +2015,53 @@ recursiveExecuteNoUnwrap(JsonPathExecContext *cxt, JsonPathItem *jsp,
2033
2015
case jpiDouble :
2034
2016
{
2035
2017
JsonbValue jbv ;
2036
- MemoryContext mcxt = CurrentMemoryContext ;
2018
+ ErrorData * edata = NULL ;
2037
2019
2038
2020
if (JsonbType (jb ) == jbvScalar )
2039
2021
jb = JsonbExtractScalar (jb -> val .binary .data , & jbv );
2040
2022
2041
- PG_TRY ();
2023
+ if ( jb -> type == jbvNumeric )
2042
2024
{
2043
- if (jb -> type == jbvNumeric )
2044
- {
2045
- /* only check success of numeric to double cast */
2046
- DirectFunctionCall1 (numeric_float8 ,
2047
- NumericGetDatum (jb -> val .numeric ));
2048
- res = jperOk ;
2049
- }
2050
- else if (jb -> type == jbvString )
2051
- {
2052
- /* cast string as double */
2053
- char * str = pnstrdup (jb -> val .string .val ,
2054
- jb -> val .string .len );
2055
- Datum val = DirectFunctionCall1 (
2056
- float8in , CStringGetDatum (str ));
2057
- pfree (str );
2025
+ /* only check success of numeric to double cast */
2026
+ (void ) numeric_float8_internal (jb -> val .numeric , & edata );
2027
+ }
2028
+ else if (jb -> type == jbvString )
2029
+ {
2030
+ /* cast string as double */
2031
+ char * str = pnstrdup (jb -> val .string .val ,
2032
+ jb -> val .string .len );
2033
+ double val ;
2058
2034
2035
+ val = float8in_internal_safe (str , NULL , "double precision" ,
2036
+ str , & edata );
2037
+ pfree (str );
2038
+
2039
+ if (!edata )
2040
+ {
2059
2041
jb = & jbv ;
2060
2042
jb -> type = jbvNumeric ;
2061
- jb -> val .numeric = DatumGetNumeric (DirectFunctionCall1 (
2062
- float8_numeric , val ));
2063
- res = jperOk ;
2064
-
2043
+ jb -> val .numeric = float8_numeric_internal (val , & edata );
2065
2044
}
2066
- else
2067
- res = jperMakeError (ERRCODE_NON_NUMERIC_JSON_ITEM );
2068
2045
}
2069
- PG_CATCH ();
2046
+ else
2047
+ {
2048
+ res = jperMakeError (ERRCODE_NON_NUMERIC_JSON_ITEM );
2049
+ break ;
2050
+ }
2051
+
2052
+ if (edata )
2070
2053
{
2071
- if (ERRCODE_TO_CATEGORY (geterrcode () ) !=
2072
- ERRCODE_DATA_EXCEPTION )
2073
- PG_RE_THROW ( );
2054
+ if (ERRCODE_TO_CATEGORY (edata -> sqlerrcode ) !=
2055
+ ERRCODE_DATA_EXCEPTION )
2056
+ ThrowErrorData ( edata );
2074
2057
2075
- FlushErrorState ();
2076
- MemoryContextSwitchTo (mcxt );
2058
+ FreeErrorData (edata );
2077
2059
res = jperMakeError (ERRCODE_NON_NUMERIC_JSON_ITEM );
2078
2060
}
2079
- PG_END_TRY ();
2080
-
2081
- if (res == jperOk )
2061
+ else
2062
+ {
2082
2063
res = recursiveExecuteNext (cxt , jsp , NULL , jb , found , true);
2064
+ }
2083
2065
}
2084
2066
break ;
2085
2067
case jpiDatetime :
0 commit comments