<br />
<b>Warning</b>:  The magic method SFML_Singleton::__wakeup() must have public visibility in <b>/home/public/wp-content/plugins/sf-move-login/inc/classes/class-sfml-singleton.php</b> on line <b>72</b><br />
{"id":44,"date":"2015-05-28T15:40:16","date_gmt":"2015-05-28T21:40:16","guid":{"rendered":"http:\/\/www.munderwood.ca\/?p=44"},"modified":"2016-09-14T13:24:05","modified_gmt":"2016-09-14T19:24:05","slug":"altering-postgresql-columns-from-one-enum-to-another","status":"publish","type":"post","link":"https:\/\/www.munderwood.ca\/index.php\/2015\/05\/28\/altering-postgresql-columns-from-one-enum-to-another\/","title":{"rendered":"Altering PostgreSQL columns from one enum to another"},"content":{"rendered":"<p>Altering the type of a column in postgres from one enum type to another requires an intermediate cast to\u00a0<span class=\"theme:tomorrow lang:default decode:true crayon-inline\">text<\/span>. Additionally, if there is a default value for the field, it cannot be altered and instead must be dropped and re-added as the new type.<\/p>\n<h2>Simple case: New type contains all old-type values<\/h2>\n<p>In the simple version, the new enum type contains (at least) all of the same labels\u00a0as the old one. For instance, as with these two:<\/p>\n<pre class=\"lang:pgsql decode:true\">CREATE TYPE old_enum AS ENUM ('a', 'b', 'c', 'd');\r\nCREATE TYPE new_enum AS ENUM ('a', 'b', 'c', 'd', 'e');<\/pre>\n<h3>No default on column<\/h3>\n<p>If a table has an <span class=\"theme:tomorrow lang:default decode:true crayon-inline \">old_enum<\/span>\u00a0column and we want to turn it into a <span class=\"theme:tomorrow lang:default decode:true crayon-inline \">new_enum<\/span>\u00a0one, with no default value in place on the column, we can use the following command:<\/p>\n<pre class=\"lang:pgsql mark:4 decode:true\">ALTER TABLE table_name\r\n  ALTER COLUMN column_name\r\n    SET DATA TYPE new_enum\r\n    USING column_name::text::new_enum;<\/pre>\n<p>The <span class=\"theme:tomorrow lang:default decode:true crayon-inline \">USING<\/span>\u00a0expression casts the current value of <span class=\"theme:tomorrow lang:default decode:true crayon-inline \">column_name<\/span>\u00a0to <span class=\"theme:tomorrow lang:default decode:true crayon-inline\">text<\/span>, and then to <span class=\"theme:tomorrow lang:default decode:true crayon-inline\">new_enum<\/span>. This works because\u00a0every allowed value of the first enum type exists in the second.<\/p>\n<h3>With a default value<\/h3>\n<p>This case is not significantly more difficult to deal with. If there is a default value on the column, we simply remove it before altering the enum type of the column, and then add a new one when we&#8217;re done:<\/p>\n<pre class=\"lang:pgsql mark:2,6 decode:true\">ALTER TABLE table_name\r\n  ALTER COLUMN column_name DROP DEFAULT,\r\n  ALTER COLUMN column_name\r\n    SET DATA TYPE new_enum\r\n    USING column_name::text::new_enum,\r\n  ALTER COLUMN column_name SET DEFAULT 'a';\r\n<\/pre>\n<h2>Converting enum\u00a0labels<\/h2>\n<p>A more complicated scenario arises when not all of the old labels appear in the new enum. I&#8217;ll assume that there is a mapping from the old ones to the new, at least for every label that is known to appear in a row of the table. If there isn&#8217;t, then the conversion is probably not a good idea in the first place.<\/p>\n<p>Consider now an even newer type,<\/p>\n<pre class=\"lang:pgsql decode:true\">CREATE TYPE newer_enum AS ENUM ('alpha', 'beta', 'c', 'd', 'e');<\/pre>\n<p>We still want to convert from the <span class=\"theme:tomorrow lang:default decode:true crayon-inline\">old_enum<\/span>\u00a0type, but now we also want to map the label &#8216;a&#8217; to &#8216;alpha&#8217;, and &#8216;b&#8217; to &#8216;beta&#8217;, while leaving &#8216;c&#8217; and &#8216;d&#8217; alone. This can be accomplished by manually applying each required change via a <span class=\"theme:tomorrow lang:default decode:true crayon-inline \">CASE<\/span>\u00a0 statement in the <span class=\"theme:tomorrow lang:default decode:true crayon-inline \">USING<\/span>\u00a0 expression:<\/p>\n<pre class=\"lang:pgsql mark:6-9 decode:true\">ALTER TABLE table_name\r\n  ALTER COLUMN column_name DROP DEFAULT,\r\n  ALTER COLUMN column_name\r\n    SET DATA TYPE newer_enum\r\n    USING (\r\n      CASE column_name::text\r\n        WHEN 'a' THEN 'alpha'\r\n        WHEN 'b' THEN 'beta'\r\n        ELSE column_name::text\r\n      END CASE\r\n    )::newer_enum,\r\n  ALTER COLUMN column_name SET DEFAULT 'alpha';<\/pre>\n<p>For each record, this statement returns &#8216;alpha&#8217; or &#8216;beta&#8217; if the column contains &#8216;a&#8217; or &#8216;b&#8217;, respectively, or otherwise returns the current value in the column cast as text. The returned value in all cases is then cast to the newer enum type.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Altering the type of a column in postgres from one enum type to another requires an intermediate cast to\u00a0text. Additionally, if there is a default value for the field, it cannot be altered and instead must be dropped and re-added as the new type. Simple case: New type contains all old-type values In the simple &#8230; <span class=\"more\"><a class=\"more-link\" href=\"https:\/\/www.munderwood.ca\/index.php\/2015\/05\/28\/altering-postgresql-columns-from-one-enum-to-another\/\">[Read more&#8230;]<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/www.munderwood.ca\/index.php\/wp-json\/wp\/v2\/posts\/44"}],"collection":[{"href":"https:\/\/www.munderwood.ca\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.munderwood.ca\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.munderwood.ca\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.munderwood.ca\/index.php\/wp-json\/wp\/v2\/comments?post=44"}],"version-history":[{"count":4,"href":"https:\/\/www.munderwood.ca\/index.php\/wp-json\/wp\/v2\/posts\/44\/revisions"}],"predecessor-version":[{"id":92,"href":"https:\/\/www.munderwood.ca\/index.php\/wp-json\/wp\/v2\/posts\/44\/revisions\/92"}],"wp:attachment":[{"href":"https:\/\/www.munderwood.ca\/index.php\/wp-json\/wp\/v2\/media?parent=44"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.munderwood.ca\/index.php\/wp-json\/wp\/v2\/categories?post=44"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.munderwood.ca\/index.php\/wp-json\/wp\/v2\/tags?post=44"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}