{"id":1043,"date":"2004-08-13T06:18:00","date_gmt":"2004-08-13T06:18:00","guid":{"rendered":"\/blogs\/bobb\/post\/UDTs-and-UDAggs-Serialization-and-Construction.aspx"},"modified":"2013-01-04T00:01:27","modified_gmt":"2013-01-04T08:01:27","slug":"udts-and-udaggs-serialization-and-construction","status":"publish","type":"post","link":"https:\/\/www.sqlskills.com\/blogs\/bobb\/udts-and-udaggs-serialization-and-construction\/","title":{"rendered":"UDTs and UDAggs &#8211; Serialization and Construction"},"content":{"rendered":"<p>\nI was talking with <a href=\"http:\/\/www.danal.com\" class=\"broken_link\">Dan Sullivan<\/a> this week about UDTs in SQL Server 2005 and he&#39;s made an interesting discovery. About a week ago, I&#39;d happened to mention to Dan that UDTs and UDAggs (user-defined aggregates) are supposed to have a pattern of &quot;deserialize-do action-serialize&quot;. He thought I&#39;d misunderstood. Then he went off to write an improved UDT\/UDAgg for his talk at <a href=\"http:\/\/www.corpedgroup.com\/\">Windev<\/a>. Dan has an engineering background and is excited about using UDTs for data types like Linear Dimension (he wrote the LDim example in <a href=\"http:\/\/www.informit.com\/imprint\/index.aspx?st=61085&amp;aspxerrorpath=\/IsbnHandler.ashx\">our book<\/a>).\n<\/p>\n<p>\nWhat Dan discovered in attempting to implement some initialization inside the constructor is that, inside SQL Server operations, the constructor is never called! His UDT used Format.UserDefined, which means he implements the IBinarySerialize interface to Read and Write the UDT state. The engine just allocates some bare memory for an instance&nbsp;with the IL &ldquo;newobj&rdquo; instruction, then calls IBinarySerialize.Read to fill it out. What this means is that any internal fields that you would initialize inside a constructor must also be initialized when IBinarySerialize.Read is called as well. Dan found this out the hard way, reference types he&#39;d expected to be initialized in the constructor were null when Read is called.\n<\/p>\n<p>\nHe&#39;s made a common implementation pattern in his UDTs: always have an Initialize or Init method and call it both in the constructor (for &quot;ordinary&quot; or client usage) and in IBinarySerialize.Read (for use inside SQL Server 2005). A good thing to keep in mind if you&#39;re writing a UDT.\n<\/p>\n<p>\nWhen I asked if this wasn&#39;t against the &quot;rules&quot;, his response was that C# always calls the constructor after newobj, but it&#39;s not a .NET requirement. <a href=\"http:\/\/www.drdobbs.com\/database\/\" class=\"broken_link\">Niels Berglund<\/a> mentioned that this behavior is also true in Format.Native too, but all its fields are value types, so they are all initialized to zero by the runtime.\n<\/p>\n<p>\nNiels also mentioned an interesting pattern he observed by tracing through a UDAgg he&#39;d written with Format.UserDefined.UDAggs implement an Init() method instead of a constructor so that instances can be reused, for example in GROUP BY statements. The pattern Niels observed was:\n<\/p>\n<p>\n1. Init<br \/>\n2. Write (but Accumulate hasn&#39;t been called yet)<br \/>\n3. Read-Accumulate-Write (for each row processed)<br \/>\n4. Read-Terminate\n<\/p>\n<p>\nThis pattern had puzzled him at the time, but alongside Dan&#39;s UDT observations this makes sense. I&#39;d originally thought that the Read-Accumulate-Write pattern was for parallel processing, but it always happens even on a single processor. At this point we&#39;re all thinking it might a hedge based on how thread scheduling works in SQL Server.\n<\/p>\n<p>\nSo don&#39;t forget Dan&#39;s &quot;Initialize in Read or constructor&quot; pattern when you write Format.UserDefined UDTs. I think I have the good fortune to work with some pretty observant folks.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I was talking with Dan Sullivan this week about UDTs in SQL Server 2005 and he&#39;s made an interesting discovery. About a week ago, I&#39;d happened to mention to Dan that UDTs and UDAggs (user-defined aggregates) are supposed to have a pattern of &quot;deserialize-do action-serialize&quot;. He thought I&#39;d misunderstood. Then he went off to write [&hellip;]<\/p>\n","protected":false},"author":7,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[28,38],"tags":[],"class_list":["post-1043","post","type-post","status-publish","format-standard","hentry","category-sql-server-2005","category-sqlclr"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v21.9.1 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>UDTs and UDAggs - Serialization and Construction - Bob Beauchemin<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.sqlskills.com\/blogs\/bobb\/udts-and-udaggs-serialization-and-construction\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"UDTs and UDAggs - Serialization and Construction - Bob Beauchemin\" \/>\n<meta property=\"og:description\" content=\"I was talking with Dan Sullivan this week about UDTs in SQL Server 2005 and he&#039;s made an interesting discovery. About a week ago, I&#039;d happened to mention to Dan that UDTs and UDAggs (user-defined aggregates) are supposed to have a pattern of &quot;deserialize-do action-serialize&quot;. He thought I&#039;d misunderstood. Then he went off to write [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.sqlskills.com\/blogs\/bobb\/udts-and-udaggs-serialization-and-construction\/\" \/>\n<meta property=\"og:site_name\" content=\"Bob Beauchemin\" \/>\n<meta property=\"article:published_time\" content=\"2004-08-13T06:18:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2013-01-04T08:01:27+00:00\" \/>\n<meta name=\"author\" content=\"Bob Beauchemin\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Bob Beauchemin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"2 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/udts-and-udaggs-serialization-and-construction\/\",\"url\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/udts-and-udaggs-serialization-and-construction\/\",\"name\":\"UDTs and UDAggs - Serialization and Construction - Bob Beauchemin\",\"isPartOf\":{\"@id\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/#website\"},\"datePublished\":\"2004-08-13T06:18:00+00:00\",\"dateModified\":\"2013-01-04T08:01:27+00:00\",\"author\":{\"@id\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/#\/schema\/person\/62bfa986c5b5d28fcffd8b4fc409c73e\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/udts-and-udaggs-serialization-and-construction\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.sqlskills.com\/blogs\/bobb\/udts-and-udaggs-serialization-and-construction\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/udts-and-udaggs-serialization-and-construction\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"SQL Server 2005\",\"item\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/category\/sql-server-2005\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"UDTs and UDAggs &#8211; Serialization and Construction\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/#website\",\"url\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/\",\"name\":\"Bob Beauchemin\",\"description\":\"SQL Server Blog\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/#\/schema\/person\/62bfa986c5b5d28fcffd8b4fc409c73e\",\"name\":\"Bob Beauchemin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/6f80e6cc667410857fa6a21931dc528b8092f4d112bf7a8ff7c267674d44ee37?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/6f80e6cc667410857fa6a21931dc528b8092f4d112bf7a8ff7c267674d44ee37?s=96&d=mm&r=g\",\"caption\":\"Bob Beauchemin\"},\"sameAs\":[\"http:\/www.sqlskills.com\/blogs\/bobb\/\"],\"url\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/author\/bobb\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"UDTs and UDAggs - Serialization and Construction - Bob Beauchemin","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.sqlskills.com\/blogs\/bobb\/udts-and-udaggs-serialization-and-construction\/","og_locale":"en_US","og_type":"article","og_title":"UDTs and UDAggs - Serialization and Construction - Bob Beauchemin","og_description":"I was talking with Dan Sullivan this week about UDTs in SQL Server 2005 and he&#39;s made an interesting discovery. About a week ago, I&#39;d happened to mention to Dan that UDTs and UDAggs (user-defined aggregates) are supposed to have a pattern of &quot;deserialize-do action-serialize&quot;. He thought I&#39;d misunderstood. Then he went off to write [&hellip;]","og_url":"https:\/\/www.sqlskills.com\/blogs\/bobb\/udts-and-udaggs-serialization-and-construction\/","og_site_name":"Bob Beauchemin","article_published_time":"2004-08-13T06:18:00+00:00","article_modified_time":"2013-01-04T08:01:27+00:00","author":"Bob Beauchemin","twitter_misc":{"Written by":"Bob Beauchemin","Est. reading time":"2 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.sqlskills.com\/blogs\/bobb\/udts-and-udaggs-serialization-and-construction\/","url":"https:\/\/www.sqlskills.com\/blogs\/bobb\/udts-and-udaggs-serialization-and-construction\/","name":"UDTs and UDAggs - Serialization and Construction - Bob Beauchemin","isPartOf":{"@id":"https:\/\/www.sqlskills.com\/blogs\/bobb\/#website"},"datePublished":"2004-08-13T06:18:00+00:00","dateModified":"2013-01-04T08:01:27+00:00","author":{"@id":"https:\/\/www.sqlskills.com\/blogs\/bobb\/#\/schema\/person\/62bfa986c5b5d28fcffd8b4fc409c73e"},"breadcrumb":{"@id":"https:\/\/www.sqlskills.com\/blogs\/bobb\/udts-and-udaggs-serialization-and-construction\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.sqlskills.com\/blogs\/bobb\/udts-and-udaggs-serialization-and-construction\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.sqlskills.com\/blogs\/bobb\/udts-and-udaggs-serialization-and-construction\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.sqlskills.com\/blogs\/bobb\/"},{"@type":"ListItem","position":2,"name":"SQL Server 2005","item":"https:\/\/www.sqlskills.com\/blogs\/bobb\/category\/sql-server-2005\/"},{"@type":"ListItem","position":3,"name":"UDTs and UDAggs &#8211; Serialization and Construction"}]},{"@type":"WebSite","@id":"https:\/\/www.sqlskills.com\/blogs\/bobb\/#website","url":"https:\/\/www.sqlskills.com\/blogs\/bobb\/","name":"Bob Beauchemin","description":"SQL Server Blog","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.sqlskills.com\/blogs\/bobb\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.sqlskills.com\/blogs\/bobb\/#\/schema\/person\/62bfa986c5b5d28fcffd8b4fc409c73e","name":"Bob Beauchemin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.sqlskills.com\/blogs\/bobb\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/6f80e6cc667410857fa6a21931dc528b8092f4d112bf7a8ff7c267674d44ee37?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/6f80e6cc667410857fa6a21931dc528b8092f4d112bf7a8ff7c267674d44ee37?s=96&d=mm&r=g","caption":"Bob Beauchemin"},"sameAs":["http:\/www.sqlskills.com\/blogs\/bobb\/"],"url":"https:\/\/www.sqlskills.com\/blogs\/bobb\/author\/bobb\/"}]}},"_links":{"self":[{"href":"https:\/\/www.sqlskills.com\/blogs\/bobb\/wp-json\/wp\/v2\/posts\/1043","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.sqlskills.com\/blogs\/bobb\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.sqlskills.com\/blogs\/bobb\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.sqlskills.com\/blogs\/bobb\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/www.sqlskills.com\/blogs\/bobb\/wp-json\/wp\/v2\/comments?post=1043"}],"version-history":[{"count":0,"href":"https:\/\/www.sqlskills.com\/blogs\/bobb\/wp-json\/wp\/v2\/posts\/1043\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.sqlskills.com\/blogs\/bobb\/wp-json\/wp\/v2\/media?parent=1043"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sqlskills.com\/blogs\/bobb\/wp-json\/wp\/v2\/categories?post=1043"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sqlskills.com\/blogs\/bobb\/wp-json\/wp\/v2\/tags?post=1043"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}