{"action":"created","comment":{"url":"https://api.github.com/repos/realm/realm-java/pulls/comments/40769506","id":40769506,"diff_hunk":"@@ -144,6 +150,216 @@ JNIEXPORT void JNICALL Java_io_realm_internal_Table_nativeRenameColumn\n     } CATCH_STD()\n }\n \n+JNIEXPORT jboolean JNICALL Java_io_realm_internal_Table_nativeIsColumnNullable\n+  (JNIEnv *env, jobject, jlong nativeTablePtr, jlong columnIndex)\n+{\n+    Table *table = TBL(nativeTablePtr);\n+    if (!TBL_AND_COL_INDEX_VALID(env, table, columnIndex)) {\n+        return false;\n+    }\n+    if (table->has_shared_type()) {\n+        ThrowException(env, UnsupportedOperation, \"Not allowed to convert field in subtable.\");\n+        return false;\n+    }\n+    size_t column_index = S(columnIndex);\n+    return table->is_nullable(column_index);\n+}\n+\n+JNIEXPORT void JNICALL Java_io_realm_internal_Table_nativeConvertColumnToNullable\n+  (JNIEnv *env, jobject, jlong nativeTablePtr, jlong columnIndex)\n+{\n+    Table *table = TBL(nativeTablePtr);\n+    if (!TBL_AND_COL_INDEX_VALID(env, table, columnIndex)) {\n+        return;\n+    }\n+    if (table->has_shared_type()) {\n+        ThrowException(env, UnsupportedOperation, \"Not allowed to convert field in subtable.\");\n+        return;\n+    }\n+    try {\n+        size_t column_index = S(columnIndex);\n+        if (table->is_nullable(column_index)) {\n+            return; // column is already nullable\n+        }\n+\n+        std::string column_name = table->get_column_name(column_index);\n+        DataType column_type = table->get_column_type(column_index);\n+        if (column_type == type_Link ||\n+            column_type == type_LinkList ||\n+            column_type == type_Mixed ||\n+            column_type == type_Table) {\n+            ThrowException(env, IllegalArgument, \"Wrong type - cannot be converted to nullable.\");\n+        }\n+\n+        std::string tmp_column_name;\n+\n+        size_t j = 0;\n+        while (true) {\n+            std::ostringstream ss;\n+            ss << std::string(\"__TMP__\") << j;\n+            if (table->get_column_index(ss.str()) == realm::not_found) {\n+                table->insert_column(column_index, column_type, ss.str(), true);\n+                tmp_column_name = ss.str();\n+                break;\n+            }\n+            j++;\n+        }\n+\n+        for (size_t i = 0; i < table->size(); ++i) {\n+            switch (column_type) {\n+                case type_String:\n+                    table->set_string(column_index, i, table->get_string(column_index + 1, i));\n+                    break;\n+                case type_Binary:\n+                    table->set_binary(column_index, i, table->get_binary(column_index + 1, i));\n+                    break;\n+                case type_Int:\n+                    table->set_int(column_index, i, table->get_int(column_index + 1, i));\n+                    break;\n+                case type_Bool:\n+                    table->set_bool(column_index, i, table->get_bool(column_index + 1, i));\n+                    break;\n+                case type_DateTime:\n+                    table->set_datetime(column_index, i, table->get_datetime(column_index + 1, i));\n+                    break;\n+                case type_Float:\n+                    table->set_float(column_index, i, table->get_float(column_index + 1, i));\n+                    break;\n+                case type_Double:\n+                    table->set_double(column_index, i, table->get_double(column_index + 1, i));\n+                    break;\n+                case type_Link:\n+                case type_LinkList:\n+                case type_Mixed:\n+                case type_Table:\n+                    // checked previously\n+                    break;\n+            }\n+        }\n+        if (table->has_search_index(column_index + 1)) {","path":"realm-jni/src/io_realm_internal_table.cpp","position":144,"original_position":144,"commit_id":"cf8403f23df44e3314b7919f55d4c2fe52b6e4f0","original_commit_id":"cf8403f23df44e3314b7919f55d4c2fe52b6e4f0","user":{"login":"kneth","id":1225363,"avatar_url":"https://avatars.githubusercontent.com/u/1225363?v=3","gravatar_id":"","url":"https://api.github.com/users/kneth","html_url":"https://github.com/kneth","followers_url":"https://api.github.com/users/kneth/followers","following_url":"https://api.github.com/users/kneth/following{/other_user}","gists_url":"https://api.github.com/users/kneth/gists{/gist_id}","starred_url":"https://api.github.com/users/kneth/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kneth/subscriptions","organizations_url":"https://api.github.com/users/kneth/orgs","repos_url":"https://api.github.com/users/kneth/repos","events_url":"https://api.github.com/users/kneth/events{/privacy}","received_events_url":"https://api.github.com/users/kneth/received_events","type":"User","site_admin":false},"body":"The new column is not added to the table at the end but *inserted* before the original column. So we have: `|__TMP__0|TMP__2__|__TMP__1|`. The variable `column_index` will now point to `__TMP__2` while `column_index + 1` will point to `__TMP__1`.","created_at":"2015-09-30T08:30:00Z","updated_at":"2015-09-30T08:30:00Z","html_url":"https://github.com/realm/realm-java/pull/1396#discussion_r40769506","pull_request_url":"https://api.github.com/repos/realm/realm-java/pulls/1396","_links":{"self":{"href":"https://api.github.com/repos/realm/realm-java/pulls/comments/40769506"},"html":{"href":"https://github.com/realm/realm-java/pull/1396#discussion_r40769506"},"pull_request":{"href":"https://api.github.com/repos/realm/realm-java/pulls/1396"}}},"pull_request":{"url":"https://api.github.com/repos/realm/realm-java/pulls/1396","id":42672327,"html_url":"https://github.com/realm/realm-java/pull/1396","diff_url":"https://github.com/realm/realm-java/pull/1396.diff","patch_url":"https://github.com/realm/realm-java/pull/1396.patch","issue_url":"https://api.github.com/repos/realm/realm-java/issues/1396","number":1396,"state":"open","locked":false,"title":"Null support for all types","user":{"login":"beeender","id":449296,"avatar_url":"https://avatars.githubusercontent.com/u/449296?v=3","gravatar_id":"","url":"https://api.github.com/users/beeender","html_url":"https://github.com/beeender","followers_url":"https://api.github.com/users/beeender/followers","following_url":"https://api.github.com/users/beeender/following{/other_user}","gists_url":"https://api.github.com/users/beeender/gists{/gist_id}","starred_url":"https://api.github.com/users/beeender/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/beeender/subscriptions","organizations_url":"https://api.github.com/users/beeender/orgs","repos_url":"https://api.github.com/users/beeender/repos","events_url":"https://api.github.com/users/beeender/events{/privacy}","received_events_url":"https://api.github.com/users/beeender/received_events","type":"User","site_admin":false},"body":"Fully null support for all types\r\n#1098 is merged to this one as well.\r\n#1376 is merged for core integration. And #1376 should be MERGED FIRST.\r\n\r\nSee https://github.com/realm/realm-wiki/wiki/NULL-in-Realm-Bindings for more information on rules and etc..\r\n\r\nTODO checks from #1098 nullable string and bytes.\r\n - [x] Basic support for strings (insert, retrieve, query)\r\n - [x] Basic support for binary data (insert, retrieve)\r\n - [x] Basic support for booleans\r\n - [x] Basic support for integers\r\n - [x] Basic support for dates\r\n - [x] Migration for String\r\n - [x] JSON\r\n - [x] Sorting on nullable String columns doesn't work\r\n\r\nChecks for all types null support\r\n - [x] Migration testing\r\n - [x] Dynamic object testing (Will be handled by CM's PR)\r\n - [x] Handling null for linklist (JSON and setter)\r\n - [x] Fix JSON stream parser after handling linklist\r\n - [x] `@Required` for link \r\n - [x] Check `copyToOrUpdate` method\r\n - [x] Handle NaN value for float/double\r\n - [x] `isNull` for link query\r\n - [x] 'max' 'min' 'avg' return Boxed type (Number), clean up interface in `RealmQuery`.\r\n - [x] Align behavior of nullable bytes with cocoa team\r\n - [x] `io.realm.internal.Table.convertToNotNullableColumn()`","created_at":"2015-08-18T08:19:55Z","updated_at":"2015-09-30T08:30:00Z","closed_at":null,"merged_at":null,"merge_commit_sha":"aae0339a24a80f727362c727fad1a1fc29f8c45a","assignee":{"login":"beeender","id":449296,"avatar_url":"https://avatars.githubusercontent.com/u/449296?v=3","gravatar_id":"","url":"https://api.github.com/users/beeender","html_url":"https://github.com/beeender","followers_url":"https://api.github.com/users/beeender/followers","following_url":"https://api.github.com/users/beeender/following{/other_user}","gists_url":"https://api.github.com/users/beeender/gists{/gist_id}","starred_url":"https://api.github.com/users/beeender/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/beeender/subscriptions","organizations_url":"https://api.github.com/users/beeender/orgs","repos_url":"https://api.github.com/users/beeender/repos","events_url":"https://api.github.com/users/beeender/events{/privacy}","received_events_url":"https://api.github.com/users/beeender/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/realm/realm-java/pulls/1396/commits","review_comments_url":"https://api.github.com/repos/realm/realm-java/pulls/1396/comments","review_comment_url":"https://api.github.com/repos/realm/realm-java/pulls/comments{/number}","comments_url":"https://api.github.com/repos/realm/realm-java/issues/1396/comments","statuses_url":"https://api.github.com/repos/realm/realm-java/statuses/cf8403f23df44e3314b7919f55d4c2fe52b6e4f0","head":{"label":"realm:mc-null-support","ref":"mc-null-support","sha":"cf8403f23df44e3314b7919f55d4c2fe52b6e4f0","user":{"login":"realm","id":7575099,"avatar_url":"https://avatars.githubusercontent.com/u/7575099?v=3","gravatar_id":"","url":"https://api.github.com/users/realm","html_url":"https://github.com/realm","followers_url":"https://api.github.com/users/realm/followers","following_url":"https://api.github.com/users/realm/following{/other_user}","gists_url":"https://api.github.com/users/realm/gists{/gist_id}","starred_url":"https://api.github.com/users/realm/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/realm/subscriptions","organizations_url":"https://api.github.com/users/realm/orgs","repos_url":"https://api.github.com/users/realm/repos","events_url":"https://api.github.com/users/realm/events{/privacy}","received_events_url":"https://api.github.com/users/realm/received_events","type":"Organization","site_admin":false},"repo":{"id":4084908,"name":"realm-java","full_name":"realm/realm-java","owner":{"login":"realm","id":7575099,"avatar_url":"https://avatars.githubusercontent.com/u/7575099?v=3","gravatar_id":"","url":"https://api.github.com/users/realm","html_url":"https://github.com/realm","followers_url":"https://api.github.com/users/realm/followers","following_url":"https://api.github.com/users/realm/following{/other_user}","gists_url":"https://api.github.com/users/realm/gists{/gist_id}","starred_url":"https://api.github.com/users/realm/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/realm/subscriptions","organizations_url":"https://api.github.com/users/realm/orgs","repos_url":"https://api.github.com/users/realm/repos","events_url":"https://api.github.com/users/realm/events{/privacy}","received_events_url":"https://api.github.com/users/realm/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/realm/realm-java","description":"Realm is a mobile database: a replacement for SQLite & ORMs","fork":false,"url":"https://api.github.com/repos/realm/realm-java","forks_url":"https://api.github.com/repos/realm/realm-java/forks","keys_url":"https://api.github.com/repos/realm/realm-java/keys{/key_id}","collaborators_url":"https://api.github.com/repos/realm/realm-java/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/realm/realm-java/teams","hooks_url":"https://api.github.com/repos/realm/realm-java/hooks","issue_events_url":"https://api.github.com/repos/realm/realm-java/issues/events{/number}","events_url":"https://api.github.com/repos/realm/realm-java/events","assignees_url":"https://api.github.com/repos/realm/realm-java/assignees{/user}","branches_url":"https://api.github.com/repos/realm/realm-java/branches{/branch}","tags_url":"https://api.github.com/repos/realm/realm-java/tags","blobs_url":"https://api.github.com/repos/realm/realm-java/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/realm/realm-java/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/realm/realm-java/git/refs{/sha}","trees_url":"https://api.github.com/repos/realm/realm-java/git/trees{/sha}","statuses_url":"https://api.github.com/repos/realm/realm-java/statuses/{sha}","languages_url":"https://api.github.com/repos/realm/realm-java/languages","stargazers_url":"https://api.github.com/repos/realm/realm-java/stargazers","contributors_url":"https://api.github.com/repos/realm/realm-java/contributors","subscribers_url":"https://api.github.com/repos/realm/realm-java/subscribers","subscription_url":"https://api.github.com/repos/realm/realm-java/subscription","commits_url":"https://api.github.com/repos/realm/realm-java/commits{/sha}","git_commits_url":"https://api.github.com/repos/realm/realm-java/git/commits{/sha}","comments_url":"https://api.github.com/repos/realm/realm-java/comments{/number}","issue_comment_url":"https://api.github.com/repos/realm/realm-java/issues/comments{/number}","contents_url":"https://api.github.com/repos/realm/realm-java/contents/{+path}","compare_url":"https://api.github.com/repos/realm/realm-java/compare/{base}...{head}","merges_url":"https://api.github.com/repos/realm/realm-java/merges","archive_url":"https://api.github.com/repos/realm/realm-java/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/realm/realm-java/downloads","issues_url":"https://api.github.com/repos/realm/realm-java/issues{/number}","pulls_url":"https://api.github.com/repos/realm/realm-java/pulls{/number}","milestones_url":"https://api.github.com/repos/realm/realm-java/milestones{/number}","notifications_url":"https://api.github.com/repos/realm/realm-java/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/realm/realm-java/labels{/name}","releases_url":"https://api.github.com/repos/realm/realm-java/releases{/id}","created_at":"2012-04-20T09:18:42Z","updated_at":"2015-09-30T03:49:29Z","pushed_at":"2015-09-30T08:23:35Z","git_url":"git://github.com/realm/realm-java.git","ssh_url":"git@github.com:realm/realm-java.git","clone_url":"https://github.com/realm/realm-java.git","svn_url":"https://github.com/realm/realm-java","homepage":"http://realm.io","size":57276,"stargazers_count":2542,"watchers_count":2542,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":259,"mirror_url":null,"open_issues_count":148,"forks":259,"open_issues":148,"watchers":2542,"default_branch":"master"}},"base":{"label":"realm:master","ref":"master","sha":"69401df1ff069554cc442dcc0d7f3bc000806289","user":{"login":"realm","id":7575099,"avatar_url":"https://avatars.githubusercontent.com/u/7575099?v=3","gravatar_id":"","url":"https://api.github.com/users/realm","html_url":"https://github.com/realm","followers_url":"https://api.github.com/users/realm/followers","following_url":"https://api.github.com/users/realm/following{/other_user}","gists_url":"https://api.github.com/users/realm/gists{/gist_id}","starred_url":"https://api.github.com/users/realm/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/realm/subscriptions","organizations_url":"https://api.github.com/users/realm/orgs","repos_url":"https://api.github.com/users/realm/repos","events_url":"https://api.github.com/users/realm/events{/privacy}","received_events_url":"https://api.github.com/users/realm/received_events","type":"Organization","site_admin":false},"repo":{"id":4084908,"name":"realm-java","full_name":"realm/realm-java","owner":{"login":"realm","id":7575099,"avatar_url":"https://avatars.githubusercontent.com/u/7575099?v=3","gravatar_id":"","url":"https://api.github.com/users/realm","html_url":"https://github.com/realm","followers_url":"https://api.github.com/users/realm/followers","following_url":"https://api.github.com/users/realm/following{/other_user}","gists_url":"https://api.github.com/users/realm/gists{/gist_id}","starred_url":"https://api.github.com/users/realm/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/realm/subscriptions","organizations_url":"https://api.github.com/users/realm/orgs","repos_url":"https://api.github.com/users/realm/repos","events_url":"https://api.github.com/users/realm/events{/privacy}","received_events_url":"https://api.github.com/users/realm/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/realm/realm-java","description":"Realm is a mobile database: a replacement for SQLite & ORMs","fork":false,"url":"https://api.github.com/repos/realm/realm-java","forks_url":"https://api.github.com/repos/realm/realm-java/forks","keys_url":"https://api.github.com/repos/realm/realm-java/keys{/key_id}","collaborators_url":"https://api.github.com/repos/realm/realm-java/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/realm/realm-java/teams","hooks_url":"https://api.github.com/repos/realm/realm-java/hooks","issue_events_url":"https://api.github.com/repos/realm/realm-java/issues/events{/number}","events_url":"https://api.github.com/repos/realm/realm-java/events","assignees_url":"https://api.github.com/repos/realm/realm-java/assignees{/user}","branches_url":"https://api.github.com/repos/realm/realm-java/branches{/branch}","tags_url":"https://api.github.com/repos/realm/realm-java/tags","blobs_url":"https://api.github.com/repos/realm/realm-java/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/realm/realm-java/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/realm/realm-java/git/refs{/sha}","trees_url":"https://api.github.com/repos/realm/realm-java/git/trees{/sha}","statuses_url":"https://api.github.com/repos/realm/realm-java/statuses/{sha}","languages_url":"https://api.github.com/repos/realm/realm-java/languages","stargazers_url":"https://api.github.com/repos/realm/realm-java/stargazers","contributors_url":"https://api.github.com/repos/realm/realm-java/contributors","subscribers_url":"https://api.github.com/repos/realm/realm-java/subscribers","subscription_url":"https://api.github.com/repos/realm/realm-java/subscription","commits_url":"https://api.github.com/repos/realm/realm-java/commits{/sha}","git_commits_url":"https://api.github.com/repos/realm/realm-java/git/commits{/sha}","comments_url":"https://api.github.com/repos/realm/realm-java/comments{/number}","issue_comment_url":"https://api.github.com/repos/realm/realm-java/issues/comments{/number}","contents_url":"https://api.github.com/repos/realm/realm-java/contents/{+path}","compare_url":"https://api.github.com/repos/realm/realm-java/compare/{base}...{head}","merges_url":"https://api.github.com/repos/realm/realm-java/merges","archive_url":"https://api.github.com/repos/realm/realm-java/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/realm/realm-java/downloads","issues_url":"https://api.github.com/repos/realm/realm-java/issues{/number}","pulls_url":"https://api.github.com/repos/realm/realm-java/pulls{/number}","milestones_url":"https://api.github.com/repos/realm/realm-java/milestones{/number}","notifications_url":"https://api.github.com/repos/realm/realm-java/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/realm/realm-java/labels{/name}","releases_url":"https://api.github.com/repos/realm/realm-java/releases{/id}","created_at":"2012-04-20T09:18:42Z","updated_at":"2015-09-30T03:49:29Z","pushed_at":"2015-09-30T08:23:35Z","git_url":"git://github.com/realm/realm-java.git","ssh_url":"git@github.com:realm/realm-java.git","clone_url":"https://github.com/realm/realm-java.git","svn_url":"https://github.com/realm/realm-java","homepage":"http://realm.io","size":57276,"stargazers_count":2542,"watchers_count":2542,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":259,"mirror_url":null,"open_issues_count":148,"forks":259,"open_issues":148,"watchers":2542,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/realm/realm-java/pulls/1396"},"html":{"href":"https://github.com/realm/realm-java/pull/1396"},"issue":{"href":"https://api.github.com/repos/realm/realm-java/issues/1396"},"comments":{"href":"https://api.github.com/repos/realm/realm-java/issues/1396/comments"},"review_comments":{"href":"https://api.github.com/repos/realm/realm-java/pulls/1396/comments"},"review_comment":{"href":"https://api.github.com/repos/realm/realm-java/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/realm/realm-java/pulls/1396/commits"},"statuses":{"href":"https://api.github.com/repos/realm/realm-java/statuses/cf8403f23df44e3314b7919f55d4c2fe52b6e4f0"}}}}