Changeset: 378cd3d91d93 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/378cd3d91d93
Modified Files:
        monetdb5/modules/atoms/json.c
        monetdb5/modules/atoms/pg_jsonpath/jsonpath.c
        monetdb5/modules/atoms/pg_jsonpath/jsonpath.h
        monetdb5/modules/atoms/pg_jsonpath/jsonpath_exec.c
        monetdb5/modules/atoms/pg_jsonpath/jsonpath_scan.l
        monetdb5/modules/atoms/pg_jsonpath/postgres_defines_internal.h
Branch: json-extend
Log Message:

do error handling


diffs (truncated from 594 to 300 lines):

diff --git a/monetdb5/modules/atoms/json.c b/monetdb5/modules/atoms/json.c
--- a/monetdb5/modules/atoms/json.c
+++ b/monetdb5/modules/atoms/json.c
@@ -1653,12 +1653,16 @@ JSONfilter(json *ret, const json *js, co
                return MAL_SUCCEED;
        }
 
-       struct Node* escontext = init_escontext();
+       char errmsg[1024] = {0};
+       struct Node* escontext = init_escontext(errmsg); // TODO: can be a 
implementation detail of lex and parse. Pass on allocator as parameter
        if (!escontext)
                throw(MAL, "json.filter", SQLSTATE(HY013) MAL_MALLOC_FAIL);
 
        JsonPathParseResult* path = parsejsonpath(*expr, strlen(*expr), 
escontext);
-
+       if (errmsg[0]) {
+               return createException(MAL, SQLSTATE(HY013), "JsonPathQuery 
iternal error: %s", errmsg);
+       }
+       assert(path);
 
        yyjson_alc* alc = yyjson_alc_dyn_new(); // TODO initialize this with 
gdk memory functions.
        yyjson_read_err* read_error = NULL;
@@ -1668,14 +1672,16 @@ JSONfilter(json *ret, const json *js, co
        bool error;
        List* vars = NULL;
        const char *column_name = NULL;
-       // TODO pass the result as yyjson document
-       yyjson_val *res = JsonPathQuery((Datum) root, path, JSW_UNCONDITIONAL, 
&empty, &error, vars, column_name, alc);
+       yyjson_val *res = JsonPathQuery((Datum) root, path, JSW_UNCONDITIONAL, 
&empty, &error, vars, column_name, alc, errmsg);
+       if (!res && errmsg[0])
+               return createException(MAL, SQLSTATE(HY013), "JsonPathQuery 
iternal error: %s", errmsg);
+
        if (!res)
-               throw(MAL, "json.unfold", SQLSTATE(HY013) "JsonPathQuery 
error");
+               throw(MAL, "json.filter", SQLSTATE(HY013) "JsonPathQuery 
error");
 
        size_t* len = NULL;
        yyjson_write_err* write_error = NULL;
-       char* tmp_res = yyjson_val_write_opts(res, 0, alc, len, write_error); 
// TODO use different allocation or doc write
+       char* tmp_res = yyjson_val_write_opts(res, 0, alc, len, write_error); 
// TODO use different allocator for result
 
        *ret = GDKstrdup(tmp_res);
        yyjson_alc_dyn_free(alc);
diff --git a/monetdb5/modules/atoms/pg_jsonpath/jsonpath.c 
b/monetdb5/modules/atoms/pg_jsonpath/jsonpath.c
--- a/monetdb5/modules/atoms/pg_jsonpath/jsonpath.c
+++ b/monetdb5/modules/atoms/pg_jsonpath/jsonpath.c
@@ -140,7 +140,7 @@ jspOperationName(JsonPathItemType type)
                case jpiTimestampTz:
                        return "timestamp_tz";
                default:
-                       elog(ERROR, "unrecognized jsonpath item type: %d", 
type);
+                       // elog(ERROR, "unrecognized jsonpath item type: %d", 
type); TODO error handling
                        return NULL;
        }
 }
diff --git a/monetdb5/modules/atoms/pg_jsonpath/jsonpath.h 
b/monetdb5/modules/atoms/pg_jsonpath/jsonpath.h
--- a/monetdb5/modules/atoms/pg_jsonpath/jsonpath.h
+++ b/monetdb5/modules/atoms/pg_jsonpath/jsonpath.h
@@ -174,7 +174,7 @@ extern const char *jspOperationName(Json
  * Parsing support data structures.
  */
 
-extern struct Node * init_escontext(void);
+extern struct Node * init_escontext(char* errmsg);
 
 extern JsonPathParseResult *parsejsonpath(const char *str, int len,
                                                                                
  struct Node *escontext);
@@ -197,12 +197,12 @@ typedef struct JsonPathVariable
 
 
 /* SQL/JSON query functions */
-extern bool JsonPathExists(Datum jb, JsonPath *jp, bool *error, List *vars, 
yyjson_alc* alc);
+extern bool JsonPathExists(Datum jb, JsonPath *jp, bool *error, List *vars, 
yyjson_alc* alc, char* errmsg);
 extern JsonbValue *JsonPathQuery(Datum jb, JsonPath *jp, JsonWrapper wrapper,
                                                   bool *empty, bool *error, 
List *vars,
-                                                  const char *column_name, 
yyjson_alc* alc);
+                                                  const char *column_name, 
yyjson_alc* alc, char* errmsg);
 extern JsonbValue *JsonPathValue(Datum jb, JsonPath *jp, bool *empty,
                                                                 bool *error, 
List *vars,
-                                                                const char 
*column_name, yyjson_alc* alc);
+                                                                const char 
*column_name, yyjson_alc* alc, char* errmsg);
 
 #endif
diff --git a/monetdb5/modules/atoms/pg_jsonpath/jsonpath_exec.c 
b/monetdb5/modules/atoms/pg_jsonpath/jsonpath_exec.c
--- a/monetdb5/modules/atoms/pg_jsonpath/jsonpath_exec.c
+++ b/monetdb5/modules/atoms/pg_jsonpath/jsonpath_exec.c
@@ -101,6 +101,7 @@ typedef struct JsonPathExecContext
        bool            throwErrors;    /* with "false" all suppressible errors 
are
                                                                 * suppressed */
        bool            useTz;
+       char* _errmsg;
 } JsonPathExecContext;
 
 /* Context for LIKE_REGEX execution. */
