{"action":"created","comment":{"url":"https://api.github.com/repos/mldbai/mldb/pulls/comments/49724031","id":49724031,"diff_hunk":"@@ -1307,6 +1307,92 @@ RegisterVectorOp<SumOp> registerVectorSum(\"vector_sum\");\n RegisterVectorOp<ProductOp> registerVectorProduct(\"vector_product\");\n RegisterVectorOp<QuotientOp> registerVectorQuotient(\"vector_quotient\");\n \n+void\n+ParseConcatArguments(bool& skipNulls, Utf8String& separator, bool& columnValue,\n+                     const ExpressionValue::Row & argRow)\n+{\n+    bool check[3] = {false, false, false};\n+    auto assertArg = [&] (size_t field, const string & name) {\n+        if (check[field]) {\n+            throw HttpReturnException(\n+                400, \"Argument \" + name + \" is specified more than once\");\n+        }\n+        check[field] = true;\n+    };\n+\n+    for (auto& arg : argRow) {\n+        const ColumnName& columnName = std::get<0>(arg);\n+        if (columnName == ColumnName(\"skipNulls\")) {\n+            assertArg(0, \"splitNulls\");\n+            skipNulls = std::get<1>(arg).asBool();\n+        }\n+        else if (columnName == ColumnName(\"separator\")) {\n+            assertArg(1, \"separator\");\n+            separator = std::get<1>(arg).toUtf8String();\n+        }\n+        else if (columnName == ColumnName(\"columnValue\")) {\n+            assertArg(2, \"columnValue\");\n+            columnValue = std::get<1>(arg).asBool();\n+        }\n+        else {\n+            throw HttpReturnException(400, \"Unknown argument in tokenize\",\n+                                      \"argument\", columnName);\n+        }\n+    }\n+}\n+\n+BoundFunction concat(const std::vector<BoundSqlExpression> & args)\n+{\n+    return {[=] (const std::vector<ExpressionValue> & args,\n+                 const SqlRowScope & context) -> ExpressionValue\n+            {\n+                bool skipNulls = true;\n+                Utf8String separator(\",\");\n+                bool columnValue = true;\n+\n+                if (args.size() == 0) {\n+                    throw HttpReturnException(\n+                        400, \"concat requires at least one argument\");\n+                }\n+\n+                if (args.size() > 2) {\n+                    throw HttpReturnException(\n+                        400, \"concat requires at most two arguments\");\n+                }\n+\n+                if (args.size() == 2) {","path":"sql/builtin_functions.cc","position":66,"original_position":66,"commit_id":"a088e2463b0f03ba28a61f0b271198ae8854d800","original_commit_id":"a088e2463b0f03ba28a61f0b271198ae8854d800","user":{"login":"guyd","id":683788,"avatar_url":"https://avatars.githubusercontent.com/u/683788?v=3","gravatar_id":"","url":"https://api.github.com/users/guyd","html_url":"https://github.com/guyd","followers_url":"https://api.github.com/users/guyd/followers","following_url":"https://api.github.com/users/guyd/following{/other_user}","gists_url":"https://api.github.com/users/guyd/gists{/gist_id}","starred_url":"https://api.github.com/users/guyd/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/guyd/subscriptions","organizations_url":"https://api.github.com/users/guyd/orgs","repos_url":"https://api.github.com/users/guyd/repos","events_url":"https://api.github.com/users/guyd/events{/privacy}","received_events_url":"https://api.github.com/users/guyd/received_events","type":"User","site_admin":false},"body":"Actually, this one too can be handled at bind time.  This would avoid reparsing that static input for all rows in the dataset.","created_at":"2016-01-14T13:16:00Z","updated_at":"2016-01-14T13:16:00Z","html_url":"https://github.com/mldbai/mldb/pull/66#discussion_r49724031","pull_request_url":"https://api.github.com/repos/mldbai/mldb/pulls/66","_links":{"self":{"href":"https://api.github.com/repos/mldbai/mldb/pulls/comments/49724031"},"html":{"href":"https://github.com/mldbai/mldb/pull/66#discussion_r49724031"},"pull_request":{"href":"https://api.github.com/repos/mldbai/mldb/pulls/66"}}},"pull_request":{"url":"https://api.github.com/repos/mldbai/mldb/pulls/66","id":55963383,"html_url":"https://github.com/mldbai/mldb/pull/66","diff_url":"https://github.com/mldbai/mldb/pull/66.diff","patch_url":"https://github.com/mldbai/mldb/pull/66.patch","issue_url":"https://api.github.com/repos/mldbai/mldb/issues/66","number":66,"state":"open","locked":false,"title":"MLDB-1253 concat function + test","user":{"login":"FinchPowers","id":607566,"avatar_url":"https://avatars.githubusercontent.com/u/607566?v=3","gravatar_id":"","url":"https://api.github.com/users/FinchPowers","html_url":"https://github.com/FinchPowers","followers_url":"https://api.github.com/users/FinchPowers/followers","following_url":"https://api.github.com/users/FinchPowers/following{/other_user}","gists_url":"https://api.github.com/users/FinchPowers/gists{/gist_id}","starred_url":"https://api.github.com/users/FinchPowers/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/FinchPowers/subscriptions","organizations_url":"https://api.github.com/users/FinchPowers/orgs","repos_url":"https://api.github.com/users/FinchPowers/repos","events_url":"https://api.github.com/users/FinchPowers/events{/privacy}","received_events_url":"https://api.github.com/users/FinchPowers/received_events","type":"User","site_admin":false},"body":"","created_at":"2016-01-13T22:09:05Z","updated_at":"2016-01-14T13:16:00Z","closed_at":null,"merged_at":null,"merge_commit_sha":"a4e0cca49effb5c1e9b0c977e22857506c8f80f8","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/mldbai/mldb/pulls/66/commits","review_comments_url":"https://api.github.com/repos/mldbai/mldb/pulls/66/comments","review_comment_url":"https://api.github.com/repos/mldbai/mldb/pulls/comments{/number}","comments_url":"https://api.github.com/repos/mldbai/mldb/issues/66/comments","statuses_url":"https://api.github.com/repos/mldbai/mldb/statuses/a088e2463b0f03ba28a61f0b271198ae8854d800","head":{"label":"mldbai:MLDB-1253_concat_function","ref":"MLDB-1253_concat_function","sha":"a088e2463b0f03ba28a61f0b271198ae8854d800","user":{"login":"mldbai","id":11510172,"avatar_url":"https://avatars.githubusercontent.com/u/11510172?v=3","gravatar_id":"","url":"https://api.github.com/users/mldbai","html_url":"https://github.com/mldbai","followers_url":"https://api.github.com/users/mldbai/followers","following_url":"https://api.github.com/users/mldbai/following{/other_user}","gists_url":"https://api.github.com/users/mldbai/gists{/gist_id}","starred_url":"https://api.github.com/users/mldbai/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mldbai/subscriptions","organizations_url":"https://api.github.com/users/mldbai/orgs","repos_url":"https://api.github.com/users/mldbai/repos","events_url":"https://api.github.com/users/mldbai/events{/privacy}","received_events_url":"https://api.github.com/users/mldbai/received_events","type":"Organization","site_admin":false},"repo":{"id":47634692,"name":"mldb","full_name":"mldbai/mldb","owner":{"login":"mldbai","id":11510172,"avatar_url":"https://avatars.githubusercontent.com/u/11510172?v=3","gravatar_id":"","url":"https://api.github.com/users/mldbai","html_url":"https://github.com/mldbai","followers_url":"https://api.github.com/users/mldbai/followers","following_url":"https://api.github.com/users/mldbai/following{/other_user}","gists_url":"https://api.github.com/users/mldbai/gists{/gist_id}","starred_url":"https://api.github.com/users/mldbai/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mldbai/subscriptions","organizations_url":"https://api.github.com/users/mldbai/orgs","repos_url":"https://api.github.com/users/mldbai/repos","events_url":"https://api.github.com/users/mldbai/events{/privacy}","received_events_url":"https://api.github.com/users/mldbai/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/mldbai/mldb","description":"MLDB is the Machine Learning Database","fork":false,"url":"https://api.github.com/repos/mldbai/mldb","forks_url":"https://api.github.com/repos/mldbai/mldb/forks","keys_url":"https://api.github.com/repos/mldbai/mldb/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mldbai/mldb/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mldbai/mldb/teams","hooks_url":"https://api.github.com/repos/mldbai/mldb/hooks","issue_events_url":"https://api.github.com/repos/mldbai/mldb/issues/events{/number}","events_url":"https://api.github.com/repos/mldbai/mldb/events","assignees_url":"https://api.github.com/repos/mldbai/mldb/assignees{/user}","branches_url":"https://api.github.com/repos/mldbai/mldb/branches{/branch}","tags_url":"https://api.github.com/repos/mldbai/mldb/tags","blobs_url":"https://api.github.com/repos/mldbai/mldb/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mldbai/mldb/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mldbai/mldb/git/refs{/sha}","trees_url":"https://api.github.com/repos/mldbai/mldb/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mldbai/mldb/statuses/{sha}","languages_url":"https://api.github.com/repos/mldbai/mldb/languages","stargazers_url":"https://api.github.com/repos/mldbai/mldb/stargazers","contributors_url":"https://api.github.com/repos/mldbai/mldb/contributors","subscribers_url":"https://api.github.com/repos/mldbai/mldb/subscribers","subscription_url":"https://api.github.com/repos/mldbai/mldb/subscription","commits_url":"https://api.github.com/repos/mldbai/mldb/commits{/sha}","git_commits_url":"https://api.github.com/repos/mldbai/mldb/git/commits{/sha}","comments_url":"https://api.github.com/repos/mldbai/mldb/comments{/number}","issue_comment_url":"https://api.github.com/repos/mldbai/mldb/issues/comments{/number}","contents_url":"https://api.github.com/repos/mldbai/mldb/contents/{+path}","compare_url":"https://api.github.com/repos/mldbai/mldb/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mldbai/mldb/merges","archive_url":"https://api.github.com/repos/mldbai/mldb/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mldbai/mldb/downloads","issues_url":"https://api.github.com/repos/mldbai/mldb/issues{/number}","pulls_url":"https://api.github.com/repos/mldbai/mldb/pulls{/number}","milestones_url":"https://api.github.com/repos/mldbai/mldb/milestones{/number}","notifications_url":"https://api.github.com/repos/mldbai/mldb/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mldbai/mldb/labels{/name}","releases_url":"https://api.github.com/repos/mldbai/mldb/releases{/id}","created_at":"2015-12-08T16:34:16Z","updated_at":"2016-01-13T21:27:39Z","pushed_at":"2016-01-13T23:32:44Z","git_url":"git://github.com/mldbai/mldb.git","ssh_url":"git@github.com:mldbai/mldb.git","clone_url":"https://github.com/mldbai/mldb.git","svn_url":"https://github.com/mldbai/mldb","homepage":"http://mldb.ai","size":8577,"stargazers_count":13,"watchers_count":13,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":12,"forks":1,"open_issues":12,"watchers":13,"default_branch":"master"}},"base":{"label":"mldbai:master","ref":"master","sha":"cc07f81fcb3da587011505e8a8343324e5e00636","user":{"login":"mldbai","id":11510172,"avatar_url":"https://avatars.githubusercontent.com/u/11510172?v=3","gravatar_id":"","url":"https://api.github.com/users/mldbai","html_url":"https://github.com/mldbai","followers_url":"https://api.github.com/users/mldbai/followers","following_url":"https://api.github.com/users/mldbai/following{/other_user}","gists_url":"https://api.github.com/users/mldbai/gists{/gist_id}","starred_url":"https://api.github.com/users/mldbai/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mldbai/subscriptions","organizations_url":"https://api.github.com/users/mldbai/orgs","repos_url":"https://api.github.com/users/mldbai/repos","events_url":"https://api.github.com/users/mldbai/events{/privacy}","received_events_url":"https://api.github.com/users/mldbai/received_events","type":"Organization","site_admin":false},"repo":{"id":47634692,"name":"mldb","full_name":"mldbai/mldb","owner":{"login":"mldbai","id":11510172,"avatar_url":"https://avatars.githubusercontent.com/u/11510172?v=3","gravatar_id":"","url":"https://api.github.com/users/mldbai","html_url":"https://github.com/mldbai","followers_url":"https://api.github.com/users/mldbai/followers","following_url":"https://api.github.com/users/mldbai/following{/other_user}","gists_url":"https://api.github.com/users/mldbai/gists{/gist_id}","starred_url":"https://api.github.com/users/mldbai/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mldbai/subscriptions","organizations_url":"https://api.github.com/users/mldbai/orgs","repos_url":"https://api.github.com/users/mldbai/repos","events_url":"https://api.github.com/users/mldbai/events{/privacy}","received_events_url":"https://api.github.com/users/mldbai/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/mldbai/mldb","description":"MLDB is the Machine Learning Database","fork":false,"url":"https://api.github.com/repos/mldbai/mldb","forks_url":"https://api.github.com/repos/mldbai/mldb/forks","keys_url":"https://api.github.com/repos/mldbai/mldb/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mldbai/mldb/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mldbai/mldb/teams","hooks_url":"https://api.github.com/repos/mldbai/mldb/hooks","issue_events_url":"https://api.github.com/repos/mldbai/mldb/issues/events{/number}","events_url":"https://api.github.com/repos/mldbai/mldb/events","assignees_url":"https://api.github.com/repos/mldbai/mldb/assignees{/user}","branches_url":"https://api.github.com/repos/mldbai/mldb/branches{/branch}","tags_url":"https://api.github.com/repos/mldbai/mldb/tags","blobs_url":"https://api.github.com/repos/mldbai/mldb/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mldbai/mldb/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mldbai/mldb/git/refs{/sha}","trees_url":"https://api.github.com/repos/mldbai/mldb/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mldbai/mldb/statuses/{sha}","languages_url":"https://api.github.com/repos/mldbai/mldb/languages","stargazers_url":"https://api.github.com/repos/mldbai/mldb/stargazers","contributors_url":"https://api.github.com/repos/mldbai/mldb/contributors","subscribers_url":"https://api.github.com/repos/mldbai/mldb/subscribers","subscription_url":"https://api.github.com/repos/mldbai/mldb/subscription","commits_url":"https://api.github.com/repos/mldbai/mldb/commits{/sha}","git_commits_url":"https://api.github.com/repos/mldbai/mldb/git/commits{/sha}","comments_url":"https://api.github.com/repos/mldbai/mldb/comments{/number}","issue_comment_url":"https://api.github.com/repos/mldbai/mldb/issues/comments{/number}","contents_url":"https://api.github.com/repos/mldbai/mldb/contents/{+path}","compare_url":"https://api.github.com/repos/mldbai/mldb/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mldbai/mldb/merges","archive_url":"https://api.github.com/repos/mldbai/mldb/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mldbai/mldb/downloads","issues_url":"https://api.github.com/repos/mldbai/mldb/issues{/number}","pulls_url":"https://api.github.com/repos/mldbai/mldb/pulls{/number}","milestones_url":"https://api.github.com/repos/mldbai/mldb/milestones{/number}","notifications_url":"https://api.github.com/repos/mldbai/mldb/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mldbai/mldb/labels{/name}","releases_url":"https://api.github.com/repos/mldbai/mldb/releases{/id}","created_at":"2015-12-08T16:34:16Z","updated_at":"2016-01-13T21:27:39Z","pushed_at":"2016-01-13T23:32:44Z","git_url":"git://github.com/mldbai/mldb.git","ssh_url":"git@github.com:mldbai/mldb.git","clone_url":"https://github.com/mldbai/mldb.git","svn_url":"https://github.com/mldbai/mldb","homepage":"http://mldb.ai","size":8577,"stargazers_count":13,"watchers_count":13,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":12,"forks":1,"open_issues":12,"watchers":13,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/mldbai/mldb/pulls/66"},"html":{"href":"https://github.com/mldbai/mldb/pull/66"},"issue":{"href":"https://api.github.com/repos/mldbai/mldb/issues/66"},"comments":{"href":"https://api.github.com/repos/mldbai/mldb/issues/66/comments"},"review_comments":{"href":"https://api.github.com/repos/mldbai/mldb/pulls/66/comments"},"review_comment":{"href":"https://api.github.com/repos/mldbai/mldb/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/mldbai/mldb/pulls/66/commits"},"statuses":{"href":"https://api.github.com/repos/mldbai/mldb/statuses/a088e2463b0f03ba28a61f0b271198ae8854d800"}}}}