Changeset: 2cc10043c915 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/2cc10043c915
Modified Files:
        sql/backends/monet5/vaults/json/json.c
Branch: newjson
Log Message:

wip


diffs (180 lines):

diff --git a/sql/backends/monet5/vaults/json/json.c 
b/sql/backends/monet5/vaults/json/json.c
--- a/sql/backends/monet5/vaults/json/json.c
+++ b/sql/backends/monet5/vaults/json/json.c
@@ -87,13 +87,135 @@ read_json_file(JSONFileHandle *jfh)
        return content;
 }
 
+typedef struct jobject {
+       struct jobject *parent;
+       list *fields;
+} jobject;
+
+static jobject *
+new_jobject(allocator *sa, jobject *parent)
+{
+       jobject *res = SA_NEW(sa, jobject);
+       res->parent = parent;
+       res->fields = sa_list(sa);
+       return res;
+}
+
+static size_t
+json2subtypes(mvc *sql, JSONterm *t, sql_alias **alias_pptr, list *types, list 
*exps, list *names, jobject **parent_pptr)
+{
+       sql_subtype *tpe = NULL;
+       sql_exp *ne = NULL;
+       sql_alias *nalias = NULL;
+       const char *cname = NULL;
+       size_t offset = 1;
+       jobject *parent = *parent_pptr;
+       sql_alias *alias = *alias_pptr;
+
+       switch(t->kind) {
+               case JSON_ARRAY:
+                       tpe = sql_create_subtype(sql->sa, SA_ZNEW(sql->sa, 
sql_type), 0, 0);
+                       tpe->type->composite = true;
+                       tpe->multiset = MS_ARRAY;
+                       cname = alias->name;
+                       // append to parent fields
+                       if (parent && parent->fields) {
+                               sql_arg *field = sql_create_arg(sql->sa, cname, 
tpe, false); // ?inout
+                               list_append(parent->fields, field);
+                       }
+                       ne = exp_column(sql->sa, alias, cname, tpe, CARD_MULTI, 
1, 0, 0);
+                       list_append(types, tpe);
+                       list_append(exps , ne);
+                       list_append(names, (char*)cname);
+                       nalias = &ne->alias;
+                       *alias_pptr = nalias;
+                       offset += json2subtypes(sql, t+1, alias_pptr, types, 
exps, names, parent_pptr);
+                       break;
+               case JSON_OBJECT:
+                       tpe = sql_create_subtype(sql->sa, SA_ZNEW(sql->sa, 
sql_type), 0, 0);
+                       tpe->type->composite = true;
+                       // new object
+                       jobject *jo = new_jobject(sql->sa, parent);
+                       tpe->type->d.fields = jo->fields;
+                       cname = alias->name;
+                       if (parent) {
+                               sql_arg *field = sql_create_arg(sql->sa, cname, 
tpe, false); // ?inout
+                               list_append(parent->fields, field);
+                       }
+                       ne = exp_column(sql->sa, alias, cname, tpe, CARD_MULTI, 
1, 0, 0);
+                       set_basecol(ne);
+                       ne->alias.label = -(sql->nid++);
+                       list_append(exps, ne);
+                       list_append(types, tpe);
+                       list_append(names, (char*)cname);
+                       nalias = &ne->alias;
+                       *alias_pptr = nalias;
+                       *parent_pptr = jo;
+                       offset += json2subtypes(sql, t+1, alias_pptr, types, 
exps, names, parent_pptr);
+                       break;
+               case JSON_ELEMENT:
+                       cname = sa_strndup(sql->sa, t->value, t->valuelen);
+                       nalias = a_create(sql->sa, cname);
+                       nalias->parent = alias;
+                       *alias_pptr = nalias;
+                       offset += json2subtypes(sql, t+1, alias_pptr, types, 
exps, names, parent_pptr);
+                       break;
+               case JSON_STRING:
+                       tpe = sql_bind_localtype("str");
+                       cname = alias->name;
+                       // append to parent fields
+                       if (parent) {
+                               sql_arg *field = sql_create_arg(sql->sa, cname, 
tpe, false); // ?inout
+                               list_append(parent->fields, field);
+                       }
+                       ne = exp_column(sql->sa, alias->parent, cname, tpe, 
CARD_MULTI, 1, 0, 0);
+                       set_basecol(ne);
+                       ne->alias.label = -(sql->nid++);
+                       list_append(exps, ne);
+                       list_append(types, tpe);
+                       list_append(names, (char*)cname);
+                       // adjust one level
+                       *alias_pptr = alias->parent;
+                       offset += json2subtypes(sql, t+1, alias_pptr, types, 
exps, names, parent_pptr);
+                       break;
+               case JSON_NUMBER:
+                       tpe = sql_bind_localtype("int");
+                       cname = alias->name;
+                       // append to parent fields
+                       if (parent) {
+                               sql_arg *field = sql_create_arg(sql->sa, cname, 
tpe, false); // ?inout
+                               list_append(parent->fields, field);
+                       }
+                       ne = exp_column(sql->sa, alias->parent, cname, tpe, 
CARD_MULTI, 1, 0, 0);
+                       set_basecol(ne);
+                       ne->alias.label = -(sql->nid++);
+                       list_append(exps, ne);
+                       list_append(types, tpe);
+                       list_append(names, (char*)cname);
+                       // adjust one level
+                       *alias_pptr = alias->parent;
+                       offset += json2subtypes(sql, t+1, alias_pptr, types, 
exps, names, parent_pptr);
+                       break;
+               case JSON_VALUE:
+                       // break one level
+                       if (parent)
+                               *parent_pptr = parent->parent;
+                       if (alias)
+                               *alias_pptr = alias->parent;
+                       break;
+               default:
+                       // error ?
+                       offset = 0;
+                       break;
+       }
+       return offset;
+}
+
 
 static str
 json_relation(mvc *sql, sql_subfunc *f, char *filename, list *res_exps, char 
*tname)
 {
-       (void) sql;
-       (void) f;
-       (void) res_exps;
+       char *res = MAL_SUCCEED;
        f->tname = tname;
        allocator *sa = sa_create(NULL);
        JSONFileHandle *jfh = json_open(filename, sa);
@@ -102,13 +224,32 @@ json_relation(mvc *sql, sql_subfunc *f, 
                json_str = read_json_file(jfh);
                json_close(jfh);
        }
-       JSON *jt = JSONparse(json_str);
-       if (jt) {
-
+       JSON *jt = JSONparse(json_str); // should take allocator
+       if (jt && jt->error == NULL) {
+               list *types = sa_list(sql->sa);
+               list *names = sa_list(sql->sa);
+               size_t offset = 0;
+               sql_alias *alias = a_create(sql->sa, tname);
+               jobject *jo = NULL;
+               do {
+                       size_t prev_offset = offset;
+                       offset += json2subtypes(sql, jt->elm + offset, &alias, 
types, res_exps, names, &jo);
+                       if (offset == prev_offset) {
+                               res = createException(SQL, SQLSTATE(42000), 
"json" "json2subtypes failure for %s", filename);
+                               break;
+                       }
+               } while(offset < (size_t)jt->free);
+               JSONfree(jt);
+               if (res == MAL_SUCCEED) {
+                       f->res = types;
+                       f->coltypes = types;
+                       f->colnames = names;
+               }
+       } else {
+               res = jt ? jt->error : createException(SQL, SQLSTATE(42000), 
"json" "Failure parsing %s", filename);
        }
-       JSONfree(jt);
        sa_destroy(sa);
-       return MAL_SUCCEED;
+       return res;
 }
 
 
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to