@@ -169,8 +170,7 @@ typedef struct JsonTablePlanRowSource
 do { \
        if (jspThrowErrors(cxt)) \
                throw_error; \
-       else \
-               return jperError; \
+       return jperError; \
 } while (0)
 
 typedef JsonPathBool (*JsonPathPredicateCallback) (JsonPathItem *jsp,
@@ -183,7 +183,7 @@ static JsonPathExecResult executeJsonPat
                                                                                
  JsonPathGetVarCallback getVar_,
                                                                                
  JsonPathCountVarsCallback countVars,
                                                                                
  Jsonb *json, bool throwErrors,
-                                                                               
  JsonValueList *result, bool useTz, yyjson_alc* alc);
+                                                                               
  JsonValueList *result, bool useTz, JsonPathExecContext* cxt);
 static JsonPathExecResult executeItem(JsonPathExecContext *cxt,
                                                                          
JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found);
 static JsonPathExecResult executeItemOptUnwrapTarget(JsonPathExecContext *cxt,
@@ -237,7 +237,7 @@ JsonItemFromDatum(Datum val, Oid typid, 
 static int     JsonbArraySize(JsonbValue *jb);
 static JsonPathBool executeComparison(JsonPathItem *cmp, JsonbValue *lv,
                                                                          
JsonbValue *rv, void *p);
-static JsonPathBool compareItems(int32 op, JsonbValue *jb1, JsonbValue *jb2,
+static JsonPathBool compareItems(JsonPathExecContext *cxt, int32 op, 
JsonbValue *jb1, JsonbValue *jb2,
                                                                 bool useTz);
 static int     compareNumeric(Numeric a, Numeric b);
 static JsonPathExecResult getArrayIndex(JsonPathExecContext *cxt,
@@ -288,9 +288,8 @@ static JsonPathExecResult
 executeJsonPath(JsonPath *path, void *vars, JsonPathGetVarCallback getVar_,
                                JsonPathCountVarsCallback countVars,
                                Jsonb *json, bool throwErrors, JsonValueList 
*result,
-                               bool useTz, yyjson_alc* alc)
+                               bool useTz, JsonPathExecContext* cxt)
 {
-       JsonPathExecContext cxt;
        JsonPathExecResult res;
        JsonPathItem* jsp;
        JsonbValue*     jbv;
@@ -300,22 +299,21 @@ executeJsonPath(JsonPath *path, void *va
        
        jbv = json;
 
-       cxt.vars = vars;
-       cxt.getVar_ = getVar_;
-       cxt.laxMode = (path->lax);
-       cxt.ignoreStructuralErrors = cxt.laxMode;
-       cxt.root = cxt.current = jbv;
-       cxt.baseObject.jbc = NULL;
-       cxt.baseObject.id = 0;
+       cxt->vars = vars;
+       cxt->getVar_ = getVar_;
+       cxt->laxMode = (path->lax);
+       cxt->ignoreStructuralErrors = cxt->laxMode;
+       cxt->root = cxt->current = jbv;
+       cxt->baseObject.jbc = NULL;
+       cxt->baseObject.id = 0;
        /* 1 + number of base objects in vars */
-       cxt.lastGeneratedObjectId = 1 + countVars(vars);
-       cxt.innermostArraySize = -1;
-       cxt.throwErrors = throwErrors;
-       cxt.useTz = useTz;
-       cxt.alc = alc;
-       cxt.mutable_doc = yyjson_mut_doc_new(alc);
+       cxt->lastGeneratedObjectId = 1 + countVars(vars);
+       cxt->innermostArraySize = -1;
+       cxt->throwErrors = throwErrors;
+       cxt->useTz = useTz;
+       cxt->mutable_doc = yyjson_mut_doc_new(cxt->alc);
 
-       if (jspStrictAbsenceOfErrors(&cxt) && !result)
+       if (jspStrictAbsenceOfErrors(cxt) && !result)
        {
                /*
                 * In strict mode we must get a complete list of values to 
check that
@@ -323,7 +321,7 @@ executeJsonPath(JsonPath *path, void *va
                 */
                JsonValueList vals = {0};
 
-               res = executeItem(&cxt, jsp, jbv, &vals);
+               res = executeItem(cxt, jsp, jbv, &vals);
 
                if (jperIsError(res))
                        return res;
@@ -331,7 +329,7 @@ executeJsonPath(JsonPath *path, void *va
                return JsonValueListIsEmpty(&vals) ? jperNotFound : jperOk;
        }
 
-       res = executeItem(&cxt, jsp, jbv, result);
+       res = executeItem(cxt, jsp, jbv, result);
 
        Assert(!throwErrors || !jperIsError(res));
 
@@ -415,11 +413,12 @@ executeItemOptUnwrapTarget(JsonPathExecC
 
                                                        if (cxt->vars == NULL ||
                                                                (v = 
cxt->getVar_(cxt->vars, cxt->alc , varName, varNameLength,
-                                                                               
                &baseObject, &baseObjectId)) == NULL)
+                                                                               
                &baseObject, &baseObjectId)) == NULL) {
                                                                ereport(ERROR,
                                                                                
(errcode(ERRCODE_UNDEFINED_OBJECT),
-                                                                               
errmsg("could not find jsonpath variable \"%s\"",
-                                                                               
                pnstrdup(varName, varNameLength))));
+                                                                               
errmsg("could not find jsonpath variable \"%s\"", varName)));
+                                                               return 
jperError;
+                                                                               
                }
 
                                                        if (baseObjectId > 0)
                                                        {
@@ -430,6 +429,7 @@ executeItemOptUnwrapTarget(JsonPathExecC
                                                break;
                                        default:
                                                elog(ERROR, "unexpected 
jsonpath item type");
+                                               return jperError;
                                }
                                yyjson_doc* doc = 
yyjson_mut_val_imut_copy(mut_val, cxt->alc);
                                v = yyjson_doc_get_root(doc);
@@ -510,8 +510,10 @@ executeItemOptUnwrapTarget(JsonPathExecC
                        {
                                bool            hasNext = (elem = jsp->next);
 
-                               if (JsonbType(jb) != jbvBinary)
+                               if (JsonbType(jb) != jbvBinary) {
                                        elog(ERROR, "invalid jsonb object type: 
%d", JsonbType(jb));
+                                       return jperError;
+                               }
 
                                return executeAnyItem
                                        (cxt, hasNext ? elem : NULL,
@@ -687,15 +689,9 @@ executeItemOptUnwrapTarget(JsonPathExecC
                                else if (!jspIgnoreStructuralErrors(cxt))
                                {
                                        Assert(found);
-
-                                       if (!jspThrowErrors(cxt))
-                                               return jperError;
-
-                                       ereport(ERROR,
+                                       RETURN_ERROR(ereport(ERROR,
                                                        
(errcode(ERRCODE_SQL_JSON_MEMBER_NOT_FOUND), \
-                                                        errmsg("JSON object 
does not contain key \"%s\"",
-                                                                       
pnstrdup(key.val.string.val,
-                                                                               
         key.val.string.len))));
+                                                        errmsg("JSON object 
does not contain key \"%s\"", key))));
                                }
                        }
                        else if (unwrap && JsonbType(jb) == jbvArray)
@@ -856,8 +852,10 @@ executeItemOptUnwrapTarget(JsonPathExecC
                                int                     last;
                                bool            hasNext = (elem = jsp->next);
 
-                               if (cxt->innermostArraySize < 0)
+                               if (cxt->innermostArraySize < 0) {
                                        elog(ERROR, "evaluating jsonpath LAST 
outside of array subscript");
+                                       return jperError;
+                               }
 
                                if (!hasNext && !found)
                                {
@@ -1047,10 +1045,6 @@ executeItemOptUnwrapTarget(JsonPathExecC
                                {
                                        case jbvString:
 
-                                               /*
-                                                * Value is not necessarily 
null-terminated, so we do
-                                                * pnstrdup() here.
-                                                */
                                                tmp = (char*) 
yyjson_get_str(jb);
                                                break;
                                        case jbvNumeric:
@@ -1089,6 +1083,7 @@ executeItemOptUnwrapTarget(JsonPathExecC
 
                default:
                        elog(ERROR, "unrecognized jsonpath item type: %d", 
jsp->type);
+                       return jperError;
        }
 
        return res;
@@ -1205,8 +1200,10 @@ executeBoolItem(JsonPathExecContext *cxt
        /* since this function recurses, it could be driven to stack overflow */
        check_stack_depth();
 
-       if (!canHaveNext && jspHasNext(jsp))
+       if (!canHaveNext && jspHasNext(jsp)) {
                elog(ERROR, "boolean jsonpath item cannot have next item");
+               assert(0); // cannot happen
+       }
 
        switch (jsp->type)
        {
@@ -1318,6 +1315,7 @@ executeBoolItem(JsonPathExecContext *cxt
 
                default:
                        elog(ERROR, "invalid boolean jsonpath item type: %d", 
jsp->type);
+                       assert(0); // cannot happen
                        return jpbUnknown;
        }
 }
@@ -1967,7 +1965,7 @@ executeComparison(JsonPathItem *cmp, Jso
 {
        JsonPathExecContext *cxt = (JsonPathExecContext *) p;
 
-       return compareItems(cmp->type, lv, rv, cxt->useTz);
+       return compareItems(cxt, cmp->type, lv, rv, cxt->useTz);
 }
 
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to