{"action":"created","comment":{"url":"https://api.github.com/repos/vega/vega-lite/pulls/comments/186278870","pull_request_review_id":117831654,"id":186278870,"diff_hunk":"@@ -52,77 +53,85 @@ export class ParseNode extends DataFlowNode {\n     this._parse = parse;\n   }\n \n-  public static make(parent: DataFlowNode, model: Model) {\n-    const parse = {};\n-    const calcFieldMap = {};\n-\n-    (model.transforms || []).forEach((transform: Transform) => {\n-      if (isCalculate(transform)) {\n-        calcFieldMap[transform.as] = true;\n-      } else if (isFilter(transform)) {\n-        forEachLeaf(transform.filter, (filter) => {\n-          if (isFieldPredicate(filter)) {\n-            if (filter.timeUnit) {\n-              parse[filter.field] = 'date';\n-            }\n-          }\n-        });\n-      }\n-    }, {});\n+  /**\n+   * Creates a parse node from a data.format.parse and updates ancestorParse.\n+   */\n+  public static makeExplicit(parent: DataFlowNode, model: Model, ancestorParse: AncestorParse) {\n+    // Custom parse\n+    let explicit = {};\n+    const data = model.data;\n+    if (data && data.format && data.format.parse) {\n+      explicit = data.format.parse;\n+    }\n+\n+    return this.makeWithAncestors(parent, explicit, {}, ancestorParse);\n+  }\n+\n+  /**\n+   * Creates a parse node for implicit parsing from a model and updates ancestorParse.\n+   */\n+  public static makeImplicit(parent: DataFlowNode, model: Model, ancestorParse: AncestorParse) {\n+    const implicit = {};\n \n     if (isUnitModel(model) || isFacetModel(model)) {\n       // Parse encoded fields\n       model.forEachFieldDef(fieldDef => {\n         if (isTimeFieldDef(fieldDef)) {\n-          parse[fieldDef.field] = 'date';\n+          implicit[fieldDef.field] = 'date';\n         } else if (isNumberFieldDef(fieldDef)) {\n-          if (calcFieldMap[fieldDef.field] || isCountingAggregateOp(fieldDef.aggregate)) {\n+          if (isCountingAggregateOp(fieldDef.aggregate)) {\n             return;\n           }\n-          parse[fieldDef.field] = 'number';\n+          implicit[fieldDef.field] = 'number';\n         } else if (accessPathDepth(fieldDef.field) > 1) {\n           // For non-date/non-number (strings and booleans), derive a flattened field for a referenced nested field.\n           // (Parsing numbers / dates already flattens numeric and temporal fields.)\n-          parse[fieldDef.field] = 'flatten';\n+          implicit[fieldDef.field] = 'flatten';\n         }\n       });\n     }\n \n-    // Custom parse should override inferred parse\n-    const data = model.data;\n-    if (data && data.format) {\n-      const p = data.format.parse;\n-      if (p === null) {\n-        return null;  // disable parsing completely\n-      } else if (p) {\n-        keys(p).forEach(field => {\n-          parse[field] = p[field];\n-        });\n+    return this.makeWithAncestors(parent, {}, implicit, ancestorParse);\n+  }\n+\n+  /**\n+   * Creates a parse node from two sets of explicit and implicit parse and updates ancestorParse.\n+   */\n+  public static makeWithAncestors(parent: DataFlowNode, explicit: Dict<string>, implicit: Dict<string>, ancestorParse: AncestorParse) {\n+    // We should not parse what has already been parsed in a parent (explicitly or implicitly) or what has been derived (maked as \"derived\").\n+    for (const field of keys(implicit)) {\n+      const parsedAs = ancestorParse.getWithExplicit(field);\n+      if (parsedAs.value !== undefined) {\n+        // We always ignore derived fields even if they are implicitly defined because we expects users to create the right types.\n+        if (parsedAs.explicit || parsedAs.value === implicit[field] || parsedAs.value === 'derived') {\n+          delete implicit[field];\n+        } else {\n+          log.warn(log.message.differentParse(field, implicit[field], parsedAs.value));\n+        }\n       }\n     }\n \n-    // We should not parse what has already been parsed in a parent\n-    const modelParse = model.component.data.ancestorParse;\n-    keys(modelParse).forEach(field => {\n-      if (parse[field] !== modelParse[field]) {\n-        log.warn(log.message.differentParse(field, parse[field], modelParse[field]));\n+    for (const field of keys(explicit)) {\n+      const parsedAs = ancestorParse.get(field);\n+      if (parsedAs !== undefined) {\n+        if (parsedAs === explicit[field]) {\n+          delete explicit[field];\n       } else {\n-        delete parse[field];\n-      }\n-    });\n-\n-    // filter out parse == null (do not parse the field)\n-    for (const field of keys(parse)) {\n-      if (parse[field] === null) {\n-        delete parse[field];\n+          log.warn(log.message.differentParse(field, explicit[field], parsedAs));\n+        }\n       }\n     }\n \n-    if (keys(parse).length === 0) {\n+    const parse = new Split(explicit, implicit);\n+\n+    // add the format parse from this model so that children don't parse the same field again\n+    ancestorParse.copyAll(parse);","path":"src/compile/data/formatparse.ts","position":null,"original_position":159,"commit_id":"749ca5cda59b782722f1f2953aeeba8eca41a9ff","original_commit_id":"e78074f836a0a5a4b39304fdd211a8ad5fbcd0c5","user":{"login":"domoritz","id":589034,"avatar_url":"https://avatars2.githubusercontent.com/u/589034?v=4","gravatar_id":"","url":"https://api.github.com/users/domoritz","html_url":"https://github.com/domoritz","followers_url":"https://api.github.com/users/domoritz/followers","following_url":"https://api.github.com/users/domoritz/following{/other_user}","gists_url":"https://api.github.com/users/domoritz/gists{/gist_id}","starred_url":"https://api.github.com/users/domoritz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/domoritz/subscriptions","organizations_url":"https://api.github.com/users/domoritz/orgs","repos_url":"https://api.github.com/users/domoritz/repos","events_url":"https://api.github.com/users/domoritz/events{/privacy}","received_events_url":"https://api.github.com/users/domoritz/received_events","type":"User","site_admin":false},"body":"ancestorParse is not a parse node, it's an object to track what has been parsed already","created_at":"2018-05-06T05:25:20Z","updated_at":"2018-05-06T05:25:20Z","html_url":"https://github.com/vega/vega-lite/pull/3697#discussion_r186278870","pull_request_url":"https://api.github.com/repos/vega/vega-lite/pulls/3697","author_association":"OWNER","_links":{"self":{"href":"https://api.github.com/repos/vega/vega-lite/pulls/comments/186278870"},"html":{"href":"https://github.com/vega/vega-lite/pull/3697#discussion_r186278870"},"pull_request":{"href":"https://api.github.com/repos/vega/vega-lite/pulls/3697"}},"in_reply_to_id":186278618},"pull_request":{"url":"https://api.github.com/repos/vega/vega-lite/pulls/3697","id":185892821,"html_url":"https://github.com/vega/vega-lite/pull/3697","diff_url":"https://github.com/vega/vega-lite/pull/3697.diff","patch_url":"https://github.com/vega/vega-lite/pull/3697.patch","issue_url":"https://api.github.com/repos/vega/vega-lite/issues/3697","number":3697,"state":"open","locked":false,"title":"Disable format parsing and track parsed fields","user":{"login":"domoritz","id":589034,"avatar_url":"https://avatars2.githubusercontent.com/u/589034?v=4","gravatar_id":"","url":"https://api.github.com/users/domoritz","html_url":"https://github.com/domoritz","followers_url":"https://api.github.com/users/domoritz/followers","following_url":"https://api.github.com/users/domoritz/following{/other_user}","gists_url":"https://api.github.com/users/domoritz/gists{/gist_id}","starred_url":"https://api.github.com/users/domoritz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/domoritz/subscriptions","organizations_url":"https://api.github.com/users/domoritz/orgs","repos_url":"https://api.github.com/users/domoritz/repos","events_url":"https://api.github.com/users/domoritz/events{/privacy}","received_events_url":"https://api.github.com/users/domoritz/received_events","type":"User","site_admin":false},"body":"Fixes #3665.\r\n\r\nCC @saulshanabrook","created_at":"2018-05-04T04:59:03Z","updated_at":"2018-05-06T05:25:20Z","closed_at":null,"merged_at":null,"merge_commit_sha":"03d0621fd0c095c7ad4b65f33ef5770109d6fecd","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/vega/vega-lite/pulls/3697/commits","review_comments_url":"https://api.github.com/repos/vega/vega-lite/pulls/3697/comments","review_comment_url":"https://api.github.com/repos/vega/vega-lite/pulls/comments{/number}","comments_url":"https://api.github.com/repos/vega/vega-lite/issues/3697/comments","statuses_url":"https://api.github.com/repos/vega/vega-lite/statuses/749ca5cda59b782722f1f2953aeeba8eca41a9ff","head":{"label":"vega:dom/format-null","ref":"dom/format-null","sha":"749ca5cda59b782722f1f2953aeeba8eca41a9ff","user":{"login":"vega","id":11796929,"avatar_url":"https://avatars3.githubusercontent.com/u/11796929?v=4","gravatar_id":"","url":"https://api.github.com/users/vega","html_url":"https://github.com/vega","followers_url":"https://api.github.com/users/vega/followers","following_url":"https://api.github.com/users/vega/following{/other_user}","gists_url":"https://api.github.com/users/vega/gists{/gist_id}","starred_url":"https://api.github.com/users/vega/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vega/subscriptions","organizations_url":"https://api.github.com/users/vega/orgs","repos_url":"https://api.github.com/users/vega/repos","events_url":"https://api.github.com/users/vega/events{/privacy}","received_events_url":"https://api.github.com/users/vega/received_events","type":"Organization","site_admin":false},"repo":{"id":26931359,"name":"vega-lite","full_name":"vega/vega-lite","owner":{"login":"vega","id":11796929,"avatar_url":"https://avatars3.githubusercontent.com/u/11796929?v=4","gravatar_id":"","url":"https://api.github.com/users/vega","html_url":"https://github.com/vega","followers_url":"https://api.github.com/users/vega/followers","following_url":"https://api.github.com/users/vega/following{/other_user}","gists_url":"https://api.github.com/users/vega/gists{/gist_id}","starred_url":"https://api.github.com/users/vega/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vega/subscriptions","organizations_url":"https://api.github.com/users/vega/orgs","repos_url":"https://api.github.com/users/vega/repos","events_url":"https://api.github.com/users/vega/events{/privacy}","received_events_url":"https://api.github.com/users/vega/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/vega/vega-lite","description":"A concise grammar of interactive graphics, built on Vega.","fork":false,"url":"https://api.github.com/repos/vega/vega-lite","forks_url":"https://api.github.com/repos/vega/vega-lite/forks","keys_url":"https://api.github.com/repos/vega/vega-lite/keys{/key_id}","collaborators_url":"https://api.github.com/repos/vega/vega-lite/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/vega/vega-lite/teams","hooks_url":"https://api.github.com/repos/vega/vega-lite/hooks","issue_events_url":"https://api.github.com/repos/vega/vega-lite/issues/events{/number}","events_url":"https://api.github.com/repos/vega/vega-lite/events","assignees_url":"https://api.github.com/repos/vega/vega-lite/assignees{/user}","branches_url":"https://api.github.com/repos/vega/vega-lite/branches{/branch}","tags_url":"https://api.github.com/repos/vega/vega-lite/tags","blobs_url":"https://api.github.com/repos/vega/vega-lite/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/vega/vega-lite/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/vega/vega-lite/git/refs{/sha}","trees_url":"https://api.github.com/repos/vega/vega-lite/git/trees{/sha}","statuses_url":"https://api.github.com/repos/vega/vega-lite/statuses/{sha}","languages_url":"https://api.github.com/repos/vega/vega-lite/languages","stargazers_url":"https://api.github.com/repos/vega/vega-lite/stargazers","contributors_url":"https://api.github.com/repos/vega/vega-lite/contributors","subscribers_url":"https://api.github.com/repos/vega/vega-lite/subscribers","subscription_url":"https://api.github.com/repos/vega/vega-lite/subscription","commits_url":"https://api.github.com/repos/vega/vega-lite/commits{/sha}","git_commits_url":"https://api.github.com/repos/vega/vega-lite/git/commits{/sha}","comments_url":"https://api.github.com/repos/vega/vega-lite/comments{/number}","issue_comment_url":"https://api.github.com/repos/vega/vega-lite/issues/comments{/number}","contents_url":"https://api.github.com/repos/vega/vega-lite/contents/{+path}","compare_url":"https://api.github.com/repos/vega/vega-lite/compare/{base}...{head}","merges_url":"https://api.github.com/repos/vega/vega-lite/merges","archive_url":"https://api.github.com/repos/vega/vega-lite/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/vega/vega-lite/downloads","issues_url":"https://api.github.com/repos/vega/vega-lite/issues{/number}","pulls_url":"https://api.github.com/repos/vega/vega-lite/pulls{/number}","milestones_url":"https://api.github.com/repos/vega/vega-lite/milestones{/number}","notifications_url":"https://api.github.com/repos/vega/vega-lite/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/vega/vega-lite/labels{/name}","releases_url":"https://api.github.com/repos/vega/vega-lite/releases{/id}","deployments_url":"https://api.github.com/repos/vega/vega-lite/deployments","created_at":"2014-11-20T20:52:04Z","updated_at":"2018-05-06T05:17:34Z","pushed_at":"2018-05-06T05:17:32Z","git_url":"git://github.com/vega/vega-lite.git","ssh_url":"git@github.com:vega/vega-lite.git","clone_url":"https://github.com/vega/vega-lite.git","svn_url":"https://github.com/vega/vega-lite","homepage":"https://vega.github.io/vega-lite/","size":82306,"stargazers_count":1252,"watchers_count":1252,"language":"TypeScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":162,"mirror_url":null,"archived":false,"open_issues_count":213,"license":{"key":"other","name":"Other","spdx_id":null,"url":null},"forks":162,"open_issues":213,"watchers":1252,"default_branch":"master"}},"base":{"label":"vega:master","ref":"master","sha":"9c4a40291a9c5c7cf3cee3d8b9da991c5e1ff736","user":{"login":"vega","id":11796929,"avatar_url":"https://avatars3.githubusercontent.com/u/11796929?v=4","gravatar_id":"","url":"https://api.github.com/users/vega","html_url":"https://github.com/vega","followers_url":"https://api.github.com/users/vega/followers","following_url":"https://api.github.com/users/vega/following{/other_user}","gists_url":"https://api.github.com/users/vega/gists{/gist_id}","starred_url":"https://api.github.com/users/vega/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vega/subscriptions","organizations_url":"https://api.github.com/users/vega/orgs","repos_url":"https://api.github.com/users/vega/repos","events_url":"https://api.github.com/users/vega/events{/privacy}","received_events_url":"https://api.github.com/users/vega/received_events","type":"Organization","site_admin":false},"repo":{"id":26931359,"name":"vega-lite","full_name":"vega/vega-lite","owner":{"login":"vega","id":11796929,"avatar_url":"https://avatars3.githubusercontent.com/u/11796929?v=4","gravatar_id":"","url":"https://api.github.com/users/vega","html_url":"https://github.com/vega","followers_url":"https://api.github.com/users/vega/followers","following_url":"https://api.github.com/users/vega/following{/other_user}","gists_url":"https://api.github.com/users/vega/gists{/gist_id}","starred_url":"https://api.github.com/users/vega/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vega/subscriptions","organizations_url":"https://api.github.com/users/vega/orgs","repos_url":"https://api.github.com/users/vega/repos","events_url":"https://api.github.com/users/vega/events{/privacy}","received_events_url":"https://api.github.com/users/vega/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/vega/vega-lite","description":"A concise grammar of interactive graphics, built on Vega.","fork":false,"url":"https://api.github.com/repos/vega/vega-lite","forks_url":"https://api.github.com/repos/vega/vega-lite/forks","keys_url":"https://api.github.com/repos/vega/vega-lite/keys{/key_id}","collaborators_url":"https://api.github.com/repos/vega/vega-lite/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/vega/vega-lite/teams","hooks_url":"https://api.github.com/repos/vega/vega-lite/hooks","issue_events_url":"https://api.github.com/repos/vega/vega-lite/issues/events{/number}","events_url":"https://api.github.com/repos/vega/vega-lite/events","assignees_url":"https://api.github.com/repos/vega/vega-lite/assignees{/user}","branches_url":"https://api.github.com/repos/vega/vega-lite/branches{/branch}","tags_url":"https://api.github.com/repos/vega/vega-lite/tags","blobs_url":"https://api.github.com/repos/vega/vega-lite/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/vega/vega-lite/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/vega/vega-lite/git/refs{/sha}","trees_url":"https://api.github.com/repos/vega/vega-lite/git/trees{/sha}","statuses_url":"https://api.github.com/repos/vega/vega-lite/statuses/{sha}","languages_url":"https://api.github.com/repos/vega/vega-lite/languages","stargazers_url":"https://api.github.com/repos/vega/vega-lite/stargazers","contributors_url":"https://api.github.com/repos/vega/vega-lite/contributors","subscribers_url":"https://api.github.com/repos/vega/vega-lite/subscribers","subscription_url":"https://api.github.com/repos/vega/vega-lite/subscription","commits_url":"https://api.github.com/repos/vega/vega-lite/commits{/sha}","git_commits_url":"https://api.github.com/repos/vega/vega-lite/git/commits{/sha}","comments_url":"https://api.github.com/repos/vega/vega-lite/comments{/number}","issue_comment_url":"https://api.github.com/repos/vega/vega-lite/issues/comments{/number}","contents_url":"https://api.github.com/repos/vega/vega-lite/contents/{+path}","compare_url":"https://api.github.com/repos/vega/vega-lite/compare/{base}...{head}","merges_url":"https://api.github.com/repos/vega/vega-lite/merges","archive_url":"https://api.github.com/repos/vega/vega-lite/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/vega/vega-lite/downloads","issues_url":"https://api.github.com/repos/vega/vega-lite/issues{/number}","pulls_url":"https://api.github.com/repos/vega/vega-lite/pulls{/number}","milestones_url":"https://api.github.com/repos/vega/vega-lite/milestones{/number}","notifications_url":"https://api.github.com/repos/vega/vega-lite/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/vega/vega-lite/labels{/name}","releases_url":"https://api.github.com/repos/vega/vega-lite/releases{/id}","deployments_url":"https://api.github.com/repos/vega/vega-lite/deployments","created_at":"2014-11-20T20:52:04Z","updated_at":"2018-05-06T05:17:34Z","pushed_at":"2018-05-06T05:17:32Z","git_url":"git://github.com/vega/vega-lite.git","ssh_url":"git@github.com:vega/vega-lite.git","clone_url":"https://github.com/vega/vega-lite.git","svn_url":"https://github.com/vega/vega-lite","homepage":"https://vega.github.io/vega-lite/","size":82306,"stargazers_count":1252,"watchers_count":1252,"language":"TypeScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":162,"mirror_url":null,"archived":false,"open_issues_count":213,"license":{"key":"other","name":"Other","spdx_id":null,"url":null},"forks":162,"open_issues":213,"watchers":1252,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/vega/vega-lite/pulls/3697"},"html":{"href":"https://github.com/vega/vega-lite/pull/3697"},"issue":{"href":"https://api.github.com/repos/vega/vega-lite/issues/3697"},"comments":{"href":"https://api.github.com/repos/vega/vega-lite/issues/3697/comments"},"review_comments":{"href":"https://api.github.com/repos/vega/vega-lite/pulls/3697/comments"},"review_comment":{"href":"https://api.github.com/repos/vega/vega-lite/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/vega/vega-lite/pulls/3697/commits"},"statuses":{"href":"https://api.github.com/repos/vega/vega-lite/statuses/749ca5cda59b782722f1f2953aeeba8eca41a9ff"}},"author_association":"OWNER"}}
{"actor":{"display_login":"domoritz"}}